@open-mercato/core 0.6.7-develop.6785.1.1dd7cfac55 → 0.6.7-develop.6795.1.8a3f27921c
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/generated/entities.ids.generated.js +1 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/modules/auth/backend/settings/page.js +14 -9
- package/dist/modules/auth/backend/settings/page.js.map +2 -2
- package/dist/modules/customers/cli.js +17 -7
- package/dist/modules/customers/cli.js.map +2 -2
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +229 -216
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
- package/dist/modules/customers/search.js +50 -29
- package/dist/modules/customers/search.js.map +2 -2
- package/dist/modules/data_sync/api/mappings/[id]/route.js +22 -9
- package/dist/modules/data_sync/api/mappings/[id]/route.js.map +2 -2
- package/dist/modules/data_sync/api/mappings/route.js +13 -4
- package/dist/modules/data_sync/api/mappings/route.js.map +2 -2
- package/dist/modules/data_sync/api/options.js +7 -2
- package/dist/modules/data_sync/api/options.js.map +2 -2
- package/dist/modules/data_sync/api/run.js +7 -2
- package/dist/modules/data_sync/api/run.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/cancel.js +8 -3
- package/dist/modules/data_sync/api/runs/[id]/cancel.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/retry.js +7 -2
- package/dist/modules/data_sync/api/runs/[id]/retry.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/route.js +8 -3
- package/dist/modules/data_sync/api/runs/[id]/route.js.map +2 -2
- package/dist/modules/data_sync/api/runs.js +7 -2
- package/dist/modules/data_sync/api/runs.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/[id]/route.js +19 -6
- package/dist/modules/data_sync/api/schedules/[id]/route.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/route.js +13 -4
- package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
- package/dist/modules/data_sync/api/validate.js +9 -4
- package/dist/modules/data_sync/api/validate.js.map +2 -2
- package/dist/modules/design_system/acl.js +9 -0
- package/dist/modules/design_system/acl.js.map +7 -0
- package/dist/modules/design_system/backend/design-system/page.js +11 -0
- package/dist/modules/design_system/backend/design-system/page.js.map +7 -0
- package/dist/modules/design_system/backend/design-system/page.meta.js +15 -0
- package/dist/modules/design_system/backend/design-system/page.meta.js.map +7 -0
- package/dist/modules/design_system/gallery/components/CodeSnippet.js +52 -0
- package/dist/modules/design_system/gallery/components/CodeSnippet.js.map +7 -0
- package/dist/modules/design_system/gallery/components/EntryCard.js +63 -0
- package/dist/modules/design_system/gallery/components/EntryCard.js.map +7 -0
- package/dist/modules/design_system/gallery/components/GalleryShell.js +163 -0
- package/dist/modules/design_system/gallery/components/GalleryShell.js.map +7 -0
- package/dist/modules/design_system/gallery/components/VariantPreview.js +9 -0
- package/dist/modules/design_system/gallery/components/VariantPreview.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/banners.js +186 -0
- package/dist/modules/design_system/gallery/entries/banners.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/buttons.js +361 -0
- package/dist/modules/design_system/gallery/entries/buttons.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/charts.js +457 -0
- package/dist/modules/design_system/gallery/entries/charts.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/dates.js +306 -0
- package/dist/modules/design_system/gallery/entries/dates.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/detail.js +358 -0
- package/dist/modules/design_system/gallery/entries/detail.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/display.js +785 -0
- package/dist/modules/design_system/gallery/entries/display.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/feedback.js +658 -0
- package/dist/modules/design_system/gallery/entries/feedback.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/filters.js +505 -0
- package/dist/modules/design_system/gallery/entries/filters.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/foundations.js +453 -0
- package/dist/modules/design_system/gallery/entries/foundations.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/icons.js +140 -0
- package/dist/modules/design_system/gallery/entries/icons.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/inputs.js +1217 -0
- package/dist/modules/design_system/gallery/entries/inputs.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/messages.js +334 -0
- package/dist/modules/design_system/gallery/entries/messages.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/navigation.js +475 -0
- package/dist/modules/design_system/gallery/entries/navigation.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/notifications.js +257 -0
- package/dist/modules/design_system/gallery/entries/notifications.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/overlays.js +576 -0
- package/dist/modules/design_system/gallery/entries/overlays.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/scaffolding.js +378 -0
- package/dist/modules/design_system/gallery/entries/scaffolding.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/schedule.js +297 -0
- package/dist/modules/design_system/gallery/entries/schedule.js.map +7 -0
- package/dist/modules/design_system/gallery/registry.js +139 -0
- package/dist/modules/design_system/gallery/registry.js.map +7 -0
- package/dist/modules/design_system/gallery/types.js +1 -0
- package/dist/modules/design_system/gallery/types.js.map +7 -0
- package/dist/modules/design_system/index.js +9 -0
- package/dist/modules/design_system/index.js.map +7 -0
- package/dist/modules/design_system/setup.js +14 -0
- package/dist/modules/design_system/setup.js.map +7 -0
- package/dist/modules/inbox_ops/search.js +15 -4
- package/dist/modules/inbox_ops/search.js.map +2 -2
- package/dist/modules/integrations/api/[id]/credentials/route.js +11 -5
- package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
- package/dist/modules/integrations/api/[id]/health/route.js +6 -3
- package/dist/modules/integrations/api/[id]/health/route.js.map +2 -2
- package/dist/modules/integrations/api/[id]/route.js +6 -3
- package/dist/modules/integrations/api/[id]/route.js.map +2 -2
- package/dist/modules/integrations/api/[id]/state/route.js +6 -3
- package/dist/modules/integrations/api/[id]/state/route.js.map +2 -2
- package/dist/modules/integrations/api/[id]/version/route.js +6 -3
- package/dist/modules/integrations/api/[id]/version/route.js.map +2 -2
- package/dist/modules/integrations/api/logs/route.js +6 -3
- package/dist/modules/integrations/api/logs/route.js.map +2 -2
- package/dist/modules/integrations/api/route.js +6 -3
- package/dist/modules/integrations/api/route.js.map +2 -2
- package/dist/modules/integrations/api/umes-read.js +2 -2
- package/dist/modules/integrations/api/umes-read.js.map +2 -2
- package/dist/modules/integrations/lib/organization-scope.js +2 -9
- package/dist/modules/integrations/lib/organization-scope.js.map +2 -2
- package/dist/modules/messages/search.js +10 -5
- package/dist/modules/messages/search.js.map +2 -2
- package/dist/modules/query_index/data/entities.js +2 -1
- package/dist/modules/query_index/data/entities.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +32 -50
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/migrations/Migration20260731105052_query_index.js +17 -0
- package/dist/modules/query_index/migrations/Migration20260731105052_query_index.js.map +7 -0
- package/generated/entities.ids.generated.ts +1 -0
- package/package.json +16 -16
- package/src/modules/auth/backend/settings/page.tsx +17 -8
- package/src/modules/customers/cli.ts +17 -7
- package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +24 -13
- package/src/modules/customers/i18n/de.json +17 -0
- package/src/modules/customers/i18n/en.json +17 -0
- package/src/modules/customers/i18n/es.json +17 -0
- package/src/modules/customers/i18n/pl.json +17 -0
- package/src/modules/customers/search.ts +59 -27
- package/src/modules/data_sync/AGENTS.md +1 -0
- package/src/modules/data_sync/api/mappings/[id]/route.ts +22 -9
- package/src/modules/data_sync/api/mappings/route.ts +13 -4
- package/src/modules/data_sync/api/options.ts +7 -2
- package/src/modules/data_sync/api/run.ts +7 -2
- package/src/modules/data_sync/api/runs/[id]/cancel.ts +8 -3
- package/src/modules/data_sync/api/runs/[id]/retry.ts +7 -2
- package/src/modules/data_sync/api/runs/[id]/route.ts +8 -3
- package/src/modules/data_sync/api/runs.ts +7 -2
- package/src/modules/data_sync/api/schedules/[id]/route.ts +19 -6
- package/src/modules/data_sync/api/schedules/route.ts +13 -4
- package/src/modules/data_sync/api/validate.ts +9 -4
- package/src/modules/design_system/AGENTS.md +34 -0
- package/src/modules/design_system/acl.ts +5 -0
- package/src/modules/design_system/backend/design-system/page.meta.ts +11 -0
- package/src/modules/design_system/backend/design-system/page.tsx +14 -0
- package/src/modules/design_system/gallery/components/CodeSnippet.tsx +55 -0
- package/src/modules/design_system/gallery/components/EntryCard.tsx +95 -0
- package/src/modules/design_system/gallery/components/GalleryShell.tsx +206 -0
- package/src/modules/design_system/gallery/components/VariantPreview.tsx +15 -0
- package/src/modules/design_system/gallery/entries/banners.tsx +226 -0
- package/src/modules/design_system/gallery/entries/buttons.tsx +422 -0
- package/src/modules/design_system/gallery/entries/charts.tsx +518 -0
- package/src/modules/design_system/gallery/entries/dates.tsx +325 -0
- package/src/modules/design_system/gallery/entries/detail.tsx +403 -0
- package/src/modules/design_system/gallery/entries/display.tsx +893 -0
- package/src/modules/design_system/gallery/entries/feedback.tsx +746 -0
- package/src/modules/design_system/gallery/entries/filters.tsx +570 -0
- package/src/modules/design_system/gallery/entries/foundations.tsx +529 -0
- package/src/modules/design_system/gallery/entries/icons.tsx +168 -0
- package/src/modules/design_system/gallery/entries/inputs.tsx +1516 -0
- package/src/modules/design_system/gallery/entries/messages.tsx +339 -0
- package/src/modules/design_system/gallery/entries/navigation.tsx +573 -0
- package/src/modules/design_system/gallery/entries/notifications.tsx +285 -0
- package/src/modules/design_system/gallery/entries/overlays.tsx +677 -0
- package/src/modules/design_system/gallery/entries/scaffolding.tsx +430 -0
- package/src/modules/design_system/gallery/entries/schedule.tsx +307 -0
- package/src/modules/design_system/gallery/registry.ts +152 -0
- package/src/modules/design_system/gallery/types.ts +32 -0
- package/src/modules/design_system/i18n/.hardcoded-allowlist.json +71 -0
- package/src/modules/design_system/i18n/de.json +46 -0
- package/src/modules/design_system/i18n/en.json +46 -0
- package/src/modules/design_system/i18n/es.json +46 -0
- package/src/modules/design_system/i18n/pl.json +46 -0
- package/src/modules/design_system/index.ts +7 -0
- package/src/modules/design_system/setup.ts +12 -0
- package/src/modules/inbox_ops/i18n/de.json +3 -0
- package/src/modules/inbox_ops/i18n/en.json +3 -0
- package/src/modules/inbox_ops/i18n/es.json +3 -0
- package/src/modules/inbox_ops/i18n/pl.json +3 -0
- package/src/modules/inbox_ops/search.ts +20 -4
- package/src/modules/integrations/api/[id]/credentials/route.ts +11 -5
- package/src/modules/integrations/api/[id]/health/route.ts +6 -3
- package/src/modules/integrations/api/[id]/route.ts +6 -3
- package/src/modules/integrations/api/[id]/state/route.ts +6 -3
- package/src/modules/integrations/api/[id]/version/route.ts +6 -3
- package/src/modules/integrations/api/logs/route.ts +6 -3
- package/src/modules/integrations/api/route.ts +6 -3
- package/src/modules/integrations/api/umes-read.ts +2 -2
- package/src/modules/integrations/lib/organization-scope.ts +5 -25
- package/src/modules/messages/i18n/de.json +2 -0
- package/src/modules/messages/i18n/en.json +2 -0
- package/src/modules/messages/i18n/es.json +2 -0
- package/src/modules/messages/i18n/pl.json +2 -0
- package/src/modules/messages/search.ts +11 -5
- package/src/modules/query_index/data/entities.ts +7 -0
- package/src/modules/query_index/lib/engine.ts +40 -63
- package/src/modules/query_index/migrations/.snapshot-open-mercato.json +12 -0
- package/src/modules/query_index/migrations/Migration20260731105052_query_index.ts +35 -0
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
3
|
+
import { Button } from '@open-mercato/ui/primitives/button'
|
|
4
|
+
import {
|
|
5
|
+
AddressesSection,
|
|
6
|
+
AttachmentsSection,
|
|
7
|
+
DetailFieldsSection,
|
|
8
|
+
ErrorMessage,
|
|
9
|
+
LoadingMessage,
|
|
10
|
+
NotesSection,
|
|
11
|
+
type AddressDataAdapter,
|
|
12
|
+
type DetailFieldConfig,
|
|
13
|
+
type NotesSectionProps,
|
|
14
|
+
} from '@open-mercato/ui/backend/detail'
|
|
15
|
+
import type { GalleryEntry } from '../types'
|
|
16
|
+
|
|
17
|
+
// Component titles and variant names are proper nouns from the codebase and
|
|
18
|
+
// are deliberately not translated. `code` MUST contain the entry's importPath
|
|
19
|
+
// (enforced by the registry-integrity test) and is always reviewed alongside
|
|
20
|
+
// its sibling `render`.
|
|
21
|
+
|
|
22
|
+
// Data-backed sections (Notes/Addresses) take adapter objects — the demos pass
|
|
23
|
+
// inline in-memory adapters, so previews never touch an API. AttachmentsSection
|
|
24
|
+
// fetches through `apiCall` internally and cannot take an adapter; it is shown
|
|
25
|
+
// in its `recordId={null}` state, where fetching is disabled by design.
|
|
26
|
+
|
|
27
|
+
const saveNoop = async () => {}
|
|
28
|
+
|
|
29
|
+
const fieldGrid: DetailFieldConfig[] = [
|
|
30
|
+
{
|
|
31
|
+
key: 'first-name',
|
|
32
|
+
kind: 'text',
|
|
33
|
+
label: 'First name',
|
|
34
|
+
value: 'Anna',
|
|
35
|
+
emptyLabel: 'Add first name',
|
|
36
|
+
onSave: saveNoop,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
key: 'phone',
|
|
40
|
+
kind: 'text',
|
|
41
|
+
label: 'Phone',
|
|
42
|
+
value: null,
|
|
43
|
+
emptyLabel: 'Add phone',
|
|
44
|
+
onSave: saveNoop,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
key: 'status',
|
|
48
|
+
kind: 'select',
|
|
49
|
+
label: 'Status',
|
|
50
|
+
value: 'active',
|
|
51
|
+
emptyLabel: 'Set status',
|
|
52
|
+
options: [
|
|
53
|
+
{ value: 'active', label: 'Active' },
|
|
54
|
+
{ value: 'inactive', label: 'Inactive' },
|
|
55
|
+
],
|
|
56
|
+
onSave: saveNoop,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
key: 'notes',
|
|
60
|
+
kind: 'multiline',
|
|
61
|
+
label: 'Notes',
|
|
62
|
+
value: 'Prefers email contact.',
|
|
63
|
+
emptyLabel: 'Add notes',
|
|
64
|
+
onSave: saveNoop,
|
|
65
|
+
gridClassName: 'sm:col-span-2 md:col-span-3',
|
|
66
|
+
},
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
const fieldGridWithCustom: DetailFieldConfig[] = [
|
|
70
|
+
{
|
|
71
|
+
key: 'email',
|
|
72
|
+
kind: 'text',
|
|
73
|
+
label: 'Email',
|
|
74
|
+
value: 'anna@example.com',
|
|
75
|
+
emptyLabel: 'Add email',
|
|
76
|
+
onSave: saveNoop,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
key: 'owner',
|
|
80
|
+
kind: 'custom',
|
|
81
|
+
label: 'Owner',
|
|
82
|
+
emptyLabel: 'Unassigned',
|
|
83
|
+
render: () => (
|
|
84
|
+
<div className="space-y-1">
|
|
85
|
+
<div className="text-xs text-muted-foreground">Owner</div>
|
|
86
|
+
<Badge variant="muted">Unassigned</Badge>
|
|
87
|
+
</div>
|
|
88
|
+
),
|
|
89
|
+
},
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
// Sections resolve their labels through an app translator in real pages; the
|
|
93
|
+
// gallery translator just surfaces each key's fallback (or last segment).
|
|
94
|
+
const galleryTranslator = (key: string, fallback?: string) =>
|
|
95
|
+
fallback ?? key.split('.').pop() ?? key
|
|
96
|
+
|
|
97
|
+
const notesAdapter: NotesSectionProps['dataAdapter'] = {
|
|
98
|
+
list: async () => [
|
|
99
|
+
{
|
|
100
|
+
id: 'note-1',
|
|
101
|
+
body: 'Asked for a revised quote — follow up on Friday.',
|
|
102
|
+
createdAt: '2026-07-15T09:30:00.000Z',
|
|
103
|
+
authorName: 'Anna Nowak',
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: 'note-2',
|
|
107
|
+
body: 'Prefers email contact over phone.',
|
|
108
|
+
createdAt: '2026-07-10T14:05:00.000Z',
|
|
109
|
+
authorName: 'Jan Kowalski',
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
create: async () => {},
|
|
113
|
+
update: async () => {},
|
|
114
|
+
delete: async () => {},
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const addressesAdapter: AddressDataAdapter = {
|
|
118
|
+
list: async () => [
|
|
119
|
+
{
|
|
120
|
+
id: 'address-1',
|
|
121
|
+
name: 'Headquarters',
|
|
122
|
+
addressLine1: 'Prosta 51',
|
|
123
|
+
city: 'Warszawa',
|
|
124
|
+
postalCode: '00-838',
|
|
125
|
+
country: 'PL',
|
|
126
|
+
isPrimary: true,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: 'address-2',
|
|
130
|
+
name: 'Warehouse',
|
|
131
|
+
addressLine1: 'Magazynowa 7',
|
|
132
|
+
city: 'Pruszków',
|
|
133
|
+
postalCode: '05-800',
|
|
134
|
+
country: 'PL',
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
create: async () => {},
|
|
138
|
+
update: async () => {},
|
|
139
|
+
delete: async () => {},
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const detailFieldsSectionEntry: GalleryEntry = {
|
|
143
|
+
id: 'detail-fields-section',
|
|
144
|
+
title: 'DetailFieldsSection',
|
|
145
|
+
importPath: '@open-mercato/ui/backend/detail',
|
|
146
|
+
variants: [
|
|
147
|
+
{
|
|
148
|
+
id: 'field-grid',
|
|
149
|
+
title: 'Inline-editable field grid',
|
|
150
|
+
render: () => (
|
|
151
|
+
<div className="w-full">
|
|
152
|
+
<DetailFieldsSection fields={fieldGrid} />
|
|
153
|
+
</div>
|
|
154
|
+
),
|
|
155
|
+
code: `import { DetailFieldsSection, type DetailFieldConfig } from '@open-mercato/ui/backend/detail'
|
|
156
|
+
|
|
157
|
+
const fields: DetailFieldConfig[] = [
|
|
158
|
+
{ key: 'first-name', kind: 'text', label: 'First name', value: person.firstName, emptyLabel: 'Add first name', onSave: saveFirstName },
|
|
159
|
+
{ key: 'phone', kind: 'text', label: 'Phone', value: person.phone, emptyLabel: 'Add phone', onSave: savePhone },
|
|
160
|
+
{
|
|
161
|
+
key: 'status', kind: 'select', label: 'Status', value: person.status, emptyLabel: 'Set status',
|
|
162
|
+
options: [{ value: 'active', label: 'Active' }, { value: 'inactive', label: 'Inactive' }],
|
|
163
|
+
onSave: saveStatus,
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
key: 'notes', kind: 'multiline', label: 'Notes', value: person.notes, emptyLabel: 'Add notes',
|
|
167
|
+
onSave: saveNotes, gridClassName: 'sm:col-span-2 md:col-span-3',
|
|
168
|
+
},
|
|
169
|
+
]
|
|
170
|
+
|
|
171
|
+
<DetailFieldsSection fields={fields} />`,
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
id: 'custom-field',
|
|
175
|
+
title: 'With a custom field cell',
|
|
176
|
+
render: () => (
|
|
177
|
+
<div className="w-full">
|
|
178
|
+
<DetailFieldsSection fields={fieldGridWithCustom} />
|
|
179
|
+
</div>
|
|
180
|
+
),
|
|
181
|
+
code: `import { DetailFieldsSection, type DetailFieldConfig } from '@open-mercato/ui/backend/detail'
|
|
182
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
183
|
+
|
|
184
|
+
const fields: DetailFieldConfig[] = [
|
|
185
|
+
{ key: 'email', kind: 'text', label: 'Email', value: person.email, emptyLabel: 'Add email', onSave: saveEmail },
|
|
186
|
+
{
|
|
187
|
+
key: 'owner', kind: 'custom', label: 'Owner', emptyLabel: 'Unassigned',
|
|
188
|
+
render: () => (
|
|
189
|
+
<div className="space-y-1">
|
|
190
|
+
<div className="text-xs text-muted-foreground">Owner</div>
|
|
191
|
+
<Badge variant="muted">Unassigned</Badge>
|
|
192
|
+
</div>
|
|
193
|
+
),
|
|
194
|
+
},
|
|
195
|
+
]
|
|
196
|
+
|
|
197
|
+
<DetailFieldsSection fields={fields} />`,
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const loadingMessageEntry: GalleryEntry = {
|
|
203
|
+
id: 'loading-message',
|
|
204
|
+
title: 'LoadingMessage',
|
|
205
|
+
importPath: '@open-mercato/ui/backend/detail',
|
|
206
|
+
variants: [
|
|
207
|
+
{
|
|
208
|
+
id: 'default',
|
|
209
|
+
title: 'default',
|
|
210
|
+
render: () => (
|
|
211
|
+
<div className="w-full max-w-md">
|
|
212
|
+
<LoadingMessage label="Loading customer…" />
|
|
213
|
+
</div>
|
|
214
|
+
),
|
|
215
|
+
code: `import { LoadingMessage } from '@open-mercato/ui/backend/detail'
|
|
216
|
+
|
|
217
|
+
if (isLoading) return <LoadingMessage label={t('customers.people.detail.loading')} />`,
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const errorMessageEntry: GalleryEntry = {
|
|
223
|
+
id: 'error-message',
|
|
224
|
+
title: 'ErrorMessage',
|
|
225
|
+
importPath: '@open-mercato/ui/backend/detail',
|
|
226
|
+
variants: [
|
|
227
|
+
{
|
|
228
|
+
id: 'basic',
|
|
229
|
+
title: 'Label only',
|
|
230
|
+
render: () => (
|
|
231
|
+
<div className="w-full max-w-md">
|
|
232
|
+
<ErrorMessage label="Failed to load customer." />
|
|
233
|
+
</div>
|
|
234
|
+
),
|
|
235
|
+
code: `import { ErrorMessage } from '@open-mercato/ui/backend/detail'
|
|
236
|
+
|
|
237
|
+
if (error) return <ErrorMessage label={error} />`,
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
id: 'with-description-action',
|
|
241
|
+
title: 'With description and action',
|
|
242
|
+
render: () => (
|
|
243
|
+
<div className="w-full max-w-md">
|
|
244
|
+
<ErrorMessage
|
|
245
|
+
label="Failed to load attachments."
|
|
246
|
+
description="The storage service did not respond in time."
|
|
247
|
+
action={
|
|
248
|
+
<Button variant="outline" size="sm">
|
|
249
|
+
Retry
|
|
250
|
+
</Button>
|
|
251
|
+
}
|
|
252
|
+
/>
|
|
253
|
+
</div>
|
|
254
|
+
),
|
|
255
|
+
code: `import { ErrorMessage } from '@open-mercato/ui/backend/detail'
|
|
256
|
+
import { Button } from '@open-mercato/ui/primitives/button'
|
|
257
|
+
|
|
258
|
+
<ErrorMessage
|
|
259
|
+
label="Failed to load attachments."
|
|
260
|
+
description="The storage service did not respond in time."
|
|
261
|
+
action={<Button variant="outline" size="sm" onClick={retry}>Retry</Button>}
|
|
262
|
+
/>`,
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const notesSectionEntry: GalleryEntry = {
|
|
268
|
+
id: 'notes-section',
|
|
269
|
+
title: 'NotesSection',
|
|
270
|
+
importPath: '@open-mercato/ui/backend/detail',
|
|
271
|
+
variants: [
|
|
272
|
+
{
|
|
273
|
+
id: 'mock-adapter',
|
|
274
|
+
title: 'Timeline (inline mock adapter — no API)',
|
|
275
|
+
render: () => (
|
|
276
|
+
<div className="w-full max-w-2xl">
|
|
277
|
+
<NotesSection
|
|
278
|
+
entityId="person-1"
|
|
279
|
+
viewerUserId="user-1"
|
|
280
|
+
viewerName="Anna Nowak"
|
|
281
|
+
emptyLabel="No notes yet"
|
|
282
|
+
addActionLabel="Add note"
|
|
283
|
+
emptyState={{
|
|
284
|
+
title: 'No notes yet',
|
|
285
|
+
actionLabel: 'Add note',
|
|
286
|
+
description: 'Notes added here are visible to the whole team.',
|
|
287
|
+
}}
|
|
288
|
+
translator={galleryTranslator}
|
|
289
|
+
dataAdapter={notesAdapter}
|
|
290
|
+
/>
|
|
291
|
+
</div>
|
|
292
|
+
),
|
|
293
|
+
code: `import { NotesSection, type NotesDataAdapter } from '@open-mercato/ui/backend/detail'
|
|
294
|
+
|
|
295
|
+
// Implement the adapter against your module's API (apiCall) — never fork the section.
|
|
296
|
+
const notesAdapter: NotesDataAdapter = {
|
|
297
|
+
list: async ({ entityId }) => fetchNotes(entityId),
|
|
298
|
+
create: async ({ entityId, body }) => createNote(entityId, body),
|
|
299
|
+
update: async ({ id, patch }) => updateNote(id, patch),
|
|
300
|
+
delete: async ({ id }) => deleteNote(id),
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
<NotesSection
|
|
304
|
+
entityId={personId}
|
|
305
|
+
viewerUserId={viewer.id}
|
|
306
|
+
viewerName={viewer.name}
|
|
307
|
+
emptyLabel={t('customers.people.detail.notes.empty')}
|
|
308
|
+
addActionLabel={t('customers.people.detail.notes.add')}
|
|
309
|
+
emptyState={{
|
|
310
|
+
title: t('customers.people.detail.notes.emptyTitle'),
|
|
311
|
+
actionLabel: t('customers.people.detail.notes.add'),
|
|
312
|
+
}}
|
|
313
|
+
translator={t}
|
|
314
|
+
dataAdapter={notesAdapter}
|
|
315
|
+
/>`,
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const addressesSectionEntry: GalleryEntry = {
|
|
321
|
+
id: 'addresses-section',
|
|
322
|
+
title: 'AddressesSection',
|
|
323
|
+
importPath: '@open-mercato/ui/backend/detail',
|
|
324
|
+
variants: [
|
|
325
|
+
{
|
|
326
|
+
id: 'mock-adapter',
|
|
327
|
+
title: 'Address tiles (inline mock adapter — no API)',
|
|
328
|
+
render: () => (
|
|
329
|
+
<div className="w-full max-w-2xl">
|
|
330
|
+
<AddressesSection
|
|
331
|
+
entityId="person-1"
|
|
332
|
+
emptyLabel="No addresses yet"
|
|
333
|
+
addActionLabel="Add address"
|
|
334
|
+
emptyState={{ title: 'No addresses yet', actionLabel: 'Add address' }}
|
|
335
|
+
translator={galleryTranslator}
|
|
336
|
+
dataAdapter={addressesAdapter}
|
|
337
|
+
/>
|
|
338
|
+
</div>
|
|
339
|
+
),
|
|
340
|
+
code: `import { AddressesSection, type AddressDataAdapter } from '@open-mercato/ui/backend/detail'
|
|
341
|
+
|
|
342
|
+
const addressesAdapter: AddressDataAdapter = {
|
|
343
|
+
list: async ({ entityId }) => fetchAddresses(entityId),
|
|
344
|
+
create: async ({ entityId, payload }) => createAddress(entityId, payload),
|
|
345
|
+
update: async ({ id, payload }) => updateAddress(id, payload),
|
|
346
|
+
delete: async ({ id }) => deleteAddress(id),
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
<AddressesSection
|
|
350
|
+
entityId={personId}
|
|
351
|
+
emptyLabel={t('customers.people.detail.addresses.empty')}
|
|
352
|
+
addActionLabel={t('customers.people.detail.addresses.add')}
|
|
353
|
+
emptyState={{
|
|
354
|
+
title: t('customers.people.detail.addresses.emptyTitle'),
|
|
355
|
+
actionLabel: t('customers.people.detail.addresses.add'),
|
|
356
|
+
}}
|
|
357
|
+
translator={t}
|
|
358
|
+
dataAdapter={addressesAdapter}
|
|
359
|
+
/>`,
|
|
360
|
+
},
|
|
361
|
+
],
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const attachmentsSectionEntry: GalleryEntry = {
|
|
365
|
+
id: 'attachments-section',
|
|
366
|
+
title: 'AttachmentsSection',
|
|
367
|
+
importPath: '@open-mercato/ui/backend/detail',
|
|
368
|
+
variants: [
|
|
369
|
+
{
|
|
370
|
+
id: 'unsaved-record',
|
|
371
|
+
title: 'Unsaved record (recordId null — API fetch disabled)',
|
|
372
|
+
render: () => (
|
|
373
|
+
<div className="w-full max-w-2xl">
|
|
374
|
+
<AttachmentsSection
|
|
375
|
+
entityId="customers:person"
|
|
376
|
+
recordId={null}
|
|
377
|
+
title="Attachments"
|
|
378
|
+
description="Files linked to this record."
|
|
379
|
+
/>
|
|
380
|
+
</div>
|
|
381
|
+
),
|
|
382
|
+
code: `import { AttachmentsSection } from '@open-mercato/ui/backend/detail'
|
|
383
|
+
|
|
384
|
+
// Fetches /api/attachments internally once recordId is set;
|
|
385
|
+
// with recordId={null} it renders the save-first placeholder.
|
|
386
|
+
<AttachmentsSection
|
|
387
|
+
entityId="customers:person"
|
|
388
|
+
recordId={person?.id ?? null}
|
|
389
|
+
title={t('customers.people.detail.attachments.title')}
|
|
390
|
+
description={t('customers.people.detail.attachments.description')}
|
|
391
|
+
/>`,
|
|
392
|
+
},
|
|
393
|
+
],
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
export const entries: GalleryEntry[] = [
|
|
397
|
+
detailFieldsSectionEntry,
|
|
398
|
+
loadingMessageEntry,
|
|
399
|
+
errorMessageEntry,
|
|
400
|
+
notesSectionEntry,
|
|
401
|
+
addressesSectionEntry,
|
|
402
|
+
attachmentsSectionEntry,
|
|
403
|
+
]
|