@open-mercato/ui 0.7.1-develop.7193.1.910a5b0a1e → 0.7.1-develop.7195.1.b5efd1d51a
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/.turbo/turbo-build.log +2 -2
- package/dist/backend/AppShell.js +66 -7
- package/dist/backend/AppShell.js.map +2 -2
- package/dist/backend/CrudForm.js +14 -8
- package/dist/backend/CrudForm.js.map +2 -2
- package/dist/backend/DataTable.js +108 -11
- package/dist/backend/DataTable.js.map +2 -2
- package/dist/backend/forms/ActionsDropdown.js +35 -5
- package/dist/backend/forms/ActionsDropdown.js.map +2 -2
- package/dist/backend/forms/index.js.map +2 -2
- package/dist/backend/icons/lucideRegistry.generated.js +6 -0
- package/dist/backend/icons/lucideRegistry.generated.js.map +2 -2
- package/dist/backend/injection/spotIds.js +2 -0
- package/dist/backend/injection/spotIds.js.map +2 -2
- package/dist/backend/inputs/DurationInput.js +182 -0
- package/dist/backend/inputs/DurationInput.js.map +7 -0
- package/dist/backend/inputs/EventSelect.js.map +2 -2
- package/dist/backend/inputs/index.js +1 -0
- package/dist/backend/inputs/index.js.map +2 -2
- package/dist/backend/nav/navBadges.js +38 -0
- package/dist/backend/nav/navBadges.js.map +7 -0
- package/dist/primitives/segmented-control.js +4 -4
- package/dist/primitives/segmented-control.js.map +1 -1
- package/dist/primitives/sheet.js +21 -11
- package/dist/primitives/sheet.js.map +2 -2
- package/dist/primitives/textarea.js +54 -4
- package/dist/primitives/textarea.js.map +2 -2
- package/package.json +3 -3
- package/src/backend/AppShell.tsx +106 -2
- package/src/backend/CrudForm.tsx +28 -9
- package/src/backend/DataTable.tsx +176 -22
- package/src/backend/__tests__/CrudForm.density.test.tsx +113 -0
- package/src/backend/__tests__/DataTable.propBulkActions.test.tsx +200 -0
- package/src/backend/__tests__/DataTable.render.test.tsx +76 -0
- package/src/backend/__tests__/navBadges.test.ts +57 -0
- package/src/backend/forms/ActionsDropdown.tsx +73 -6
- package/src/backend/forms/index.ts +1 -1
- package/src/backend/icons/lucideRegistry.generated.tsx +6 -0
- package/src/backend/injection/spotIds.ts +8 -0
- package/src/backend/inputs/DurationInput.tsx +207 -0
- package/src/backend/inputs/EventSelect.tsx +2 -0
- package/src/backend/inputs/__tests__/DurationInput.test.tsx +220 -0
- package/src/backend/inputs/index.ts +1 -0
- package/src/backend/nav/navBadges.ts +61 -0
- package/src/primitives/__tests__/segmented-control.test.tsx +2 -2
- package/src/primitives/__tests__/textarea.test.tsx +50 -0
- package/src/primitives/segmented-control.tsx +7 -7
- package/src/primitives/sheet.tsx +7 -1
- package/src/primitives/textarea.tsx +77 -4
|
@@ -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:
|
|
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:
|
|
5
|
-
"mappings": ";
|
|
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,
|
|
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,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/backend/injection/spotIds.ts"],
|
|
4
|
-
"sourcesContent": ["import type { InjectionSpotId } from '@open-mercato/shared/modules/widgets/injection'\nimport {\n crudFormExtensionSpotId,\n dataTableExtensionSpotId,\n} from '@open-mercato/shared/modules/widgets/extension-points'\n\nexport const BACKEND_RECORD_CURRENT_INJECTION_SPOT_ID: InjectionSpotId = 'backend:record:current'\nexport const BACKEND_LAYOUT_TOP_INJECTION_SPOT_ID: InjectionSpotId = 'backend:layout:top'\nexport const BACKEND_LAYOUT_FOOTER_INJECTION_SPOT_ID: InjectionSpotId = 'backend:layout:footer'\nexport const BACKEND_SIDEBAR_TOP_INJECTION_SPOT_ID: InjectionSpotId = 'backend:sidebar:top'\nexport const BACKEND_SIDEBAR_FOOTER_INJECTION_SPOT_ID: InjectionSpotId = 'backend:sidebar:footer'\n\n// Standardized backend chrome spot ids\nexport const BACKEND_TOPBAR_PROFILE_MENU_INJECTION_SPOT_ID: InjectionSpotId = 'backend:topbar:profile-menu'\nexport const BACKEND_TOPBAR_ACTIONS_INJECTION_SPOT_ID: InjectionSpotId = 'backend:topbar:actions'\nexport const BACKEND_SIDEBAR_NAV_INJECTION_SPOT_ID: InjectionSpotId = 'backend:sidebar:nav'\nexport const BACKEND_SIDEBAR_NAV_FOOTER_INJECTION_SPOT_ID: InjectionSpotId = 'backend:sidebar:nav:footer'\n\n// Standardized global status spot ids\nexport const GLOBAL_SIDEBAR_STATUS_BADGES_INJECTION_SPOT_ID: InjectionSpotId = 'global:sidebar:status-badges'\nexport const GLOBAL_HEADER_STATUS_INDICATORS_INJECTION_SPOT_ID: InjectionSpotId = 'global:header:status-indicators'\n\n// Standardized pattern helpers\nexport const CrudFormInjectionSpots = {\n base: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId),\n beforeFields: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, 'before-fields'),\n afterFields: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, 'after-fields'),\n header: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, 'header'),\n fields: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, 'fields'),\n footer: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, 'footer'),\n sidebar: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, 'sidebar'),\n group: (entityId: string, groupId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, `group:${groupId}`),\n fieldBefore: (entityId: string, fieldId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, `field:${fieldId}:before`),\n fieldAfter: (entityId: string, fieldId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, `field:${fieldId}:after`),\n} as const\n\nexport const DataTableInjectionSpots = {\n header: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'header'),\n footer: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'footer'),\n toolbar: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'toolbar'),\n // Slot rendered immediately after the search input on the same row as the\n // FilterBar \u2014 intended for compact, icon-sized triggers (AI assistants,\n // saved view shortcuts, etc.). Hosts pass the resolved spot ID through to\n // FilterBar's `searchTrailing` prop. Stays empty when the table has no\n // search input.\n searchTrailing: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'search-trailing'),\n emptyState: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'empty-state'),\n columns: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'columns'),\n rowActions: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'row-actions'),\n bulkActions: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'bulk-actions'),\n filters: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'filters'),\n} as const\n\n// Portal chrome spot IDs (FROZEN once shipped)\nexport const PORTAL_SIDEBAR_MAIN_INJECTION_SPOT_ID: InjectionSpotId = 'menu:portal:sidebar:main'\nexport const PORTAL_SIDEBAR_ACCOUNT_INJECTION_SPOT_ID: InjectionSpotId = 'menu:portal:sidebar:account'\nexport const PORTAL_HEADER_ACTIONS_INJECTION_SPOT_ID: InjectionSpotId = 'menu:portal:header:actions'\nexport const PORTAL_USER_DROPDOWN_INJECTION_SPOT_ID: InjectionSpotId = 'menu:portal:user-dropdown'\n\n// Portal page injection spots (FROZEN once shipped)\nexport const PortalInjectionSpots = {\n dashboardSections: 'portal:dashboard:sections' as InjectionSpotId,\n dashboardProfile: 'portal:dashboard:profile' as InjectionSpotId,\n dashboardSidebar: 'portal:dashboard:sidebar' as InjectionSpotId,\n pageBefore: (pageId: string): InjectionSpotId => `portal:${pageId}:before` as InjectionSpotId,\n pageAfter: (pageId: string): InjectionSpotId => `portal:${pageId}:after` as InjectionSpotId,\n} as const\n\nexport const DetailInjectionSpots = {\n header: (entityId: string): InjectionSpotId => `detail:${entityId}:header`,\n tabs: (entityId: string): InjectionSpotId => `detail:${entityId}:tabs`,\n sidebar: (entityId: string): InjectionSpotId => `detail:${entityId}:sidebar`,\n footer: (entityId: string): InjectionSpotId => `detail:${entityId}:footer`,\n statusBadges: (entityId: string): InjectionSpotId => `detail:${entityId}:status-badges`,\n} as const\n"],
|
|
5
|
-
"mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEA,MAAM,2CAA4D;AAClE,MAAM,uCAAwD;AAC9D,MAAM,0CAA2D;AACjE,MAAM,wCAAyD;AAC/D,MAAM,2CAA4D;AAGlE,MAAM,gDAAiE;AACvE,MAAM,2CAA4D;AAClE,MAAM,wCAAyD;AAC/D,MAAM,+CAAgE;
|
|
4
|
+
"sourcesContent": ["import type { InjectionSpotId } from '@open-mercato/shared/modules/widgets/injection'\nimport {\n crudFormExtensionSpotId,\n dataTableExtensionSpotId,\n} from '@open-mercato/shared/modules/widgets/extension-points'\n\nexport const BACKEND_RECORD_CURRENT_INJECTION_SPOT_ID: InjectionSpotId = 'backend:record:current'\nexport const BACKEND_LAYOUT_TOP_INJECTION_SPOT_ID: InjectionSpotId = 'backend:layout:top'\nexport const BACKEND_LAYOUT_FOOTER_INJECTION_SPOT_ID: InjectionSpotId = 'backend:layout:footer'\nexport const BACKEND_SIDEBAR_TOP_INJECTION_SPOT_ID: InjectionSpotId = 'backend:sidebar:top'\nexport const BACKEND_SIDEBAR_FOOTER_INJECTION_SPOT_ID: InjectionSpotId = 'backend:sidebar:footer'\n\n// Standardized backend chrome spot ids\nexport const BACKEND_TOPBAR_PROFILE_MENU_INJECTION_SPOT_ID: InjectionSpotId = 'backend:topbar:profile-menu'\nexport const BACKEND_TOPBAR_ACTIONS_INJECTION_SPOT_ID: InjectionSpotId = 'backend:topbar:actions'\nexport const BACKEND_SIDEBAR_NAV_INJECTION_SPOT_ID: InjectionSpotId = 'backend:sidebar:nav'\nexport const BACKEND_SIDEBAR_NAV_FOOTER_INJECTION_SPOT_ID: InjectionSpotId = 'backend:sidebar:nav:footer'\n\n/**\n * Headless mount point for modules that publish live counts onto sidebar nav\n * items through `setNavBadge`. Rendered once per shell and always \u2014 a feeder\n * must keep counting while the sidebar is collapsed or off-screen on mobile \u2014\n * and its widgets are expected to render nothing.\n */\nexport const BACKEND_NAV_BADGES_INJECTION_SPOT_ID: InjectionSpotId = 'backend:nav:badges'\n\n// Standardized global status spot ids\nexport const GLOBAL_SIDEBAR_STATUS_BADGES_INJECTION_SPOT_ID: InjectionSpotId = 'global:sidebar:status-badges'\nexport const GLOBAL_HEADER_STATUS_INDICATORS_INJECTION_SPOT_ID: InjectionSpotId = 'global:header:status-indicators'\n\n// Standardized pattern helpers\nexport const CrudFormInjectionSpots = {\n base: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId),\n beforeFields: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, 'before-fields'),\n afterFields: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, 'after-fields'),\n header: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, 'header'),\n fields: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, 'fields'),\n footer: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, 'footer'),\n sidebar: (entityId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, 'sidebar'),\n group: (entityId: string, groupId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, `group:${groupId}`),\n fieldBefore: (entityId: string, fieldId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, `field:${fieldId}:before`),\n fieldAfter: (entityId: string, fieldId: string): InjectionSpotId => crudFormExtensionSpotId(entityId, `field:${fieldId}:after`),\n} as const\n\nexport const DataTableInjectionSpots = {\n header: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'header'),\n footer: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'footer'),\n toolbar: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'toolbar'),\n // Slot rendered immediately after the search input on the same row as the\n // FilterBar \u2014 intended for compact, icon-sized triggers (AI assistants,\n // saved view shortcuts, etc.). Hosts pass the resolved spot ID through to\n // FilterBar's `searchTrailing` prop. Stays empty when the table has no\n // search input.\n searchTrailing: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'search-trailing'),\n emptyState: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'empty-state'),\n columns: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'columns'),\n rowActions: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'row-actions'),\n bulkActions: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'bulk-actions'),\n filters: (tableId: string): InjectionSpotId => dataTableExtensionSpotId(tableId, 'filters'),\n} as const\n\n// Portal chrome spot IDs (FROZEN once shipped)\nexport const PORTAL_SIDEBAR_MAIN_INJECTION_SPOT_ID: InjectionSpotId = 'menu:portal:sidebar:main'\nexport const PORTAL_SIDEBAR_ACCOUNT_INJECTION_SPOT_ID: InjectionSpotId = 'menu:portal:sidebar:account'\nexport const PORTAL_HEADER_ACTIONS_INJECTION_SPOT_ID: InjectionSpotId = 'menu:portal:header:actions'\nexport const PORTAL_USER_DROPDOWN_INJECTION_SPOT_ID: InjectionSpotId = 'menu:portal:user-dropdown'\n\n// Portal page injection spots (FROZEN once shipped)\nexport const PortalInjectionSpots = {\n dashboardSections: 'portal:dashboard:sections' as InjectionSpotId,\n dashboardProfile: 'portal:dashboard:profile' as InjectionSpotId,\n dashboardSidebar: 'portal:dashboard:sidebar' as InjectionSpotId,\n pageBefore: (pageId: string): InjectionSpotId => `portal:${pageId}:before` as InjectionSpotId,\n pageAfter: (pageId: string): InjectionSpotId => `portal:${pageId}:after` as InjectionSpotId,\n} as const\n\nexport const DetailInjectionSpots = {\n header: (entityId: string): InjectionSpotId => `detail:${entityId}:header`,\n tabs: (entityId: string): InjectionSpotId => `detail:${entityId}:tabs`,\n sidebar: (entityId: string): InjectionSpotId => `detail:${entityId}:sidebar`,\n footer: (entityId: string): InjectionSpotId => `detail:${entityId}:footer`,\n statusBadges: (entityId: string): InjectionSpotId => `detail:${entityId}:status-badges`,\n} as const\n"],
|
|
5
|
+
"mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEA,MAAM,2CAA4D;AAClE,MAAM,uCAAwD;AAC9D,MAAM,0CAA2D;AACjE,MAAM,wCAAyD;AAC/D,MAAM,2CAA4D;AAGlE,MAAM,gDAAiE;AACvE,MAAM,2CAA4D;AAClE,MAAM,wCAAyD;AAC/D,MAAM,+CAAgE;AAQtE,MAAM,uCAAwD;AAG9D,MAAM,iDAAkE;AACxE,MAAM,oDAAqE;AAG3E,MAAM,yBAAyB;AAAA,EACpC,MAAM,CAAC,aAAsC,wBAAwB,QAAQ;AAAA,EAC7E,cAAc,CAAC,aAAsC,wBAAwB,UAAU,eAAe;AAAA,EACtG,aAAa,CAAC,aAAsC,wBAAwB,UAAU,cAAc;AAAA,EACpG,QAAQ,CAAC,aAAsC,wBAAwB,UAAU,QAAQ;AAAA,EACzF,QAAQ,CAAC,aAAsC,wBAAwB,UAAU,QAAQ;AAAA,EACzF,QAAQ,CAAC,aAAsC,wBAAwB,UAAU,QAAQ;AAAA,EACzF,SAAS,CAAC,aAAsC,wBAAwB,UAAU,SAAS;AAAA,EAC3F,OAAO,CAAC,UAAkB,YAAqC,wBAAwB,UAAU,SAAS,OAAO,EAAE;AAAA,EACnH,aAAa,CAAC,UAAkB,YAAqC,wBAAwB,UAAU,SAAS,OAAO,SAAS;AAAA,EAChI,YAAY,CAAC,UAAkB,YAAqC,wBAAwB,UAAU,SAAS,OAAO,QAAQ;AAChI;AAEO,MAAM,0BAA0B;AAAA,EACrC,QAAQ,CAAC,YAAqC,yBAAyB,SAAS,QAAQ;AAAA,EACxF,QAAQ,CAAC,YAAqC,yBAAyB,SAAS,QAAQ;AAAA,EACxF,SAAS,CAAC,YAAqC,yBAAyB,SAAS,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM1F,gBAAgB,CAAC,YAAqC,yBAAyB,SAAS,iBAAiB;AAAA,EACzG,YAAY,CAAC,YAAqC,yBAAyB,SAAS,aAAa;AAAA,EACjG,SAAS,CAAC,YAAqC,yBAAyB,SAAS,SAAS;AAAA,EAC1F,YAAY,CAAC,YAAqC,yBAAyB,SAAS,aAAa;AAAA,EACjG,aAAa,CAAC,YAAqC,yBAAyB,SAAS,cAAc;AAAA,EACnG,SAAS,CAAC,YAAqC,yBAAyB,SAAS,SAAS;AAC5F;AAGO,MAAM,wCAAyD;AAC/D,MAAM,2CAA4D;AAClE,MAAM,0CAA2D;AACjE,MAAM,yCAA0D;AAGhE,MAAM,uBAAuB;AAAA,EAClC,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,YAAY,CAAC,WAAoC,UAAU,MAAM;AAAA,EACjE,WAAW,CAAC,WAAoC,UAAU,MAAM;AAClE;AAEO,MAAM,uBAAuB;AAAA,EAClC,QAAQ,CAAC,aAAsC,UAAU,QAAQ;AAAA,EACjE,MAAM,CAAC,aAAsC,UAAU,QAAQ;AAAA,EAC/D,SAAS,CAAC,aAAsC,UAAU,QAAQ;AAAA,EAClE,QAAQ,CAAC,aAAsC,UAAU,QAAQ;AAAA,EACjE,cAAc,CAAC,aAAsC,UAAU,QAAQ;AACzE;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "@open-mercato/shared/lib/utils";
|
|
5
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
6
|
+
import { Input } from "../../primitives/input.js";
|
|
7
|
+
import { Button } from "../../primitives/button.js";
|
|
8
|
+
import {
|
|
9
|
+
Select,
|
|
10
|
+
SelectContent,
|
|
11
|
+
SelectItem,
|
|
12
|
+
SelectTrigger,
|
|
13
|
+
SelectValue
|
|
14
|
+
} from "../../primitives/select.js";
|
|
15
|
+
const singleUnitPatterns = [
|
|
16
|
+
{ regex: /^PT(\d+)S$/, unit: "seconds" },
|
|
17
|
+
{ regex: /^PT(\d+)M$/, unit: "minutes" },
|
|
18
|
+
{ regex: /^PT(\d+)H$/, unit: "hours" },
|
|
19
|
+
{ regex: /^P(\d+)D$/, unit: "days" }
|
|
20
|
+
];
|
|
21
|
+
function parseSingleUnitDuration(value) {
|
|
22
|
+
for (const { regex, unit } of singleUnitPatterns) {
|
|
23
|
+
const match = value.match(regex);
|
|
24
|
+
if (match) {
|
|
25
|
+
const amount = parseInt(match[1], 10);
|
|
26
|
+
if (!isNaN(amount)) return { amount, unit };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
function formatSingleUnitDuration(amount, unit) {
|
|
32
|
+
switch (unit) {
|
|
33
|
+
case "seconds":
|
|
34
|
+
return `PT${amount}S`;
|
|
35
|
+
case "minutes":
|
|
36
|
+
return `PT${amount}M`;
|
|
37
|
+
case "hours":
|
|
38
|
+
return `PT${amount}H`;
|
|
39
|
+
case "days":
|
|
40
|
+
return `P${amount}D`;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function isCompositeCompatibleDuration(value) {
|
|
44
|
+
if (!value) return true;
|
|
45
|
+
if (value.includes("{{")) return false;
|
|
46
|
+
return parseSingleUnitDuration(value) !== null;
|
|
47
|
+
}
|
|
48
|
+
const durationUnits = ["seconds", "minutes", "hours", "days"];
|
|
49
|
+
function DurationInput({
|
|
50
|
+
value,
|
|
51
|
+
onChange,
|
|
52
|
+
disabled = false,
|
|
53
|
+
id,
|
|
54
|
+
"aria-label": ariaLabel,
|
|
55
|
+
className
|
|
56
|
+
}) {
|
|
57
|
+
const t = useT();
|
|
58
|
+
const currentValue = value ?? "";
|
|
59
|
+
const parsed = React.useMemo(() => parseSingleUnitDuration(currentValue), [currentValue]);
|
|
60
|
+
const compositeCompatible = isCompositeCompatibleDuration(currentValue);
|
|
61
|
+
const [mode, setMode] = React.useState(
|
|
62
|
+
() => compositeCompatible ? "composite" : "raw"
|
|
63
|
+
);
|
|
64
|
+
const [unit, setUnit] = React.useState(parsed?.unit ?? "minutes");
|
|
65
|
+
React.useEffect(() => {
|
|
66
|
+
if (!isCompositeCompatibleDuration(currentValue)) setMode("raw");
|
|
67
|
+
}, [currentValue]);
|
|
68
|
+
React.useEffect(() => {
|
|
69
|
+
if (parsed && parsed.unit !== unit) setUnit(parsed.unit);
|
|
70
|
+
}, [parsed, unit]);
|
|
71
|
+
const amountLabel = ariaLabel ?? t("ui.durationInput.amountLabel", "Duration amount");
|
|
72
|
+
const unitLabel = t("ui.durationInput.unitLabel", "Duration unit");
|
|
73
|
+
const rawLabel = ariaLabel ?? t("ui.durationInput.rawLabel", "Duration expression");
|
|
74
|
+
const unitOptionLabels = {
|
|
75
|
+
seconds: t("ui.durationInput.units.seconds", "Seconds"),
|
|
76
|
+
minutes: t("ui.durationInput.units.minutes", "Minutes"),
|
|
77
|
+
hours: t("ui.durationInput.units.hours", "Hours"),
|
|
78
|
+
days: t("ui.durationInput.units.days", "Days")
|
|
79
|
+
};
|
|
80
|
+
const handleAmountChange = React.useCallback(
|
|
81
|
+
(event) => {
|
|
82
|
+
if (disabled) return;
|
|
83
|
+
const raw = event.target.value;
|
|
84
|
+
if (raw === "") {
|
|
85
|
+
onChange("");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const amount = parseInt(raw, 10);
|
|
89
|
+
if (isNaN(amount) || amount < 0) return;
|
|
90
|
+
onChange(formatSingleUnitDuration(amount, unit));
|
|
91
|
+
},
|
|
92
|
+
[disabled, onChange, unit]
|
|
93
|
+
);
|
|
94
|
+
const handleUnitChange = React.useCallback(
|
|
95
|
+
(nextUnit) => {
|
|
96
|
+
if (disabled) return;
|
|
97
|
+
const resolved = durationUnits.find((candidate) => candidate === nextUnit);
|
|
98
|
+
if (!resolved) return;
|
|
99
|
+
setUnit(resolved);
|
|
100
|
+
if (parsed) onChange(formatSingleUnitDuration(parsed.amount, resolved));
|
|
101
|
+
},
|
|
102
|
+
[disabled, onChange, parsed]
|
|
103
|
+
);
|
|
104
|
+
const handleRawChange = React.useCallback(
|
|
105
|
+
(event) => {
|
|
106
|
+
if (disabled) return;
|
|
107
|
+
onChange(event.target.value);
|
|
108
|
+
},
|
|
109
|
+
[disabled, onChange]
|
|
110
|
+
);
|
|
111
|
+
const switchToRaw = React.useCallback(() => {
|
|
112
|
+
setMode("raw");
|
|
113
|
+
}, []);
|
|
114
|
+
const switchToComposite = React.useCallback(() => {
|
|
115
|
+
if (!isCompositeCompatibleDuration(currentValue)) return;
|
|
116
|
+
setMode("composite");
|
|
117
|
+
}, [currentValue]);
|
|
118
|
+
if (mode === "raw") {
|
|
119
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
|
|
120
|
+
/* @__PURE__ */ jsx(
|
|
121
|
+
Input,
|
|
122
|
+
{
|
|
123
|
+
id,
|
|
124
|
+
type: "text",
|
|
125
|
+
value: currentValue,
|
|
126
|
+
onChange: handleRawChange,
|
|
127
|
+
disabled,
|
|
128
|
+
"aria-label": rawLabel,
|
|
129
|
+
className: "flex-1"
|
|
130
|
+
}
|
|
131
|
+
),
|
|
132
|
+
/* @__PURE__ */ jsx(
|
|
133
|
+
Button,
|
|
134
|
+
{
|
|
135
|
+
type: "button",
|
|
136
|
+
variant: "ghost",
|
|
137
|
+
size: "sm",
|
|
138
|
+
onClick: switchToComposite,
|
|
139
|
+
disabled: disabled || !compositeCompatible,
|
|
140
|
+
children: t("ui.durationInput.switchToComposite", "Use picker")
|
|
141
|
+
}
|
|
142
|
+
)
|
|
143
|
+
] });
|
|
144
|
+
}
|
|
145
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
|
|
146
|
+
/* @__PURE__ */ jsx(
|
|
147
|
+
Input,
|
|
148
|
+
{
|
|
149
|
+
id,
|
|
150
|
+
type: "number",
|
|
151
|
+
min: 0,
|
|
152
|
+
value: parsed ? String(parsed.amount) : "",
|
|
153
|
+
onChange: handleAmountChange,
|
|
154
|
+
disabled,
|
|
155
|
+
"aria-label": amountLabel,
|
|
156
|
+
className: "w-24"
|
|
157
|
+
}
|
|
158
|
+
),
|
|
159
|
+
/* @__PURE__ */ jsxs(Select, { value: unit, onValueChange: handleUnitChange, disabled, children: [
|
|
160
|
+
/* @__PURE__ */ jsx(SelectTrigger, { "aria-label": unitLabel, className: "w-32", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
161
|
+
/* @__PURE__ */ jsx(SelectContent, { children: durationUnits.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option, children: unitOptionLabels[option] }, option)) })
|
|
162
|
+
] }),
|
|
163
|
+
/* @__PURE__ */ jsx(
|
|
164
|
+
Button,
|
|
165
|
+
{
|
|
166
|
+
type: "button",
|
|
167
|
+
variant: "ghost",
|
|
168
|
+
size: "sm",
|
|
169
|
+
onClick: switchToRaw,
|
|
170
|
+
disabled,
|
|
171
|
+
children: t("ui.durationInput.switchToRaw", "Edit as text")
|
|
172
|
+
}
|
|
173
|
+
)
|
|
174
|
+
] });
|
|
175
|
+
}
|
|
176
|
+
export {
|
|
177
|
+
DurationInput,
|
|
178
|
+
formatSingleUnitDuration,
|
|
179
|
+
isCompositeCompatibleDuration,
|
|
180
|
+
parseSingleUnitDuration
|
|
181
|
+
};
|
|
182
|
+
//# sourceMappingURL=DurationInput.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/backend/inputs/DurationInput.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Input } from '../../primitives/input'\nimport { Button } from '../../primitives/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../../primitives/select'\n\nexport type DurationUnit = 'seconds' | 'minutes' | 'hours' | 'days'\n\nexport type ParsedSingleUnitDuration = { amount: number; unit: DurationUnit }\n\nconst singleUnitPatterns: Array<{ regex: RegExp; unit: DurationUnit }> = [\n { regex: /^PT(\\d+)S$/, unit: 'seconds' },\n { regex: /^PT(\\d+)M$/, unit: 'minutes' },\n { regex: /^PT(\\d+)H$/, unit: 'hours' },\n { regex: /^P(\\d+)D$/, unit: 'days' },\n]\n\nexport function parseSingleUnitDuration(value: string): ParsedSingleUnitDuration | null {\n for (const { regex, unit } of singleUnitPatterns) {\n const match = value.match(regex)\n if (match) {\n const amount = parseInt(match[1], 10)\n if (!isNaN(amount)) return { amount, unit }\n }\n }\n return null\n}\n\nexport function formatSingleUnitDuration(amount: number, unit: DurationUnit): string {\n switch (unit) {\n case 'seconds':\n return `PT${amount}S`\n case 'minutes':\n return `PT${amount}M`\n case 'hours':\n return `PT${amount}H`\n case 'days':\n return `P${amount}D`\n }\n}\n\nexport function isCompositeCompatibleDuration(value: string | null | undefined): boolean {\n if (!value) return true\n if (value.includes('{{')) return false\n return parseSingleUnitDuration(value) !== null\n}\n\nexport type DurationInputProps = {\n value?: string\n onChange: (value: string) => void\n disabled?: boolean\n id?: string\n 'aria-label'?: string\n className?: string\n}\n\nconst durationUnits: DurationUnit[] = ['seconds', 'minutes', 'hours', 'days']\n\nexport function DurationInput({\n value,\n onChange,\n disabled = false,\n id,\n 'aria-label': ariaLabel,\n className,\n}: DurationInputProps) {\n const t = useT()\n const currentValue = value ?? ''\n const parsed = React.useMemo(() => parseSingleUnitDuration(currentValue), [currentValue])\n const compositeCompatible = isCompositeCompatibleDuration(currentValue)\n\n const [mode, setMode] = React.useState<'composite' | 'raw'>(() =>\n compositeCompatible ? 'composite' : 'raw'\n )\n const [unit, setUnit] = React.useState<DurationUnit>(parsed?.unit ?? 'minutes')\n\n React.useEffect(() => {\n if (!isCompositeCompatibleDuration(currentValue)) setMode('raw')\n }, [currentValue])\n\n React.useEffect(() => {\n if (parsed && parsed.unit !== unit) setUnit(parsed.unit)\n }, [parsed, unit])\n\n const amountLabel = ariaLabel ?? t('ui.durationInput.amountLabel', 'Duration amount')\n const unitLabel = t('ui.durationInput.unitLabel', 'Duration unit')\n const rawLabel = ariaLabel ?? t('ui.durationInput.rawLabel', 'Duration expression')\n const unitOptionLabels: Record<DurationUnit, string> = {\n seconds: t('ui.durationInput.units.seconds', 'Seconds'),\n minutes: t('ui.durationInput.units.minutes', 'Minutes'),\n hours: t('ui.durationInput.units.hours', 'Hours'),\n days: t('ui.durationInput.units.days', 'Days'),\n }\n\n const handleAmountChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return\n const raw = event.target.value\n if (raw === '') {\n onChange('')\n return\n }\n const amount = parseInt(raw, 10)\n if (isNaN(amount) || amount < 0) return\n onChange(formatSingleUnitDuration(amount, unit))\n },\n [disabled, onChange, unit]\n )\n\n const handleUnitChange = React.useCallback(\n (nextUnit: string) => {\n if (disabled) return\n const resolved = durationUnits.find((candidate) => candidate === nextUnit)\n if (!resolved) return\n setUnit(resolved)\n if (parsed) onChange(formatSingleUnitDuration(parsed.amount, resolved))\n },\n [disabled, onChange, parsed]\n )\n\n const handleRawChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return\n onChange(event.target.value)\n },\n [disabled, onChange]\n )\n\n const switchToRaw = React.useCallback(() => {\n setMode('raw')\n }, [])\n\n const switchToComposite = React.useCallback(() => {\n if (!isCompositeCompatibleDuration(currentValue)) return\n setMode('composite')\n }, [currentValue])\n\n if (mode === 'raw') {\n return (\n <div className={cn('flex items-center gap-2', className)}>\n <Input\n id={id}\n type=\"text\"\n value={currentValue}\n onChange={handleRawChange}\n disabled={disabled}\n aria-label={rawLabel}\n className=\"flex-1\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={switchToComposite}\n disabled={disabled || !compositeCompatible}\n >\n {t('ui.durationInput.switchToComposite', 'Use picker')}\n </Button>\n </div>\n )\n }\n\n return (\n <div className={cn('flex items-center gap-2', className)}>\n <Input\n id={id}\n type=\"number\"\n min={0}\n value={parsed ? String(parsed.amount) : ''}\n onChange={handleAmountChange}\n disabled={disabled}\n aria-label={amountLabel}\n className=\"w-24\"\n />\n <Select value={unit} onValueChange={handleUnitChange} disabled={disabled}>\n <SelectTrigger aria-label={unitLabel} className=\"w-32\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {durationUnits.map((option) => (\n <SelectItem key={option} value={option}>\n {unitOptionLabels[option]}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={switchToRaw}\n disabled={disabled}\n >\n {t('ui.durationInput.switchToRaw', 'Edit as text')}\n </Button>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/backend/inputs/EventSelect.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useMemo } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { apiCall } from '../utils/apiCall'\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} from '../../primitives/select'\n\n/**\n * Event definition returned by the API\n */\nexport interface EventDefinition {\n id: string\n label: string\n description?: string\n category?: 'crud' | 'lifecycle' | 'system' | 'custom'\n module?: string\n entity?: string\n excludeFromTriggers?: boolean\n}\n\nexport interface EventSelectProps {\n /** Current selected event ID */\n value: string\n /** Called when event is selected */\n onChange: (eventId: string) => void\n /** Placeholder text when no event selected. Defaults to a translated string. */\n placeholder?: string\n /** Additional CSS classes */\n className?: string\n /** Whether the select is disabled */\n disabled?: boolean\n /** Filter events by category */\n categories?: Array<'crud' | 'lifecycle' | 'system' | 'custom'>\n /** Filter events by module */\n modules?: string[]\n /** Whether to exclude events marked as excludeFromTriggers (default: true) */\n excludeTriggerExcluded?: boolean\n /** Trigger size \u2014 defaults to `'default'` (DS row-height contract). */\n size?: 'sm' | 'default' | 'lg'\n}\n\n/**\n * EventSelect - A reusable select component for choosing declared events\n *\n * Fetches available events from the API and groups them by module.\n */\nexport function EventSelect({\n value,\n onChange,\n placeholder,\n className,\n disabled,\n categories,\n modules,\n excludeTriggerExcluded = true,\n size = 'default',\n}: EventSelectProps) {\n const t = useT()\n const resolvedPlaceholder = placeholder ?? t('ui.inputs.eventSelect.placeholder', 'Select an event...')\n const loadingPlaceholder = t('ui.inputs.eventSelect.loading', 'Loading...')\n const emptyPlaceholder = t('ui.inputs.eventSelect.empty', 'No events available')\n\n // Fetch events from the API\n const { data: allEvents = [], isLoading } = useQuery({\n queryKey: ['declared-events', excludeTriggerExcluded],\n queryFn: async () => {\n const result = await apiCall<{ data: EventDefinition[]; total: number }>(\n `/api/events?excludeTriggerExcluded=${excludeTriggerExcluded}`\n )\n if (!result.ok) return []\n return result.result?.data || []\n },\n staleTime: 5 * 60 * 1000, // Cache for 5 minutes\n })\n\n // Filter events based on props\n const filteredEvents = useMemo(() => {\n let events = allEvents\n\n if (categories?.length) {\n events = events.filter(e => e.category && categories.includes(e.category))\n }\n if (modules?.length) {\n events = events.filter(e => e.module && modules.includes(e.module))\n }\n\n return events\n }, [allEvents, categories, modules])\n\n // Group events by module for better UX\n const eventsByModule = useMemo(() => {\n const grouped: Record<string, EventDefinition[]> = {}\n for (const event of filteredEvents) {\n const module = event.module || 'other'\n if (!grouped[module]) grouped[module] = []\n grouped[module].push(event)\n }\n // Sort modules alphabetically\n return Object.fromEntries(\n Object.entries(grouped).sort(([a], [b]) => a.localeCompare(b))\n )\n }, [filteredEvents])\n\n // Format module name for display\n const formatModuleName = (module: string): string => {\n return module.charAt(0).toUpperCase() + module.slice(1).replace(/_/g, ' ')\n }\n\n const isEmpty = !isLoading && filteredEvents.length === 0\n\n return (\n <Select\n value={value || undefined}\n onValueChange={(next) => onChange(next ?? '')}\n disabled={disabled || isLoading}\n >\n <SelectTrigger size={size} className={className}>\n <SelectValue\n placeholder={isLoading ? loadingPlaceholder : isEmpty ? emptyPlaceholder : resolvedPlaceholder}\n />\n </SelectTrigger>\n <SelectContent>\n {Object.entries(eventsByModule).map(([module, moduleEvents]) => (\n <SelectGroup key={module}>\n <SelectLabel>{formatModuleName(module)}</SelectLabel>\n {moduleEvents.map(event => (\n <SelectItem key={event.id} value={event.id}>\n {event.label}\n </SelectItem>\n ))}\n </SelectGroup>\n ))}\n </SelectContent>\n </Select>\n )\n}\n\n/**\n * Hook for getting available events\n */\nexport function useAvailableEvents(options?: {\n categories?: Array<'crud' | 'lifecycle' | 'system' | 'custom'>\n modules?: string[]\n excludeTriggerExcluded?: boolean\n}) {\n const excludeTriggerExcluded = options?.excludeTriggerExcluded !== false\n\n const { data: allEvents = [], isLoading, error, refetch } = useQuery({\n queryKey: ['declared-events', excludeTriggerExcluded],\n queryFn: async () => {\n const result = await apiCall<{ data: EventDefinition[]; total: number }>(\n `/api/events?excludeTriggerExcluded=${excludeTriggerExcluded}`\n )\n if (!result.ok) return []\n return result.result?.data || []\n },\n staleTime: 5 * 60 * 1000,\n })\n\n const filteredEvents = useMemo(() => {\n let events = allEvents\n\n if (options?.categories?.length) {\n events = events.filter(e => e.category && options.categories!.includes(e.category))\n }\n if (options?.modules?.length) {\n events = events.filter(e => e.module && options.modules!.includes(e.module))\n }\n\n return events\n }, [allEvents, options])\n\n // Group by module\n const eventsByModule = useMemo(() => {\n const grouped: Record<string, EventDefinition[]> = {}\n for (const event of filteredEvents) {\n const module = event.module || 'other'\n if (!grouped[module]) grouped[module] = []\n grouped[module].push(event)\n }\n return Object.fromEntries(\n Object.entries(grouped).sort(([a], [b]) => a.localeCompare(b))\n )\n }, [filteredEvents])\n\n return {\n events: filteredEvents,\n eventsByModule,\n isLoading,\n error,\n refetch,\n }\n}\n\nexport default EventSelect\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useMemo } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { EventPayloadSchema } from '@open-mercato/shared/modules/events'\nimport { apiCall } from '../utils/apiCall'\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} from '../../primitives/select'\n\n/**\n * Event definition returned by the API\n */\nexport interface EventDefinition {\n id: string\n label: string\n description?: string\n category?: 'crud' | 'lifecycle' | 'system' | 'custom'\n module?: string\n entity?: string\n excludeFromTriggers?: boolean\n payloadSchema?: EventPayloadSchema\n}\n\nexport interface EventSelectProps {\n /** Current selected event ID */\n value: string\n /** Called when event is selected */\n onChange: (eventId: string) => void\n /** Placeholder text when no event selected. Defaults to a translated string. */\n placeholder?: string\n /** Additional CSS classes */\n className?: string\n /** Whether the select is disabled */\n disabled?: boolean\n /** Filter events by category */\n categories?: Array<'crud' | 'lifecycle' | 'system' | 'custom'>\n /** Filter events by module */\n modules?: string[]\n /** Whether to exclude events marked as excludeFromTriggers (default: true) */\n excludeTriggerExcluded?: boolean\n /** Trigger size \u2014 defaults to `'default'` (DS row-height contract). */\n size?: 'sm' | 'default' | 'lg'\n}\n\n/**\n * EventSelect - A reusable select component for choosing declared events\n *\n * Fetches available events from the API and groups them by module.\n */\nexport function EventSelect({\n value,\n onChange,\n placeholder,\n className,\n disabled,\n categories,\n modules,\n excludeTriggerExcluded = true,\n size = 'default',\n}: EventSelectProps) {\n const t = useT()\n const resolvedPlaceholder = placeholder ?? t('ui.inputs.eventSelect.placeholder', 'Select an event...')\n const loadingPlaceholder = t('ui.inputs.eventSelect.loading', 'Loading...')\n const emptyPlaceholder = t('ui.inputs.eventSelect.empty', 'No events available')\n\n // Fetch events from the API\n const { data: allEvents = [], isLoading } = useQuery({\n queryKey: ['declared-events', excludeTriggerExcluded],\n queryFn: async () => {\n const result = await apiCall<{ data: EventDefinition[]; total: number }>(\n `/api/events?excludeTriggerExcluded=${excludeTriggerExcluded}`\n )\n if (!result.ok) return []\n return result.result?.data || []\n },\n staleTime: 5 * 60 * 1000, // Cache for 5 minutes\n })\n\n // Filter events based on props\n const filteredEvents = useMemo(() => {\n let events = allEvents\n\n if (categories?.length) {\n events = events.filter(e => e.category && categories.includes(e.category))\n }\n if (modules?.length) {\n events = events.filter(e => e.module && modules.includes(e.module))\n }\n\n return events\n }, [allEvents, categories, modules])\n\n // Group events by module for better UX\n const eventsByModule = useMemo(() => {\n const grouped: Record<string, EventDefinition[]> = {}\n for (const event of filteredEvents) {\n const module = event.module || 'other'\n if (!grouped[module]) grouped[module] = []\n grouped[module].push(event)\n }\n // Sort modules alphabetically\n return Object.fromEntries(\n Object.entries(grouped).sort(([a], [b]) => a.localeCompare(b))\n )\n }, [filteredEvents])\n\n // Format module name for display\n const formatModuleName = (module: string): string => {\n return module.charAt(0).toUpperCase() + module.slice(1).replace(/_/g, ' ')\n }\n\n const isEmpty = !isLoading && filteredEvents.length === 0\n\n return (\n <Select\n value={value || undefined}\n onValueChange={(next) => onChange(next ?? '')}\n disabled={disabled || isLoading}\n >\n <SelectTrigger size={size} className={className}>\n <SelectValue\n placeholder={isLoading ? loadingPlaceholder : isEmpty ? emptyPlaceholder : resolvedPlaceholder}\n />\n </SelectTrigger>\n <SelectContent>\n {Object.entries(eventsByModule).map(([module, moduleEvents]) => (\n <SelectGroup key={module}>\n <SelectLabel>{formatModuleName(module)}</SelectLabel>\n {moduleEvents.map(event => (\n <SelectItem key={event.id} value={event.id}>\n {event.label}\n </SelectItem>\n ))}\n </SelectGroup>\n ))}\n </SelectContent>\n </Select>\n )\n}\n\n/**\n * Hook for getting available events\n */\nexport function useAvailableEvents(options?: {\n categories?: Array<'crud' | 'lifecycle' | 'system' | 'custom'>\n modules?: string[]\n excludeTriggerExcluded?: boolean\n}) {\n const excludeTriggerExcluded = options?.excludeTriggerExcluded !== false\n\n const { data: allEvents = [], isLoading, error, refetch } = useQuery({\n queryKey: ['declared-events', excludeTriggerExcluded],\n queryFn: async () => {\n const result = await apiCall<{ data: EventDefinition[]; total: number }>(\n `/api/events?excludeTriggerExcluded=${excludeTriggerExcluded}`\n )\n if (!result.ok) return []\n return result.result?.data || []\n },\n staleTime: 5 * 60 * 1000,\n })\n\n const filteredEvents = useMemo(() => {\n let events = allEvents\n\n if (options?.categories?.length) {\n events = events.filter(e => e.category && options.categories!.includes(e.category))\n }\n if (options?.modules?.length) {\n events = events.filter(e => e.module && options.modules!.includes(e.module))\n }\n\n return events\n }, [allEvents, options])\n\n // Group by module\n const eventsByModule = useMemo(() => {\n const grouped: Record<string, EventDefinition[]> = {}\n for (const event of filteredEvents) {\n const module = event.module || 'other'\n if (!grouped[module]) grouped[module] = []\n grouped[module].push(event)\n }\n return Object.fromEntries(\n Object.entries(grouped).sort(([a], [b]) => a.localeCompare(b))\n )\n }, [filteredEvents])\n\n return {\n events: filteredEvents,\n eventsByModule,\n isLoading,\n error,\n refetch,\n }\n}\n\nexport default EventSelect\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/inputs/index.ts"],
|
|
4
|
-
"sourcesContent": ["export * from './PhoneNumberField'\nexport * from './TagsInput'\nexport * from './LookupSelect'\nexport * from './ComboboxInput'\nexport * from './SwitchableMarkdownInput'\nexport * from './EventSelect'\nexport * from './EventPatternInput'\nexport * from './TimeInput'\nexport * from './TimePicker'\nexport * from './DateTimePicker'\nexport * from './DatePicker'\n"],
|
|
5
|
-
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
4
|
+
"sourcesContent": ["export * from './PhoneNumberField'\nexport * from './TagsInput'\nexport * from './LookupSelect'\nexport * from './ComboboxInput'\nexport * from './SwitchableMarkdownInput'\nexport * from './EventSelect'\nexport * from './EventPatternInput'\nexport * from './TimeInput'\nexport * from './TimePicker'\nexport * from './DateTimePicker'\nexport * from './DatePicker'\nexport * from './DurationInput'\n"],
|
|
5
|
+
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|