@shipfox/client-shell 22.0.0 → 22.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/main-layout.d.ts.map +1 -1
- package/dist/components/main-layout.js +16 -2
- package/dist/components/main-layout.js.map +1 -1
- package/dist/components/settings-nav.d.ts.map +1 -1
- package/dist/components/settings-nav.js +32 -24
- package/dist/components/settings-nav.js.map +1 -1
- package/dist/runtime/anchors.d.ts.map +1 -1
- package/dist/runtime/anchors.js +6 -9
- package/dist/runtime/anchors.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main-layout.d.ts","sourceRoot":"","sources":["../../src/components/main-layout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"main-layout.d.ts","sourceRoot":"","sources":["../../src/components/main-layout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;AAG9C,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAC;AAOxD,OAAO,QAAQ,wBAAwB,CAAC;IACtC,UAAU,qBAAqB;QAC7B,KAAK,CAAC,EAAE,UAAU,CAAC;KACpB;CACF;AAQD,wBAAgB,UAAU,CAAC,EACzB,UAAU,EACV,qBAA6B,GAC9B,EAAE;IACD,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;IACnC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,+BAoCA"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { FullPageLoader } from '@shipfox/react-ui/loader';
|
|
3
|
-
import { Outlet, useMatches } from '@tanstack/react-router';
|
|
3
|
+
import { Navigate, Outlet, useLocation, useMatches } from '@tanstack/react-router';
|
|
4
4
|
import { useMaybeActiveWorkspace } from '#runtime/active-workspace.js';
|
|
5
|
+
import { useAuthState } from '#runtime/auth.js';
|
|
5
6
|
import { parseWorkspaceProjectParams, useRouteParams } from '#runtime/route-inputs.js';
|
|
7
|
+
import { WorkspaceUnavailablePage } from '#runtime/workspace-setup.js';
|
|
6
8
|
import { FOCUSED_FRAME_CONTENT_CLASS_NAME } from './focused-frame.js';
|
|
7
9
|
import { NavBar } from './nav-bar.js';
|
|
8
10
|
import { NavTabs } from './nav-tabs.js';
|
|
@@ -12,10 +14,22 @@ const frameClassNames = {
|
|
|
12
14
|
focused: `${FOCUSED_FRAME_CONTENT_CLASS_NAME} px-frame py-frame`
|
|
13
15
|
};
|
|
14
16
|
export function MainLayout({ navigation, hideProjectNavigation = false }) {
|
|
17
|
+
const auth = useAuthState();
|
|
15
18
|
const workspace = useMaybeActiveWorkspace();
|
|
19
|
+
const location = useLocation();
|
|
16
20
|
const { projectSlug } = useRouteParams(parseWorkspaceProjectParams);
|
|
17
21
|
const matches = useMatches();
|
|
18
|
-
if (
|
|
22
|
+
if (auth.isLoading) return /*#__PURE__*/ _jsx(FullPageLoader, {});
|
|
23
|
+
if (!auth.isAuthenticated) {
|
|
24
|
+
return /*#__PURE__*/ _jsx(Navigate, {
|
|
25
|
+
to: '/auth/login',
|
|
26
|
+
search: {
|
|
27
|
+
redirect: location.href
|
|
28
|
+
},
|
|
29
|
+
replace: true
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (!workspace) return /*#__PURE__*/ _jsx(WorkspaceUnavailablePage, {});
|
|
19
33
|
const frame = matches.reduce((current, match)=>match.staticData.frame ?? current, 'content');
|
|
20
34
|
const appContentHeight = hideProjectNavigation ? '[--app-content-h:calc(100dvh_-_56px)]' : '[--app-content-h:calc(100dvh_-_96px)]';
|
|
21
35
|
const isFullBleedFrame = frame === 'data';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/main-layout.tsx"],"sourcesContent":["import {FullPageLoader} from '@shipfox/react-ui/loader';\nimport {Outlet, useMatches} from '@tanstack/react-router';\nimport type {NavTabEntry} from '#contract.js';\nimport {useMaybeActiveWorkspace} from '#runtime/active-workspace.js';\nimport type {RouteFrame} from '#runtime/route-frame.js';\nimport {parseWorkspaceProjectParams, useRouteParams} from '#runtime/route-inputs.js';\nimport {FOCUSED_FRAME_CONTENT_CLASS_NAME} from './focused-frame.js';\nimport {NavBar} from './nav-bar.js';\nimport {NavTabs} from './nav-tabs.js';\n\ndeclare module '@tanstack/react-router' {\n interface StaticDataRouteOption {\n frame?: RouteFrame;\n }\n}\n\nconst frameClassNames: Record<RouteFrame, string> = {\n content: 'mx-auto w-full max-w-[1120px] px-frame py-frame',\n data: 'flex min-h-0 w-full flex-1 flex-col px-frame py-frame',\n focused: `${FOCUSED_FRAME_CONTENT_CLASS_NAME} px-frame py-frame`,\n};\n\nexport function MainLayout({\n navigation,\n hideProjectNavigation = false,\n}: {\n navigation: readonly NavTabEntry[];\n hideProjectNavigation?: boolean;\n}) {\n const workspace = useMaybeActiveWorkspace();\n const {projectSlug} = useRouteParams(parseWorkspaceProjectParams);\n const matches = useMatches();\n if (!workspace) return <
|
|
1
|
+
{"version":3,"sources":["../../src/components/main-layout.tsx"],"sourcesContent":["import {FullPageLoader} from '@shipfox/react-ui/loader';\nimport {Navigate, Outlet, useLocation, useMatches} from '@tanstack/react-router';\nimport type {NavTabEntry} from '#contract.js';\nimport {useMaybeActiveWorkspace} from '#runtime/active-workspace.js';\nimport {useAuthState} from '#runtime/auth.js';\nimport type {RouteFrame} from '#runtime/route-frame.js';\nimport {parseWorkspaceProjectParams, useRouteParams} from '#runtime/route-inputs.js';\nimport {WorkspaceUnavailablePage} from '#runtime/workspace-setup.js';\nimport {FOCUSED_FRAME_CONTENT_CLASS_NAME} from './focused-frame.js';\nimport {NavBar} from './nav-bar.js';\nimport {NavTabs} from './nav-tabs.js';\n\ndeclare module '@tanstack/react-router' {\n interface StaticDataRouteOption {\n frame?: RouteFrame;\n }\n}\n\nconst frameClassNames: Record<RouteFrame, string> = {\n content: 'mx-auto w-full max-w-[1120px] px-frame py-frame',\n data: 'flex min-h-0 w-full flex-1 flex-col px-frame py-frame',\n focused: `${FOCUSED_FRAME_CONTENT_CLASS_NAME} px-frame py-frame`,\n};\n\nexport function MainLayout({\n navigation,\n hideProjectNavigation = false,\n}: {\n navigation: readonly NavTabEntry[];\n hideProjectNavigation?: boolean;\n}) {\n const auth = useAuthState();\n const workspace = useMaybeActiveWorkspace();\n const location = useLocation();\n const {projectSlug} = useRouteParams(parseWorkspaceProjectParams);\n const matches = useMatches();\n if (auth.isLoading) return <FullPageLoader />;\n if (!auth.isAuthenticated) {\n return (\n <Navigate to={'/auth/login' as never} search={{redirect: location.href} as never} replace />\n );\n }\n if (!workspace) return <WorkspaceUnavailablePage />;\n const frame = matches.reduce<RouteFrame>(\n (current, match) => match.staticData.frame ?? current,\n 'content',\n );\n const appContentHeight = hideProjectNavigation\n ? '[--app-content-h:calc(100dvh_-_56px)]'\n : '[--app-content-h:calc(100dvh_-_96px)]';\n const isFullBleedFrame = frame === 'data';\n return (\n <div className=\"h-screen w-full flex flex-col bg-background-subtle-base\">\n <NavBar hideProjectNavigation={hideProjectNavigation} />\n {hideProjectNavigation ? undefined : (\n <NavTabs entries={navigation} scope={projectSlug ? 'project' : 'workspace'} />\n )}\n <main\n className={`${isFullBleedFrame ? 'flex min-h-0 flex-1 flex-col overflow-hidden' : 'flex-1 overflow-auto'} ${appContentHeight}`}\n >\n <div className={frameClassNames[frame]}>\n <Outlet />\n </div>\n </main>\n </div>\n );\n}\n"],"names":["FullPageLoader","Navigate","Outlet","useLocation","useMatches","useMaybeActiveWorkspace","useAuthState","parseWorkspaceProjectParams","useRouteParams","WorkspaceUnavailablePage","FOCUSED_FRAME_CONTENT_CLASS_NAME","NavBar","NavTabs","frameClassNames","content","data","focused","MainLayout","navigation","hideProjectNavigation","auth","workspace","location","projectSlug","matches","isLoading","isAuthenticated","to","search","redirect","href","replace","frame","reduce","current","match","staticData","appContentHeight","isFullBleedFrame","div","className","undefined","entries","scope","main"],"mappings":";AAAA,SAAQA,cAAc,QAAO,2BAA2B;AACxD,SAAQC,QAAQ,EAAEC,MAAM,EAAEC,WAAW,EAAEC,UAAU,QAAO,yBAAyB;AAEjF,SAAQC,uBAAuB,QAAO,+BAA+B;AACrE,SAAQC,YAAY,QAAO,mBAAmB;AAE9C,SAAQC,2BAA2B,EAAEC,cAAc,QAAO,2BAA2B;AACrF,SAAQC,wBAAwB,QAAO,8BAA8B;AACrE,SAAQC,gCAAgC,QAAO,qBAAqB;AACpE,SAAQC,MAAM,QAAO,eAAe;AACpC,SAAQC,OAAO,QAAO,gBAAgB;AAQtC,MAAMC,kBAA8C;IAClDC,SAAS;IACTC,MAAM;IACNC,SAAS,GAAGN,iCAAiC,kBAAkB,CAAC;AAClE;AAEA,OAAO,SAASO,WAAW,EACzBC,UAAU,EACVC,wBAAwB,KAAK,EAI9B;IACC,MAAMC,OAAOd;IACb,MAAMe,YAAYhB;IAClB,MAAMiB,WAAWnB;IACjB,MAAM,EAACoB,WAAW,EAAC,GAAGf,eAAeD;IACrC,MAAMiB,UAAUpB;IAChB,IAAIgB,KAAKK,SAAS,EAAE,qBAAO,KAACzB;IAC5B,IAAI,CAACoB,KAAKM,eAAe,EAAE;QACzB,qBACE,KAACzB;YAAS0B,IAAI;YAAwBC,QAAQ;gBAACC,UAAUP,SAASQ,IAAI;YAAA;YAAYC,OAAO;;IAE7F;IACA,IAAI,CAACV,WAAW,qBAAO,KAACZ;IACxB,MAAMuB,QAAQR,QAAQS,MAAM,CAC1B,CAACC,SAASC,QAAUA,MAAMC,UAAU,CAACJ,KAAK,IAAIE,SAC9C;IAEF,MAAMG,mBAAmBlB,wBACrB,0CACA;IACJ,MAAMmB,mBAAmBN,UAAU;IACnC,qBACE,MAACO;QAAIC,WAAU;;0BACb,KAAC7B;gBAAOQ,uBAAuBA;;YAC9BA,wBAAwBsB,0BACvB,KAAC7B;gBAAQ8B,SAASxB;gBAAYyB,OAAOpB,cAAc,YAAY;;0BAEjE,KAACqB;gBACCJ,WAAW,GAAGF,mBAAmB,iDAAiD,uBAAuB,CAAC,EAAED,kBAAkB;0BAE9H,cAAA,KAACE;oBAAIC,WAAW3B,eAAe,CAACmB,MAAM;8BACpC,cAAA,KAAC9B;;;;;AAKX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-nav.d.ts","sourceRoot":"","sources":["../../src/components/settings-nav.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAOvD,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,KAAK,GACN,EAAE;IACD,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACzC,KAAK,EAAE,WAAW,GAAG,SAAS,CAAC;CAChC,
|
|
1
|
+
{"version":3,"file":"settings-nav.d.ts","sourceRoot":"","sources":["../../src/components/settings-nav.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAOvD,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,KAAK,GACN,EAAE;IACD,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACzC,KAAK,EAAE,WAAW,GAAG,SAAS,CAAC;CAChC,sCAoDA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Button } from '@shipfox/react-ui/button';
|
|
3
2
|
import { Icon } from '@shipfox/react-ui/icon';
|
|
3
|
+
import { cn } from '@shipfox/react-ui/utils';
|
|
4
4
|
import { Link, useMatchRoute } from '@tanstack/react-router';
|
|
5
5
|
import { parseWorkspaceParams, parseWorkspaceProjectParams, useRouteParams } from '#runtime/route-inputs.js';
|
|
6
6
|
export function SettingsNav({ entries, scope }) {
|
|
@@ -17,30 +17,38 @@ export function SettingsNav({ entries, scope }) {
|
|
|
17
17
|
};
|
|
18
18
|
return /*#__PURE__*/ _jsx("nav", {
|
|
19
19
|
"aria-label": `${scope === 'workspace' ? 'Workspace' : 'Project'} settings`,
|
|
20
|
-
className: "flex flex-col
|
|
21
|
-
children:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
to
|
|
25
|
-
|
|
26
|
-
}));
|
|
27
|
-
return /*#__PURE__*/ _jsx(Button, {
|
|
28
|
-
asChild: true,
|
|
29
|
-
variant: active ? 'secondary' : 'transparent',
|
|
30
|
-
className: "w-full justify-start",
|
|
31
|
-
children: /*#__PURE__*/ _jsxs(Link, {
|
|
20
|
+
className: "flex min-w-0 flex-col",
|
|
21
|
+
children: /*#__PURE__*/ _jsx("ul", {
|
|
22
|
+
className: "divide-y divide-border-neutral-base",
|
|
23
|
+
children: scopedEntries.map((entry)=>{
|
|
24
|
+
const to = `${settingsPath}/${entry.pathSegment}`;
|
|
25
|
+
const active = Boolean(matchRoute({
|
|
32
26
|
to: to,
|
|
33
|
-
params: paramsForLink
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
27
|
+
params: paramsForLink
|
|
28
|
+
}));
|
|
29
|
+
return /*#__PURE__*/ _jsx("li", {
|
|
30
|
+
className: "py-tight first:pt-0 last:pb-0",
|
|
31
|
+
children: /*#__PURE__*/ _jsxs(Link, {
|
|
32
|
+
to: to,
|
|
33
|
+
params: paramsForLink,
|
|
34
|
+
"aria-current": active ? 'page' : undefined,
|
|
35
|
+
className: cn('relative flex min-h-32 w-full items-center justify-start gap-inline rounded-4 px-tight text-left text-sm font-medium text-foreground-neutral-base outline-none transition-colors hover:bg-background-neutral-hover focus-visible:shadow-border-interactive-with-active', active && 'bg-background-neutral-hover'),
|
|
36
|
+
children: [
|
|
37
|
+
active ? /*#__PURE__*/ _jsx("span", {
|
|
38
|
+
"aria-hidden": "true",
|
|
39
|
+
"data-settings-active-bar": true,
|
|
40
|
+
className: "absolute inset-y-0 left-0 w-2 rounded-l-4 bg-border-highlights-interactive"
|
|
41
|
+
}) : null,
|
|
42
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
43
|
+
name: entry.icon,
|
|
44
|
+
className: "size-16",
|
|
45
|
+
"aria-hidden": "true"
|
|
46
|
+
}),
|
|
47
|
+
entry.label
|
|
48
|
+
]
|
|
49
|
+
})
|
|
50
|
+
}, entry.id);
|
|
51
|
+
})
|
|
44
52
|
})
|
|
45
53
|
});
|
|
46
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/settings-nav.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/components/settings-nav.tsx"],"sourcesContent":["import {Icon} from '@shipfox/react-ui/icon';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {Link, useMatchRoute} from '@tanstack/react-router';\nimport type {SettingsSectionEntry} from '#contract.js';\nimport {\n parseWorkspaceParams,\n parseWorkspaceProjectParams,\n useRouteParams,\n} from '#runtime/route-inputs.js';\n\nexport function SettingsNav({\n entries,\n scope,\n}: {\n entries: readonly SettingsSectionEntry[];\n scope: 'workspace' | 'project';\n}) {\n const params = useRouteParams((input): {workspaceSlug?: string; projectSlug?: string} =>\n scope === 'workspace' ? parseWorkspaceParams(input) : parseWorkspaceProjectParams(input),\n );\n const matchRoute = useMatchRoute();\n if (!params.workspaceSlug || (scope === 'project' && !params.projectSlug)) return null;\n const scopedEntries = entries.filter((entry) => (entry.scope ?? 'workspace') === scope);\n const settingsPath =\n scope === 'workspace'\n ? '/w/$workspaceSlug/settings'\n : '/w/$workspaceSlug/p/$projectSlug/settings';\n const paramsForLink =\n scope === 'workspace'\n ? {workspaceSlug: params.workspaceSlug}\n : {workspaceSlug: params.workspaceSlug, projectSlug: params.projectSlug};\n\n return (\n <nav\n aria-label={`${scope === 'workspace' ? 'Workspace' : 'Project'} settings`}\n className=\"flex min-w-0 flex-col\"\n >\n <ul className=\"divide-y divide-border-neutral-base\">\n {scopedEntries.map((entry) => {\n const to = `${settingsPath}/${entry.pathSegment}`;\n const active = Boolean(matchRoute({to: to as never, params: paramsForLink as never}));\n return (\n <li key={entry.id} className=\"py-tight first:pt-0 last:pb-0\">\n <Link\n to={to as never}\n params={paramsForLink as never}\n aria-current={active ? 'page' : undefined}\n className={cn(\n 'relative flex min-h-32 w-full items-center justify-start gap-inline rounded-4 px-tight text-left text-sm font-medium text-foreground-neutral-base outline-none transition-colors hover:bg-background-neutral-hover focus-visible:shadow-border-interactive-with-active',\n active && 'bg-background-neutral-hover',\n )}\n >\n {active ? (\n <span\n aria-hidden=\"true\"\n data-settings-active-bar\n className=\"absolute inset-y-0 left-0 w-2 rounded-l-4 bg-border-highlights-interactive\"\n />\n ) : null}\n <Icon name={entry.icon} className=\"size-16\" aria-hidden=\"true\" />\n {entry.label}\n </Link>\n </li>\n );\n })}\n </ul>\n </nav>\n );\n}\n"],"names":["Icon","cn","Link","useMatchRoute","parseWorkspaceParams","parseWorkspaceProjectParams","useRouteParams","SettingsNav","entries","scope","params","input","matchRoute","workspaceSlug","projectSlug","scopedEntries","filter","entry","settingsPath","paramsForLink","nav","aria-label","className","ul","map","to","pathSegment","active","Boolean","li","aria-current","undefined","span","aria-hidden","data-settings-active-bar","name","icon","label","id"],"mappings":";AAAA,SAAQA,IAAI,QAAO,yBAAyB;AAC5C,SAAQC,EAAE,QAAO,0BAA0B;AAC3C,SAAQC,IAAI,EAAEC,aAAa,QAAO,yBAAyB;AAE3D,SACEC,oBAAoB,EACpBC,2BAA2B,EAC3BC,cAAc,QACT,2BAA2B;AAElC,OAAO,SAASC,YAAY,EAC1BC,OAAO,EACPC,KAAK,EAIN;IACC,MAAMC,SAASJ,eAAe,CAACK,QAC7BF,UAAU,cAAcL,qBAAqBO,SAASN,4BAA4BM;IAEpF,MAAMC,aAAaT;IACnB,IAAI,CAACO,OAAOG,aAAa,IAAKJ,UAAU,aAAa,CAACC,OAAOI,WAAW,EAAG,OAAO;IAClF,MAAMC,gBAAgBP,QAAQQ,MAAM,CAAC,CAACC,QAAU,AAACA,CAAAA,MAAMR,KAAK,IAAI,WAAU,MAAOA;IACjF,MAAMS,eACJT,UAAU,cACN,+BACA;IACN,MAAMU,gBACJV,UAAU,cACN;QAACI,eAAeH,OAAOG,aAAa;IAAA,IACpC;QAACA,eAAeH,OAAOG,aAAa;QAAEC,aAAaJ,OAAOI,WAAW;IAAA;IAE3E,qBACE,KAACM;QACCC,cAAY,GAAGZ,UAAU,cAAc,cAAc,UAAU,SAAS,CAAC;QACzEa,WAAU;kBAEV,cAAA,KAACC;YAAGD,WAAU;sBACXP,cAAcS,GAAG,CAAC,CAACP;gBAClB,MAAMQ,KAAK,GAAGP,aAAa,CAAC,EAAED,MAAMS,WAAW,EAAE;gBACjD,MAAMC,SAASC,QAAQhB,WAAW;oBAACa,IAAIA;oBAAaf,QAAQS;gBAAsB;gBAClF,qBACE,KAACU;oBAAkBP,WAAU;8BAC3B,cAAA,MAACpB;wBACCuB,IAAIA;wBACJf,QAAQS;wBACRW,gBAAcH,SAAS,SAASI;wBAChCT,WAAWrB,GACT,0QACA0B,UAAU;;4BAGXA,uBACC,KAACK;gCACCC,eAAY;gCACZC,0BAAwB;gCACxBZ,WAAU;iCAEV;0CACJ,KAACtB;gCAAKmC,MAAMlB,MAAMmB,IAAI;gCAAEd,WAAU;gCAAUW,eAAY;;4BACvDhB,MAAMoB,KAAK;;;mBAlBPpB,MAAMqB,EAAE;YAsBrB;;;AAIR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anchors.d.ts","sourceRoot":"","sources":["../../src/runtime/anchors.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,WAAW,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAKpE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,sBAAsB,CAAC;AAO9D,OAAO,EAAC,kBAAkB,EAAC,MAAM,mBAAmB,CAAC;AAErD,wBAAgB,mBAAmB,CAAC,EAClC,UAAU,EACV,gBAAgB,GACjB,EAAE;IACD,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;IACnC,gBAAgB,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACnD;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"anchors.d.ts","sourceRoot":"","sources":["../../src/runtime/anchors.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,WAAW,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAKpE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,sBAAsB,CAAC;AAO9D,OAAO,EAAC,kBAAkB,EAAC,MAAM,mBAAmB,CAAC;AAErD,wBAAgB,mBAAmB,CAAC,EAClC,UAAU,EACV,gBAAgB,GACjB,EAAE;IACD,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;IACnC,gBAAgB,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACnD;;;;;;;;;;;;;EAgHA"}
|
package/dist/runtime/anchors.js
CHANGED
|
@@ -5,7 +5,7 @@ import { createRootRouteWithContext, createRoute, Outlet, redirect } from '@tans
|
|
|
5
5
|
import { MainLayout } from '#components/main-layout.js';
|
|
6
6
|
import { NotFoundPage } from '#components/not-found-page.js';
|
|
7
7
|
import { SettingsNav } from '#components/settings-nav.js';
|
|
8
|
-
import {
|
|
8
|
+
import { useMaybeActiveWorkspace } from './active-workspace.js';
|
|
9
9
|
import { anchorPaths } from './anchor-paths.js';
|
|
10
10
|
import { rememberLastWorkspaceId } from './last-workspace.js';
|
|
11
11
|
import { parseWorkspaceParams, parseWorkspaceProjectParams, useRouteParams } from './route-inputs.js';
|
|
@@ -116,11 +116,8 @@ export function buildAnchorSkeleton({ navigation, settingsSections }) {
|
|
|
116
116
|
getParentRoute: ()=>workspaceLayout,
|
|
117
117
|
path: '/settings',
|
|
118
118
|
component: ()=>{
|
|
119
|
-
const workspace = useActiveWorkspace();
|
|
120
119
|
return /*#__PURE__*/ _jsx(SettingsAnchorLayout, {
|
|
121
120
|
scope: "workspace",
|
|
122
|
-
title: "Workspace settings",
|
|
123
|
-
description: `Configure ${workspace.name}.`,
|
|
124
121
|
settingsSections: settingsSections
|
|
125
122
|
});
|
|
126
123
|
}
|
|
@@ -144,22 +141,22 @@ function SettingsAnchorLayout({ scope, title, description, settingsSections }) {
|
|
|
144
141
|
const params = useRouteParams((input)=>scope === 'workspace' ? parseWorkspaceParams(input) : parseWorkspaceProjectParams(input));
|
|
145
142
|
if (!params.workspaceSlug || scope === 'project' && !params.projectSlug) return null;
|
|
146
143
|
return /*#__PURE__*/ _jsxs("div", {
|
|
147
|
-
className:
|
|
144
|
+
className: title ? 'flex w-full flex-col gap-section' : 'w-full',
|
|
148
145
|
children: [
|
|
149
|
-
/*#__PURE__*/ _jsxs("header", {
|
|
146
|
+
title ? /*#__PURE__*/ _jsxs("header", {
|
|
150
147
|
className: "flex flex-col gap-inline",
|
|
151
148
|
children: [
|
|
152
149
|
/*#__PURE__*/ _jsx(Header, {
|
|
153
150
|
variant: "h2",
|
|
154
151
|
children: title
|
|
155
152
|
}),
|
|
156
|
-
/*#__PURE__*/ _jsx(Text, {
|
|
153
|
+
description ? /*#__PURE__*/ _jsx(Text, {
|
|
157
154
|
size: "sm",
|
|
158
155
|
className: "text-foreground-neutral-muted",
|
|
159
156
|
children: description
|
|
160
|
-
})
|
|
157
|
+
}) : null
|
|
161
158
|
]
|
|
162
|
-
}),
|
|
159
|
+
}) : null,
|
|
163
160
|
/*#__PURE__*/ _jsxs("div", {
|
|
164
161
|
className: "grid grid-cols-[180px_minmax(0,1fr)] gap-region max-[760px]:grid-cols-1",
|
|
165
162
|
children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/runtime/anchors.tsx"],"sourcesContent":["import {ShipfoxLoader} from '@shipfox/react-ui/loader';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {createRootRouteWithContext, createRoute, Outlet, redirect} from '@tanstack/react-router';\nimport {MainLayout} from '#components/main-layout.js';\nimport {NotFoundPage} from '#components/not-found-page.js';\nimport {SettingsNav} from '#components/settings-nav.js';\nimport type {NavTabEntry, SettingsSectionEntry} from '#contract.js';\nimport {useActiveWorkspace, useMaybeActiveWorkspace} from './active-workspace.js';\nimport {anchorPaths} from './anchor-paths.js';\nimport {rememberLastWorkspaceId} from './last-workspace.js';\nimport {parseWorkspaceParams, parseWorkspaceProjectParams, useRouteParams} from './route-inputs.js';\nimport type {RouterContext} from './router-context.js';\nimport type {WorkspaceSetupState} from './workspace-setup.js';\nimport {\n WorkspaceLayoutErrorRoute,\n WorkspaceSetupPending,\n WorkspaceUnavailablePage,\n} from './workspace-setup.js';\n\nexport {routePathForAnchor} from './anchor-paths.js';\n\nexport function buildAnchorSkeleton({\n navigation,\n settingsSections,\n}: {\n navigation: readonly NavTabEntry[];\n settingsSections: readonly SettingsSectionEntry[];\n}) {\n const rootRoute = createRootRouteWithContext<RouterContext>()({\n component: Outlet,\n notFoundComponent: NotFoundPage,\n });\n const workspaceLayout = createRoute({\n getParentRoute: () => rootRoute,\n path: anchorPaths.workspaceLayout,\n staticData: {frame: 'content'},\n beforeLoad: async ({context, params, location}) => {\n const auth = context.auth;\n if (!auth || auth.isLoading || !context.queryClient) return;\n if (!auth.isAuthenticated)\n throw redirect({to: '/auth/login' as never, search: {redirect: location.href} as never});\n const workspace = auth.workspaces.find(\n (candidate) => candidate.slug === params.workspaceSlug,\n );\n if (!workspace) throw redirect({to: '/'});\n try {\n if (auth.user?.id) rememberLastWorkspaceId(auth.user.id, workspace.id);\n } catch {\n // Local storage is best effort.\n }\n if (!context.workspaceSetup)\n throw new Error('Client composition includes workspace routes but no workspaceSetup gate.');\n return await context.workspaceSetup({\n queryClient: context.queryClient,\n workspaceId: workspace.id,\n workspaceSlug: params.workspaceSlug,\n pathname: location.pathname,\n });\n },\n pendingComponent: () => (\n <div className=\"flex h-screen items-center justify-center\">\n <ShipfoxLoader size={64} animation=\"circular\" color=\"orange\" background=\"dark\" />\n </div>\n ),\n errorComponent: WorkspaceLayoutErrorRoute,\n component: () => {\n const setupState = workspaceLayout.useRouteContext() as {\n hideProjectNavigation?: boolean;\n unavailable?: boolean;\n };\n const workspace = useMaybeActiveWorkspace();\n return setupState.hideProjectNavigation === undefined ? (\n <WorkspaceSetupPending />\n ) : setupState.unavailable ? (\n <WorkspaceUnavailablePage workspaceName={workspace?.name} />\n ) : (\n <MainLayout\n navigation={navigation}\n hideProjectNavigation={setupState.hideProjectNavigation}\n />\n );\n },\n });\n const projectLayout = createRoute({\n getParentRoute: () => workspaceLayout,\n path: '/p/$projectSlug',\n staticData: {frame: 'content'},\n beforeLoad: async ({context, params}) => {\n const auth = context.auth;\n if (!auth || auth.isLoading || !context.queryClient) return;\n if ((context as RouterContext & Partial<WorkspaceSetupState>).unavailable) return;\n const workspace = auth.workspaces.find(\n (candidate) => candidate.slug === params.workspaceSlug,\n );\n if (!workspace) throw redirect({to: '/'});\n if (!context.projectSlugResolver) {\n throw new Error('Client composition includes project routes but no project slug resolver.');\n }\n const projectId = await context.projectSlugResolver({\n queryClient: context.queryClient,\n workspaceId: workspace.id,\n projectSlug: params.projectSlug,\n });\n if (!projectId) {\n throw redirect({\n to: '/w/$workspaceSlug',\n params: {workspaceSlug: params.workspaceSlug},\n });\n }\n },\n component: Outlet,\n });\n const projectSettings = createRoute({\n getParentRoute: () => projectLayout,\n path: '/settings',\n component: () => (\n <SettingsAnchorLayout\n scope=\"project\"\n title=\"Project settings\"\n description=\"Configure this project.\"\n settingsSections={settingsSections}\n />\n ),\n });\n const workspaceSettings = createRoute({\n getParentRoute: () => workspaceLayout,\n path: '/settings',\n component: () => {\n const workspace = useActiveWorkspace();\n return (\n <SettingsAnchorLayout\n scope=\"workspace\"\n title=\"Workspace settings\"\n description={`Configure ${workspace.name}.`}\n settingsSections={settingsSections}\n />\n );\n },\n });\n return {\n anchors: {root: rootRoute, workspaceLayout, projectLayout, workspaceSettings, projectSettings},\n rootRoute,\n workspaceLayout,\n projectLayout,\n workspaceSettings,\n projectSettings,\n };\n}\n\nfunction SettingsAnchorLayout({\n scope,\n title,\n description,\n settingsSections,\n}: {\n scope: 'workspace' | 'project';\n title: string;\n description: string;\n settingsSections: readonly SettingsSectionEntry[];\n}) {\n const params = useRouteParams((input): {workspaceSlug?: string; projectSlug?: string} =>\n scope === 'workspace' ? parseWorkspaceParams(input) : parseWorkspaceProjectParams(input),\n );\n if (!params.workspaceSlug || (scope === 'project' && !params.projectSlug)) return null;\n\n return (\n <div className=\"flex w-full flex-col gap-section\">\n <header className=\"flex flex-col gap-inline\">\n <Header variant=\"h2\">{title}</Header>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {description}\n </Text>\n </header>\n\n <div className=\"grid grid-cols-[180px_minmax(0,1fr)] gap-region max-[760px]:grid-cols-1\">\n <SettingsNav entries={settingsSections} scope={scope} />\n <Outlet />\n </div>\n </div>\n );\n}\n"],"names":["ShipfoxLoader","Header","Text","createRootRouteWithContext","createRoute","Outlet","redirect","MainLayout","NotFoundPage","SettingsNav","useActiveWorkspace","useMaybeActiveWorkspace","anchorPaths","rememberLastWorkspaceId","parseWorkspaceParams","parseWorkspaceProjectParams","useRouteParams","WorkspaceLayoutErrorRoute","WorkspaceSetupPending","WorkspaceUnavailablePage","routePathForAnchor","buildAnchorSkeleton","navigation","settingsSections","rootRoute","component","notFoundComponent","workspaceLayout","getParentRoute","path","staticData","frame","beforeLoad","context","params","location","auth","isLoading","queryClient","isAuthenticated","to","search","href","workspace","workspaces","find","candidate","slug","workspaceSlug","user","id","workspaceSetup","Error","workspaceId","pathname","pendingComponent","div","className","size","animation","color","background","errorComponent","setupState","useRouteContext","hideProjectNavigation","undefined","unavailable","workspaceName","name","projectLayout","projectSlugResolver","projectId","projectSlug","projectSettings","SettingsAnchorLayout","scope","title","description","workspaceSettings","anchors","root","input","header","variant","entries"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/runtime/anchors.tsx"],"sourcesContent":["import {ShipfoxLoader} from '@shipfox/react-ui/loader';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {createRootRouteWithContext, createRoute, Outlet, redirect} from '@tanstack/react-router';\nimport {MainLayout} from '#components/main-layout.js';\nimport {NotFoundPage} from '#components/not-found-page.js';\nimport {SettingsNav} from '#components/settings-nav.js';\nimport type {NavTabEntry, SettingsSectionEntry} from '#contract.js';\nimport {useMaybeActiveWorkspace} from './active-workspace.js';\nimport {anchorPaths} from './anchor-paths.js';\nimport {rememberLastWorkspaceId} from './last-workspace.js';\nimport {parseWorkspaceParams, parseWorkspaceProjectParams, useRouteParams} from './route-inputs.js';\nimport type {RouterContext} from './router-context.js';\nimport type {WorkspaceSetupState} from './workspace-setup.js';\nimport {\n WorkspaceLayoutErrorRoute,\n WorkspaceSetupPending,\n WorkspaceUnavailablePage,\n} from './workspace-setup.js';\n\nexport {routePathForAnchor} from './anchor-paths.js';\n\nexport function buildAnchorSkeleton({\n navigation,\n settingsSections,\n}: {\n navigation: readonly NavTabEntry[];\n settingsSections: readonly SettingsSectionEntry[];\n}) {\n const rootRoute = createRootRouteWithContext<RouterContext>()({\n component: Outlet,\n notFoundComponent: NotFoundPage,\n });\n const workspaceLayout = createRoute({\n getParentRoute: () => rootRoute,\n path: anchorPaths.workspaceLayout,\n staticData: {frame: 'content'},\n beforeLoad: async ({context, params, location}) => {\n const auth = context.auth;\n if (!auth || auth.isLoading || !context.queryClient) return;\n if (!auth.isAuthenticated)\n throw redirect({to: '/auth/login' as never, search: {redirect: location.href} as never});\n const workspace = auth.workspaces.find(\n (candidate) => candidate.slug === params.workspaceSlug,\n );\n if (!workspace) throw redirect({to: '/'});\n try {\n if (auth.user?.id) rememberLastWorkspaceId(auth.user.id, workspace.id);\n } catch {\n // Local storage is best effort.\n }\n if (!context.workspaceSetup)\n throw new Error('Client composition includes workspace routes but no workspaceSetup gate.');\n return await context.workspaceSetup({\n queryClient: context.queryClient,\n workspaceId: workspace.id,\n workspaceSlug: params.workspaceSlug,\n pathname: location.pathname,\n });\n },\n pendingComponent: () => (\n <div className=\"flex h-screen items-center justify-center\">\n <ShipfoxLoader size={64} animation=\"circular\" color=\"orange\" background=\"dark\" />\n </div>\n ),\n errorComponent: WorkspaceLayoutErrorRoute,\n component: () => {\n const setupState = workspaceLayout.useRouteContext() as {\n hideProjectNavigation?: boolean;\n unavailable?: boolean;\n };\n const workspace = useMaybeActiveWorkspace();\n return setupState.hideProjectNavigation === undefined ? (\n <WorkspaceSetupPending />\n ) : setupState.unavailable ? (\n <WorkspaceUnavailablePage workspaceName={workspace?.name} />\n ) : (\n <MainLayout\n navigation={navigation}\n hideProjectNavigation={setupState.hideProjectNavigation}\n />\n );\n },\n });\n const projectLayout = createRoute({\n getParentRoute: () => workspaceLayout,\n path: '/p/$projectSlug',\n staticData: {frame: 'content'},\n beforeLoad: async ({context, params}) => {\n const auth = context.auth;\n if (!auth || auth.isLoading || !context.queryClient) return;\n if ((context as RouterContext & Partial<WorkspaceSetupState>).unavailable) return;\n const workspace = auth.workspaces.find(\n (candidate) => candidate.slug === params.workspaceSlug,\n );\n if (!workspace) throw redirect({to: '/'});\n if (!context.projectSlugResolver) {\n throw new Error('Client composition includes project routes but no project slug resolver.');\n }\n const projectId = await context.projectSlugResolver({\n queryClient: context.queryClient,\n workspaceId: workspace.id,\n projectSlug: params.projectSlug,\n });\n if (!projectId) {\n throw redirect({\n to: '/w/$workspaceSlug',\n params: {workspaceSlug: params.workspaceSlug},\n });\n }\n },\n component: Outlet,\n });\n const projectSettings = createRoute({\n getParentRoute: () => projectLayout,\n path: '/settings',\n component: () => (\n <SettingsAnchorLayout\n scope=\"project\"\n title=\"Project settings\"\n description=\"Configure this project.\"\n settingsSections={settingsSections}\n />\n ),\n });\n const workspaceSettings = createRoute({\n getParentRoute: () => workspaceLayout,\n path: '/settings',\n component: () => {\n return <SettingsAnchorLayout scope=\"workspace\" settingsSections={settingsSections} />;\n },\n });\n return {\n anchors: {root: rootRoute, workspaceLayout, projectLayout, workspaceSettings, projectSettings},\n rootRoute,\n workspaceLayout,\n projectLayout,\n workspaceSettings,\n projectSettings,\n };\n}\n\nfunction SettingsAnchorLayout({\n scope,\n title,\n description,\n settingsSections,\n}: {\n scope: 'workspace' | 'project';\n title?: string;\n description?: string;\n settingsSections: readonly SettingsSectionEntry[];\n}) {\n const params = useRouteParams((input): {workspaceSlug?: string; projectSlug?: string} =>\n scope === 'workspace' ? parseWorkspaceParams(input) : parseWorkspaceProjectParams(input),\n );\n if (!params.workspaceSlug || (scope === 'project' && !params.projectSlug)) return null;\n\n return (\n <div className={title ? 'flex w-full flex-col gap-section' : 'w-full'}>\n {title ? (\n <header className=\"flex flex-col gap-inline\">\n <Header variant=\"h2\">{title}</Header>\n {description ? (\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {description}\n </Text>\n ) : null}\n </header>\n ) : null}\n\n <div className=\"grid grid-cols-[180px_minmax(0,1fr)] gap-region max-[760px]:grid-cols-1\">\n <SettingsNav entries={settingsSections} scope={scope} />\n <Outlet />\n </div>\n </div>\n );\n}\n"],"names":["ShipfoxLoader","Header","Text","createRootRouteWithContext","createRoute","Outlet","redirect","MainLayout","NotFoundPage","SettingsNav","useMaybeActiveWorkspace","anchorPaths","rememberLastWorkspaceId","parseWorkspaceParams","parseWorkspaceProjectParams","useRouteParams","WorkspaceLayoutErrorRoute","WorkspaceSetupPending","WorkspaceUnavailablePage","routePathForAnchor","buildAnchorSkeleton","navigation","settingsSections","rootRoute","component","notFoundComponent","workspaceLayout","getParentRoute","path","staticData","frame","beforeLoad","context","params","location","auth","isLoading","queryClient","isAuthenticated","to","search","href","workspace","workspaces","find","candidate","slug","workspaceSlug","user","id","workspaceSetup","Error","workspaceId","pathname","pendingComponent","div","className","size","animation","color","background","errorComponent","setupState","useRouteContext","hideProjectNavigation","undefined","unavailable","workspaceName","name","projectLayout","projectSlugResolver","projectId","projectSlug","projectSettings","SettingsAnchorLayout","scope","title","description","workspaceSettings","anchors","root","input","header","variant","entries"],"mappings":"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"}
|