@open-mercato/ui 0.7.1-develop.7191.1.3c9346566b → 0.7.1-develop.7194.1.ab4fc81f82

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.
Files changed (58) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/backend/AppShell.js +66 -7
  3. package/dist/backend/AppShell.js.map +2 -2
  4. package/dist/backend/CrudForm.js +14 -8
  5. package/dist/backend/CrudForm.js.map +2 -2
  6. package/dist/backend/DataTable.js +167 -24
  7. package/dist/backend/DataTable.js.map +2 -2
  8. package/dist/backend/PerspectiveSidebar.js +60 -21
  9. package/dist/backend/PerspectiveSidebar.js.map +2 -2
  10. package/dist/backend/forms/ActionsDropdown.js +35 -5
  11. package/dist/backend/forms/ActionsDropdown.js.map +2 -2
  12. package/dist/backend/forms/index.js.map +2 -2
  13. package/dist/backend/icons/lucideRegistry.generated.js +6 -0
  14. package/dist/backend/icons/lucideRegistry.generated.js.map +2 -2
  15. package/dist/backend/injection/spotIds.js +2 -0
  16. package/dist/backend/injection/spotIds.js.map +2 -2
  17. package/dist/backend/inputs/DurationInput.js +182 -0
  18. package/dist/backend/inputs/DurationInput.js.map +7 -0
  19. package/dist/backend/inputs/EventSelect.js.map +2 -2
  20. package/dist/backend/inputs/index.js +1 -0
  21. package/dist/backend/inputs/index.js.map +2 -2
  22. package/dist/backend/nav/navBadges.js +38 -0
  23. package/dist/backend/nav/navBadges.js.map +7 -0
  24. package/dist/backend/views/NewViewForm.js +46 -38
  25. package/dist/backend/views/NewViewForm.js.map +2 -2
  26. package/dist/primitives/segmented-control.js +4 -4
  27. package/dist/primitives/segmented-control.js.map +1 -1
  28. package/dist/primitives/sheet.js +21 -11
  29. package/dist/primitives/sheet.js.map +2 -2
  30. package/dist/primitives/textarea.js +54 -4
  31. package/dist/primitives/textarea.js.map +2 -2
  32. package/package.json +3 -3
  33. package/src/backend/AppShell.tsx +106 -2
  34. package/src/backend/CrudForm.tsx +28 -9
  35. package/src/backend/DataTable.tsx +293 -36
  36. package/src/backend/PerspectiveSidebar.tsx +80 -21
  37. package/src/backend/__tests__/CrudForm.density.test.tsx +113 -0
  38. package/src/backend/__tests__/DataTable.exportSectionTitles.test.tsx +134 -0
  39. package/src/backend/__tests__/DataTable.perspectiveReconcile.test.tsx +312 -0
  40. package/src/backend/__tests__/DataTable.propBulkActions.test.tsx +200 -0
  41. package/src/backend/__tests__/DataTable.render.test.tsx +76 -0
  42. package/src/backend/__tests__/PerspectiveSidebar.roleAutosave.test.tsx +252 -0
  43. package/src/backend/__tests__/navBadges.test.ts +57 -0
  44. package/src/backend/forms/ActionsDropdown.tsx +73 -6
  45. package/src/backend/forms/index.ts +1 -1
  46. package/src/backend/icons/lucideRegistry.generated.tsx +6 -0
  47. package/src/backend/injection/spotIds.ts +8 -0
  48. package/src/backend/inputs/DurationInput.tsx +207 -0
  49. package/src/backend/inputs/EventSelect.tsx +2 -0
  50. package/src/backend/inputs/__tests__/DurationInput.test.tsx +220 -0
  51. package/src/backend/inputs/index.ts +1 -0
  52. package/src/backend/nav/navBadges.ts +61 -0
  53. package/src/backend/views/NewViewForm.tsx +46 -32
  54. package/src/primitives/__tests__/segmented-control.test.tsx +2 -2
  55. package/src/primitives/__tests__/textarea.test.tsx +50 -0
  56. package/src/primitives/segmented-control.tsx +7 -7
  57. package/src/primitives/sheet.tsx +7 -1
  58. package/src/primitives/textarea.tsx +77 -4
@@ -62,6 +62,7 @@ function PerspectiveSidebar({
62
62
  const [sharedIds, setSharedIds] = React.useState(/* @__PURE__ */ new Set());
63
63
  const [pendingCloneBaselineIds, setPendingCloneBaselineIds] = React.useState(null);
64
64
  const autosaveRef = React.useRef(null);
65
+ const pendingAutosaveActionRef = React.useRef(null);
65
66
  const isDefaultUserChangeRef = React.useRef(false);
66
67
  const isDefaultRef = React.useRef(isDefault);
67
68
  isDefaultRef.current = isDefault;
@@ -69,41 +70,79 @@ function PerspectiveSidebar({
69
70
  onSaveRef.current = onSave;
70
71
  const perspectivesRef = React.useRef(perspectives);
71
72
  perspectivesRef.current = perspectives;
73
+ const rolePerspectivesRef = React.useRef(rolePerspectives);
74
+ rolePerspectivesRef.current = rolePerspectives;
75
+ const activePerspectiveIdRef = React.useRef(activePerspectiveId);
76
+ activePerspectiveIdRef.current = activePerspectiveId;
72
77
  const flushAutosave = React.useCallback(() => {
73
78
  if (autosaveRef.current) {
74
79
  clearTimeout(autosaveRef.current);
75
80
  autosaveRef.current = null;
76
81
  }
82
+ pendingAutosaveActionRef.current = null;
83
+ }, []);
84
+ const runPendingAutosave = React.useCallback(() => {
85
+ if (!autosaveRef.current) return;
86
+ clearTimeout(autosaveRef.current);
87
+ autosaveRef.current = null;
88
+ const pending = pendingAutosaveActionRef.current;
89
+ pendingAutosaveActionRef.current = null;
90
+ pending?.();
77
91
  }, []);
78
92
  const scheduleAutosave = React.useCallback(() => {
79
93
  if (!activePerspectiveId || mode.type === "new") return;
80
94
  const activePersonal = perspectivesRef.current.find((p) => p.id === activePerspectiveId);
81
- if (!activePersonal) return;
95
+ if (!activePersonal) {
96
+ const activeRole = rolePerspectivesRef.current.find((p) => p.id === activePerspectiveId);
97
+ if (!activeRole) return;
98
+ flushAutosave();
99
+ const warnedId = activeRole.id;
100
+ const emitWarning = () => {
101
+ autosaveRef.current = null;
102
+ pendingAutosaveActionRef.current = null;
103
+ if (activePerspectiveIdRef.current !== warnedId) return;
104
+ flash(
105
+ t(
106
+ "ui.perspectives.autosave.sharedView",
107
+ "Shared views do not save automatically. Use Clone to keep these changes in your own view."
108
+ ),
109
+ "warning"
110
+ );
111
+ };
112
+ pendingAutosaveActionRef.current = emitWarning;
113
+ autosaveRef.current = setTimeout(emitWarning, 400);
114
+ return;
115
+ }
82
116
  flushAutosave();
83
117
  const targetId = activePersonal.id;
84
118
  const targetName = activePersonal.name;
85
- autosaveRef.current = setTimeout(async () => {
119
+ const runSave = () => {
86
120
  autosaveRef.current = null;
87
- try {
88
- await onSaveRef.current({
89
- name: targetName,
90
- isDefault: isDefaultRef.current,
91
- applyToRoles: [],
92
- setRoleDefault: false,
93
- perspectiveId: targetId
94
- });
95
- flash(t("ui.perspectives.autosave.success", "View saved"), "success");
96
- } catch (err) {
97
- if (surfaceRecordConflict(err, t)) return;
98
- flash(t("ui.perspectives.autosave.error", "Failed to save view"), "error");
99
- }
100
- }, 400);
121
+ pendingAutosaveActionRef.current = null;
122
+ void (async () => {
123
+ try {
124
+ await onSaveRef.current({
125
+ name: targetName,
126
+ isDefault: isDefaultRef.current,
127
+ applyToRoles: [],
128
+ setRoleDefault: false,
129
+ perspectiveId: targetId
130
+ });
131
+ flash(t("ui.perspectives.autosave.success", "View saved"), "success");
132
+ } catch (err) {
133
+ if (surfaceRecordConflict(err, t)) return;
134
+ flash(t("ui.perspectives.autosave.error", "Failed to save view"), "error");
135
+ }
136
+ })();
137
+ };
138
+ pendingAutosaveActionRef.current = runSave;
139
+ autosaveRef.current = setTimeout(runSave, 400);
101
140
  }, [activePerspectiveId, mode.type, flushAutosave, t]);
102
141
  React.useEffect(() => {
103
142
  return () => {
104
- flushAutosave();
143
+ runPendingAutosave();
105
144
  };
106
- }, [flushAutosave]);
145
+ }, [runPendingAutosave]);
107
146
  const resetMode = () => {
108
147
  setMode({ type: "idle" });
109
148
  setName("");
@@ -127,7 +166,7 @@ function PerspectiveSidebar({
127
166
  };
128
167
  React.useEffect(() => {
129
168
  if (!open) {
130
- flushAutosave();
169
+ runPendingAutosave();
131
170
  setError(null);
132
171
  resetMode();
133
172
  setRenamingId(null);
@@ -334,7 +373,7 @@ function PerspectiveSidebar({
334
373
  }
335
374
  ),
336
375
  (perspectives ?? emptyArray).map((p) => {
337
- const isActive = activePerspectiveId === p.id;
376
+ const isActive = !isNew && activePerspectiveId === p.id;
338
377
  const deleting = deletingIds.includes(p.id);
339
378
  const isShared = sharedIds.has(p.id);
340
379
  return /* @__PURE__ */ jsx(
@@ -372,7 +411,7 @@ function PerspectiveSidebar({
372
411
  const rpName = rp.name.trim();
373
412
  return !perspectives.some((pp) => pp.name.trim() === rpName);
374
413
  }).map((p) => {
375
- const isActive = activePerspectiveId === p.id;
414
+ const isActive = !isNew && activePerspectiveId === p.id;
376
415
  const clearing = roleClearingIds.includes(p.roleId);
377
416
  return /* @__PURE__ */ jsx(
378
417
  ViewChip,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/backend/PerspectiveSidebar.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { ArrowLeft, Plus } from 'lucide-react'\nimport { Alert } from '../primitives/alert'\nimport { Button } from '../primitives/button'\nimport { Checkbox } from '../primitives/checkbox'\nimport { Spinner } from '../primitives/spinner'\nimport { useConfirmDialog } from './confirm-dialog'\nimport { flash } from './FlashMessages'\nimport { surfaceRecordConflict } from './conflicts'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type {\n PerspectiveDto,\n PerspectiveSettings,\n RolePerspectiveDto,\n} from '@open-mercato/shared/modules/perspectives/types'\nimport { ViewChip } from './views/ViewChip'\nimport { NewViewForm } from './views/NewViewForm'\nimport { ShareForm } from './views/ShareForm'\nimport { type SidebarMode } from './views/types'\nimport { ColumnChooserSection, type ColumnChooserField } from './columns/ColumnChooserPanel'\n\nexport type { ColumnChooserField } from './columns/ColumnChooserPanel'\n\nexport type PerspectiveSidebarProps = {\n open: boolean\n onOpenChange: (open: boolean) => void\n loading: boolean\n perspectives: PerspectiveDto[]\n rolePerspectives: RolePerspectiveDto[]\n roles: Array<{ id: string; name: string; hasPerspective: boolean; hasDefault: boolean }>\n activePerspectiveId: string | null\n onActivatePerspective: (perspective: PerspectiveDto | RolePerspectiveDto, source: 'personal' | 'role') => void\n onDeletePerspective: (perspectiveId: string) => Promise<void>\n onClearRole: (perspective: RolePerspectiveDto) => Promise<void>\n onSave: (input: { name: string; isDefault: boolean; applyToRoles: string[]; setRoleDefault: boolean; perspectiveId?: string | null; settings?: PerspectiveSettings }) => Promise<void>\n canApplyToRoles: boolean\n availableColumns: ColumnChooserField[]\n visibleColumnKeys: string[]\n columnOrder: string[]\n onToggleColumn: (key: string) => void\n onReorderColumns: (orderedIds: string[]) => void\n saving: boolean\n deletingIds: string[]\n roleClearingIds: string[]\n apiWarning?: string | null\n}\n\nconst emptyArray: any[] = []\n\nexport function PerspectiveSidebar({\n open,\n onOpenChange,\n loading,\n perspectives,\n rolePerspectives,\n roles,\n activePerspectiveId,\n onActivatePerspective,\n onDeletePerspective,\n onClearRole,\n onSave,\n canApplyToRoles,\n availableColumns,\n visibleColumnKeys,\n columnOrder,\n onToggleColumn,\n onReorderColumns,\n saving,\n deletingIds,\n roleClearingIds,\n apiWarning,\n}: PerspectiveSidebarProps) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n React.useEffect(() => {\n if (!open) return\n if (typeof document === 'undefined') return\n document.body.dataset.columnChooserOpen = 'true'\n return () => {\n delete document.body.dataset.columnChooserOpen\n }\n }, [open])\n\n function perspectiveLabel(p: PerspectiveDto | RolePerspectiveDto) {\n return p.name.trim().length ? p.name : t('ui.perspectives.untitled', 'Untitled view')\n }\n\n const [name, setName] = React.useState('')\n const [isDefault, setIsDefault] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const [mode, setMode] = React.useState<SidebarMode>({ type: 'idle' })\n const [renamingId, setRenamingId] = React.useState<string | null>(null)\n const [renameValue, setRenameValue] = React.useState('')\n const [shareRoles, setShareRoles] = React.useState<string[]>([])\n const [shareSetDefault, setShareSetDefault] = React.useState(false)\n const [sharedIds, setSharedIds] = React.useState<Set<string>>(new Set())\n const [pendingCloneBaselineIds, setPendingCloneBaselineIds] = React.useState<Set<string> | null>(null)\n\n const autosaveRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)\n const isDefaultUserChangeRef = React.useRef(false)\n const isDefaultRef = React.useRef(isDefault)\n isDefaultRef.current = isDefault\n\n const onSaveRef = React.useRef(onSave)\n onSaveRef.current = onSave\n\n const perspectivesRef = React.useRef(perspectives)\n perspectivesRef.current = perspectives\n\n const flushAutosave = React.useCallback(() => {\n if (autosaveRef.current) {\n clearTimeout(autosaveRef.current)\n autosaveRef.current = null\n }\n }, [])\n\n const scheduleAutosave = React.useCallback(() => {\n if (!activePerspectiveId || mode.type === 'new') return\n const activePersonal = perspectivesRef.current.find((p) => p.id === activePerspectiveId)\n if (!activePersonal) return\n flushAutosave()\n const targetId = activePersonal.id\n const targetName = activePersonal.name\n autosaveRef.current = setTimeout(async () => {\n autosaveRef.current = null\n try {\n await onSaveRef.current({\n name: targetName,\n isDefault: isDefaultRef.current,\n applyToRoles: [],\n setRoleDefault: false,\n perspectiveId: targetId,\n })\n flash(t('ui.perspectives.autosave.success', 'View saved'), 'success')\n } catch (err: unknown) {\n if (surfaceRecordConflict(err, t)) return\n flash(t('ui.perspectives.autosave.error', 'Failed to save view'), 'error')\n }\n }, 400)\n }, [activePerspectiveId, mode.type, flushAutosave, t])\n\n React.useEffect(() => {\n return () => { flushAutosave() }\n }, [flushAutosave])\n\n const resetMode = () => {\n setMode({ type: 'idle' })\n setName('')\n setShareRoles([])\n setShareSetDefault(false)\n }\n\n const startNewMode = () => {\n setMode({ type: 'new' })\n setName('')\n setIsDefault(false)\n setRenamingId(null)\n setShareRoles([])\n setShareSetDefault(false)\n }\n\n const startShareMode = (p: PerspectiveDto) => {\n setMode({ type: 'share', perspectiveId: p.id, perspectiveName: p.name, perspectiveIsDefault: p.isDefault })\n setName('')\n setRenamingId(null)\n setShareRoles([])\n setShareSetDefault(false)\n }\n\n React.useEffect(() => {\n if (!open) {\n flushAutosave()\n setError(null)\n resetMode()\n setRenamingId(null)\n setSharedIds(new Set())\n setPendingCloneBaselineIds(null)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open])\n\n React.useEffect(() => {\n if (!open) return\n const active = perspectives.find((p) => p.id === activePerspectiveId)\n ?? rolePerspectives.find((p) => p.id === activePerspectiveId)\n isDefaultUserChangeRef.current = false\n if (active) {\n setIsDefault(active.isDefault)\n } else {\n setIsDefault(false)\n }\n requestAnimationFrame(() => { isDefaultUserChangeRef.current = true })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, activePerspectiveId])\n\n const handleSaveNew = async () => {\n setError(null)\n try {\n await onSave({ name: name.trim(), isDefault, applyToRoles: [], setRoleDefault: false, perspectiveId: null })\n resetMode()\n } catch (err: unknown) {\n if (surfaceRecordConflict(err, t)) return\n setError(err instanceof Error ? err.message : 'Failed to save view')\n }\n }\n\n const handleToggleColumnWithAutosave = React.useCallback((key: string) => {\n onToggleColumn(key)\n scheduleAutosave()\n }, [onToggleColumn, scheduleAutosave])\n\n const handleReorderColumnsWithAutosave = React.useCallback((orderedIds: string[]) => {\n onReorderColumns(orderedIds)\n scheduleAutosave()\n }, [onReorderColumns, scheduleAutosave])\n\n const handleRename = async (p: PerspectiveDto | RolePerspectiveDto) => {\n const trimmed = renameValue.trim()\n if (!trimmed) {\n setRenamingId(null)\n return\n }\n const conflict = perspectivesRef.current.some(\n (item) => item.id !== p.id && item.name.trim() === trimmed,\n )\n if (conflict) {\n flash(t('ui.perspectives.error.nameExists', 'View with this name already exists'), 'error')\n return\n }\n setError(null)\n try {\n await onSave({\n name: trimmed,\n isDefault: p.isDefault,\n applyToRoles: [],\n setRoleDefault: false,\n perspectiveId: p.id,\n })\n setRenamingId(null)\n } catch (err: unknown) {\n if (surfaceRecordConflict(err, t)) return\n setError(err instanceof Error ? err.message : 'Failed to rename view')\n }\n }\n\n const handleClone = async (p: PerspectiveDto | RolePerspectiveDto) => {\n const originalName = perspectiveLabel(p)\n setError(null)\n const baseline = new Set(perspectivesRef.current.map((item) => item.id))\n const originalSettingsKey = JSON.stringify(p.settings ?? {})\n const sharedRoleIds = Array.from(\n new Set(\n rolePerspectives\n .filter((rp) => JSON.stringify(rp.settings ?? {}) === originalSettingsKey)\n .map((rp) => rp.roleId),\n ),\n )\n const buildCloneName = (n: number) =>\n n <= 1 ? `${originalName} (copy)` : `${originalName} (copy ${n})`\n const existingNames = new Set(\n perspectivesRef.current.map((item) => item.name.trim()),\n )\n let counter = 1\n while (existingNames.has(buildCloneName(counter))) {\n counter += 1\n }\n const clonedSettings = structuredClone(p.settings)\n const MAX_ATTEMPTS = 50\n let lastErr: unknown = null\n for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt += 1) {\n try {\n await onSave({\n name: buildCloneName(counter),\n isDefault: false,\n applyToRoles: sharedRoleIds,\n setRoleDefault: false,\n perspectiveId: null,\n settings: clonedSettings,\n })\n setPendingCloneBaselineIds(baseline)\n return\n } catch (err: unknown) {\n const errMessage = err instanceof Error ? err.message : ''\n const msg = errMessage.toLowerCase()\n const isDuplicate = msg.includes('duplicate key') || msg.includes('unique constraint')\n if (!isDuplicate) {\n if (surfaceRecordConflict(err, t)) return\n setError(errMessage || 'Failed to clone view')\n return\n }\n lastErr = err\n counter += 1\n }\n }\n if (surfaceRecordConflict(lastErr, t)) return\n setError(lastErr instanceof Error ? lastErr.message : 'Failed to clone view')\n }\n\n React.useEffect(() => {\n if (!pendingCloneBaselineIds) return\n const created = perspectives.find((item) => !pendingCloneBaselineIds.has(item.id))\n if (!created) return\n setRenamingId(created.id)\n setRenameValue(created.name)\n setPendingCloneBaselineIds(null)\n }, [perspectives, pendingCloneBaselineIds])\n\n const handleDelete = async (p: PerspectiveDto) => {\n const confirmed = await confirm({\n title: t('ui.perspectives.delete.title', 'Delete \"{name}\"?', { name: perspectiveLabel(p) }),\n text: t('ui.perspectives.delete.text', 'This view will be removed for you and all shared roles. This cannot be undone.'),\n confirmText: t('common.delete', 'Delete'),\n variant: 'destructive',\n })\n if (confirmed) {\n await onDeletePerspective(p.id)\n }\n }\n\n const handleDeleteRole = async (p: RolePerspectiveDto) => {\n const confirmed = await confirm({\n title: t('ui.perspectives.delete.title', 'Delete \"{name}\"?', { name: perspectiveLabel(p) }),\n text: t('ui.perspectives.deleteRole.text', 'This shared view will be removed for the role. This cannot be undone.'),\n confirmText: t('common.delete', 'Delete'),\n variant: 'destructive',\n })\n if (confirmed) {\n await onClearRole(p)\n }\n }\n\n const handleShareApply = async () => {\n if (mode.type !== 'share') return\n setError(null)\n try {\n await onSave({ name: mode.perspectiveName, isDefault: mode.perspectiveIsDefault, applyToRoles: shareRoles, setRoleDefault: shareSetDefault, perspectiveId: mode.perspectiveId })\n setSharedIds((prev) => new Set([...prev, mode.perspectiveId]))\n resetMode()\n } catch (err: unknown) {\n if (surfaceRecordConflict(err, t)) return\n setError(err instanceof Error ? err.message : 'Failed to share view')\n }\n }\n\n const toggleShareRole = (roleId: string) => {\n setShareRoles((prev) => {\n const next = new Set(prev)\n if (next.has(roleId)) next.delete(roleId)\n else next.add(roleId)\n return Array.from(next)\n })\n }\n\n if (!open) return null\n\n const isNew = mode.type === 'new'\n const isShare = mode.type === 'share'\n\n return (\n <div className=\"fixed inset-0 z-modal\">\n <div className=\"absolute inset-0 bg-black/20\" onClick={() => onOpenChange(false)} role=\"presentation\" />\n <div className=\"fixed right-0 top-0 h-full w-full sm:w-80 bg-background shadow-xl border-l flex flex-col\">\n <div className=\"flex items-center p-4 border-b\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => onOpenChange(false)}\n className=\"h-auto -ml-2 gap-2 px-2 text-lg font-semibold hover:bg-transparent\"\n aria-label={t('ui.perspectives.close', 'Close')}\n >\n <ArrowLeft className=\"size-5\" />\n {t('ui.perspectives.title', 'Views')}\n </Button>\n </div>\n <div className=\"flex-1 overflow-auto\">\n {/* Saved views as chips */}\n <section className=\"p-4 space-y-3\">\n <h3 className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">{t('ui.perspectives.savedViews.title', 'Saved views')}</h3>\n {loading ? <Spinner size=\"sm\" /> : null}\n <div className=\"flex flex-wrap gap-1.5\">\n {/* + New chip */}\n <Button\n type=\"button\"\n variant={isNew ? 'secondary' : 'outline'}\n size=\"sm\"\n className={`h-8 px-3 py-1.5 text-sm ${!isNew ? 'border-dashed' : ''}`}\n onClick={startNewMode}\n >\n <Plus className=\"size-3 mr-1\" />\n {t('ui.perspectives.savedViews.new', 'New')}\n </Button>\n {(perspectives ?? emptyArray).map((p) => {\n const isActive = activePerspectiveId === p.id\n const deleting = deletingIds.includes(p.id)\n const isShared = sharedIds.has(p.id)\n return (\n <ViewChip\n key={p.id}\n id={p.id}\n label={perspectiveLabel(p)}\n kind=\"personal\"\n isActive={isActive}\n disabled={deleting}\n isShared={isShared}\n isRenaming={renamingId === p.id}\n renameValue={renameValue}\n canApplyToRoles={canApplyToRoles}\n deleting={deleting}\n onActivate={() => { onActivatePerspective(p, 'personal'); resetMode() }}\n onRenameValueChange={setRenameValue}\n onRenameConfirm={() => void handleRename(p)}\n onRenameCancel={() => setRenamingId(null)}\n onRenameStart={() => { setRenamingId(p.id); setRenameValue(p.name) }}\n onClone={() => void handleClone(p)}\n onShareStart={() => startShareMode(p)}\n onDelete={() => void handleDelete(p)}\n />\n )\n })}\n {rolePerspectives\n .filter((rp) => {\n const rpName = rp.name.trim()\n return !perspectives.some((pp) => pp.name.trim() === rpName)\n })\n .map((p) => {\n const isActive = activePerspectiveId === p.id\n const clearing = roleClearingIds.includes(p.roleId)\n return (\n <ViewChip\n key={p.id}\n id={p.id}\n label={perspectiveLabel(p)}\n kind=\"role\"\n isActive={isActive}\n disabled={clearing}\n isShared={false}\n isRenaming={renamingId === p.id}\n renameValue={renameValue}\n canApplyToRoles={canApplyToRoles}\n deleting={clearing}\n onActivate={() => { onActivatePerspective(p, 'role'); resetMode() }}\n onRenameValueChange={setRenameValue}\n onRenameConfirm={() => void handleRename(p)}\n onRenameCancel={() => setRenamingId(null)}\n onClone={() => void handleClone(p)}\n onDelete={() => void handleDeleteRole(p)}\n />\n )\n })}\n </div>\n\n {/* Inline form slot \u2014 shared between New and Share modes */}\n {isNew ? (\n <NewViewForm\n name={name}\n onNameChange={setName}\n onSubmit={() => void handleSaveNew()}\n onCancel={resetMode}\n saving={saving}\n />\n ) : null}\n\n {isShare ? (\n <ShareForm\n roles={roles}\n shareRoles={shareRoles}\n shareSetDefault={shareSetDefault}\n onToggleRole={toggleShareRole}\n onToggleSetDefault={setShareSetDefault}\n onApply={() => void handleShareApply()}\n onCancel={resetMode}\n />\n ) : null}\n\n {apiWarning ? (\n <Alert status=\"warning\" className=\"text-xs\">{apiWarning}</Alert>\n ) : null}\n {error ? <div className=\"text-sm text-status-error-text\">{error}</div> : null}\n </section>\n\n {/* Set as default \u2014 separated from chips (border-t) and from columns (ColumnList owns border-t) */}\n <div className=\"flex items-center px-4 mt-2 pt-2 pb-2\">\n <label className=\"inline-flex items-center gap-2 text-sm leading-none\">\n <Checkbox\n checked={isDefault}\n onCheckedChange={(checked) => {\n setIsDefault(checked === true)\n if (isDefaultUserChangeRef.current) {\n scheduleAutosave()\n }\n }}\n />\n {t('ui.perspectives.form.makeDefault', 'Set as default')}\n </label>\n </div>\n\n <ColumnChooserSection\n availableColumns={availableColumns}\n visibleColumnKeys={visibleColumnKeys}\n columnOrder={columnOrder}\n onToggleColumn={handleToggleColumnWithAutosave}\n onReorderColumns={handleReorderColumnsWithAutosave}\n dndContextId=\"perspective-columns\"\n />\n </div>\n </div>\n {ConfirmDialogElement}\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { ArrowLeft, Plus } from 'lucide-react'\nimport { Alert } from '../primitives/alert'\nimport { Button } from '../primitives/button'\nimport { Checkbox } from '../primitives/checkbox'\nimport { Spinner } from '../primitives/spinner'\nimport { useConfirmDialog } from './confirm-dialog'\nimport { flash } from './FlashMessages'\nimport { surfaceRecordConflict } from './conflicts'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type {\n PerspectiveDto,\n PerspectiveSettings,\n RolePerspectiveDto,\n} from '@open-mercato/shared/modules/perspectives/types'\nimport { ViewChip } from './views/ViewChip'\nimport { NewViewForm } from './views/NewViewForm'\nimport { ShareForm } from './views/ShareForm'\nimport { type SidebarMode } from './views/types'\nimport { ColumnChooserSection, type ColumnChooserField } from './columns/ColumnChooserPanel'\n\nexport type { ColumnChooserField } from './columns/ColumnChooserPanel'\n\nexport type PerspectiveSidebarProps = {\n open: boolean\n onOpenChange: (open: boolean) => void\n loading: boolean\n perspectives: PerspectiveDto[]\n rolePerspectives: RolePerspectiveDto[]\n roles: Array<{ id: string; name: string; hasPerspective: boolean; hasDefault: boolean }>\n activePerspectiveId: string | null\n onActivatePerspective: (perspective: PerspectiveDto | RolePerspectiveDto, source: 'personal' | 'role') => void\n onDeletePerspective: (perspectiveId: string) => Promise<void>\n onClearRole: (perspective: RolePerspectiveDto) => Promise<void>\n onSave: (input: { name: string; isDefault: boolean; applyToRoles: string[]; setRoleDefault: boolean; perspectiveId?: string | null; settings?: PerspectiveSettings }) => Promise<void>\n canApplyToRoles: boolean\n availableColumns: ColumnChooserField[]\n visibleColumnKeys: string[]\n columnOrder: string[]\n onToggleColumn: (key: string) => void\n onReorderColumns: (orderedIds: string[]) => void\n saving: boolean\n deletingIds: string[]\n roleClearingIds: string[]\n apiWarning?: string | null\n}\n\nconst emptyArray: any[] = []\n\nexport function PerspectiveSidebar({\n open,\n onOpenChange,\n loading,\n perspectives,\n rolePerspectives,\n roles,\n activePerspectiveId,\n onActivatePerspective,\n onDeletePerspective,\n onClearRole,\n onSave,\n canApplyToRoles,\n availableColumns,\n visibleColumnKeys,\n columnOrder,\n onToggleColumn,\n onReorderColumns,\n saving,\n deletingIds,\n roleClearingIds,\n apiWarning,\n}: PerspectiveSidebarProps) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n React.useEffect(() => {\n if (!open) return\n if (typeof document === 'undefined') return\n document.body.dataset.columnChooserOpen = 'true'\n return () => {\n delete document.body.dataset.columnChooserOpen\n }\n }, [open])\n\n function perspectiveLabel(p: PerspectiveDto | RolePerspectiveDto) {\n return p.name.trim().length ? p.name : t('ui.perspectives.untitled', 'Untitled view')\n }\n\n const [name, setName] = React.useState('')\n const [isDefault, setIsDefault] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const [mode, setMode] = React.useState<SidebarMode>({ type: 'idle' })\n const [renamingId, setRenamingId] = React.useState<string | null>(null)\n const [renameValue, setRenameValue] = React.useState('')\n const [shareRoles, setShareRoles] = React.useState<string[]>([])\n const [shareSetDefault, setShareSetDefault] = React.useState(false)\n const [sharedIds, setSharedIds] = React.useState<Set<string>>(new Set())\n const [pendingCloneBaselineIds, setPendingCloneBaselineIds] = React.useState<Set<string> | null>(null)\n\n const autosaveRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)\n const pendingAutosaveActionRef = React.useRef<(() => void) | null>(null)\n const isDefaultUserChangeRef = React.useRef(false)\n const isDefaultRef = React.useRef(isDefault)\n isDefaultRef.current = isDefault\n\n const onSaveRef = React.useRef(onSave)\n onSaveRef.current = onSave\n\n const perspectivesRef = React.useRef(perspectives)\n perspectivesRef.current = perspectives\n\n const rolePerspectivesRef = React.useRef(rolePerspectives)\n rolePerspectivesRef.current = rolePerspectives\n\n const activePerspectiveIdRef = React.useRef(activePerspectiveId)\n activePerspectiveIdRef.current = activePerspectiveId\n\n const flushAutosave = React.useCallback(() => {\n if (autosaveRef.current) {\n clearTimeout(autosaveRef.current)\n autosaveRef.current = null\n }\n pendingAutosaveActionRef.current = null\n }, [])\n\n // Closing the panel or unmounting inside the debounce window must not drop\n // a pending autosave save or shared-view warning in silence \u2014 that is the\n // same discarded-edit bug (#5113) the debounce itself was added to fix.\n // Run whatever is pending immediately instead of just cancelling it.\n const runPendingAutosave = React.useCallback(() => {\n if (!autosaveRef.current) return\n clearTimeout(autosaveRef.current)\n autosaveRef.current = null\n const pending = pendingAutosaveActionRef.current\n pendingAutosaveActionRef.current = null\n pending?.()\n }, [])\n\n const scheduleAutosave = React.useCallback(() => {\n if (!activePerspectiveId || mode.type === 'new') return\n const activePersonal = perspectivesRef.current.find((p) => p.id === activePerspectiveId)\n if (!activePersonal) {\n // Role perspectives live in their own collection and are shared, so they\n // are never autosaved into. Say so instead of dropping the edit in\n // silence \u2014 the old early return made a discarded change look saved\n // (#5113). The timer is reused purely to debounce the hint across a burst\n // of column toggles.\n const activeRole = rolePerspectivesRef.current.find((p) => p.id === activePerspectiveId)\n if (!activeRole) return\n flushAutosave()\n const warnedId = activeRole.id\n const emitWarning = () => {\n autosaveRef.current = null\n pendingAutosaveActionRef.current = null\n // Switching away within the debounce window makes the warning obsolete \u2014\n // it would name a shared view the user is no longer editing.\n if (activePerspectiveIdRef.current !== warnedId) return\n flash(\n t(\n 'ui.perspectives.autosave.sharedView',\n 'Shared views do not save automatically. Use Clone to keep these changes in your own view.',\n ),\n 'warning',\n )\n }\n pendingAutosaveActionRef.current = emitWarning\n autosaveRef.current = setTimeout(emitWarning, 400)\n return\n }\n flushAutosave()\n const targetId = activePersonal.id\n const targetName = activePersonal.name\n const runSave = () => {\n autosaveRef.current = null\n pendingAutosaveActionRef.current = null\n void (async () => {\n try {\n await onSaveRef.current({\n name: targetName,\n isDefault: isDefaultRef.current,\n applyToRoles: [],\n setRoleDefault: false,\n perspectiveId: targetId,\n })\n flash(t('ui.perspectives.autosave.success', 'View saved'), 'success')\n } catch (err: unknown) {\n if (surfaceRecordConflict(err, t)) return\n flash(t('ui.perspectives.autosave.error', 'Failed to save view'), 'error')\n }\n })()\n }\n pendingAutosaveActionRef.current = runSave\n autosaveRef.current = setTimeout(runSave, 400)\n }, [activePerspectiveId, mode.type, flushAutosave, t])\n\n React.useEffect(() => {\n return () => { runPendingAutosave() }\n }, [runPendingAutosave])\n\n const resetMode = () => {\n setMode({ type: 'idle' })\n setName('')\n setShareRoles([])\n setShareSetDefault(false)\n }\n\n const startNewMode = () => {\n setMode({ type: 'new' })\n setName('')\n setIsDefault(false)\n setRenamingId(null)\n setShareRoles([])\n setShareSetDefault(false)\n }\n\n const startShareMode = (p: PerspectiveDto) => {\n setMode({ type: 'share', perspectiveId: p.id, perspectiveName: p.name, perspectiveIsDefault: p.isDefault })\n setName('')\n setRenamingId(null)\n setShareRoles([])\n setShareSetDefault(false)\n }\n\n React.useEffect(() => {\n if (!open) {\n runPendingAutosave()\n setError(null)\n resetMode()\n setRenamingId(null)\n setSharedIds(new Set())\n setPendingCloneBaselineIds(null)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open])\n\n React.useEffect(() => {\n if (!open) return\n const active = perspectives.find((p) => p.id === activePerspectiveId)\n ?? rolePerspectives.find((p) => p.id === activePerspectiveId)\n isDefaultUserChangeRef.current = false\n if (active) {\n setIsDefault(active.isDefault)\n } else {\n setIsDefault(false)\n }\n requestAnimationFrame(() => { isDefaultUserChangeRef.current = true })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, activePerspectiveId])\n\n const handleSaveNew = async () => {\n setError(null)\n try {\n await onSave({ name: name.trim(), isDefault, applyToRoles: [], setRoleDefault: false, perspectiveId: null })\n resetMode()\n } catch (err: unknown) {\n if (surfaceRecordConflict(err, t)) return\n setError(err instanceof Error ? err.message : 'Failed to save view')\n }\n }\n\n const handleToggleColumnWithAutosave = React.useCallback((key: string) => {\n onToggleColumn(key)\n scheduleAutosave()\n }, [onToggleColumn, scheduleAutosave])\n\n const handleReorderColumnsWithAutosave = React.useCallback((orderedIds: string[]) => {\n onReorderColumns(orderedIds)\n scheduleAutosave()\n }, [onReorderColumns, scheduleAutosave])\n\n const handleRename = async (p: PerspectiveDto | RolePerspectiveDto) => {\n const trimmed = renameValue.trim()\n if (!trimmed) {\n setRenamingId(null)\n return\n }\n const conflict = perspectivesRef.current.some(\n (item) => item.id !== p.id && item.name.trim() === trimmed,\n )\n if (conflict) {\n flash(t('ui.perspectives.error.nameExists', 'View with this name already exists'), 'error')\n return\n }\n setError(null)\n try {\n await onSave({\n name: trimmed,\n isDefault: p.isDefault,\n applyToRoles: [],\n setRoleDefault: false,\n perspectiveId: p.id,\n })\n setRenamingId(null)\n } catch (err: unknown) {\n if (surfaceRecordConflict(err, t)) return\n setError(err instanceof Error ? err.message : 'Failed to rename view')\n }\n }\n\n const handleClone = async (p: PerspectiveDto | RolePerspectiveDto) => {\n const originalName = perspectiveLabel(p)\n setError(null)\n const baseline = new Set(perspectivesRef.current.map((item) => item.id))\n const originalSettingsKey = JSON.stringify(p.settings ?? {})\n const sharedRoleIds = Array.from(\n new Set(\n rolePerspectives\n .filter((rp) => JSON.stringify(rp.settings ?? {}) === originalSettingsKey)\n .map((rp) => rp.roleId),\n ),\n )\n const buildCloneName = (n: number) =>\n n <= 1 ? `${originalName} (copy)` : `${originalName} (copy ${n})`\n const existingNames = new Set(\n perspectivesRef.current.map((item) => item.name.trim()),\n )\n let counter = 1\n while (existingNames.has(buildCloneName(counter))) {\n counter += 1\n }\n const clonedSettings = structuredClone(p.settings)\n const MAX_ATTEMPTS = 50\n let lastErr: unknown = null\n for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt += 1) {\n try {\n await onSave({\n name: buildCloneName(counter),\n isDefault: false,\n applyToRoles: sharedRoleIds,\n setRoleDefault: false,\n perspectiveId: null,\n settings: clonedSettings,\n })\n setPendingCloneBaselineIds(baseline)\n return\n } catch (err: unknown) {\n const errMessage = err instanceof Error ? err.message : ''\n const msg = errMessage.toLowerCase()\n const isDuplicate = msg.includes('duplicate key') || msg.includes('unique constraint')\n if (!isDuplicate) {\n if (surfaceRecordConflict(err, t)) return\n setError(errMessage || 'Failed to clone view')\n return\n }\n lastErr = err\n counter += 1\n }\n }\n if (surfaceRecordConflict(lastErr, t)) return\n setError(lastErr instanceof Error ? lastErr.message : 'Failed to clone view')\n }\n\n React.useEffect(() => {\n if (!pendingCloneBaselineIds) return\n const created = perspectives.find((item) => !pendingCloneBaselineIds.has(item.id))\n if (!created) return\n setRenamingId(created.id)\n setRenameValue(created.name)\n setPendingCloneBaselineIds(null)\n }, [perspectives, pendingCloneBaselineIds])\n\n const handleDelete = async (p: PerspectiveDto) => {\n const confirmed = await confirm({\n title: t('ui.perspectives.delete.title', 'Delete \"{name}\"?', { name: perspectiveLabel(p) }),\n text: t('ui.perspectives.delete.text', 'This view will be removed for you and all shared roles. This cannot be undone.'),\n confirmText: t('common.delete', 'Delete'),\n variant: 'destructive',\n })\n if (confirmed) {\n await onDeletePerspective(p.id)\n }\n }\n\n const handleDeleteRole = async (p: RolePerspectiveDto) => {\n const confirmed = await confirm({\n title: t('ui.perspectives.delete.title', 'Delete \"{name}\"?', { name: perspectiveLabel(p) }),\n text: t('ui.perspectives.deleteRole.text', 'This shared view will be removed for the role. This cannot be undone.'),\n confirmText: t('common.delete', 'Delete'),\n variant: 'destructive',\n })\n if (confirmed) {\n await onClearRole(p)\n }\n }\n\n const handleShareApply = async () => {\n if (mode.type !== 'share') return\n setError(null)\n try {\n await onSave({ name: mode.perspectiveName, isDefault: mode.perspectiveIsDefault, applyToRoles: shareRoles, setRoleDefault: shareSetDefault, perspectiveId: mode.perspectiveId })\n setSharedIds((prev) => new Set([...prev, mode.perspectiveId]))\n resetMode()\n } catch (err: unknown) {\n if (surfaceRecordConflict(err, t)) return\n setError(err instanceof Error ? err.message : 'Failed to share view')\n }\n }\n\n const toggleShareRole = (roleId: string) => {\n setShareRoles((prev) => {\n const next = new Set(prev)\n if (next.has(roleId)) next.delete(roleId)\n else next.add(roleId)\n return Array.from(next)\n })\n }\n\n if (!open) return null\n\n const isNew = mode.type === 'new'\n const isShare = mode.type === 'share'\n\n return (\n <div className=\"fixed inset-0 z-modal\">\n <div className=\"absolute inset-0 bg-black/20\" onClick={() => onOpenChange(false)} role=\"presentation\" />\n <div className=\"fixed right-0 top-0 h-full w-full sm:w-80 bg-background shadow-xl border-l flex flex-col\">\n <div className=\"flex items-center p-4 border-b\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => onOpenChange(false)}\n className=\"h-auto -ml-2 gap-2 px-2 text-lg font-semibold hover:bg-transparent\"\n aria-label={t('ui.perspectives.close', 'Close')}\n >\n <ArrowLeft className=\"size-5\" />\n {t('ui.perspectives.title', 'Views')}\n </Button>\n </div>\n <div className=\"flex-1 overflow-auto\">\n {/* Saved views as chips */}\n <section className=\"p-4 space-y-3\">\n <h3 className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">{t('ui.perspectives.savedViews.title', 'Saved views')}</h3>\n {loading ? <Spinner size=\"sm\" /> : null}\n <div className=\"flex flex-wrap gap-1.5\">\n {/* + New chip */}\n <Button\n type=\"button\"\n variant={isNew ? 'secondary' : 'outline'}\n size=\"sm\"\n className={`h-8 px-3 py-1.5 text-sm ${!isNew ? 'border-dashed' : ''}`}\n onClick={startNewMode}\n >\n <Plus className=\"size-3 mr-1\" />\n {t('ui.perspectives.savedViews.new', 'New')}\n </Button>\n {(perspectives ?? emptyArray).map((p) => {\n // While the new-view form is open the sidebar is creating, not\n // editing: keeping a chip lit reads as \"I am editing the active\n // view\" and hides the mode switch (#5113).\n const isActive = !isNew && activePerspectiveId === p.id\n const deleting = deletingIds.includes(p.id)\n const isShared = sharedIds.has(p.id)\n return (\n <ViewChip\n key={p.id}\n id={p.id}\n label={perspectiveLabel(p)}\n kind=\"personal\"\n isActive={isActive}\n disabled={deleting}\n isShared={isShared}\n isRenaming={renamingId === p.id}\n renameValue={renameValue}\n canApplyToRoles={canApplyToRoles}\n deleting={deleting}\n onActivate={() => { onActivatePerspective(p, 'personal'); resetMode() }}\n onRenameValueChange={setRenameValue}\n onRenameConfirm={() => void handleRename(p)}\n onRenameCancel={() => setRenamingId(null)}\n onRenameStart={() => { setRenamingId(p.id); setRenameValue(p.name) }}\n onClone={() => void handleClone(p)}\n onShareStart={() => startShareMode(p)}\n onDelete={() => void handleDelete(p)}\n />\n )\n })}\n {rolePerspectives\n .filter((rp) => {\n const rpName = rp.name.trim()\n return !perspectives.some((pp) => pp.name.trim() === rpName)\n })\n .map((p) => {\n // While the new-view form is open the sidebar is creating, not\n // editing: keeping a chip lit reads as \"I am editing the active\n // view\" and hides the mode switch (#5113).\n const isActive = !isNew && activePerspectiveId === p.id\n const clearing = roleClearingIds.includes(p.roleId)\n return (\n <ViewChip\n key={p.id}\n id={p.id}\n label={perspectiveLabel(p)}\n kind=\"role\"\n isActive={isActive}\n disabled={clearing}\n isShared={false}\n isRenaming={renamingId === p.id}\n renameValue={renameValue}\n canApplyToRoles={canApplyToRoles}\n deleting={clearing}\n onActivate={() => { onActivatePerspective(p, 'role'); resetMode() }}\n onRenameValueChange={setRenameValue}\n onRenameConfirm={() => void handleRename(p)}\n onRenameCancel={() => setRenamingId(null)}\n onClone={() => void handleClone(p)}\n onDelete={() => void handleDeleteRole(p)}\n />\n )\n })}\n </div>\n\n {/* Inline form slot \u2014 shared between New and Share modes */}\n {isNew ? (\n <NewViewForm\n name={name}\n onNameChange={setName}\n onSubmit={() => void handleSaveNew()}\n onCancel={resetMode}\n saving={saving}\n />\n ) : null}\n\n {isShare ? (\n <ShareForm\n roles={roles}\n shareRoles={shareRoles}\n shareSetDefault={shareSetDefault}\n onToggleRole={toggleShareRole}\n onToggleSetDefault={setShareSetDefault}\n onApply={() => void handleShareApply()}\n onCancel={resetMode}\n />\n ) : null}\n\n {apiWarning ? (\n <Alert status=\"warning\" className=\"text-xs\">{apiWarning}</Alert>\n ) : null}\n {error ? <div className=\"text-sm text-status-error-text\">{error}</div> : null}\n </section>\n\n {/* Set as default \u2014 separated from chips (border-t) and from columns (ColumnList owns border-t) */}\n <div className=\"flex items-center px-4 mt-2 pt-2 pb-2\">\n <label className=\"inline-flex items-center gap-2 text-sm leading-none\">\n <Checkbox\n checked={isDefault}\n onCheckedChange={(checked) => {\n setIsDefault(checked === true)\n if (isDefaultUserChangeRef.current) {\n scheduleAutosave()\n }\n }}\n />\n {t('ui.perspectives.form.makeDefault', 'Set as default')}\n </label>\n </div>\n\n <ColumnChooserSection\n availableColumns={availableColumns}\n visibleColumnKeys={visibleColumnKeys}\n columnOrder={columnOrder}\n onToggleColumn={handleToggleColumnWithAutosave}\n onReorderColumns={handleReorderColumnsWithAutosave}\n dndContextId=\"perspective-columns\"\n />\n </div>\n </div>\n {ConfirmDialogElement}\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -10,7 +10,10 @@ function ActionsDropdown({
10
10
  label,
11
11
  triggerMode = "label",
12
12
  ariaLabel,
13
- size = "sm"
13
+ size = "sm",
14
+ triggerClassName,
15
+ triggerIcon,
16
+ attention = false
14
17
  }) {
15
18
  const t = useT();
16
19
  const [open, setOpen] = React.useState(false);
@@ -96,7 +99,7 @@ function ActionsDropdown({
96
99
  type: "button",
97
100
  variant: "outline",
98
101
  size,
99
- className: triggerMode === "icon" ? "px-2" : void 0,
102
+ className: `${triggerMode === "icon" ? "px-2 " : ""}${triggerClassName ?? ""}`.trim() || void 0,
100
103
  "aria-haspopup": "menu",
101
104
  "aria-expanded": open,
102
105
  "aria-label": resolvedAriaLabel,
@@ -109,11 +112,18 @@ function ActionsDropdown({
109
112
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: resolvedAriaLabel })
110
113
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
111
114
  resolvedLabel,
112
- /* @__PURE__ */ jsx(Zap, { className: "size-4 ml-1" }),
115
+ triggerIcon === false ? null : triggerIcon ? React.createElement(triggerIcon, { className: "size-4 ml-1" }) : /* @__PURE__ */ jsx(Zap, { className: "size-4 ml-1" }),
113
116
  /* @__PURE__ */ jsx(ChevronDown, { className: `size-3.5 transition-transform duration-150 ${open ? "rotate-180" : ""}` })
114
117
  ] })
115
118
  }
116
119
  ),
120
+ attention && /* @__PURE__ */ jsx(
121
+ "span",
122
+ {
123
+ "aria-hidden": "true",
124
+ className: "pointer-events-none absolute right-0.5 top-0.5 size-2 rounded-full bg-status-warning-icon ring-2 ring-background"
125
+ }
126
+ ),
117
127
  open && anchorRect && createPortal(
118
128
  /* @__PURE__ */ jsx(
119
129
  "div",
@@ -128,7 +138,27 @@ function ActionsDropdown({
128
138
  left: anchorRect.right,
129
139
  transform: `translate(-100%, ${direction === "down" ? "0" : "-100%"})`
130
140
  },
131
- children: items.map((item) => {
141
+ children: items.map((item, index) => {
142
+ if ("header" in item) {
143
+ return /* @__PURE__ */ jsx(
144
+ "div",
145
+ {
146
+ className: "px-2 pb-1 pt-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground",
147
+ children: item.header
148
+ },
149
+ item.id ?? `header-${index}`
150
+ );
151
+ }
152
+ if ("separator" in item) {
153
+ return /* @__PURE__ */ jsx(
154
+ "div",
155
+ {
156
+ role: "separator",
157
+ className: "my-1 h-px bg-border"
158
+ },
159
+ item.id ?? `separator-${index}`
160
+ );
161
+ }
132
162
  const Icon = item.icon;
133
163
  return /* @__PURE__ */ jsxs(
134
164
  Button,
@@ -136,7 +166,7 @@ function ActionsDropdown({
136
166
  type: "button",
137
167
  variant: "ghost",
138
168
  size: "sm",
139
- className: "w-full justify-start h-auto min-h-8 py-1.5 whitespace-normal text-left leading-snug",
169
+ className: `w-full justify-start h-auto min-h-8 py-1.5 whitespace-normal text-left leading-snug${item.destructive ? " text-destructive hover:text-destructive hover:bg-destructive/10 focus-visible:text-destructive" : ""}`,
140
170
  role: "menuitem",
141
171
  disabled: item.disabled,
142
172
  onClick: () => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/backend/forms/ActionsDropdown.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { createPortal } from 'react-dom'\nimport { Zap, ChevronDown, Loader2, MoreHorizontal } from 'lucide-react'\nimport { Button } from '../../primitives/button'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport type ActionItem = {\n /** Unique key */\n id: string\n /** Display label */\n label: string\n /** Lucide icon component (optional) */\n icon?: React.ComponentType<{ className?: string }>\n /** Click handler */\n onSelect: () => void\n /** Disable the item */\n disabled?: boolean\n /** Show a loading spinner instead of the icon */\n loading?: boolean\n}\n\nexport type ActionsDropdownProps = {\n /** Items to render inside the dropdown */\n items: ActionItem[]\n /** Button label (default: translated 'Actions') */\n label?: string\n /** Trigger style */\n triggerMode?: 'label' | 'icon'\n /** Accessible label for icon trigger */\n ariaLabel?: string\n /** Button size (default: 'sm') */\n size?: 'sm' | 'default'\n}\n\nexport function ActionsDropdown({\n items,\n label,\n triggerMode = 'label',\n ariaLabel,\n size = 'sm',\n}: ActionsDropdownProps) {\n const t = useT()\n const [open, setOpen] = React.useState(false)\n const btnRef = React.useRef<HTMLButtonElement>(null)\n const menuRef = React.useRef<HTMLDivElement>(null)\n const [anchorRect, setAnchorRect] = React.useState<DOMRect | null>(null)\n const hoverTimeoutRef = React.useRef<NodeJS.Timeout | null>(null)\n const [direction, setDirection] = React.useState<'down' | 'up'>('down')\n\n const resolvedLabel = label ?? t('ui.actions.actions', 'Actions')\n const resolvedAriaLabel = ariaLabel ?? resolvedLabel\n\n const updatePosition = React.useCallback(() => {\n if (!btnRef.current) return\n const rect = btnRef.current.getBoundingClientRect()\n setAnchorRect(rect)\n const spaceBelow = window.innerHeight - rect.bottom\n const spaceAbove = rect.top\n setDirection(spaceBelow < 200 && spaceAbove > spaceBelow ? 'up' : 'down')\n }, [])\n\n React.useEffect(() => {\n if (!open) return\n updatePosition()\n function onDocClick(event: MouseEvent) {\n const target = event.target as Node\n if (\n menuRef.current && !menuRef.current.contains(target) &&\n btnRef.current && !btnRef.current.contains(target)\n ) {\n setOpen(false)\n }\n }\n function onKey(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n setOpen(false)\n btnRef.current?.focus()\n }\n }\n function onScrollOrResize() {\n updatePosition()\n }\n document.addEventListener('mousedown', onDocClick)\n document.addEventListener('keydown', onKey)\n window.addEventListener('scroll', onScrollOrResize, true)\n window.addEventListener('resize', onScrollOrResize)\n return () => {\n document.removeEventListener('mousedown', onDocClick)\n document.removeEventListener('keydown', onKey)\n window.removeEventListener('scroll', onScrollOrResize, true)\n window.removeEventListener('resize', onScrollOrResize)\n }\n }, [open, updatePosition])\n\n React.useEffect(() => {\n return () => {\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current)\n }\n }\n }, [])\n\n const handleMouseEnter = () => {\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current)\n }\n setOpen(true)\n updatePosition()\n }\n\n const handleMouseLeave = (event: React.MouseEvent) => {\n const nextTarget = event.relatedTarget as Node | null\n if (nextTarget && (btnRef.current?.contains(nextTarget) || menuRef.current?.contains(nextTarget))) {\n return\n }\n hoverTimeoutRef.current = setTimeout(() => {\n setOpen(false)\n }, 150)\n }\n\n if (!items.length) return null\n\n return (\n <div\n className=\"relative inline-block\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n <Button\n ref={btnRef}\n type=\"button\"\n variant=\"outline\"\n size={size}\n className={triggerMode === 'icon' ? 'px-2' : undefined}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-label={resolvedAriaLabel}\n onClick={() => {\n setOpen((prev) => !prev)\n requestAnimationFrame(updatePosition)\n }}\n >\n {triggerMode === 'icon' ? (\n <>\n <MoreHorizontal className=\"size-4\" />\n <span className=\"sr-only\">{resolvedAriaLabel}</span>\n </>\n ) : (\n <>\n {resolvedLabel}\n <Zap className=\"size-4 ml-1\" />\n <ChevronDown className={`size-3.5 transition-transform duration-150 ${open ? 'rotate-180' : ''}`} />\n </>\n )}\n </Button>\n {open && anchorRect && createPortal(\n <div\n ref={menuRef}\n role=\"menu\"\n className=\"fixed min-w-52 w-max max-w-xs rounded-md border bg-background p-1 shadow-md focus-visible:outline-none z-dropdown\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n style={{\n top: direction === 'down' ? anchorRect.bottom + 4 : anchorRect.top - 4,\n left: anchorRect.right,\n transform: `translate(-100%, ${direction === 'down' ? '0' : '-100%'})`,\n }}\n >\n {items.map((item) => {\n const Icon = item.icon\n return (\n <Button\n key={item.id}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"w-full justify-start h-auto min-h-8 py-1.5 whitespace-normal text-left leading-snug\"\n role=\"menuitem\"\n disabled={item.disabled}\n onClick={() => {\n setOpen(false)\n item.onSelect()\n }}\n >\n {item.loading ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : Icon ? (\n <Icon className=\"size-4\" />\n ) : (\n <span className=\"size-4\" />\n )}\n {item.label}\n </Button>\n )\n })}\n </div>,\n document.body,\n )}\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { createPortal } from 'react-dom'\nimport { Zap, ChevronDown, Loader2, MoreHorizontal } from 'lucide-react'\nimport { Button } from '../../primitives/button'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport type ActionItem = {\n /** Unique key */\n id: string\n /** Display label */\n label: string\n /** Lucide icon component (optional) */\n icon?: React.ComponentType<{ className?: string }>\n /** Click handler */\n onSelect: () => void\n /** Disable the item */\n disabled?: boolean\n /** Show a loading spinner instead of the icon */\n loading?: boolean\n /** Render the item in the destructive token (e.g. Delete, Clear) */\n destructive?: boolean\n}\n\n/** A visual divider between groups of items. */\nexport type ActionSeparator = {\n /** Optional key; falls back to the array index */\n id?: string\n separator: true\n}\n\n/** A muted uppercase section label grouping the items beneath it. */\nexport type ActionHeader = {\n /** Optional key; falls back to the array index */\n id?: string\n /** The section label text */\n header: string\n}\n\nexport type ActionMenuEntry = ActionItem | ActionSeparator | ActionHeader\n\nexport type ActionsDropdownProps = {\n /** Items to render inside the dropdown (may include separators) */\n items: ActionMenuEntry[]\n /** Button label (default: translated 'Actions') */\n label?: string\n /** Trigger style */\n triggerMode?: 'label' | 'icon'\n /** Accessible label for icon trigger */\n ariaLabel?: string\n /** Button size (default: 'sm') */\n size?: 'sm' | 'default'\n /** Extra classes for the trigger button (e.g. to match a dense toolbar row) */\n triggerClassName?: string\n /**\n * Leading icon inside the label-mode trigger. Defaults to `Zap`; pass a\n * component to override, or `false` to render just the label + chevron.\n */\n triggerIcon?: React.ComponentType<{ className?: string }> | false\n /**\n * Render a small warning dot on the trigger \u2014 for when an item inside the\n * menu needs attention (e.g. required fields still blank).\n */\n attention?: boolean\n}\n\nexport function ActionsDropdown({\n items,\n label,\n triggerMode = 'label',\n ariaLabel,\n size = 'sm',\n triggerClassName,\n triggerIcon,\n attention = false,\n}: ActionsDropdownProps) {\n const t = useT()\n const [open, setOpen] = React.useState(false)\n const btnRef = React.useRef<HTMLButtonElement>(null)\n const menuRef = React.useRef<HTMLDivElement>(null)\n const [anchorRect, setAnchorRect] = React.useState<DOMRect | null>(null)\n const hoverTimeoutRef = React.useRef<NodeJS.Timeout | null>(null)\n const [direction, setDirection] = React.useState<'down' | 'up'>('down')\n\n const resolvedLabel = label ?? t('ui.actions.actions', 'Actions')\n const resolvedAriaLabel = ariaLabel ?? resolvedLabel\n\n const updatePosition = React.useCallback(() => {\n if (!btnRef.current) return\n const rect = btnRef.current.getBoundingClientRect()\n setAnchorRect(rect)\n const spaceBelow = window.innerHeight - rect.bottom\n const spaceAbove = rect.top\n setDirection(spaceBelow < 200 && spaceAbove > spaceBelow ? 'up' : 'down')\n }, [])\n\n React.useEffect(() => {\n if (!open) return\n updatePosition()\n function onDocClick(event: MouseEvent) {\n const target = event.target as Node\n if (\n menuRef.current && !menuRef.current.contains(target) &&\n btnRef.current && !btnRef.current.contains(target)\n ) {\n setOpen(false)\n }\n }\n function onKey(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n setOpen(false)\n btnRef.current?.focus()\n }\n }\n function onScrollOrResize() {\n updatePosition()\n }\n document.addEventListener('mousedown', onDocClick)\n document.addEventListener('keydown', onKey)\n window.addEventListener('scroll', onScrollOrResize, true)\n window.addEventListener('resize', onScrollOrResize)\n return () => {\n document.removeEventListener('mousedown', onDocClick)\n document.removeEventListener('keydown', onKey)\n window.removeEventListener('scroll', onScrollOrResize, true)\n window.removeEventListener('resize', onScrollOrResize)\n }\n }, [open, updatePosition])\n\n React.useEffect(() => {\n return () => {\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current)\n }\n }\n }, [])\n\n const handleMouseEnter = () => {\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current)\n }\n setOpen(true)\n updatePosition()\n }\n\n const handleMouseLeave = (event: React.MouseEvent) => {\n const nextTarget = event.relatedTarget as Node | null\n if (nextTarget && (btnRef.current?.contains(nextTarget) || menuRef.current?.contains(nextTarget))) {\n return\n }\n hoverTimeoutRef.current = setTimeout(() => {\n setOpen(false)\n }, 150)\n }\n\n if (!items.length) return null\n\n return (\n <div\n className=\"relative inline-block\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n <Button\n ref={btnRef}\n type=\"button\"\n variant=\"outline\"\n size={size}\n className={`${triggerMode === 'icon' ? 'px-2 ' : ''}${triggerClassName ?? ''}`.trim() || undefined}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-label={resolvedAriaLabel}\n onClick={() => {\n setOpen((prev) => !prev)\n requestAnimationFrame(updatePosition)\n }}\n >\n {triggerMode === 'icon' ? (\n <>\n <MoreHorizontal className=\"size-4\" />\n <span className=\"sr-only\">{resolvedAriaLabel}</span>\n </>\n ) : (\n <>\n {resolvedLabel}\n {triggerIcon === false\n ? null\n : triggerIcon\n ? React.createElement(triggerIcon, { className: 'size-4 ml-1' })\n : <Zap className=\"size-4 ml-1\" />}\n <ChevronDown className={`size-3.5 transition-transform duration-150 ${open ? 'rotate-180' : ''}`} />\n </>\n )}\n </Button>\n {attention && (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute right-0.5 top-0.5 size-2 rounded-full bg-status-warning-icon ring-2 ring-background\"\n />\n )}\n {open && anchorRect && createPortal(\n <div\n ref={menuRef}\n role=\"menu\"\n className=\"fixed min-w-52 w-max max-w-xs rounded-md border bg-background p-1 shadow-md focus-visible:outline-none z-dropdown\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n style={{\n top: direction === 'down' ? anchorRect.bottom + 4 : anchorRect.top - 4,\n left: anchorRect.right,\n transform: `translate(-100%, ${direction === 'down' ? '0' : '-100%'})`,\n }}\n >\n {items.map((item, index) => {\n if ('header' in item) {\n return (\n <div\n key={item.id ?? `header-${index}`}\n className=\"px-2 pb-1 pt-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground\"\n >\n {item.header}\n </div>\n )\n }\n if ('separator' in item) {\n return (\n <div\n key={item.id ?? `separator-${index}`}\n role=\"separator\"\n className=\"my-1 h-px bg-border\"\n />\n )\n }\n const Icon = item.icon\n return (\n <Button\n key={item.id}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className={`w-full justify-start h-auto min-h-8 py-1.5 whitespace-normal text-left leading-snug${\n item.destructive\n ? ' text-destructive hover:text-destructive hover:bg-destructive/10 focus-visible:text-destructive'\n : ''\n }`}\n role=\"menuitem\"\n disabled={item.disabled}\n onClick={() => {\n setOpen(false)\n item.onSelect()\n }}\n >\n {item.loading ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : Icon ? (\n <Icon className=\"size-4\" />\n ) : (\n <span className=\"size-4\" />\n )}\n {item.label}\n </Button>\n )\n })}\n </div>,\n document.body,\n )}\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/backend/forms/index.ts"],
4
- "sourcesContent": ["export { FormActionButtons, type FormActionButtonsProps } from './FormActionButtons'\nexport { ActionsDropdown, type ActionItem, type ActionsDropdownProps } from './ActionsDropdown'\nexport { FormHeader, type FormHeaderProps, type FormHeaderEditProps, type FormHeaderDetailProps } from './FormHeader'\nexport { FormFooter, type FormFooterProps } from './FormFooter'\n"],
5
- "mappings": "AAAA,SAAS,yBAAsD;AAC/D,SAAS,uBAAmE;AAC5E,SAAS,kBAA8F;AACvG,SAAS,kBAAwC;",
4
+ "sourcesContent": ["export { FormActionButtons, type FormActionButtonsProps } from './FormActionButtons'\nexport { ActionsDropdown, type ActionItem, type ActionSeparator, type ActionHeader, type ActionMenuEntry, type ActionsDropdownProps } from './ActionsDropdown'\nexport { FormHeader, type FormHeaderProps, type FormHeaderEditProps, type FormHeaderDetailProps } from './FormHeader'\nexport { FormFooter, type FormFooterProps } from './FormFooter'\n"],
5
+ "mappings": "AAAA,SAAS,yBAAsD;AAC/D,SAAS,uBAAkI;AAC3I,SAAS,kBAA8F;AACvG,SAAS,kBAAwC;",
6
6
  "names": []
7
7
  }
@@ -61,6 +61,7 @@ import {
61
61
  Flag,
62
62
  Flame,
63
63
  FolderTree,
64
+ FunctionSquare,
64
65
  Gauge,
65
66
  GitBranch,
66
67
  GitCompareArrows,
@@ -111,6 +112,7 @@ import {
111
112
  PhoneCall,
112
113
  PieChart,
113
114
  PlusSquare,
115
+ Radio,
114
116
  Receipt,
115
117
  ReceiptText,
116
118
  RefreshCcw,
@@ -156,6 +158,7 @@ import {
156
158
  UserRound,
157
159
  Users,
158
160
  UserX,
161
+ Variable,
159
162
  Wallet,
160
163
  Warehouse,
161
164
  Webhook,
@@ -228,6 +231,7 @@ const LUCIDE_ICON_REGISTRY = {
228
231
  "flag": Flag,
229
232
  "flame": Flame,
230
233
  "folder-tree": FolderTree,
234
+ "function-square": FunctionSquare,
231
235
  "gauge": Gauge,
232
236
  "git-branch": GitBranch,
233
237
  "git-compare-arrows": GitCompareArrows,
@@ -278,6 +282,7 @@ const LUCIDE_ICON_REGISTRY = {
278
282
  "phone-call": PhoneCall,
279
283
  "pie-chart": PieChart,
280
284
  "plus-square": PlusSquare,
285
+ "radio": Radio,
281
286
  "receipt": Receipt,
282
287
  "receipt-text": ReceiptText,
283
288
  "refresh-ccw": RefreshCcw,
@@ -323,6 +328,7 @@ const LUCIDE_ICON_REGISTRY = {
323
328
  "user-round": UserRound,
324
329
  "user-x": UserX,
325
330
  "users": Users,
331
+ "variable": Variable,
326
332
  "wallet": Wallet,
327
333
  "warehouse": Warehouse,
328
334
  "webhook": Webhook,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/backend/icons/lucideRegistry.generated.tsx"],
4
- "sourcesContent": ["/* eslint-disable */\n// AUTO-GENERATED by @open-mercato/ui build. Do not edit by hand.\n// Generated from discovered icon string usages across the repo.\n\nimport type { LucideIcon } from 'lucide-react';\nimport {\n Activity,\n AlarmClock,\n AlertCircle,\n AlertOctagon,\n AlertTriangle,\n Apple,\n Archive,\n AtSign,\n Award,\n BadgeCheck,\n Ban,\n Banknote,\n BarChart2,\n BarChart3,\n Bell,\n Bolt,\n Book,\n Bookmark,\n Bot,\n Box,\n Boxes,\n Briefcase,\n BriefcaseBusiness,\n Building,\n Building2,\n Calendar,\n CalendarCheck,\n CalendarClock,\n CalendarCog,\n CalendarMinus,\n CalendarOff,\n CalendarX,\n Check,\n CheckCircle,\n CheckCircle2,\n CheckSquare,\n Circle,\n ClipboardCheck,\n ClipboardList,\n Clock,\n Clock3,\n Coins,\n Copy,\n CopyX,\n CreditCard,\n Crown,\n Database,\n DollarSign,\n Download,\n ExternalLink,\n Eye,\n FileCheck,\n FileClock,\n FileMinus,\n FilePenLine,\n Files,\n FileSpreadsheet,\n FileText,\n FilterX,\n Flag,\n Flame,\n FolderTree,\n Gauge,\n GitBranch,\n GitCompareArrows,\n GitPullRequestArrow,\n Globe,\n GraduationCap,\n Hammer,\n Hand,\n Handshake,\n Headphones,\n Heart,\n HelpCircle,\n Hourglass,\n Inbox,\n Key,\n KeyRound,\n Layers,\n Leaf,\n Lightbulb,\n LineChart,\n Link,\n List,\n ListChecks,\n ListX,\n Loader,\n Loader2,\n Lock,\n Mail,\n MailOpen,\n Map,\n MapPin,\n MapPinned,\n Megaphone,\n MessageCircle,\n MessageSquareReply,\n MinusCircle,\n Monitor,\n Notebook,\n Package,\n PackageCheck,\n PackagePlus,\n PackageSearch,\n PackageX,\n PauseCircle,\n PenLine,\n Percent,\n Phone,\n PhoneCall,\n PieChart,\n PlusSquare,\n Receipt,\n ReceiptText,\n RefreshCcw,\n RefreshCw,\n Repeat2,\n Reply,\n RotateCcw,\n Ruler,\n Send,\n Settings,\n Shapes,\n Share2,\n Shield,\n ShieldAlert,\n ShieldCheck,\n ShoppingBag,\n ShoppingCart,\n Shuffle,\n Sliders,\n Smartphone,\n Snowflake,\n Sparkles,\n Star,\n StickyNote,\n Store,\n Tag,\n Target,\n ThumbsUp,\n Ticket,\n Timer,\n Trash2,\n TrendingUp,\n TriangleAlert,\n Trophy,\n Truck,\n Undo,\n Undo2,\n Unlock,\n User,\n UserCheck,\n UserMinus,\n UserPlus,\n UserRound,\n Users,\n UserX,\n Wallet,\n Warehouse,\n Webhook,\n Workflow,\n Wrench,\n X,\n XCircle,\n ZapOff,\n} from 'lucide-react';\n\nexport const LUCIDE_ICON_REGISTRY: Record<string, LucideIcon> = {\n 'activity': Activity,\n 'alarm-clock': AlarmClock,\n 'alert-circle': AlertCircle,\n 'alert-octagon': AlertOctagon,\n 'alert-triangle': AlertTriangle,\n 'apple': Apple,\n 'archive': Archive,\n 'at-sign': AtSign,\n 'award': Award,\n 'badge-check': BadgeCheck,\n 'ban': Ban,\n 'banknote': Banknote,\n 'bar-chart-2': BarChart2,\n 'bar-chart-3': BarChart3,\n 'bell': Bell,\n 'bolt': Bolt,\n 'book': Book,\n 'bookmark': Bookmark,\n 'bot': Bot,\n 'box': Box,\n 'boxes': Boxes,\n 'briefcase': Briefcase,\n 'briefcase-business': BriefcaseBusiness,\n 'building': Building,\n 'building2': Building2,\n 'calendar': Calendar,\n 'calendar-check': CalendarCheck,\n 'calendar-clock': CalendarClock,\n 'calendar-cog': CalendarCog,\n 'calendar-minus': CalendarMinus,\n 'calendar-off': CalendarOff,\n 'calendar-x': CalendarX,\n 'check': Check,\n 'check-circle': CheckCircle,\n 'check-circle-2': CheckCircle2,\n 'check-square': CheckSquare,\n 'circle': Circle,\n 'clipboard-check': ClipboardCheck,\n 'clipboard-list': ClipboardList,\n 'clock': Clock,\n 'clock-3': Clock3,\n 'coins': Coins,\n 'copy': Copy,\n 'copy-x': CopyX,\n 'credit-card': CreditCard,\n 'crown': Crown,\n 'database': Database,\n 'dollar-sign': DollarSign,\n 'download': Download,\n 'external-link': ExternalLink,\n 'eye': Eye,\n 'file-check': FileCheck,\n 'file-clock': FileClock,\n 'file-minus': FileMinus,\n 'file-pen-line': FilePenLine,\n 'file-spreadsheet': FileSpreadsheet,\n 'file-text': FileText,\n 'files': Files,\n 'filter-x': FilterX,\n 'flag': Flag,\n 'flame': Flame,\n 'folder-tree': FolderTree,\n 'gauge': Gauge,\n 'git-branch': GitBranch,\n 'git-compare-arrows': GitCompareArrows,\n 'git-pull-request-arrow': GitPullRequestArrow,\n 'globe': Globe,\n 'graduation-cap': GraduationCap,\n 'hammer': Hammer,\n 'hand': Hand,\n 'handshake': Handshake,\n 'headphones': Headphones,\n 'heart': Heart,\n 'help-circle': HelpCircle,\n 'hourglass': Hourglass,\n 'inbox': Inbox,\n 'key': Key,\n 'key-round': KeyRound,\n 'layers': Layers,\n 'leaf': Leaf,\n 'lightbulb': Lightbulb,\n 'line-chart': LineChart,\n 'link': Link,\n 'list': List,\n 'list-checks': ListChecks,\n 'list-x': ListX,\n 'loader': Loader,\n 'loader-2': Loader2,\n 'lock': Lock,\n 'mail': Mail,\n 'mail-open': MailOpen,\n 'map': Map,\n 'map-pin': MapPin,\n 'map-pinned': MapPinned,\n 'megaphone': Megaphone,\n 'message-circle': MessageCircle,\n 'message-square-reply': MessageSquareReply,\n 'minus-circle': MinusCircle,\n 'monitor': Monitor,\n 'notebook': Notebook,\n 'package': Package,\n 'package-check': PackageCheck,\n 'package-plus': PackagePlus,\n 'package-search': PackageSearch,\n 'package-x': PackageX,\n 'pause-circle': PauseCircle,\n 'pen-line': PenLine,\n 'percent': Percent,\n 'phone': Phone,\n 'phone-call': PhoneCall,\n 'pie-chart': PieChart,\n 'plus-square': PlusSquare,\n 'receipt': Receipt,\n 'receipt-text': ReceiptText,\n 'refresh-ccw': RefreshCcw,\n 'refresh-cw': RefreshCw,\n 'repeat-2': Repeat2,\n 'reply': Reply,\n 'rotate-ccw': RotateCcw,\n 'ruler': Ruler,\n 'send': Send,\n 'settings': Settings,\n 'shapes': Shapes,\n 'share-2': Share2,\n 'shield': Shield,\n 'shield-alert': ShieldAlert,\n 'shield-check': ShieldCheck,\n 'shopping-bag': ShoppingBag,\n 'shopping-cart': ShoppingCart,\n 'shuffle': Shuffle,\n 'sliders': Sliders,\n 'smartphone': Smartphone,\n 'snowflake': Snowflake,\n 'sparkles': Sparkles,\n 'star': Star,\n 'sticky-note': StickyNote,\n 'store': Store,\n 'tag': Tag,\n 'target': Target,\n 'thumbs-up': ThumbsUp,\n 'ticket': Ticket,\n 'timer': Timer,\n 'trash-2': Trash2,\n 'trending-up': TrendingUp,\n 'triangle-alert': TriangleAlert,\n 'trophy': Trophy,\n 'truck': Truck,\n 'undo': Undo,\n 'undo-2': Undo2,\n 'unlock': Unlock,\n 'user': User,\n 'user-check': UserCheck,\n 'user-minus': UserMinus,\n 'user-plus': UserPlus,\n 'user-round': UserRound,\n 'user-x': UserX,\n 'users': Users,\n 'wallet': Wallet,\n 'warehouse': Warehouse,\n 'webhook': Webhook,\n 'workflow': Workflow,\n 'wrench': Wrench,\n 'x': X,\n 'x-circle': XCircle,\n 'zap-off': ZapOff,\n};\n"],
5
- "mappings": "AAKA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,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",
4
+ "sourcesContent": ["/* eslint-disable */\n// AUTO-GENERATED by @open-mercato/ui build. Do not edit by hand.\n// Generated from discovered icon string usages across the repo.\n\nimport type { LucideIcon } from 'lucide-react';\nimport {\n Activity,\n AlarmClock,\n AlertCircle,\n AlertOctagon,\n AlertTriangle,\n Apple,\n Archive,\n AtSign,\n Award,\n BadgeCheck,\n Ban,\n Banknote,\n BarChart2,\n BarChart3,\n Bell,\n Bolt,\n Book,\n Bookmark,\n Bot,\n Box,\n Boxes,\n Briefcase,\n BriefcaseBusiness,\n Building,\n Building2,\n Calendar,\n CalendarCheck,\n CalendarClock,\n CalendarCog,\n CalendarMinus,\n CalendarOff,\n CalendarX,\n Check,\n CheckCircle,\n CheckCircle2,\n CheckSquare,\n Circle,\n ClipboardCheck,\n ClipboardList,\n Clock,\n Clock3,\n Coins,\n Copy,\n CopyX,\n CreditCard,\n Crown,\n Database,\n DollarSign,\n Download,\n ExternalLink,\n Eye,\n FileCheck,\n FileClock,\n FileMinus,\n FilePenLine,\n Files,\n FileSpreadsheet,\n FileText,\n FilterX,\n Flag,\n Flame,\n FolderTree,\n FunctionSquare,\n Gauge,\n GitBranch,\n GitCompareArrows,\n GitPullRequestArrow,\n Globe,\n GraduationCap,\n Hammer,\n Hand,\n Handshake,\n Headphones,\n Heart,\n HelpCircle,\n Hourglass,\n Inbox,\n Key,\n KeyRound,\n Layers,\n Leaf,\n Lightbulb,\n LineChart,\n Link,\n List,\n ListChecks,\n ListX,\n Loader,\n Loader2,\n Lock,\n Mail,\n MailOpen,\n Map,\n MapPin,\n MapPinned,\n Megaphone,\n MessageCircle,\n MessageSquareReply,\n MinusCircle,\n Monitor,\n Notebook,\n Package,\n PackageCheck,\n PackagePlus,\n PackageSearch,\n PackageX,\n PauseCircle,\n PenLine,\n Percent,\n Phone,\n PhoneCall,\n PieChart,\n PlusSquare,\n Radio,\n Receipt,\n ReceiptText,\n RefreshCcw,\n RefreshCw,\n Repeat2,\n Reply,\n RotateCcw,\n Ruler,\n Send,\n Settings,\n Shapes,\n Share2,\n Shield,\n ShieldAlert,\n ShieldCheck,\n ShoppingBag,\n ShoppingCart,\n Shuffle,\n Sliders,\n Smartphone,\n Snowflake,\n Sparkles,\n Star,\n StickyNote,\n Store,\n Tag,\n Target,\n ThumbsUp,\n Ticket,\n Timer,\n Trash2,\n TrendingUp,\n TriangleAlert,\n Trophy,\n Truck,\n Undo,\n Undo2,\n Unlock,\n User,\n UserCheck,\n UserMinus,\n UserPlus,\n UserRound,\n Users,\n UserX,\n Variable,\n Wallet,\n Warehouse,\n Webhook,\n Workflow,\n Wrench,\n X,\n XCircle,\n ZapOff,\n} from 'lucide-react';\n\nexport const LUCIDE_ICON_REGISTRY: Record<string, LucideIcon> = {\n 'activity': Activity,\n 'alarm-clock': AlarmClock,\n 'alert-circle': AlertCircle,\n 'alert-octagon': AlertOctagon,\n 'alert-triangle': AlertTriangle,\n 'apple': Apple,\n 'archive': Archive,\n 'at-sign': AtSign,\n 'award': Award,\n 'badge-check': BadgeCheck,\n 'ban': Ban,\n 'banknote': Banknote,\n 'bar-chart-2': BarChart2,\n 'bar-chart-3': BarChart3,\n 'bell': Bell,\n 'bolt': Bolt,\n 'book': Book,\n 'bookmark': Bookmark,\n 'bot': Bot,\n 'box': Box,\n 'boxes': Boxes,\n 'briefcase': Briefcase,\n 'briefcase-business': BriefcaseBusiness,\n 'building': Building,\n 'building2': Building2,\n 'calendar': Calendar,\n 'calendar-check': CalendarCheck,\n 'calendar-clock': CalendarClock,\n 'calendar-cog': CalendarCog,\n 'calendar-minus': CalendarMinus,\n 'calendar-off': CalendarOff,\n 'calendar-x': CalendarX,\n 'check': Check,\n 'check-circle': CheckCircle,\n 'check-circle-2': CheckCircle2,\n 'check-square': CheckSquare,\n 'circle': Circle,\n 'clipboard-check': ClipboardCheck,\n 'clipboard-list': ClipboardList,\n 'clock': Clock,\n 'clock-3': Clock3,\n 'coins': Coins,\n 'copy': Copy,\n 'copy-x': CopyX,\n 'credit-card': CreditCard,\n 'crown': Crown,\n 'database': Database,\n 'dollar-sign': DollarSign,\n 'download': Download,\n 'external-link': ExternalLink,\n 'eye': Eye,\n 'file-check': FileCheck,\n 'file-clock': FileClock,\n 'file-minus': FileMinus,\n 'file-pen-line': FilePenLine,\n 'file-spreadsheet': FileSpreadsheet,\n 'file-text': FileText,\n 'files': Files,\n 'filter-x': FilterX,\n 'flag': Flag,\n 'flame': Flame,\n 'folder-tree': FolderTree,\n 'function-square': FunctionSquare,\n 'gauge': Gauge,\n 'git-branch': GitBranch,\n 'git-compare-arrows': GitCompareArrows,\n 'git-pull-request-arrow': GitPullRequestArrow,\n 'globe': Globe,\n 'graduation-cap': GraduationCap,\n 'hammer': Hammer,\n 'hand': Hand,\n 'handshake': Handshake,\n 'headphones': Headphones,\n 'heart': Heart,\n 'help-circle': HelpCircle,\n 'hourglass': Hourglass,\n 'inbox': Inbox,\n 'key': Key,\n 'key-round': KeyRound,\n 'layers': Layers,\n 'leaf': Leaf,\n 'lightbulb': Lightbulb,\n 'line-chart': LineChart,\n 'link': Link,\n 'list': List,\n 'list-checks': ListChecks,\n 'list-x': ListX,\n 'loader': Loader,\n 'loader-2': Loader2,\n 'lock': Lock,\n 'mail': Mail,\n 'mail-open': MailOpen,\n 'map': Map,\n 'map-pin': MapPin,\n 'map-pinned': MapPinned,\n 'megaphone': Megaphone,\n 'message-circle': MessageCircle,\n 'message-square-reply': MessageSquareReply,\n 'minus-circle': MinusCircle,\n 'monitor': Monitor,\n 'notebook': Notebook,\n 'package': Package,\n 'package-check': PackageCheck,\n 'package-plus': PackagePlus,\n 'package-search': PackageSearch,\n 'package-x': PackageX,\n 'pause-circle': PauseCircle,\n 'pen-line': PenLine,\n 'percent': Percent,\n 'phone': Phone,\n 'phone-call': PhoneCall,\n 'pie-chart': PieChart,\n 'plus-square': PlusSquare,\n 'radio': Radio,\n 'receipt': Receipt,\n 'receipt-text': ReceiptText,\n 'refresh-ccw': RefreshCcw,\n 'refresh-cw': RefreshCw,\n 'repeat-2': Repeat2,\n 'reply': Reply,\n 'rotate-ccw': RotateCcw,\n 'ruler': Ruler,\n 'send': Send,\n 'settings': Settings,\n 'shapes': Shapes,\n 'share-2': Share2,\n 'shield': Shield,\n 'shield-alert': ShieldAlert,\n 'shield-check': ShieldCheck,\n 'shopping-bag': ShoppingBag,\n 'shopping-cart': ShoppingCart,\n 'shuffle': Shuffle,\n 'sliders': Sliders,\n 'smartphone': Smartphone,\n 'snowflake': Snowflake,\n 'sparkles': Sparkles,\n 'star': Star,\n 'sticky-note': StickyNote,\n 'store': Store,\n 'tag': Tag,\n 'target': Target,\n 'thumbs-up': ThumbsUp,\n 'ticket': Ticket,\n 'timer': Timer,\n 'trash-2': Trash2,\n 'trending-up': TrendingUp,\n 'triangle-alert': TriangleAlert,\n 'trophy': Trophy,\n 'truck': Truck,\n 'undo': Undo,\n 'undo-2': Undo2,\n 'unlock': Unlock,\n 'user': User,\n 'user-check': UserCheck,\n 'user-minus': UserMinus,\n 'user-plus': UserPlus,\n 'user-round': UserRound,\n 'user-x': UserX,\n 'users': Users,\n 'variable': Variable,\n 'wallet': Wallet,\n 'warehouse': Warehouse,\n 'webhook': Webhook,\n 'workflow': Workflow,\n 'wrench': Wrench,\n 'x': X,\n 'x-circle': XCircle,\n 'zap-off': ZapOff,\n};\n"],
5
+ "mappings": "AAKA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,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",
6
6
  "names": []
7
7
  }
@@ -11,6 +11,7 @@ const BACKEND_TOPBAR_PROFILE_MENU_INJECTION_SPOT_ID = "backend:topbar:profile-me
11
11
  const BACKEND_TOPBAR_ACTIONS_INJECTION_SPOT_ID = "backend:topbar:actions";
12
12
  const BACKEND_SIDEBAR_NAV_INJECTION_SPOT_ID = "backend:sidebar:nav";
13
13
  const BACKEND_SIDEBAR_NAV_FOOTER_INJECTION_SPOT_ID = "backend:sidebar:nav:footer";
14
+ const BACKEND_NAV_BADGES_INJECTION_SPOT_ID = "backend:nav:badges";
14
15
  const GLOBAL_SIDEBAR_STATUS_BADGES_INJECTION_SPOT_ID = "global:sidebar:status-badges";
15
16
  const GLOBAL_HEADER_STATUS_INDICATORS_INJECTION_SPOT_ID = "global:header:status-indicators";
16
17
  const CrudFormInjectionSpots = {
@@ -62,6 +63,7 @@ const DetailInjectionSpots = {
62
63
  export {
63
64
  BACKEND_LAYOUT_FOOTER_INJECTION_SPOT_ID,
64
65
  BACKEND_LAYOUT_TOP_INJECTION_SPOT_ID,
66
+ BACKEND_NAV_BADGES_INJECTION_SPOT_ID,
65
67
  BACKEND_RECORD_CURRENT_INJECTION_SPOT_ID,
66
68
  BACKEND_SIDEBAR_FOOTER_INJECTION_SPOT_ID,
67
69
  BACKEND_SIDEBAR_NAV_FOOTER_INJECTION_SPOT_ID,