Open a folder chip on its folder, in the folder that really holds it

A bot's folder chip went to bare /admin/files instead of the folder it
named, and even once there the computer volume pointed at the wrong
directory, so the folder a bot linked to looked empty.

The chip lost its folder because folderRefUrl only accepted a ref's
volume name (computer) while the chip hands it the browser's
(computers), so storageVolumeFromRef found nothing and the whole query
was dropped. Both spellings resolve now, through parseStorageSpec, so a
bad owner falls back cleanly instead of emitting owner=0.

The deeper bug: a computer's home was assumed to be
DATA_DIR/computers/<id>, but on a bind mount it can be anywhere on the
docker host, and a computer the app didn't provision (the main one on a
server reached at MAIN_COMPUTER_URL, i.e. a dev server outside docker)
records nothing at all. resolveComputerHomeDir holds the precedence:
the directory provisionComputer actually bound in
(containers.metadata.data_dir), else the new MAIN_COMPUTER_DATA_DIR app
setting for the main computer, else the conventional folder.

A path that isn't on disk also no longer reads as an empty folder:
listStorageEntries reports it as missing and the page says so, so a
stale folder link can't look like a folder nothing has written yet.
This commit is contained in:
2026-10-22 10:57:14 +01:00
parent 841149921b
commit fd75111bb1
13 changed files with 329 additions and 17 deletions
+14 -2
View File
@@ -10,6 +10,8 @@
* name's extension: the ref says which one it is.
*/
import {
isStorageVolume,
parseStorageSpec,
StorageBrowserPath,
storageSpecHref,
storageVolumeFromRef,
@@ -96,11 +98,21 @@ export function parseFolderRefHref({
/**
* Where a folder ref opens: the files browser, on that folder. A volume the
* browser doesn't know lands on its first folder.
*
* Both spellings of a volume come through here: a ref names it the way a
* bot writes it (`computer`), the files browser the way it stores it
* (`computers`). Either one resolves, so a chip never loses its folder and
* drops back to the files browser's first folder.
*/
export function folderRefUrl({ volume, owner_id, path }: RefParams) {
const known = storageVolumeFromRef({ name: volume });
const from_ref = storageVolumeFromRef({ name: volume });
const known = from_ref || (isStorageVolume(volume) ? volume : null);
if (!known) return StorageBrowserPath;
return storageSpecHref({ spec: { volume: known, owner_id: Number(owner_id) }, path });
const spec = parseStorageSpec({ volume: known, owner_id });
if (!spec) return StorageBrowserPath;
return storageSpecHref({ spec, path });
}