projects: drive list selection from a ?selected= url param, not a global
mirror of the dashboards change: the /projects list row was a <div onClick> setting SELECTED_PROJECT (a global) with no url change on-page. selection now lives in the url as ?selected=<id>, read by the list, the screen (mobile panel), and the preview. rows are real <Link>s (publish/edit/delete kept as sibling buttons); edit-save and delete update/clear the param; NewProjectRedirect drops its now-redundant setSelected. NOT runtime-tested yet (server not restarted) — verify /projects preview, create/edit/delete/publish, and mobile panel flows on next restart. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,6 @@ import { useDashboardState } from 'state/useDashboardState';
|
||||
import type { LayoutNode, ProjectType } from 'officerdev';
|
||||
import {
|
||||
WorkspaceView,
|
||||
SELECTED_PROJECT,
|
||||
CREATING_PROJECT,
|
||||
EDITING_PROJECT,
|
||||
NEW_PROJ_NAME,
|
||||
@@ -22,7 +21,9 @@ import { defaultLayout } from './defaultLayout';
|
||||
export const ProjectListScreen = () => {
|
||||
const workspace = useDashboardState<LayoutNode>('screens/projects', defaultLayout);
|
||||
const isMobile = useIsMobile();
|
||||
const [selected, setSelected] = useGlobal<string | null>(SELECTED_PROJECT, null);
|
||||
// Selection lives in the URL (?selected=<id>); on mobile it (or an active create) drives the panel shown.
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const selected = searchParams.get('selected');
|
||||
const [creating] = useGlobal<boolean>(CREATING_PROJECT, false);
|
||||
const mobilePanelId = isMobile && (selected || creating) ? 'proj-home-right' : undefined;
|
||||
|
||||
@@ -33,7 +34,14 @@ export const ProjectListScreen = () => {
|
||||
locked
|
||||
mobilePanelId={mobilePanelId}
|
||||
onMobilePanelChange={(id) => {
|
||||
if (!id) setSelected(null);
|
||||
if (!id)
|
||||
setSearchParams(
|
||||
(p) => {
|
||||
p.delete('selected');
|
||||
return p;
|
||||
},
|
||||
{ replace: true },
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -48,13 +56,12 @@ export const NewProjectRedirect = () => {
|
||||
const [, setTemplateIdx] = useGlobal<number>(NEW_PROJ_TEMPLATE, 0);
|
||||
const [, setCreating] = useGlobal<boolean>(CREATING_PROJECT, false);
|
||||
const [, setEditing] = useGlobal<string | null>(EDITING_PROJECT, null);
|
||||
const [, setSelected] = useGlobal<string | null>(SELECTED_PROJECT, null);
|
||||
const [, setProjectType] = useGlobal<ProjectType>(NEW_PROJ_TYPE, 'app');
|
||||
const [, setHasBackend] = useGlobal<boolean>(NEW_PROJ_HAS_BACKEND, false);
|
||||
const [, setHasAuth] = useGlobal<boolean>(NEW_PROJ_HAS_AUTH, false);
|
||||
|
||||
useEffect(() => {
|
||||
setSelected(null);
|
||||
// Redirect lands on a clean /projects (no ?selected), so selection is naturally cleared.
|
||||
setEditing(null);
|
||||
setName(params.get('name') || generateSlug());
|
||||
setDescription('');
|
||||
|
||||
Reference in New Issue
Block a user