This commit is contained in:
2026-05-31 20:19:44 +12:00
parent 2f2466ecac
commit 84792c0947
59 changed files with 5412 additions and 898 deletions
@@ -4,6 +4,7 @@ import {
ClipboardList,
DollarSign,
FlaskConical,
Gauge,
LayoutDashboard,
ShieldCheck,
TrendingUp,
@@ -13,6 +14,10 @@ import {
import type { ComponentType } from 'svelte';
import { featureFlags } from '$lib/features';
import {
canOpenDashboard
} from '$lib/workspace-access';
import type { AppSession } from '$lib/session';
export type SearchItem = {
href: string;
@@ -27,6 +32,7 @@ export type NavItem = {
shortLabel: string;
icon: ComponentType;
moduleKey?: string;
badge?: string;
};
export type FooterLink = {
@@ -50,7 +56,7 @@ export const dashboardItem: NavItem = {
};
export const mixCalculatorItem: NavItem = {
href: featureFlags.mixCalculatorSessionHistory ? '/mix-calculator' : '/mix-calculator/new',
href: '/mix-calculator',
label: 'Mix Calculator',
shortLabel: 'MC',
icon: Calculator,
@@ -65,6 +71,15 @@ export const reportingItem: NavItem = {
moduleKey: 'products'
};
export const throughputItem: NavItem = {
href: '/throughput',
label: 'Throughput',
shortLabel: 'OT',
icon: Gauge,
moduleKey: 'operations_throughput',
badge: 'test'
};
export const workingDocumentItems: NavItem[] = [
{ href: '/raw-materials', label: 'Raw Materials', shortLabel: 'RM', icon: Wheat, moduleKey: 'raw_materials' },
{ href: '/mixes', label: 'Mix Master', shortLabel: 'MM', icon: FlaskConical, moduleKey: 'mix_master' },
@@ -83,6 +98,7 @@ export const accessControlItem: NavItem = {
export const clientNavigationItems: NavItem[] = [
dashboardItem,
mixCalculatorItem,
throughputItem,
...workingDocumentItems,
accessControlItem
];
@@ -128,8 +144,8 @@ export const baseSearchItems: SearchItem[] = [
]
: []),
{
href: '/mix-calculator/new',
label: 'Create Mix Calculation',
href: '/mix-calculator',
label: 'Open Mix Calculator',
description: 'Run a new client-specific mix calculation session.',
keywords: 'new mix calculator session client batch size product bags print'
},
@@ -167,26 +183,30 @@ export function pageTitle(pathname: string) {
return clientNavigationItems.find((item) => matchesRoute(item.href, pathname))?.label ?? 'Dashboard';
}
export function clientBreadcrumbs(pathname: string): Crumb[] {
const root: Crumb = { label: 'Workspace', href: '/' };
export function clientBreadcrumbs(pathname: string, session?: AppSession | null): Crumb[] {
const crumbs: Crumb[] = [];
if (canOpenDashboard(session)) {
crumbs.push({ label: 'Workspace', href: '/' });
}
if (pathname === '/') {
return [root, { label: 'Dashboard' }];
return crumbs.length ? [...crumbs, { label: 'Dashboard' }] : [{ label: 'Dashboard' }];
}
if (pathname.startsWith('/mix-calculator')) {
const trail: Crumb[] = [root, { label: 'Mix Calculator', href: '/mix-calculator' }];
if (pathname === '/mix-calculator/new') trail.push({ label: 'New Session' });
else if (pathname.endsWith('/print')) trail.push({ label: 'Print' });
else if (pathname !== '/mix-calculator') trail.push({ label: 'Session' });
return trail;
return [...crumbs, { label: 'Mix Calculator' }];
}
if (pathname.startsWith('/mixes')) {
const trail: Crumb[] = [root, { label: 'Mix Master', href: '/mixes' }];
if (pathname === '/mixes/new') trail.push({ label: 'New Mix' });
else if (pathname !== '/mixes') trail.push({ label: 'Detail' });
return trail;
return [...crumbs, { label: 'Mix Master' }];
}
if (pathname.startsWith('/throughput')) {
const base: Crumb[] = [...crumbs, { label: 'Throughput', href: '/throughput' }];
if (pathname === '/throughput/add') return [...base, { label: 'Add Entry' }];
if (pathname === '/throughput') return base.slice(0, -1).concat([{ label: 'Throughput' }]);
return base;
}
const sectionMap: Record<string, string> = {
@@ -195,10 +215,11 @@ export function clientBreadcrumbs(pathname: string): Crumb[] {
'/scenarios': 'Scenarios',
'/client-access': 'Client Access',
'/reporting': 'Reporting',
'/settings': 'Settings'
'/settings': 'Settings',
'/throughput': 'Throughput'
};
const section = sectionMap[pathname];
if (section) return [root, { label: section }];
if (section) return [...crumbs, { label: section }];
return [root, { label: pageTitle(pathname) }];
return [...crumbs, { label: pageTitle(pathname) }];
}