{}}>
{
- dashResponse.setWorkspace(org.id);
- close();
- }}
+ href={`/dash/org?org=${org.id}`}
+ onClick={() => close()}
>
diff --git a/client/www/pages/dash/index.tsx b/client/www/pages/dash/index.tsx
index 9b73e941f4..9d8afdf0c0 100644
--- a/client/www/pages/dash/index.tsx
+++ b/client/www/pages/dash/index.tsx
@@ -282,6 +282,24 @@ function Dashboard() {
...(cliOauthTicket ? { [cliOauthParamName]: cliOauthTicket } : {}),
};
+ // Build the canonical /dash query. `org` is how the workspace lives in the
+ // URL, so it's always included for an org workspace and no call site has to
+ // remember it. Defaults to the current workspace; pass `workspace` to target
+ // another. Hand the result to router.replace/push.
+ const dashQueryParams = (input?: {
+ app?: string;
+ tab?: string;
+ workspace?: string | 'personal';
+ }) => {
+ const workspace = input?.workspace ?? fetchedDash.data.currentWorkspaceId;
+ return {
+ s: 'main',
+ ...(input?.app ? { app: input.app } : {}),
+ t: input?.tab ?? tab,
+ ...(workspace !== 'personal' ? { org: workspace } : {}),
+ };
+ };
+
// Local states
const [hideAppId, setHideAppId] = useLocalStorage('hide_app_id', false);
@@ -340,13 +358,7 @@ function Dashboard() {
useEffect(() => {
if (!app) return;
if (!router.query.app || !router.query.t) {
- router.replace({
- query: {
- s: 'main',
- app: app.id,
- t: tab,
- },
- });
+ router.replace({ query: dashQueryParams({ app: app.id }) });
}
}, [app, router.query.app]);
@@ -370,13 +382,7 @@ function Dashboard() {
const replaceDefault = () => {
if (!defaultAppId) return;
- router.replace({
- query: {
- s: 'main',
- app: defaultAppId,
- t: tab,
- },
- });
+ router.replace({ query: dashQueryParams({ app: defaultAppId }) });
setLocallySavedApp({
id: defaultAppId,
@@ -399,19 +405,17 @@ function Dashboard() {
dashResponse.data?.currentWorkspaceId &&
dashResponse.data?.currentWorkspaceId !== 'personal'
) {
- dashResponse.setWorkspace('personal');
+ // The app is personally owned; follow it to the personal account.
+ router.replace({
+ query: dashQueryParams({ app: appId, workspace: 'personal' }),
+ });
} else if (
res?.app?.org_id &&
res?.app?.org_id !== router.query.org
) {
- dashResponse.setWorkspace(res.app.org_id);
+ // The app lives in another org; follow it there.
router.replace({
- query: {
- s: 'main',
- app: appId,
- org: res?.app?.org_id,
- t: tab,
- },
+ query: dashQueryParams({ app: appId, workspace: res.app.org_id }),
});
} else {
replaceDefault();
@@ -470,9 +474,7 @@ function Dashboard() {
}
router
- .push({
- query: q,
- })
+ .push({ query: dashQueryParams({ app: q.app, tab: q.t }) })
.then(() => {
if (opts?.cb) {
opts.cb();
@@ -537,10 +539,14 @@ function Dashboard() {
}
if (apps.length === 0) {
+ const workspaceId = dashResponse.data.currentWorkspaceId;
router.replace(
{
pathname: '/dash/new',
- query: cliTicketQuery,
+ query: {
+ ...cliTicketQuery,
+ ...(workspaceId !== 'personal' ? { org: workspaceId } : {}),
+ },
},
undefined,
{ shallow: true },
@@ -1035,10 +1041,11 @@ function AppCombobox({
appId: string;
tab: MainTabId;
}) {
+ const workspaceId = useFetchedDash().data.currentWorkspaceId;
const currentApp = apps.find((a) => a.id === appId) || null;
const [appQuery, setAppQuery] = useState('');
const [pinnedIds, setPinnedIds] = useState(() =>
- getPinnedAppIds(localStorage.getItem('workspace')),
+ getPinnedAppIds(workspaceId),
);
const comboboxInputRef = useRef(null);
@@ -1126,9 +1133,8 @@ function AppCombobox({
onPointerDown={(e) => {
e.preventDefault();
e.stopPropagation();
- const wsId = localStorage.getItem('workspace');
- togglePinnedApp(app.id, wsId);
- setPinnedIds(getPinnedAppIds(wsId));
+ togglePinnedApp(app.id, workspaceId);
+ setPinnedIds(getPinnedAppIds(workspaceId));
}}
title={isPinned ? 'Unpin app' : 'Pin app to top'}
>