@open-mercato/ui 0.6.8-develop.7099.1.7ba2771d06 → 0.7.0
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 +1 -1
- package/dist/ai/records/ActivityCard.js +3 -4
- package/dist/ai/records/ActivityCard.js.map +2 -2
- package/dist/ai/records/DealCard.js +3 -4
- package/dist/ai/records/DealCard.js.map +2 -2
- package/dist/ai/records/ProductCard.js +2 -3
- package/dist/ai/records/ProductCard.js.map +2 -2
- package/dist/backend/AppShell.js +106 -129
- package/dist/backend/AppShell.js.map +2 -2
- package/dist/backend/DataTable.js +9 -22
- package/dist/backend/DataTable.js.map +2 -2
- package/dist/backend/detail/NotesSection.js +20 -26
- package/dist/backend/detail/NotesSection.js.map +2 -2
- package/dist/backend/icons/lucideRegistry.generated.js +0 -4
- package/dist/backend/icons/lucideRegistry.generated.js.map +2 -2
- package/dist/backend/injection/useRegisteredComponent.js +6 -24
- package/dist/backend/injection/useRegisteredComponent.js.map +2 -2
- package/dist/backend/inputs/ComboboxInput.js +4 -8
- package/dist/backend/inputs/ComboboxInput.js.map +2 -2
- package/dist/backend/inputs/LookupSelect.js +9 -9
- package/dist/backend/inputs/LookupSelect.js.map +2 -2
- package/dist/backend/sidebar/SidebarCustomizationEditor.js +30 -36
- package/dist/backend/sidebar/SidebarCustomizationEditor.js.map +2 -2
- package/dist/backend/utils/crud.js.map +2 -2
- package/dist/backend/utils/useAutoDiscoveredFields.js +8 -4
- package/dist/backend/utils/useAutoDiscoveredFields.js.map +2 -2
- package/dist/primitives/alert.js +1 -1
- package/dist/primitives/alert.js.map +2 -2
- package/dist/primitives/icon-button.js +1 -20
- package/dist/primitives/icon-button.js.map +2 -2
- package/dist/primitives/pagination.js +9 -14
- package/dist/primitives/pagination.js.map +2 -2
- package/dist/primitives/rich-editor.js +7 -14
- package/dist/primitives/rich-editor.js.map +2 -2
- package/dist/utils/format.js +5 -5
- package/dist/utils/format.js.map +2 -2
- package/package.json +4 -5
- package/src/ai/parts/__tests__/ConfirmationCard.test.tsx +0 -2
- package/src/ai/records/ActivityCard.tsx +3 -4
- package/src/ai/records/DealCard.tsx +3 -4
- package/src/ai/records/ProductCard.tsx +2 -3
- package/src/backend/AppShell.tsx +58 -89
- package/src/backend/DataTable.tsx +12 -46
- package/src/backend/__tests__/AppShell.test.tsx +1 -162
- package/src/backend/__tests__/DataTable.render.test.tsx +0 -37
- package/src/backend/__tests__/NotesSection.test.tsx +0 -89
- package/src/backend/detail/NotesSection.tsx +67 -92
- package/src/backend/icons/lucideRegistry.generated.tsx +0 -4
- package/src/backend/injection/useRegisteredComponent.tsx +8 -49
- package/src/backend/inputs/ComboboxInput.tsx +5 -21
- package/src/backend/inputs/LookupSelect.tsx +14 -10
- package/src/backend/inputs/__tests__/ComboboxInput.test.tsx +0 -142
- package/src/backend/inputs/__tests__/LookupSelect.test.tsx +40 -63
- package/src/backend/sidebar/SidebarCustomizationEditor.tsx +11 -14
- package/src/backend/utils/__tests__/useAutoDiscoveredFields.groupLabels.test.tsx +59 -0
- package/src/backend/utils/crud.ts +0 -2
- package/src/backend/utils/useAutoDiscoveredFields.ts +10 -4
- package/src/primitives/__tests__/alert.test.tsx +1 -41
- package/src/primitives/__tests__/icon-button.test.tsx +0 -70
- package/src/primitives/__tests__/notification.test.tsx +1 -1
- package/src/primitives/__tests__/pagination.test.tsx +0 -54
- package/src/primitives/__tests__/rich-editor.test.tsx +0 -43
- package/src/primitives/alert.tsx +2 -5
- package/src/primitives/icon-button.tsx +1 -20
- package/src/primitives/pagination.tsx +9 -40
- package/src/primitives/rich-editor.tsx +4 -9
- package/src/utils/__tests__/format.test.ts +14 -27
- package/src/utils/format.ts +5 -10
- package/src/backend/__tests__/DataTable.cappedPagination.test.tsx +0 -122
- package/src/backend/__tests__/DataTable.headerWrap.test.tsx +0 -111
- package/src/backend/__tests__/useRegisteredComponent.identity.test.tsx +0 -305
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Generated lucide registry with
|
|
1
|
+
Generated lucide registry with 159 icons -> /home/runner/work/open-mercato/open-mercato/packages/ui/src/backend/icons/lucideRegistry.generated.tsx
|
|
2
2
|
[build:ui] found 400 entry points
|
|
3
3
|
[build:ui] built successfully
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
Phone,
|
|
11
11
|
StickyNote
|
|
12
12
|
} from "lucide-react";
|
|
13
|
-
import { useT
|
|
13
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
14
14
|
import { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from "./RecordCardShell.js";
|
|
15
15
|
import { formatDate } from "../../utils/format.js";
|
|
16
16
|
function pickActivityIcon(type) {
|
|
@@ -26,11 +26,10 @@ function pickActivityIcon(type) {
|
|
|
26
26
|
}
|
|
27
27
|
function ActivityCard(props) {
|
|
28
28
|
const t = useT();
|
|
29
|
-
const locale = useLocale();
|
|
30
29
|
const Icon = pickActivityIcon(props.type);
|
|
31
30
|
const status = props.status ? { label: props.status, variant: statusToTagVariant(props.status) } : null;
|
|
32
|
-
const dueDate = formatDate(props.dueDate
|
|
33
|
-
const completedAt = formatDate(props.completedAt
|
|
31
|
+
const dueDate = formatDate(props.dueDate);
|
|
32
|
+
const completedAt = formatDate(props.completedAt);
|
|
34
33
|
const items = [
|
|
35
34
|
props.type ? { label: t("ai_assistant.chat.records.fields.type", "Type"), value: props.type } : null,
|
|
36
35
|
dueDate ? {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ai/records/ActivityCard.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport {\n Activity as ActivityIcon,\n CalendarClock,\n CheckCircle2,\n ListChecks,\n Mail,\n MessageSquare,\n Phone,\n StickyNote,\n} from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\nimport { useT
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport {\n Activity as ActivityIcon,\n CalendarClock,\n CheckCircle2,\n ListChecks,\n Mail,\n MessageSquare,\n Phone,\n StickyNote,\n} from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from './RecordCardShell'\nimport type { ActivityRecordPayload } from './types'\nimport { formatDate } from '../../utils/format'\n\nfunction pickActivityIcon(type: string | null | undefined): LucideIcon {\n if (!type) return ActivityIcon\n const t = type.toLowerCase()\n if (t.includes('call')) return Phone\n if (t.includes('mail') || t.includes('email')) return Mail\n if (t.includes('meeting') || t.includes('chat')) return MessageSquare\n if (t.includes('task') || t.includes('todo')) return ListChecks\n if (t.includes('note')) return StickyNote\n if (t.includes('done') || t.includes('complete')) return CheckCircle2\n return ActivityIcon\n}\n\nexport interface ActivityCardProps extends ActivityRecordPayload {}\n\nexport function ActivityCard(props: ActivityCardProps) {\n const t = useT()\n const Icon = pickActivityIcon(props.type)\n const status = props.status\n ? { label: props.status, variant: statusToTagVariant(props.status) }\n : null\n const dueDate = formatDate(props.dueDate)\n const completedAt = formatDate(props.completedAt)\n\n const items = [\n props.type ? { label: t('ai_assistant.chat.records.fields.type', 'Type'), value: props.type } : null,\n dueDate\n ? {\n label: t('ai_assistant.chat.records.fields.due', 'Due'),\n value: (\n <span className=\"inline-flex items-center gap-1\">\n <CalendarClock className=\"size-3 text-muted-foreground\" aria-hidden />\n {dueDate}\n </span>\n ),\n }\n : null,\n completedAt\n ? {\n label: t('ai_assistant.chat.records.fields.completed', 'Completed'),\n value: (\n <span className=\"inline-flex items-center gap-1\">\n <CheckCircle2 className=\"size-3 text-status-success-icon\" aria-hidden />\n {completedAt}\n </span>\n ),\n }\n : null,\n props.relatedTo ? { label: t('ai_assistant.chat.records.fields.related', 'Related'), value: props.relatedTo } : null,\n props.ownerName ? { label: t('ai_assistant.chat.records.fields.owner', 'Owner'), value: props.ownerName } : null,\n ].filter(Boolean) as { label: string; value: React.ReactNode }[]\n\n const subtitle = [props.type, props.relatedTo].filter(Boolean).join(' \u2022 ')\n\n return (\n <RecordCardShell\n kindLabel={t('ai_assistant.chat.records.kinds.activity', 'Activity')}\n kindIcon={<Icon className=\"size-4\" aria-hidden />}\n title={props.title}\n subtitle={subtitle || undefined}\n status={status}\n href={props.href}\n id={props.id}\n className={props.className}\n dataKind=\"activity\"\n >\n <div className=\"space-y-2\">\n <KeyValueList items={items} />\n {props.description ? (\n <p className=\"line-clamp-3 text-muted-foreground\">{props.description}</p>\n ) : null}\n {props.tags && props.tags.length > 0 ? <TagRow tags={props.tags} /> : null}\n </div>\n </RecordCardShell>\n )\n}\n\nexport default ActivityCard\n"],
|
|
5
|
+
"mappings": ";AAgDY,SACE,KADF;AA7CZ;AAAA,EACE,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,YAAY;AACrB,SAAS,cAAc,iBAAiB,QAAQ,0BAA0B;AAE1E,SAAS,kBAAkB;AAE3B,SAAS,iBAAiB,MAA6C;AACrE,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,IAAI,KAAK,YAAY;AAC3B,MAAI,EAAE,SAAS,MAAM,EAAG,QAAO;AAC/B,MAAI,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,OAAO,EAAG,QAAO;AACtD,MAAI,EAAE,SAAS,SAAS,KAAK,EAAE,SAAS,MAAM,EAAG,QAAO;AACxD,MAAI,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,MAAM,EAAG,QAAO;AACrD,MAAI,EAAE,SAAS,MAAM,EAAG,QAAO;AAC/B,MAAI,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,UAAU,EAAG,QAAO;AACzD,SAAO;AACT;AAIO,SAAS,aAAa,OAA0B;AACrD,QAAM,IAAI,KAAK;AACf,QAAM,OAAO,iBAAiB,MAAM,IAAI;AACxC,QAAM,SAAS,MAAM,SACjB,EAAE,OAAO,MAAM,QAAQ,SAAS,mBAAmB,MAAM,MAAM,EAAE,IACjE;AACJ,QAAM,UAAU,WAAW,MAAM,OAAO;AACxC,QAAM,cAAc,WAAW,MAAM,WAAW;AAEhD,QAAM,QAAQ;AAAA,IACZ,MAAM,OAAO,EAAE,OAAO,EAAE,yCAAyC,MAAM,GAAG,OAAO,MAAM,KAAK,IAAI;AAAA,IAChG,UACI;AAAA,MACE,OAAO,EAAE,wCAAwC,KAAK;AAAA,MACtD,OACE,qBAAC,UAAK,WAAU,kCACd;AAAA,4BAAC,iBAAc,WAAU,gCAA+B,eAAW,MAAC;AAAA,QACnE;AAAA,SACH;AAAA,IAEJ,IACA;AAAA,IACJ,cACI;AAAA,MACE,OAAO,EAAE,8CAA8C,WAAW;AAAA,MAClE,OACE,qBAAC,UAAK,WAAU,kCACd;AAAA,4BAAC,gBAAa,WAAU,mCAAkC,eAAW,MAAC;AAAA,QACrE;AAAA,SACH;AAAA,IAEJ,IACA;AAAA,IACJ,MAAM,YAAY,EAAE,OAAO,EAAE,4CAA4C,SAAS,GAAG,OAAO,MAAM,UAAU,IAAI;AAAA,IAChH,MAAM,YAAY,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,MAAM,UAAU,IAAI;AAAA,EAC9G,EAAE,OAAO,OAAO;AAEhB,QAAM,WAAW,CAAC,MAAM,MAAM,MAAM,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,UAAK;AAEzE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,EAAE,4CAA4C,UAAU;AAAA,MACnE,UAAU,oBAAC,QAAK,WAAU,UAAS,eAAW,MAAC;AAAA,MAC/C,OAAO,MAAM;AAAA,MACb,UAAU,YAAY;AAAA,MACtB;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,IAAI,MAAM;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,UAAS;AAAA,MAET,+BAAC,SAAI,WAAU,aACb;AAAA,4BAAC,gBAAa,OAAc;AAAA,QAC3B,MAAM,cACL,oBAAC,OAAE,WAAU,sCAAsC,gBAAM,aAAY,IACnE;AAAA,QACH,MAAM,QAAQ,MAAM,KAAK,SAAS,IAAI,oBAAC,UAAO,MAAM,MAAM,MAAM,IAAK;AAAA,SACxE;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,uBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Briefcase, Building2, CalendarDays, CircleDollarSign, User } from "lucide-react";
|
|
4
|
-
import { useT
|
|
4
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
5
5
|
import { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from "./RecordCardShell.js";
|
|
6
6
|
import { formatCurrency, formatDate } from "../../utils/format.js";
|
|
7
7
|
function DealCard(props) {
|
|
8
8
|
const t = useT();
|
|
9
|
-
const locale = useLocale();
|
|
10
9
|
const status = props.status ? { label: props.status, variant: statusToTagVariant(props.status) } : null;
|
|
11
10
|
const stage = props.stage && props.stage !== props.status ? props.stage : null;
|
|
12
|
-
const amount = formatCurrency(props.amount, props.currency
|
|
13
|
-
const closeDate = formatDate(props.closeDate
|
|
11
|
+
const amount = formatCurrency(props.amount, props.currency);
|
|
12
|
+
const closeDate = formatDate(props.closeDate);
|
|
14
13
|
const items = [
|
|
15
14
|
stage ? { label: t("ai_assistant.chat.records.fields.stage", "Stage"), value: stage } : null,
|
|
16
15
|
amount ? { label: t("ai_assistant.chat.records.fields.amount", "Amount"), value: /* @__PURE__ */ jsx("span", { className: "font-medium", children: amount }) } : null,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ai/records/DealCard.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Briefcase, Building2, CalendarDays, CircleDollarSign, User } from 'lucide-react'\nimport { useT
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Briefcase, Building2, CalendarDays, CircleDollarSign, User } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from './RecordCardShell'\nimport type { DealRecordPayload } from './types'\nimport { formatCurrency, formatDate } from '../../utils/format'\n\nexport interface DealCardProps extends DealRecordPayload {}\n\nexport function DealCard(props: DealCardProps) {\n const t = useT()\n const status = props.status\n ? { label: props.status, variant: statusToTagVariant(props.status) }\n : null\n const stage = props.stage && props.stage !== props.status ? props.stage : null\n const amount = formatCurrency(props.amount, props.currency)\n const closeDate = formatDate(props.closeDate)\n\n const items = [\n stage ? { label: t('ai_assistant.chat.records.fields.stage', 'Stage'), value: stage } : null,\n amount ? { label: t('ai_assistant.chat.records.fields.amount', 'Amount'), value: <span className=\"font-medium\">{amount}</span> } : null,\n closeDate ? { label: t('ai_assistant.chat.records.fields.close', 'Close'), value: closeDate } : null,\n props.companyName ? { label: t('ai_assistant.chat.records.fields.company', 'Company'), value: props.companyName } : null,\n props.personName ? { label: t('ai_assistant.chat.records.fields.contact', 'Contact'), value: props.personName } : null,\n props.ownerName ? { label: t('ai_assistant.chat.records.fields.owner', 'Owner'), value: props.ownerName } : null,\n ].filter(Boolean) as { label: string; value: React.ReactNode }[]\n\n const subtitleParts: string[] = []\n if (props.companyName) subtitleParts.push(props.companyName)\n if (props.personName && !props.companyName) subtitleParts.push(props.personName)\n if (amount) subtitleParts.push(amount)\n\n return (\n <RecordCardShell\n kindLabel={t('ai_assistant.chat.records.kinds.deal', 'Deal')}\n kindIcon={<Briefcase className=\"size-4\" aria-hidden />}\n title={props.title}\n subtitle={subtitleParts.join(' \u2022 ')}\n status={status}\n href={props.href}\n id={props.id}\n className={props.className}\n dataKind=\"deal\"\n >\n <div className=\"space-y-2\">\n <KeyValueList items={items} />\n {props.description ? (\n <p className=\"line-clamp-2 text-muted-foreground\">{props.description}</p>\n ) : null}\n {props.tags && props.tags.length > 0 ? <TagRow tags={props.tags} /> : null}\n </div>\n </RecordCardShell>\n )\n}\n\nexport default DealCard\n\n// Re-export icons consumers may want when extending the layout\nexport { Briefcase, Building2, CalendarDays, CircleDollarSign, User }\n"],
|
|
5
|
+
"mappings": ";AAsBqF,cAwB/E,YAxB+E;AAnBrF,SAAS,WAAW,WAAW,cAAc,kBAAkB,YAAY;AAC3E,SAAS,YAAY;AACrB,SAAS,cAAc,iBAAiB,QAAQ,0BAA0B;AAE1E,SAAS,gBAAgB,kBAAkB;AAIpC,SAAS,SAAS,OAAsB;AAC7C,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,MAAM,SACjB,EAAE,OAAO,MAAM,QAAQ,SAAS,mBAAmB,MAAM,MAAM,EAAE,IACjE;AACJ,QAAM,QAAQ,MAAM,SAAS,MAAM,UAAU,MAAM,SAAS,MAAM,QAAQ;AAC1E,QAAM,SAAS,eAAe,MAAM,QAAQ,MAAM,QAAQ;AAC1D,QAAM,YAAY,WAAW,MAAM,SAAS;AAE5C,QAAM,QAAQ;AAAA,IACZ,QAAQ,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,MAAM,IAAI;AAAA,IACxF,SAAS,EAAE,OAAO,EAAE,2CAA2C,QAAQ,GAAG,OAAO,oBAAC,UAAK,WAAU,eAAe,kBAAO,EAAQ,IAAI;AAAA,IACnI,YAAY,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,UAAU,IAAI;AAAA,IAChG,MAAM,cAAc,EAAE,OAAO,EAAE,4CAA4C,SAAS,GAAG,OAAO,MAAM,YAAY,IAAI;AAAA,IACpH,MAAM,aAAa,EAAE,OAAO,EAAE,4CAA4C,SAAS,GAAG,OAAO,MAAM,WAAW,IAAI;AAAA,IAClH,MAAM,YAAY,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,MAAM,UAAU,IAAI;AAAA,EAC9G,EAAE,OAAO,OAAO;AAEhB,QAAM,gBAA0B,CAAC;AACjC,MAAI,MAAM,YAAa,eAAc,KAAK,MAAM,WAAW;AAC3D,MAAI,MAAM,cAAc,CAAC,MAAM,YAAa,eAAc,KAAK,MAAM,UAAU;AAC/E,MAAI,OAAQ,eAAc,KAAK,MAAM;AAErC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,EAAE,wCAAwC,MAAM;AAAA,MAC3D,UAAU,oBAAC,aAAU,WAAU,UAAS,eAAW,MAAC;AAAA,MACpD,OAAO,MAAM;AAAA,MACb,UAAU,cAAc,KAAK,UAAK;AAAA,MAClC;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,IAAI,MAAM;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,UAAS;AAAA,MAET,+BAAC,SAAI,WAAU,aACb;AAAA,4BAAC,gBAAa,OAAc;AAAA,QAC3B,MAAM,cACL,oBAAC,OAAE,WAAU,sCAAsC,gBAAM,aAAY,IACnE;AAAA,QACH,MAAM,QAAQ,MAAM,KAAK,SAAS,IAAI,oBAAC,UAAO,MAAM,MAAM,MAAM,IAAK;AAAA,SACxE;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,mBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Package, Tag as TagIcon } from "lucide-react";
|
|
4
|
-
import { useT
|
|
4
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
5
5
|
import { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from "./RecordCardShell.js";
|
|
6
6
|
import { formatCurrency } from "../../utils/format.js";
|
|
7
7
|
function ProductCard(props) {
|
|
8
8
|
const t = useT();
|
|
9
|
-
const locale = useLocale();
|
|
10
9
|
const status = props.status ? { label: props.status, variant: statusToTagVariant(props.status) } : null;
|
|
11
|
-
const price = formatCurrency(props.price, props.currency
|
|
10
|
+
const price = formatCurrency(props.price, props.currency);
|
|
12
11
|
const leading = props.imageUrl ? /* @__PURE__ */ jsx("div", { className: "relative size-12 overflow-hidden rounded-md border border-border bg-muted", children: /* @__PURE__ */ jsx(
|
|
13
12
|
"img",
|
|
14
13
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ai/records/ProductCard.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Package, Tag as TagIcon } from 'lucide-react'\nimport { useT
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Package, Tag as TagIcon } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from './RecordCardShell'\nimport type { ProductRecordPayload } from './types'\nimport { formatCurrency } from '../../utils/format'\n\nexport interface ProductCardProps extends ProductRecordPayload {}\n\nexport function ProductCard(props: ProductCardProps) {\n const t = useT()\n const status = props.status\n ? { label: props.status, variant: statusToTagVariant(props.status) }\n : null\n const price = formatCurrency(props.price, props.currency)\n\n const leading = props.imageUrl ? (\n <div className=\"relative size-12 overflow-hidden rounded-md border border-border bg-muted\">\n <img\n src={props.imageUrl}\n alt={props.name}\n className=\"size-full object-cover\"\n loading=\"lazy\"\n />\n </div>\n ) : (\n <div className=\"flex size-12 items-center justify-center rounded-md border border-border bg-muted text-muted-foreground\" aria-hidden>\n <Package className=\"size-5\" />\n </div>\n )\n\n const items = [\n props.sku ? { label: t('ai_assistant.chat.records.fields.sku', 'SKU'), value: <span className=\"font-mono text-[11px]\">{props.sku}</span> } : null,\n price ? { label: t('ai_assistant.chat.records.fields.price', 'Price'), value: <span className=\"font-medium\">{price}</span> } : null,\n props.category ? { label: t('ai_assistant.chat.records.fields.category', 'Category'), value: props.category } : null,\n ].filter(Boolean) as { label: string; value: React.ReactNode }[]\n\n return (\n <RecordCardShell\n kindLabel={t('ai_assistant.chat.records.kinds.product', 'Product')}\n kindIcon={<Package className=\"size-4\" aria-hidden />}\n leading={leading}\n title={props.name}\n subtitle={[props.sku, price].filter(Boolean).join(' \u2022 ') || undefined}\n status={status}\n href={props.href}\n id={props.id}\n className={props.className}\n dataKind=\"product\"\n >\n <div className=\"space-y-2\">\n <KeyValueList items={items} />\n {props.description ? (\n <p className=\"line-clamp-2 text-muted-foreground\">{props.description}</p>\n ) : null}\n {props.tags && props.tags.length > 0 ? <TagRow tags={props.tags} /> : null}\n </div>\n </RecordCardShell>\n )\n}\n\nexport default ProductCard\n\nexport { Package, TagIcon }\n"],
|
|
5
|
+
"mappings": ";AAoBM,cAgCA,YAhCA;AAjBN,SAAS,SAAS,OAAO,eAAe;AACxC,SAAS,YAAY;AACrB,SAAS,cAAc,iBAAiB,QAAQ,0BAA0B;AAE1E,SAAS,sBAAsB;AAIxB,SAAS,YAAY,OAAyB;AACnD,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,MAAM,SACjB,EAAE,OAAO,MAAM,QAAQ,SAAS,mBAAmB,MAAM,MAAM,EAAE,IACjE;AACJ,QAAM,QAAQ,eAAe,MAAM,OAAO,MAAM,QAAQ;AAExD,QAAM,UAAU,MAAM,WACpB,oBAAC,SAAI,WAAU,6EACb;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,MAAM;AAAA,MACX,KAAK,MAAM;AAAA,MACX,WAAU;AAAA,MACV,SAAQ;AAAA;AAAA,EACV,GACF,IAEA,oBAAC,SAAI,WAAU,2GAA0G,eAAW,MAClI,8BAAC,WAAQ,WAAU,UAAS,GAC9B;AAGF,QAAM,QAAQ;AAAA,IACZ,MAAM,MAAM,EAAE,OAAO,EAAE,wCAAwC,KAAK,GAAG,OAAO,oBAAC,UAAK,WAAU,yBAAyB,gBAAM,KAAI,EAAQ,IAAI;AAAA,IAC7I,QAAQ,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,oBAAC,UAAK,WAAU,eAAe,iBAAM,EAAQ,IAAI;AAAA,IAC/H,MAAM,WAAW,EAAE,OAAO,EAAE,6CAA6C,UAAU,GAAG,OAAO,MAAM,SAAS,IAAI;AAAA,EAClH,EAAE,OAAO,OAAO;AAEhB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,EAAE,2CAA2C,SAAS;AAAA,MACjE,UAAU,oBAAC,WAAQ,WAAU,UAAS,eAAW,MAAC;AAAA,MAClD;AAAA,MACA,OAAO,MAAM;AAAA,MACb,UAAU,CAAC,MAAM,KAAK,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,UAAK,KAAK;AAAA,MAC5D;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,IAAI,MAAM;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,UAAS;AAAA,MAET,+BAAC,SAAI,WAAU,aACb;AAAA,4BAAC,gBAAa,OAAc;AAAA,QAC3B,MAAM,cACL,oBAAC,OAAE,WAAU,sCAAsC,gBAAM,aAAY,IACnE;AAAA,QACH,MAAM,QAAQ,MAAM,KAAK,SAAS,IAAI,oBAAC,UAAO,MAAM,MAAM,MAAM,IAAK;AAAA,SACxE;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,sBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/backend/AppShell.js
CHANGED
|
@@ -267,12 +267,6 @@ function resolveItemKey(item) {
|
|
|
267
267
|
if (candidate && candidate.length > 0) return candidate;
|
|
268
268
|
return item.href;
|
|
269
269
|
}
|
|
270
|
-
function sidebarBlockPadding(compact) {
|
|
271
|
-
return `${compact ? "px-2" : "px-3"} transition-[padding] duration-200 ease-out`;
|
|
272
|
-
}
|
|
273
|
-
function sidebarInjectionWrapper(compact) {
|
|
274
|
-
return `${sidebarBlockPadding(compact)} empty:hidden`;
|
|
275
|
-
}
|
|
276
270
|
function SerializedIcon({ markup }) {
|
|
277
271
|
return /* @__PURE__ */ jsx("span", { "aria-hidden": "true", dangerouslySetInnerHTML: { __html: markup } });
|
|
278
272
|
}
|
|
@@ -534,6 +528,10 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
534
528
|
const key = resolveGroupKey(activeGroup);
|
|
535
529
|
setOpenGroups((prev) => prev[key] === false ? { ...prev, [key]: true } : prev);
|
|
536
530
|
}, [pathname, navGroups]);
|
|
531
|
+
React.useEffect(() => {
|
|
532
|
+
setHeaderTitle(currentTitle);
|
|
533
|
+
setHeaderBreadcrumb(breadcrumb);
|
|
534
|
+
}, [currentTitle, breadcrumb]);
|
|
537
535
|
const prevPathname = React.useRef(pathname);
|
|
538
536
|
useIsomorphicLayoutEffect(() => {
|
|
539
537
|
if (pathname !== prevPathname.current) {
|
|
@@ -542,19 +540,14 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
542
540
|
setHeaderBreadcrumb(void 0);
|
|
543
541
|
}
|
|
544
542
|
}, [pathname]);
|
|
545
|
-
useIsomorphicLayoutEffect(() => {
|
|
546
|
-
setHeaderTitle(currentTitle);
|
|
547
|
-
setHeaderBreadcrumb(breadcrumb);
|
|
548
|
-
}, [currentTitle, breadcrumb]);
|
|
549
543
|
React.useEffect(() => {
|
|
550
544
|
setNavGroups(cloneSidebarGroups(resolvedGroups));
|
|
551
545
|
}, [resolvedGroups]);
|
|
552
546
|
function renderSectionSidebar(sections, title, compact, hideHeader, hideSearch) {
|
|
553
547
|
const sortedSections = [...sections].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
554
548
|
const lastVisibleIndex = sortedSections.length - 1;
|
|
555
|
-
const blockPadding = sidebarBlockPadding(compact);
|
|
556
549
|
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col gap-3", children: [
|
|
557
|
-
!hideHeader && /* @__PURE__ */ jsx("div", { className:
|
|
550
|
+
!hideHeader && /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs(
|
|
558
551
|
Link,
|
|
559
552
|
{
|
|
560
553
|
href: "/backend",
|
|
@@ -566,7 +559,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
566
559
|
]
|
|
567
560
|
}
|
|
568
561
|
) }),
|
|
569
|
-
!compact && !hideSearch && /* @__PURE__ */ jsx(
|
|
562
|
+
!compact && !hideSearch && /* @__PURE__ */ jsx(
|
|
570
563
|
SearchInput,
|
|
571
564
|
{
|
|
572
565
|
value: navQuery,
|
|
@@ -576,8 +569,8 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
576
569
|
clearLabel: t("appShell.searchNavClear", "Clear search"),
|
|
577
570
|
className: "mb-2"
|
|
578
571
|
}
|
|
579
|
-
)
|
|
580
|
-
/* @__PURE__ */ jsx("div", { "data-sidebar-scroll": "true", className:
|
|
572
|
+
),
|
|
573
|
+
/* @__PURE__ */ jsx("div", { "data-sidebar-scroll": "true", className: `flex flex-1 flex-col gap-3 overflow-y-auto scrollbar-hide pr-1 ${compact ? "-ml-2 pl-2" : "-ml-3 pl-3"}`, children: /* @__PURE__ */ jsx("nav", { className: "flex flex-col gap-2", children: sortedSections.map((section, sectionIndex) => {
|
|
581
574
|
const sectionNavQueryActive = hideSearch ? false : navQueryActive;
|
|
582
575
|
const matchesItemQuery = (item) => {
|
|
583
576
|
if (!sectionNavQueryActive) return true;
|
|
@@ -634,38 +627,29 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
634
627
|
showChildren ? childItems.map((child) => renderSectionItem(child, depth + 1)) : null
|
|
635
628
|
] }, item.id);
|
|
636
629
|
};
|
|
637
|
-
return /* @__PURE__ */ jsxs(
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
}
|
|
655
|
-
),
|
|
656
|
-
(open || compact) && /* @__PURE__ */ jsx("div", { className: `flex flex-col ${compact ? "items-center" : ""} gap-1`, children: sortedItems.map((item) => renderSectionItem(item)) })
|
|
657
|
-
]
|
|
658
|
-
},
|
|
659
|
-
section.id
|
|
660
|
-
);
|
|
630
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
631
|
+
!compact && /* @__PURE__ */ jsxs(
|
|
632
|
+
Button,
|
|
633
|
+
{
|
|
634
|
+
variant: "muted",
|
|
635
|
+
onClick: () => toggleGroup(sectionKey),
|
|
636
|
+
className: "w-full px-1 justify-between flex text-xs font-medium uppercase tracking-wider text-muted-foreground/70 py-1",
|
|
637
|
+
"aria-expanded": open,
|
|
638
|
+
children: [
|
|
639
|
+
/* @__PURE__ */ jsx("span", { children: sectionLabel }),
|
|
640
|
+
/* @__PURE__ */ jsx(Chevron, { open })
|
|
641
|
+
]
|
|
642
|
+
}
|
|
643
|
+
),
|
|
644
|
+
(open || compact) && /* @__PURE__ */ jsx("div", { className: `flex flex-col ${compact ? "items-center" : ""} gap-1`, children: sortedItems.map((item) => renderSectionItem(item)) }),
|
|
645
|
+
sectionIndex !== lastVisibleIndex && /* @__PURE__ */ jsx("div", { className: `my-2 border-t ${compact ? "-ml-2 -mr-3" : "-ml-3 -mr-4"}` })
|
|
646
|
+
] }, section.id);
|
|
661
647
|
}) }) })
|
|
662
648
|
] });
|
|
663
649
|
}
|
|
664
650
|
function renderSidebar(compact, hideHeader, forceMainOnly) {
|
|
665
|
-
const blockPadding = sidebarBlockPadding(compact);
|
|
666
|
-
const injectionWrapper = sidebarInjectionWrapper(compact);
|
|
667
651
|
if (!isChromeReady && isChromeLoading) {
|
|
668
|
-
return /* @__PURE__ */ jsxs("div", { className:
|
|
652
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-h-full gap-3", "data-testid": "backend-chrome-loading", children: [
|
|
669
653
|
!hideHeader ? /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs(
|
|
670
654
|
Link,
|
|
671
655
|
{
|
|
@@ -678,7 +662,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
678
662
|
]
|
|
679
663
|
}
|
|
680
664
|
) }) : null,
|
|
681
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-3", children: [
|
|
665
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-3 pr-1", children: [
|
|
682
666
|
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
683
667
|
/* @__PURE__ */ jsx("div", { className: "h-8 rounded bg-muted/50" }),
|
|
684
668
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2 pl-1", children: [
|
|
@@ -726,7 +710,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
726
710
|
const isMobileVariant = !!hideHeader;
|
|
727
711
|
const shouldRenderSidebarInjectionSpots = !isMobileVariant;
|
|
728
712
|
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col gap-3", children: [
|
|
729
|
-
!hideHeader && /* @__PURE__ */ jsx("div", { className:
|
|
713
|
+
!hideHeader && /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs(
|
|
730
714
|
Link,
|
|
731
715
|
{
|
|
732
716
|
href: "/backend",
|
|
@@ -738,14 +722,14 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
738
722
|
]
|
|
739
723
|
}
|
|
740
724
|
) }),
|
|
741
|
-
shouldRenderSidebarInjectionSpots ? /* @__PURE__ */ jsx(
|
|
725
|
+
shouldRenderSidebarInjectionSpots ? /* @__PURE__ */ jsx(
|
|
742
726
|
InjectionSpot,
|
|
743
727
|
{
|
|
744
728
|
spotId: BACKEND_SIDEBAR_TOP_INJECTION_SPOT_ID,
|
|
745
729
|
context: injectionContext
|
|
746
730
|
}
|
|
747
|
-
)
|
|
748
|
-
!compact && /* @__PURE__ */ jsx(
|
|
731
|
+
) : null,
|
|
732
|
+
!compact && /* @__PURE__ */ jsx(
|
|
749
733
|
SearchInput,
|
|
750
734
|
{
|
|
751
735
|
value: navQuery,
|
|
@@ -755,8 +739,8 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
755
739
|
clearLabel: t("appShell.searchNavClear", "Clear search"),
|
|
756
740
|
className: "mb-2"
|
|
757
741
|
}
|
|
758
|
-
)
|
|
759
|
-
/* @__PURE__ */ jsx("div", { "data-sidebar-scroll": "true", className:
|
|
742
|
+
),
|
|
743
|
+
/* @__PURE__ */ jsx("div", { "data-sidebar-scroll": "true", className: `flex flex-1 flex-col gap-3 overflow-y-auto scrollbar-hide pr-1 ${compact ? "-ml-2 pl-2" : "-ml-3 pl-3"}`, children: (() => {
|
|
760
744
|
const isSettingsPath = (href) => {
|
|
761
745
|
if (href === "/backend/settings") return true;
|
|
762
746
|
return resolvedSettingsPathPrefixes.some((prefix) => href.startsWith(prefix));
|
|
@@ -777,13 +761,13 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
777
761
|
return -1;
|
|
778
762
|
})();
|
|
779
763
|
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("nav", { className: "flex flex-col gap-2", "data-testid": "sidebar", children: [
|
|
780
|
-
shouldRenderSidebarInjectionSpots ? /* @__PURE__ */ jsx(
|
|
764
|
+
shouldRenderSidebarInjectionSpots ? /* @__PURE__ */ jsx(
|
|
781
765
|
InjectionSpot,
|
|
782
766
|
{
|
|
783
767
|
spotId: BACKEND_SIDEBAR_NAV_INJECTION_SPOT_ID,
|
|
784
768
|
context: injectionContext
|
|
785
769
|
}
|
|
786
|
-
)
|
|
770
|
+
) : null,
|
|
787
771
|
mainGroups.map((g, gi) => {
|
|
788
772
|
const groupId = resolveGroupKey(g);
|
|
789
773
|
const open = navQueryActive ? true : openGroups[groupId] !== false;
|
|
@@ -795,94 +779,87 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
795
779
|
return itemChildren.some((c) => matchesQuery(c.title));
|
|
796
780
|
});
|
|
797
781
|
if (visibleItems.length === 0) return null;
|
|
798
|
-
return /* @__PURE__ */ jsxs(
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
782
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
783
|
+
!compact && /* @__PURE__ */ jsxs(
|
|
784
|
+
Button,
|
|
785
|
+
{
|
|
786
|
+
variant: "muted",
|
|
787
|
+
onClick: () => toggleGroup(groupId),
|
|
788
|
+
className: "w-full px-1 justify-between flex text-xs font-medium uppercase tracking-wider text-muted-foreground/70 py-1",
|
|
789
|
+
"aria-expanded": open,
|
|
790
|
+
children: [
|
|
791
|
+
/* @__PURE__ */ jsx("span", { children: g.name }),
|
|
792
|
+
/* @__PURE__ */ jsx(Chevron, { open })
|
|
793
|
+
]
|
|
794
|
+
}
|
|
795
|
+
),
|
|
796
|
+
(open || compact) && /* @__PURE__ */ jsx("div", { className: `flex flex-col ${compact ? "items-center" : ""} gap-1`, children: visibleItems.map((i) => {
|
|
797
|
+
const allChildItems = (i.children ?? []).filter((child) => child.hidden !== true);
|
|
798
|
+
const matchingChildItems = navQueryActive ? allChildItems.filter((c) => matchesQuery(c.title)) : allChildItems;
|
|
799
|
+
const childItems = navQueryActive ? matchingChildItems : allChildItems;
|
|
800
|
+
const showChildren = navQueryActive ? matchingChildItems.length > 0 : !!pathname && allChildItems.length > 0 && pathname.startsWith(i.href);
|
|
801
|
+
const hasActiveChild = !!(pathname && allChildItems.some((c) => pathname.startsWith(c.href)));
|
|
802
|
+
const isParentActive = pathname === i.href || !navQueryActive && showChildren && !hasActiveChild;
|
|
803
|
+
const base = compact ? "w-10 h-10 justify-center" : "w-full px-3 py-2 gap-2";
|
|
804
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
805
|
+
/* @__PURE__ */ jsxs(
|
|
806
|
+
Link,
|
|
806
807
|
{
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
808
|
+
href: i.href,
|
|
809
|
+
className: `relative text-sm font-medium rounded-lg inline-flex items-center ${base} ${isParentActive ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted"} ${i.enabled === false ? "pointer-events-none opacity-50" : ""}`,
|
|
810
|
+
"aria-disabled": i.enabled === false,
|
|
811
|
+
title: compact ? i.title : void 0,
|
|
812
|
+
"data-menu-item-id": i.id ?? i.href,
|
|
813
|
+
onClick: () => setMobileOpen(false),
|
|
811
814
|
children: [
|
|
812
|
-
/* @__PURE__ */ jsx("span", {
|
|
813
|
-
/* @__PURE__ */ jsx(
|
|
815
|
+
isParentActive ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: `absolute ${compact ? "left-[-20px]" : "left-[-12px]"} top-2 w-1 h-5 rounded-r bg-foreground` }) : null,
|
|
816
|
+
/* @__PURE__ */ jsx("span", { className: "flex items-center justify-center shrink-0", children: renderIcon(
|
|
817
|
+
i.icon,
|
|
818
|
+
i.iconName,
|
|
819
|
+
i.iconMarkup,
|
|
820
|
+
DefaultIcon
|
|
821
|
+
) }),
|
|
822
|
+
!compact && /* @__PURE__ */ jsx("span", { children: i.title })
|
|
814
823
|
]
|
|
815
824
|
}
|
|
816
825
|
),
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
const isParentActive = pathname === i.href || !navQueryActive && showChildren && !hasActiveChild;
|
|
824
|
-
const base = compact ? "w-10 h-10 justify-center" : "w-full px-3 py-2 gap-2";
|
|
825
|
-
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
826
|
-
/* @__PURE__ */ jsxs(
|
|
826
|
+
showChildren ? /* @__PURE__ */ jsxs("div", { className: `relative flex flex-col ${compact ? "items-center" : ""} gap-1`, children: [
|
|
827
|
+
!compact && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "pointer-events-none absolute left-1.5 top-1 bottom-1 w-px bg-border" }),
|
|
828
|
+
childItems.map((c) => {
|
|
829
|
+
const childActive = pathname?.startsWith(c.href);
|
|
830
|
+
const childBase = compact ? "w-10 h-8 justify-center" : "w-full pl-5 pr-3 py-2 gap-2";
|
|
831
|
+
return /* @__PURE__ */ jsxs(
|
|
827
832
|
Link,
|
|
828
833
|
{
|
|
829
|
-
href:
|
|
830
|
-
className: `relative text-sm font-medium rounded-lg inline-flex items-center ${
|
|
831
|
-
"aria-disabled":
|
|
832
|
-
title: compact ?
|
|
833
|
-
"data-menu-item-id":
|
|
834
|
+
href: c.href,
|
|
835
|
+
className: `relative text-sm font-medium rounded-lg inline-flex items-center ${childBase} ${childActive ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted"} ${c.enabled === false ? "pointer-events-none opacity-50" : ""}`,
|
|
836
|
+
"aria-disabled": c.enabled === false,
|
|
837
|
+
title: compact ? c.title : void 0,
|
|
838
|
+
"data-menu-item-id": c.id ?? c.href,
|
|
834
839
|
onClick: () => setMobileOpen(false),
|
|
835
840
|
children: [
|
|
836
|
-
|
|
841
|
+
childActive ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: `absolute ${compact ? "left-[-20px]" : "left-[-12px]"} top-2 w-1 h-5 rounded-r bg-foreground` }) : null,
|
|
837
842
|
/* @__PURE__ */ jsx("span", { className: "flex items-center justify-center shrink-0", children: renderIcon(
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
DefaultIcon
|
|
843
|
+
c.icon,
|
|
844
|
+
c.iconName,
|
|
845
|
+
c.iconMarkup,
|
|
846
|
+
c.href.includes("/backend/entities/user/") && c.href.endsWith("/records") ? DataTableIcon : DefaultIcon
|
|
842
847
|
) }),
|
|
843
|
-
!compact && /* @__PURE__ */ jsx("span", { children:
|
|
848
|
+
!compact && /* @__PURE__ */ jsx("span", { children: c.title })
|
|
844
849
|
]
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
{
|
|
855
|
-
href: c.href,
|
|
856
|
-
className: `relative text-sm font-medium rounded-lg inline-flex items-center ${childBase} ${childActive ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted"} ${c.enabled === false ? "pointer-events-none opacity-50" : ""}`,
|
|
857
|
-
"aria-disabled": c.enabled === false,
|
|
858
|
-
title: compact ? c.title : void 0,
|
|
859
|
-
"data-menu-item-id": c.id ?? c.href,
|
|
860
|
-
onClick: () => setMobileOpen(false),
|
|
861
|
-
children: [
|
|
862
|
-
childActive ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: `absolute ${compact ? "left-[-20px]" : "left-[-12px]"} top-2 w-1 h-5 rounded-r bg-foreground` }) : null,
|
|
863
|
-
/* @__PURE__ */ jsx("span", { className: "flex items-center justify-center shrink-0", children: renderIcon(
|
|
864
|
-
c.icon,
|
|
865
|
-
c.iconName,
|
|
866
|
-
c.iconMarkup,
|
|
867
|
-
c.href.includes("/backend/entities/user/") && c.href.endsWith("/records") ? DataTableIcon : DefaultIcon
|
|
868
|
-
) }),
|
|
869
|
-
!compact && /* @__PURE__ */ jsx("span", { children: c.title })
|
|
870
|
-
]
|
|
871
|
-
},
|
|
872
|
-
c.href
|
|
873
|
-
);
|
|
874
|
-
})
|
|
875
|
-
] }) : null
|
|
876
|
-
] }, i.href);
|
|
877
|
-
}) })
|
|
878
|
-
]
|
|
879
|
-
},
|
|
880
|
-
groupId
|
|
881
|
-
);
|
|
850
|
+
},
|
|
851
|
+
c.href
|
|
852
|
+
);
|
|
853
|
+
})
|
|
854
|
+
] }) : null
|
|
855
|
+
] }, i.href);
|
|
856
|
+
}) }),
|
|
857
|
+
gi !== mainLastVisibleGroupIndex && /* @__PURE__ */ jsx("div", { className: `my-2 border-t ${compact ? "-ml-2 -mr-3" : "-ml-3 -mr-4"}` })
|
|
858
|
+
] }, groupId);
|
|
882
859
|
})
|
|
883
860
|
] }) });
|
|
884
861
|
})() }),
|
|
885
|
-
/* @__PURE__ */ jsxs("div", { className:
|
|
862
|
+
/* @__PURE__ */ jsxs("div", { className: "sticky bottom-0 bg-background pb-1", children: [
|
|
886
863
|
shouldRenderSidebarInjectionSpots ? /* @__PURE__ */ jsx(
|
|
887
864
|
InjectionSpot,
|
|
888
865
|
{
|
|
@@ -927,7 +904,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
927
904
|
}
|
|
928
905
|
if (!sections) return null;
|
|
929
906
|
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col gap-2", children: [
|
|
930
|
-
/* @__PURE__ */
|
|
907
|
+
/* @__PURE__ */ jsxs(
|
|
931
908
|
Link,
|
|
932
909
|
{
|
|
933
910
|
href: "/backend",
|
|
@@ -939,7 +916,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
939
916
|
/* @__PURE__ */ jsx("span", { className: "truncate", children: title })
|
|
940
917
|
]
|
|
941
918
|
}
|
|
942
|
-
)
|
|
919
|
+
),
|
|
943
920
|
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1", children: renderSectionSidebar(sections, title, false, true, true) })
|
|
944
921
|
] });
|
|
945
922
|
}
|
|
@@ -997,7 +974,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
997
974
|
children: effectiveCollapsed ? /* @__PURE__ */ jsx(PanelLeftOpen, { className: "size-4" }) : /* @__PURE__ */ jsx(PanelLeftClose, { className: "size-4" })
|
|
998
975
|
}
|
|
999
976
|
),
|
|
1000
|
-
/* @__PURE__ */ jsxs("aside", { ref: sidebarAsideRef, className: `${asideClassesBase} px-
|
|
977
|
+
/* @__PURE__ */ jsxs("aside", { ref: sidebarAsideRef, className: `${asideClassesBase} ${effectiveCollapsed ? "px-2" : "px-3"} hidden lg:block lg:sticky lg:top-0 lg:h-svh lg:self-start lg:overflow-hidden lg:relative transition-[width,padding] duration-200 ease-out`, style: { width: asideWidth }, children: [
|
|
1001
978
|
renderSidebar(effectiveCollapsed, false, isSectionView),
|
|
1002
979
|
sidebarScrollState !== "none" ? /* @__PURE__ */ jsx(
|
|
1003
980
|
"div",
|
|
@@ -1029,7 +1006,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
1029
1006
|
isSectionView ? /* @__PURE__ */ jsxs(
|
|
1030
1007
|
"aside",
|
|
1031
1008
|
{
|
|
1032
|
-
className: `${asideClassesBase} px-
|
|
1009
|
+
className: `${asideClassesBase} px-3 hidden lg:block lg:sticky lg:top-0 lg:h-svh lg:self-start lg:overflow-hidden lg:relative`,
|
|
1033
1010
|
style: { width: "240px" },
|
|
1034
1011
|
"data-testid": "appshell-section-sidebar",
|
|
1035
1012
|
children: [
|
|
@@ -1189,7 +1166,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
|
|
|
1189
1166
|
id: "mobile-drawer-tabpanel",
|
|
1190
1167
|
role: sidebarMode !== "main" ? "tabpanel" : void 0,
|
|
1191
1168
|
"aria-labelledby": sidebarMode !== "main" ? `mobile-drawer-tab-${mobileDrawerView === "main" ? "main" : "section"}` : void 0,
|
|
1192
|
-
className: "min-h-0 flex-1 overflow-y-auto overflow-x-hidden
|
|
1169
|
+
className: "min-h-0 flex-1 overflow-y-auto overflow-x-hidden p-3",
|
|
1193
1170
|
children: renderSidebar(false, true, mobileDrawerView === "main")
|
|
1194
1171
|
}
|
|
1195
1172
|
)
|