From 1da58e5231ba25e959a90885866fae662f3696ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Sat, 29 Aug 2026 09:01:41 +0100 Subject: [PATCH] an embedded browser can put its folder in a query param MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `urlPath` was the wrong tool and I reached for it because it was there. it owns the URL's PATHNAME — reads the folder out of `location.pathname`, navigates to `/files/` — which is correct for the Files screen, because that screen IS that route, and catastrophic in a panel: opening a folder in the fofos Media section took the whole app to /files. so an embedder gets its own mechanism rather than a shared one bent to fit. `pathParam` names a SEARCH param and never touches the pathname. three sources of the current folder now, mutually exclusive by construction: the pathname for /files, a named query param for an embedder, component state for an ordinary panel. two details that are not obvious and would each be a bug: a param naming a folder OUTSIDE `basePath` is ignored rather than obeyed. it arrives from a URL somebody may have edited, and the jail is the whole promise of an embedded browser — a shared link must not be a way through it. the base folder is the ABSENCE of the param, not a value. so a link to the top of an embedded browser is the plain screen URL, and nothing accumulates in the query string for having done nothing. written with `replace`, because browsing folders is not navigation anybody wants twenty back-button presses of. Co-Authored-By: Claude Opus 5 Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043 --- .../FileBrowserApp/FileBrowserApp.tsx | 18 +++++++++++++++-- .../FileBrowserApp/useFileBrowserApp.ts | 20 ++++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/FileBrowserApp.tsx b/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/FileBrowserApp.tsx index d84356c7..e4392a25 100644 --- a/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/FileBrowserApp.tsx +++ b/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/FileBrowserApp.tsx @@ -13,6 +13,13 @@ type FileBrowserAppProps = { rootOverride?: string; /** What the root crumb is called. Defaults to the base folder's own name. */ rootLabel?: string; + /** + * Keep the current folder in this query param, on the route you are already on. + * + * For an embedded browser that wants a reloadable, shareable location. NOT `urlPath`, which owns the + * pathname and navigates to `/files` — passing that from a panel takes the whole app with it. + */ + pathParam?: string; /** Put the current folder in `?path=`. Opt-in — only the /files screen is guaranteed one browser. */ urlPath?: boolean; /** @@ -22,8 +29,15 @@ type FileBrowserAppProps = { panelId?: string; }; -export const FileBrowserApp = ({ basePath = '/', rootOverride, rootLabel, urlPath, panelId }: FileBrowserAppProps) => { - const fileBrowserManager = useFileBrowserApp(basePath, rootOverride, urlPath, panelId); +export const FileBrowserApp = ({ + basePath = '/', + rootOverride, + rootLabel, + urlPath, + panelId, + pathParam, +}: FileBrowserAppProps) => { + const fileBrowserManager = useFileBrowserApp(basePath, rootOverride, urlPath, panelId, pathParam); const { handleNavigate } = fileBrowserManager; return ( diff --git a/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/useFileBrowserApp.ts b/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/useFileBrowserApp.ts index b209a597..616bb5a6 100644 --- a/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/useFileBrowserApp.ts +++ b/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/useFileBrowserApp.ts @@ -24,7 +24,25 @@ import { useTranslation } from '../../../locales'; */ export const FILES_PATH_PARAM = 'path'; -export const useFileBrowserApp = (basePath: string, rootOverride?: string, urlPath = false, panelId?: string) => { +/** + * `pathParam` — keep the current folder in a QUERY PARAM, on whatever route we are already on. + * + * This is not `urlPath` and must not be confused with it. `urlPath` owns the URL's PATHNAME: it reads + * the folder out of `location.pathname` and navigates to `/files/`. That is correct for the + * Files screen, which IS that route, and catastrophic inside a panel — a plugin passing `urlPath` + * navigated the whole app to /files the moment anybody opened a folder. + * + * So an embedder gets its own mechanism: a named search param, written with `replace` so browsing does + * not fill the back stack, and no pathname involved at all. A reload lands where you were and the link + * can be sent to somebody, which is what was actually wanted. + */ +export const useFileBrowserApp = ( + basePath: string, + rootOverride?: string, + urlPath = false, + panelId?: string, + pathParam?: string, +) => { const { t } = useTranslation(); const { user } = useAuth(); const navigate = useNavigate();