Translate the older FileNode rights, so Rename and Delete work again

Deleting a file did nothing on the live 0.15.5 server, with no error: the menu
items are gated on myRights.mayDelete and myRights.mayRename, and 0.16 was the
release that split rights up. Before it a node carried mayRead, mayWrite and
mayShare, with the one mayWrite covering everything the newer release names
separately — so both items sat permanently disabled.

Widen mayWrite into the four rights the newer shape names, alongside the
nodeType normalisation, and the UI can keep reading the 0.16 vocabulary.
This commit is contained in:
2026-08-24 09:56:53 -07:00
parent ee7542fd86
commit b8263aa785
4 changed files with 68 additions and 14 deletions
+22 -4
View File
@@ -43,12 +43,30 @@ export function fileCreate(parentId: Id | null, name: string, blobId: Id, type:
}
/**
* Fill in `nodeType` where the server does not report it, so everything
* downstream — icons, sorting, "is this a folder" — can rely on it.
* Fill in what an older server does not report, so everything downstream —
* icons, sorting, "may I delete this" — can read the 0.16 shape.
*
* Rights were split up in 0.16. Before that a node carried `mayRead`,
* `mayWrite` and `mayShare`, with the one `mayWrite` covering everything the
* newer release names separately. Without translating it, the Rename and
* Delete menu items sit permanently greyed out: no error, just nothing.
*/
export function withNodeType<T extends Partial<FileNode>>(nodes: T[]): T[] {
export function normalizeFileNodes<T extends Partial<FileNode>>(nodes: T[]): T[] {
if (supportsNodeType()) return nodes;
return nodes.map((n) => (n.nodeType ? n : { ...n, nodeType: isFile(n) ? "file" : "directory" }));
return nodes.map((n) => ({
...n,
nodeType: n.nodeType ?? (isFile(n) ? "file" : "directory"),
myRights: widenRights(n.myRights),
}));
}
type Rights = FileNode["myRights"];
function widenRights(rights: Rights | undefined): Rights | undefined {
if (!rights) return rights;
const r = rights as Rights & { mayWrite?: boolean };
if (r.mayDelete !== undefined || r.mayWrite === undefined) return rights; // already the newer shape
return { ...r, mayAddChildren: r.mayWrite, mayRename: r.mayWrite, mayDelete: r.mayWrite, mayModifyContent: r.mayWrite };
}
function isFile(n: Partial<FileNode>): boolean {