@open-mercato/core 0.9.1-develop.7496.1.3346415f94 → 0.9.1-develop.7497.1.543ea44c40
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.
|
@@ -26,7 +26,7 @@ const logger = createLogger("customers");
|
|
|
26
26
|
const ENTITY_ID = E.customers.customer_interaction;
|
|
27
27
|
const API = "/api/customers/dictionaries/activity-types";
|
|
28
28
|
const defaults = calendarEventTypes[0].behavior;
|
|
29
|
-
function initialValues(item) {
|
|
29
|
+
function initialValues(item, version) {
|
|
30
30
|
const behavior = item?.behavior ?? defaults;
|
|
31
31
|
return {
|
|
32
32
|
value: item?.key ?? "",
|
|
@@ -38,7 +38,7 @@ function initialValues(item) {
|
|
|
38
38
|
selectable: behavior.selectable,
|
|
39
39
|
...behavior.fields,
|
|
40
40
|
customFieldsetIds: [...behavior.customFieldsetIds],
|
|
41
|
-
updatedAt:
|
|
41
|
+
updatedAt: version ?? void 0
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
function ActivityTypeEditor({ title, description }) {
|
|
@@ -48,6 +48,7 @@ function ActivityTypeEditor({ title, description }) {
|
|
|
48
48
|
const [items, setItems] = React.useState([]);
|
|
49
49
|
const [rows, setRows] = React.useState([]);
|
|
50
50
|
const [selected, setSelected] = React.useState(void 0);
|
|
51
|
+
const [selectedVersion, setSelectedVersion] = React.useState(void 0);
|
|
51
52
|
const [fieldsets, setFieldsets] = React.useState([]);
|
|
52
53
|
const [fieldsetsStatus, setFieldsetsStatus] = React.useState("loading");
|
|
53
54
|
const [fieldsetAttempt, setFieldsetAttempt] = React.useState(0);
|
|
@@ -102,6 +103,10 @@ function ActivityTypeEditor({ title, description }) {
|
|
|
102
103
|
};
|
|
103
104
|
}, [selected, fieldsetAttempt]);
|
|
104
105
|
const localRow = (key) => rows.find((row) => row.value.toLowerCase() === key && !row.isInherited);
|
|
106
|
+
const openEditor = (item) => {
|
|
107
|
+
setSelectedVersion(item ? localRow(item.key)?.updatedAt ?? item.updatedAt : void 0);
|
|
108
|
+
setSelected(item);
|
|
109
|
+
};
|
|
105
110
|
const remove = async (item) => {
|
|
106
111
|
const row = localRow(item.key);
|
|
107
112
|
if (!row) return;
|
|
@@ -161,6 +166,7 @@ function ActivityTypeEditor({ title, description }) {
|
|
|
161
166
|
{ id: "behavior", title: t("customers.config.activityTypes.behavior", "Form behavior"), fields: ["baseKind", "selectable", "endTime", "allDay", "recurrence", "location", "people", "priority", "resources"] },
|
|
162
167
|
...fieldsets.length || selected?.behavior.customFieldsetIds.length ? [{ id: "fieldsets", fields: ["customFieldsetIds"] }] : []
|
|
163
168
|
];
|
|
169
|
+
const formInitialValues = React.useMemo(() => initialValues(selected ?? null, selectedVersion), [selected, selectedVersion]);
|
|
164
170
|
const save = async (values) => {
|
|
165
171
|
const key = String(values.value ?? "").trim();
|
|
166
172
|
if (!calendarEventTypeKeySchema.safeParse(key).success) throw createCrudFormError(t("customers.config.activityTypes.invalidKey", "Use a lowercase key with letters, numbers, hyphens, or underscores."), { value: t("customers.config.activityTypes.invalidKey", "Use a lowercase key with letters, numbers, hyphens, or underscores.") });
|
|
@@ -233,10 +239,10 @@ function ActivityTypeEditor({ title, description }) {
|
|
|
233
239
|
title,
|
|
234
240
|
titleHeadingLevel: 2,
|
|
235
241
|
emptyState: t("customers.config.activityTypes.empty", "No activity types available."),
|
|
236
|
-
actions: /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", onClick: () =>
|
|
242
|
+
actions: /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", onClick: () => openEditor(null), children: t("customers.config.activityTypes.new", "New activity type") }),
|
|
237
243
|
refreshButton: { label: t("customers.config.activityTypes.refresh", "Refresh"), onRefresh: load, isRefreshing: status === "loading" },
|
|
238
244
|
rowActions: (item) => {
|
|
239
|
-
const actions = [{ id: "edit", label: item.adminConfigurable ? t("customers.config.activityTypes.configure", "Configure") : t("customers.config.activityTypes.view", "View"), onSelect: () =>
|
|
245
|
+
const actions = [{ id: "edit", label: item.adminConfigurable ? t("customers.config.activityTypes.configure", "Configure") : t("customers.config.activityTypes.view", "View"), onSelect: () => openEditor(item) }];
|
|
240
246
|
if (localRow(item.key)) actions.push({
|
|
241
247
|
id: "delete",
|
|
242
248
|
label: item.source === "dictionary" ? t("customers.config.activityTypes.delete", "Delete") : t("customers.config.activityTypes.reset", "Reset override"),
|
|
@@ -271,7 +277,7 @@ function ActivityTypeEditor({ title, description }) {
|
|
|
271
277
|
readOnly: selected?.adminConfigurable === false,
|
|
272
278
|
fields,
|
|
273
279
|
groups,
|
|
274
|
-
initialValues:
|
|
280
|
+
initialValues: formInitialValues,
|
|
275
281
|
onSubmit: save,
|
|
276
282
|
submitLabel: t("customers.config.activityTypes.save", "Save"),
|
|
277
283
|
extraActions: /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: () => setSelected(void 0), children: t("customers.config.dictionaries.dialog.cancel", "Cancel") })
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/customers/components/ActivityTypeEditor.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { E } from '#generated/entities.ids.generated'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport { getTelemetryRuntime } from '@open-mercato/shared/lib/telemetry/runtime'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { RowActions, type RowActionItem } from '@open-mercato/ui/backend/RowActions'\nimport { CrudForm, type CrudField, type CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'\nimport { ErrorMessage, LoadingMessage } from '@open-mercato/ui/backend/detail'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { apiCallOrThrow, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '@open-mercato/ui/primitives/dialog'\nimport { calendarEventTypeBehaviorSchema, calendarEventTypeKeySchema, calendarEventTypes } from '../calendar-event-types'\nimport type { ScopedCalendarEventType } from '../lib/calendar/eventTypeResolver'\nimport { getCustomerDictionarySettingsSectionId } from '../lib/dictionaries'\nimport { renderDictionaryColor, renderDictionaryIcon } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'\n\nconst logger = createLogger('customers')\nconst ENTITY_ID = E.customers.customer_interaction\nconst API = '/api/customers/dictionaries/activity-types'\n\ntype DictionaryRow = { id: string; value: string; updatedAt: string | null; isInherited: boolean }\ntype Fieldset = { code: string; label: string }\ntype FormValues = Record<string, unknown>\n\nconst defaults = calendarEventTypes[0]!.behavior\n\nfunction initialValues(item: ScopedCalendarEventType | null): FormValues {\n const behavior = item?.behavior ?? defaults\n return {\n value: item?.key ?? '', label: item?.label ?? '', icon: item?.icon ?? '', color: item?.color ?? '',\n order: behavior.order, baseKind: behavior.baseKind, selectable: behavior.selectable,\n ...behavior.fields, customFieldsetIds: [...behavior.customFieldsetIds], updatedAt: item?.updatedAt ?? undefined,\n }\n}\n\nexport function ActivityTypeEditor({ title, description }: { title: string; description: string }) {\n const t = useT()\n const scopeVersion = useOrganizationScopeVersion()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [items, setItems] = React.useState<ScopedCalendarEventType[]>([])\n const [rows, setRows] = React.useState<DictionaryRow[]>([])\n const [selected, setSelected] = React.useState<ScopedCalendarEventType | null | undefined>(undefined)\n const [fieldsets, setFieldsets] = React.useState<Fieldset[]>([])\n const [fieldsetsStatus, setFieldsetsStatus] = React.useState<'loading' | 'ready' | 'error'>('loading')\n const [fieldsetAttempt, setFieldsetAttempt] = React.useState(0)\n const [status, setStatus] = React.useState<'loading' | 'ready' | 'error'>('loading')\n const { runMutation, retryLastMutation } = useGuardedMutation({\n contextId: 'customers-activity-types',\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const load = React.useCallback(async () => {\n setStatus('loading')\n try {\n const [catalog, dictionary] = await Promise.all([\n readApiResultOrThrow<{ items: ScopedCalendarEventType[] }>('/api/customers/activity-types'),\n readApiResultOrThrow<{ items: DictionaryRow[] }>(API),\n ])\n if (!Array.isArray(catalog.items) || !Array.isArray(dictionary.items)) throw new Error('[internal] Invalid activity type response')\n setItems(catalog.items)\n setRows(dictionary.items)\n setStatus('ready')\n } catch (err) {\n logger.error('customers.activity_types.settings.load failed', { err })\n getTelemetryRuntime()?.reportError(err, {\n module: 'customers',\n code: 'customers.activity_type_settings_load_failed',\n })\n setStatus('error')\n }\n }, [])\n React.useEffect(() => { void load() }, [load, scopeVersion])\n\n React.useEffect(() => {\n if (selected === undefined) return\n let active = true\n setFieldsetsStatus('loading')\n void readApiResultOrThrow<{ fieldsetsByEntity?: Record<string, Fieldset[]> }>(\n `/api/entities/definitions?entityId=${encodeURIComponent(ENTITY_ID)}`,\n ).then((result) => {\n if (!active) return\n setFieldsets(result.fieldsetsByEntity?.[ENTITY_ID] ?? [])\n setFieldsetsStatus('ready')\n }).catch((err) => {\n logger.error('customers.activity_types.fieldsets.load failed', { err })\n getTelemetryRuntime()?.reportError(err, {\n module: 'customers',\n code: 'customers.activity_type_fieldsets_load_failed',\n })\n if (active) setFieldsetsStatus('error')\n })\n return () => { active = false }\n }, [selected, fieldsetAttempt])\n\n const localRow = (key: string) => rows.find((row) => row.value.toLowerCase() === key && !row.isInherited)\n const remove = async (item: ScopedCalendarEventType) => {\n const row = localRow(item.key)\n if (!row) return\n const approved = await confirm({\n title: t('customers.config.activityTypes.resetConfirm', 'Remove the local activity type configuration?'),\n variant: 'destructive',\n })\n if (!approved) return\n try {\n await runMutation({\n operation: () => withScopedApiRequestHeaders(buildOptimisticLockHeader(row.updatedAt), () =>\n apiCallOrThrow(`${API}/${encodeURIComponent(row.id)}`, { method: 'DELETE' })),\n context: { formId: 'customers-activity-types', resourceKind: 'customers.dictionary', retryLastMutation },\n mutationPayload: { action: 'delete', id: row.id, kind: 'activity-types' },\n })\n flash(t('customers.config.activityTypes.removed', 'Activity type configuration removed.'), 'success')\n await load()\n } catch (err) {\n logger.error('customers.activity_types.settings.remove failed', { err })\n getTelemetryRuntime()?.reportError(err, {\n module: 'customers',\n code: 'customers.activity_type_settings_remove_failed',\n })\n if (!surfaceRecordConflict(err, t, { onRefresh: () => { void load() } })) {\n flash(t('customers.config.activityTypes.saveFailed', 'Failed to save activity type.'), 'error')\n }\n }\n }\n\n const fields = React.useMemo<CrudField[]>(() => {\n const label = (key: string, fallback: string) => t(`customers.config.activityTypes.fields.${key}`, fallback)\n const options = (values: readonly string[]) => values.map((value) => ({ value, label: t(`customers.config.activityTypes.options.${value}`, value) }))\n const knownFieldsets = fieldsets.map(({ code, label: fieldsetLabel }) => ({ value: code, label: fieldsetLabel }))\n const missing = selected?.behavior.customFieldsetIds.filter((code) => !fieldsets.some((fieldset) => fieldset.code === code)) ?? []\n return [\n { id: 'value', type: 'text', label: label('value', 'Stable key'), required: true, readOnly: !!selected },\n { id: 'label', type: 'text', label: label('label', 'Label'), required: true },\n { id: 'icon', type: 'text', label: label('icon', 'Icon') },\n { id: 'color', type: 'text', label: label('color', 'Color (#RRGGBB)') },\n { id: 'order', type: 'number', label: label('order', 'Display order'), required: true },\n { id: 'baseKind', type: 'select', label: label('baseKind', 'Base behavior'), options: options(['meeting', 'call', 'email', 'note', 'event', 'task']) },\n { id: 'selectable', type: 'checkbox', label: label('selectable', 'Available for new events') },\n ...(['endTime', 'allDay', 'recurrence', 'priority', 'resources'] as const).map((id): CrudField => ({ id, type: 'checkbox', label: label(id, id) })),\n { id: 'location', type: 'select', label: label('location', 'Location field'), options: options(['none', 'location', 'phoneLink']) },\n { id: 'people', type: 'select', label: label('people', 'People field'), options: options(['none', 'attendees', 'participants', 'recipients', 'assignee']) },\n { id: 'customFieldsetIds', type: 'select', multiple: true, label: label('customFieldsetIds', 'Custom-field fieldsets'),\n options: [...knownFieldsets, ...missing.map((code) => ({ value: code, label: `${code} (${t('customers.config.activityTypes.missing', 'missing')})` }))] },\n ]\n }, [fieldsets, selected, t])\n const groups: CrudFormGroup[] = [\n { id: 'appearance', title: t('customers.config.activityTypes.appearance', 'Appearance'), fields: ['value', 'label', 'icon', 'color', 'order'] },\n { id: 'behavior', title: t('customers.config.activityTypes.behavior', 'Form behavior'), fields: ['baseKind', 'selectable', 'endTime', 'allDay', 'recurrence', 'location', 'people', 'priority', 'resources'] },\n ...(fieldsets.length || selected?.behavior.customFieldsetIds.length ? [{ id: 'fieldsets', fields: ['customFieldsetIds'] }] : []),\n ]\n const save = async (values: FormValues) => {\n const key = String(values.value ?? '').trim()\n if (!calendarEventTypeKeySchema.safeParse(key).success) throw createCrudFormError(t('customers.config.activityTypes.invalidKey', 'Use a lowercase key with letters, numbers, hyphens, or underscores.'), { value: t('customers.config.activityTypes.invalidKey', 'Use a lowercase key with letters, numbers, hyphens, or underscores.') })\n if (fieldsetsStatus !== 'ready') throw createCrudFormError(t('customers.config.activityTypes.fieldsetsUnavailable', 'Fieldsets are unavailable. Retry loading before saving.'))\n const behavior = calendarEventTypeBehaviorSchema.safeParse({\n schemaVersion: 1, baseKind: values.baseKind, selectable: values.selectable === true,\n order: Number(values.order), customFieldsetIds: values.customFieldsetIds ?? [],\n fields: { endTime: values.endTime === true, allDay: values.allDay === true, recurrence: values.recurrence === true,\n location: values.location, people: values.people, priority: values.priority === true, resources: values.resources === true },\n })\n if (!behavior.success) throw createCrudFormError(t('customers.config.activityTypes.invalidBehavior', 'Check the form behavior values.'))\n const payload = { value: key, label: String(values.label ?? '').trim(), icon: String(values.icon ?? '').trim() || null,\n color: String(values.color ?? '').trim() || null, behavior: behavior.data }\n const row = selected ? localRow(selected.key) : undefined\n await apiCallOrThrow(row ? `${API}/${encodeURIComponent(row.id)}` : API, {\n method: row ? 'PATCH' : 'POST', headers: { 'content-type': 'application/json' },\n body: JSON.stringify(row ? { label: payload.label, icon: payload.icon, color: payload.color, behavior: payload.behavior } : payload),\n })\n setSelected(undefined)\n flash(t('customers.config.activityTypes.saved', 'Activity type saved.'), 'success')\n await load()\n }\n\n const columns = React.useMemo<ColumnDef<ScopedCalendarEventType>[]>(() => [\n { accessorKey: 'label', header: t('customers.config.activityTypes.columns.type', 'Activity type'), cell: ({ row }) => (\n <div className=\"flex items-center gap-2\">{row.original.color ? renderDictionaryColor(row.original.color, 'size-4 rounded-full border border-border') : null}\n {row.original.icon ? renderDictionaryIcon(row.original.icon, 'size-4') : null}<span>{row.original.labelKey\n ? t(row.original.labelKey, row.original.label)\n : row.original.label}</span></div>) },\n { accessorKey: 'key', header: t('customers.config.activityTypes.columns.key', 'Stable key') },\n { id: 'source', header: t('customers.config.activityTypes.columns.source', 'Source'), cell: ({ row }) => row.original.isLocalOverride\n ? t('customers.config.activityTypes.local', 'Local override') : row.original.isInherited\n ? t('customers.config.activityTypes.inherited', 'Inherited') : row.original.source },\n { id: 'behavior', header: t('customers.config.activityTypes.columns.behavior', 'Behavior'), cell: ({ row }) =>\n t(`customers.config.activityTypes.options.${row.original.behavior.baseKind}`, row.original.behavior.baseKind) },\n { id: 'active', header: t('customers.config.activityTypes.columns.active', 'Selectable'), cell: ({ row }) => row.original.selectable\n ? t('customers.config.activityTypes.yes', 'Yes') : t('customers.config.activityTypes.no', 'No') },\n { id: 'fields', header: t('customers.config.activityTypes.columns.fields', 'Fields'), cell: ({ row }) =>\n Object.values(row.original.behavior.fields).filter((value) => value !== false && value !== 'none').length },\n { id: 'fieldsets', header: t('customers.config.activityTypes.columns.fieldsets', 'Fieldsets'), cell: ({ row }) => row.original.behavior.customFieldsetIds.length },\n { id: 'order', header: t('customers.config.activityTypes.columns.order', 'Order'), cell: ({ row }) => row.original.behavior.order },\n ], [t])\n\n return <section id={getCustomerDictionarySettingsSectionId('activity-types')} className=\"scroll-mt-24 rounded border bg-card text-card-foreground shadow-sm\">\n <div className=\"space-y-1 border-b px-6 py-4\"><h2 className=\"text-lg font-medium\">{title}</h2><p className=\"text-sm text-muted-foreground\">{description}</p></div>\n <div className=\"px-2 py-4 sm:px-4\">\n {status === 'error' ? <div className=\"space-y-3\"><ErrorMessage label={t('customers.config.activityTypes.loadFailed', 'Failed to load activity types.')} /><Button type=\"button\" onClick={() => { void load() }}>{t('customers.config.activityTypes.retry', 'Retry')}</Button></div> :\n <DataTable<ScopedCalendarEventType> embedded columns={columns} data={items} isLoading={status === 'loading'}\n title={title} titleHeadingLevel={2} emptyState={t('customers.config.activityTypes.empty', 'No activity types available.')}\n actions={<Button type=\"button\" size=\"sm\" onClick={() => setSelected(null)}>{t('customers.config.activityTypes.new', 'New activity type')}</Button>}\n refreshButton={{ label: t('customers.config.activityTypes.refresh', 'Refresh'), onRefresh: load, isRefreshing: status === 'loading' }}\n rowActions={(item) => {\n const actions: RowActionItem[] = [{ id: 'edit', label: item.adminConfigurable\n ? t('customers.config.activityTypes.configure', 'Configure') : t('customers.config.activityTypes.view', 'View'), onSelect: () => setSelected(item) }]\n if (localRow(item.key)) actions.push({ id: 'delete', label: item.source === 'dictionary'\n ? t('customers.config.activityTypes.delete', 'Delete') : t('customers.config.activityTypes.reset', 'Reset override'),\n destructive: true, onSelect: () => { void remove(item) } })\n return <RowActions items={actions} />\n }} />}\n </div>\n <Dialog open={selected !== undefined} onOpenChange={(open) => { if (!open) setSelected(undefined) }}>\n <DialogContent className=\"max-h-screen overflow-y-auto sm:max-w-2xl\">\n <DialogHeader><DialogTitle>{selected\n ? t('customers.config.activityTypes.configure', 'Configure') : t('customers.config.activityTypes.new', 'New activity type')}</DialogTitle></DialogHeader>\n {selected?.isInherited ? <p className=\"text-sm text-muted-foreground\">{t('customers.config.activityTypes.inheritedHint', 'Saving creates a local override for this organization.')}</p> : null}\n {selected?.inactiveDictionaryOverride ? <p className=\"text-sm text-muted-foreground\">{t('customers.config.activityTypes.inactiveHint', 'A module currently prevents this override from taking effect.')}</p> : null}\n {selected?.missingCustomFieldsetIds.length ? <p className=\"text-sm text-muted-foreground\">{t('customers.config.activityTypes.missingHint', 'Some configured fieldsets no longer exist.')}: {selected.missingCustomFieldsetIds.join(', ')}</p> : null}\n {fieldsetsStatus === 'loading' ? <LoadingMessage label={t('customers.config.activityTypes.loadingFieldsets', 'Loading fieldsets\u2026')} /> : null}\n {fieldsetsStatus === 'error' ? <ErrorMessage label={t('customers.config.activityTypes.fieldsetsUnavailable', 'Fieldsets are unavailable. Retry loading before saving.')} /> : null}\n {fieldsetsStatus === 'error' ? <Button type=\"button\" onClick={() => setFieldsetAttempt((attempt) => attempt + 1)}>{t('customers.config.activityTypes.retry', 'Retry')}</Button> : null}\n {fieldsetsStatus === 'ready' && fieldsets.length === 0 ? <p className=\"text-sm text-muted-foreground\">{t('customers.config.activityTypes.noFieldsets', 'No custom-field fieldsets are defined yet.')}</p> : null}\n {selected !== undefined && fieldsetsStatus === 'ready' ? <CrudForm<FormValues> key={selected?.key ?? 'new'} embedded\n readOnly={selected?.adminConfigurable === false} fields={fields} groups={groups}\n initialValues={initialValues(selected)} onSubmit={save} submitLabel={t('customers.config.activityTypes.save', 'Save')}\n extraActions={<Button type=\"button\" variant=\"outline\" onClick={() => setSelected(undefined)}>{t('customers.config.dictionaries.dialog.cancel', 'Cancel')}</Button>} /> : null}\n </DialogContent>\n </Dialog>\n {ConfirmDialogElement}\n </section>\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { E } from '#generated/entities.ids.generated'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport { getTelemetryRuntime } from '@open-mercato/shared/lib/telemetry/runtime'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { RowActions, type RowActionItem } from '@open-mercato/ui/backend/RowActions'\nimport { CrudForm, type CrudField, type CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'\nimport { ErrorMessage, LoadingMessage } from '@open-mercato/ui/backend/detail'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { apiCallOrThrow, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '@open-mercato/ui/primitives/dialog'\nimport { calendarEventTypeBehaviorSchema, calendarEventTypeKeySchema, calendarEventTypes } from '../calendar-event-types'\nimport type { ScopedCalendarEventType } from '../lib/calendar/eventTypeResolver'\nimport { getCustomerDictionarySettingsSectionId } from '../lib/dictionaries'\nimport { renderDictionaryColor, renderDictionaryIcon } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'\n\nconst logger = createLogger('customers')\nconst ENTITY_ID = E.customers.customer_interaction\nconst API = '/api/customers/dictionaries/activity-types'\n\ntype DictionaryRow = { id: string; value: string; updatedAt: string | null; isInherited: boolean }\ntype Fieldset = { code: string; label: string }\ntype FormValues = Record<string, unknown>\n\nconst defaults = calendarEventTypes[0]!.behavior\n\nfunction initialValues(item: ScopedCalendarEventType | null, version: string | null | undefined): FormValues {\n const behavior = item?.behavior ?? defaults\n return {\n value: item?.key ?? '', label: item?.label ?? '', icon: item?.icon ?? '', color: item?.color ?? '',\n order: behavior.order, baseKind: behavior.baseKind, selectable: behavior.selectable,\n ...behavior.fields, customFieldsetIds: [...behavior.customFieldsetIds], updatedAt: version ?? undefined,\n }\n}\n\nexport function ActivityTypeEditor({ title, description }: { title: string; description: string }) {\n const t = useT()\n const scopeVersion = useOrganizationScopeVersion()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [items, setItems] = React.useState<ScopedCalendarEventType[]>([])\n const [rows, setRows] = React.useState<DictionaryRow[]>([])\n const [selected, setSelected] = React.useState<ScopedCalendarEventType | null | undefined>(undefined)\n const [selectedVersion, setSelectedVersion] = React.useState<string | null | undefined>(undefined)\n const [fieldsets, setFieldsets] = React.useState<Fieldset[]>([])\n const [fieldsetsStatus, setFieldsetsStatus] = React.useState<'loading' | 'ready' | 'error'>('loading')\n const [fieldsetAttempt, setFieldsetAttempt] = React.useState(0)\n const [status, setStatus] = React.useState<'loading' | 'ready' | 'error'>('loading')\n const { runMutation, retryLastMutation } = useGuardedMutation({\n contextId: 'customers-activity-types',\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const load = React.useCallback(async () => {\n setStatus('loading')\n try {\n const [catalog, dictionary] = await Promise.all([\n readApiResultOrThrow<{ items: ScopedCalendarEventType[] }>('/api/customers/activity-types'),\n readApiResultOrThrow<{ items: DictionaryRow[] }>(API),\n ])\n if (!Array.isArray(catalog.items) || !Array.isArray(dictionary.items)) throw new Error('[internal] Invalid activity type response')\n setItems(catalog.items)\n setRows(dictionary.items)\n setStatus('ready')\n } catch (err) {\n logger.error('customers.activity_types.settings.load failed', { err })\n getTelemetryRuntime()?.reportError(err, {\n module: 'customers',\n code: 'customers.activity_type_settings_load_failed',\n })\n setStatus('error')\n }\n }, [])\n React.useEffect(() => { void load() }, [load, scopeVersion])\n\n React.useEffect(() => {\n if (selected === undefined) return\n let active = true\n setFieldsetsStatus('loading')\n void readApiResultOrThrow<{ fieldsetsByEntity?: Record<string, Fieldset[]> }>(\n `/api/entities/definitions?entityId=${encodeURIComponent(ENTITY_ID)}`,\n ).then((result) => {\n if (!active) return\n setFieldsets(result.fieldsetsByEntity?.[ENTITY_ID] ?? [])\n setFieldsetsStatus('ready')\n }).catch((err) => {\n logger.error('customers.activity_types.fieldsets.load failed', { err })\n getTelemetryRuntime()?.reportError(err, {\n module: 'customers',\n code: 'customers.activity_type_fieldsets_load_failed',\n })\n if (active) setFieldsetsStatus('error')\n })\n return () => { active = false }\n }, [selected, fieldsetAttempt])\n\n const localRow = (key: string) => rows.find((row) => row.value.toLowerCase() === key && !row.isInherited)\n const openEditor = (item: ScopedCalendarEventType | null) => {\n setSelectedVersion(item ? localRow(item.key)?.updatedAt ?? item.updatedAt : undefined)\n setSelected(item)\n }\n const remove = async (item: ScopedCalendarEventType) => {\n const row = localRow(item.key)\n if (!row) return\n const approved = await confirm({\n title: t('customers.config.activityTypes.resetConfirm', 'Remove the local activity type configuration?'),\n variant: 'destructive',\n })\n if (!approved) return\n try {\n await runMutation({\n operation: () => withScopedApiRequestHeaders(buildOptimisticLockHeader(row.updatedAt), () =>\n apiCallOrThrow(`${API}/${encodeURIComponent(row.id)}`, { method: 'DELETE' })),\n context: { formId: 'customers-activity-types', resourceKind: 'customers.dictionary', retryLastMutation },\n mutationPayload: { action: 'delete', id: row.id, kind: 'activity-types' },\n })\n flash(t('customers.config.activityTypes.removed', 'Activity type configuration removed.'), 'success')\n await load()\n } catch (err) {\n logger.error('customers.activity_types.settings.remove failed', { err })\n getTelemetryRuntime()?.reportError(err, {\n module: 'customers',\n code: 'customers.activity_type_settings_remove_failed',\n })\n if (!surfaceRecordConflict(err, t, { onRefresh: () => { void load() } })) {\n flash(t('customers.config.activityTypes.saveFailed', 'Failed to save activity type.'), 'error')\n }\n }\n }\n\n const fields = React.useMemo<CrudField[]>(() => {\n const label = (key: string, fallback: string) => t(`customers.config.activityTypes.fields.${key}`, fallback)\n const options = (values: readonly string[]) => values.map((value) => ({ value, label: t(`customers.config.activityTypes.options.${value}`, value) }))\n const knownFieldsets = fieldsets.map(({ code, label: fieldsetLabel }) => ({ value: code, label: fieldsetLabel }))\n const missing = selected?.behavior.customFieldsetIds.filter((code) => !fieldsets.some((fieldset) => fieldset.code === code)) ?? []\n return [\n { id: 'value', type: 'text', label: label('value', 'Stable key'), required: true, readOnly: !!selected },\n { id: 'label', type: 'text', label: label('label', 'Label'), required: true },\n { id: 'icon', type: 'text', label: label('icon', 'Icon') },\n { id: 'color', type: 'text', label: label('color', 'Color (#RRGGBB)') },\n { id: 'order', type: 'number', label: label('order', 'Display order'), required: true },\n { id: 'baseKind', type: 'select', label: label('baseKind', 'Base behavior'), options: options(['meeting', 'call', 'email', 'note', 'event', 'task']) },\n { id: 'selectable', type: 'checkbox', label: label('selectable', 'Available for new events') },\n ...(['endTime', 'allDay', 'recurrence', 'priority', 'resources'] as const).map((id): CrudField => ({ id, type: 'checkbox', label: label(id, id) })),\n { id: 'location', type: 'select', label: label('location', 'Location field'), options: options(['none', 'location', 'phoneLink']) },\n { id: 'people', type: 'select', label: label('people', 'People field'), options: options(['none', 'attendees', 'participants', 'recipients', 'assignee']) },\n { id: 'customFieldsetIds', type: 'select', multiple: true, label: label('customFieldsetIds', 'Custom-field fieldsets'),\n options: [...knownFieldsets, ...missing.map((code) => ({ value: code, label: `${code} (${t('customers.config.activityTypes.missing', 'missing')})` }))] },\n ]\n }, [fieldsets, selected, t])\n const groups: CrudFormGroup[] = [\n { id: 'appearance', title: t('customers.config.activityTypes.appearance', 'Appearance'), fields: ['value', 'label', 'icon', 'color', 'order'] },\n { id: 'behavior', title: t('customers.config.activityTypes.behavior', 'Form behavior'), fields: ['baseKind', 'selectable', 'endTime', 'allDay', 'recurrence', 'location', 'people', 'priority', 'resources'] },\n ...(fieldsets.length || selected?.behavior.customFieldsetIds.length ? [{ id: 'fieldsets', fields: ['customFieldsetIds'] }] : []),\n ]\n const formInitialValues = React.useMemo(() => initialValues(selected ?? null, selectedVersion), [selected, selectedVersion])\n const save = async (values: FormValues) => {\n const key = String(values.value ?? '').trim()\n if (!calendarEventTypeKeySchema.safeParse(key).success) throw createCrudFormError(t('customers.config.activityTypes.invalidKey', 'Use a lowercase key with letters, numbers, hyphens, or underscores.'), { value: t('customers.config.activityTypes.invalidKey', 'Use a lowercase key with letters, numbers, hyphens, or underscores.') })\n if (fieldsetsStatus !== 'ready') throw createCrudFormError(t('customers.config.activityTypes.fieldsetsUnavailable', 'Fieldsets are unavailable. Retry loading before saving.'))\n const behavior = calendarEventTypeBehaviorSchema.safeParse({\n schemaVersion: 1, baseKind: values.baseKind, selectable: values.selectable === true,\n order: Number(values.order), customFieldsetIds: values.customFieldsetIds ?? [],\n fields: { endTime: values.endTime === true, allDay: values.allDay === true, recurrence: values.recurrence === true,\n location: values.location, people: values.people, priority: values.priority === true, resources: values.resources === true },\n })\n if (!behavior.success) throw createCrudFormError(t('customers.config.activityTypes.invalidBehavior', 'Check the form behavior values.'))\n const payload = { value: key, label: String(values.label ?? '').trim(), icon: String(values.icon ?? '').trim() || null,\n color: String(values.color ?? '').trim() || null, behavior: behavior.data }\n const row = selected ? localRow(selected.key) : undefined\n await apiCallOrThrow(row ? `${API}/${encodeURIComponent(row.id)}` : API, {\n method: row ? 'PATCH' : 'POST', headers: { 'content-type': 'application/json' },\n body: JSON.stringify(row ? { label: payload.label, icon: payload.icon, color: payload.color, behavior: payload.behavior } : payload),\n })\n setSelected(undefined)\n flash(t('customers.config.activityTypes.saved', 'Activity type saved.'), 'success')\n await load()\n }\n\n const columns = React.useMemo<ColumnDef<ScopedCalendarEventType>[]>(() => [\n { accessorKey: 'label', header: t('customers.config.activityTypes.columns.type', 'Activity type'), cell: ({ row }) => (\n <div className=\"flex items-center gap-2\">{row.original.color ? renderDictionaryColor(row.original.color, 'size-4 rounded-full border border-border') : null}\n {row.original.icon ? renderDictionaryIcon(row.original.icon, 'size-4') : null}<span>{row.original.labelKey\n ? t(row.original.labelKey, row.original.label)\n : row.original.label}</span></div>) },\n { accessorKey: 'key', header: t('customers.config.activityTypes.columns.key', 'Stable key') },\n { id: 'source', header: t('customers.config.activityTypes.columns.source', 'Source'), cell: ({ row }) => row.original.isLocalOverride\n ? t('customers.config.activityTypes.local', 'Local override') : row.original.isInherited\n ? t('customers.config.activityTypes.inherited', 'Inherited') : row.original.source },\n { id: 'behavior', header: t('customers.config.activityTypes.columns.behavior', 'Behavior'), cell: ({ row }) =>\n t(`customers.config.activityTypes.options.${row.original.behavior.baseKind}`, row.original.behavior.baseKind) },\n { id: 'active', header: t('customers.config.activityTypes.columns.active', 'Selectable'), cell: ({ row }) => row.original.selectable\n ? t('customers.config.activityTypes.yes', 'Yes') : t('customers.config.activityTypes.no', 'No') },\n { id: 'fields', header: t('customers.config.activityTypes.columns.fields', 'Fields'), cell: ({ row }) =>\n Object.values(row.original.behavior.fields).filter((value) => value !== false && value !== 'none').length },\n { id: 'fieldsets', header: t('customers.config.activityTypes.columns.fieldsets', 'Fieldsets'), cell: ({ row }) => row.original.behavior.customFieldsetIds.length },\n { id: 'order', header: t('customers.config.activityTypes.columns.order', 'Order'), cell: ({ row }) => row.original.behavior.order },\n ], [t])\n\n return <section id={getCustomerDictionarySettingsSectionId('activity-types')} className=\"scroll-mt-24 rounded border bg-card text-card-foreground shadow-sm\">\n <div className=\"space-y-1 border-b px-6 py-4\"><h2 className=\"text-lg font-medium\">{title}</h2><p className=\"text-sm text-muted-foreground\">{description}</p></div>\n <div className=\"px-2 py-4 sm:px-4\">\n {status === 'error' ? <div className=\"space-y-3\"><ErrorMessage label={t('customers.config.activityTypes.loadFailed', 'Failed to load activity types.')} /><Button type=\"button\" onClick={() => { void load() }}>{t('customers.config.activityTypes.retry', 'Retry')}</Button></div> :\n <DataTable<ScopedCalendarEventType> embedded columns={columns} data={items} isLoading={status === 'loading'}\n title={title} titleHeadingLevel={2} emptyState={t('customers.config.activityTypes.empty', 'No activity types available.')}\n actions={<Button type=\"button\" size=\"sm\" onClick={() => openEditor(null)}>{t('customers.config.activityTypes.new', 'New activity type')}</Button>}\n refreshButton={{ label: t('customers.config.activityTypes.refresh', 'Refresh'), onRefresh: load, isRefreshing: status === 'loading' }}\n rowActions={(item) => {\n const actions: RowActionItem[] = [{ id: 'edit', label: item.adminConfigurable\n ? t('customers.config.activityTypes.configure', 'Configure') : t('customers.config.activityTypes.view', 'View'), onSelect: () => openEditor(item) }]\n if (localRow(item.key)) actions.push({ id: 'delete', label: item.source === 'dictionary'\n ? t('customers.config.activityTypes.delete', 'Delete') : t('customers.config.activityTypes.reset', 'Reset override'),\n destructive: true, onSelect: () => { void remove(item) } })\n return <RowActions items={actions} />\n }} />}\n </div>\n <Dialog open={selected !== undefined} onOpenChange={(open) => { if (!open) setSelected(undefined) }}>\n <DialogContent className=\"max-h-screen overflow-y-auto sm:max-w-2xl\">\n <DialogHeader><DialogTitle>{selected\n ? t('customers.config.activityTypes.configure', 'Configure') : t('customers.config.activityTypes.new', 'New activity type')}</DialogTitle></DialogHeader>\n {selected?.isInherited ? <p className=\"text-sm text-muted-foreground\">{t('customers.config.activityTypes.inheritedHint', 'Saving creates a local override for this organization.')}</p> : null}\n {selected?.inactiveDictionaryOverride ? <p className=\"text-sm text-muted-foreground\">{t('customers.config.activityTypes.inactiveHint', 'A module currently prevents this override from taking effect.')}</p> : null}\n {selected?.missingCustomFieldsetIds.length ? <p className=\"text-sm text-muted-foreground\">{t('customers.config.activityTypes.missingHint', 'Some configured fieldsets no longer exist.')}: {selected.missingCustomFieldsetIds.join(', ')}</p> : null}\n {fieldsetsStatus === 'loading' ? <LoadingMessage label={t('customers.config.activityTypes.loadingFieldsets', 'Loading fieldsets\u2026')} /> : null}\n {fieldsetsStatus === 'error' ? <ErrorMessage label={t('customers.config.activityTypes.fieldsetsUnavailable', 'Fieldsets are unavailable. Retry loading before saving.')} /> : null}\n {fieldsetsStatus === 'error' ? <Button type=\"button\" onClick={() => setFieldsetAttempt((attempt) => attempt + 1)}>{t('customers.config.activityTypes.retry', 'Retry')}</Button> : null}\n {fieldsetsStatus === 'ready' && fieldsets.length === 0 ? <p className=\"text-sm text-muted-foreground\">{t('customers.config.activityTypes.noFieldsets', 'No custom-field fieldsets are defined yet.')}</p> : null}\n {selected !== undefined && fieldsetsStatus === 'ready' ? <CrudForm<FormValues> key={selected?.key ?? 'new'} embedded\n readOnly={selected?.adminConfigurable === false} fields={fields} groups={groups}\n initialValues={formInitialValues} onSubmit={save} submitLabel={t('customers.config.activityTypes.save', 'Save')}\n extraActions={<Button type=\"button\" variant=\"outline\" onClick={() => setSelected(undefined)}>{t('customers.config.dictionaries.dialog.cancel', 'Cancel')}</Button>} /> : null}\n </DialogContent>\n </Dialog>\n {ConfirmDialogElement}\n </section>\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/core",
|
|
3
|
-
"version": "0.9.1-develop.
|
|
3
|
+
"version": "0.9.1-develop.7497.1.543ea44c40",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -264,16 +264,16 @@
|
|
|
264
264
|
"zod": "^4.4.3"
|
|
265
265
|
},
|
|
266
266
|
"peerDependencies": {
|
|
267
|
-
"@open-mercato/ai-assistant": "0.9.1-develop.
|
|
268
|
-
"@open-mercato/shared": "0.9.1-develop.
|
|
269
|
-
"@open-mercato/ui": "0.9.1-develop.
|
|
267
|
+
"@open-mercato/ai-assistant": "0.9.1-develop.7497.1.543ea44c40",
|
|
268
|
+
"@open-mercato/shared": "0.9.1-develop.7497.1.543ea44c40",
|
|
269
|
+
"@open-mercato/ui": "0.9.1-develop.7497.1.543ea44c40",
|
|
270
270
|
"react": "^19.0.0",
|
|
271
271
|
"react-dom": "^19.0.0"
|
|
272
272
|
},
|
|
273
273
|
"devDependencies": {
|
|
274
|
-
"@open-mercato/ai-assistant": "0.9.1-develop.
|
|
275
|
-
"@open-mercato/shared": "0.9.1-develop.
|
|
276
|
-
"@open-mercato/ui": "0.9.1-develop.
|
|
274
|
+
"@open-mercato/ai-assistant": "0.9.1-develop.7497.1.543ea44c40",
|
|
275
|
+
"@open-mercato/shared": "0.9.1-develop.7497.1.543ea44c40",
|
|
276
|
+
"@open-mercato/ui": "0.9.1-develop.7497.1.543ea44c40",
|
|
277
277
|
"@testing-library/dom": "^10.4.1",
|
|
278
278
|
"@testing-library/jest-dom": "^7.0.1",
|
|
279
279
|
"@testing-library/react": "^16.3.3",
|
|
@@ -35,12 +35,12 @@ type FormValues = Record<string, unknown>
|
|
|
35
35
|
|
|
36
36
|
const defaults = calendarEventTypes[0]!.behavior
|
|
37
37
|
|
|
38
|
-
function initialValues(item: ScopedCalendarEventType | null): FormValues {
|
|
38
|
+
function initialValues(item: ScopedCalendarEventType | null, version: string | null | undefined): FormValues {
|
|
39
39
|
const behavior = item?.behavior ?? defaults
|
|
40
40
|
return {
|
|
41
41
|
value: item?.key ?? '', label: item?.label ?? '', icon: item?.icon ?? '', color: item?.color ?? '',
|
|
42
42
|
order: behavior.order, baseKind: behavior.baseKind, selectable: behavior.selectable,
|
|
43
|
-
...behavior.fields, customFieldsetIds: [...behavior.customFieldsetIds], updatedAt:
|
|
43
|
+
...behavior.fields, customFieldsetIds: [...behavior.customFieldsetIds], updatedAt: version ?? undefined,
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -51,6 +51,7 @@ export function ActivityTypeEditor({ title, description }: { title: string; desc
|
|
|
51
51
|
const [items, setItems] = React.useState<ScopedCalendarEventType[]>([])
|
|
52
52
|
const [rows, setRows] = React.useState<DictionaryRow[]>([])
|
|
53
53
|
const [selected, setSelected] = React.useState<ScopedCalendarEventType | null | undefined>(undefined)
|
|
54
|
+
const [selectedVersion, setSelectedVersion] = React.useState<string | null | undefined>(undefined)
|
|
54
55
|
const [fieldsets, setFieldsets] = React.useState<Fieldset[]>([])
|
|
55
56
|
const [fieldsetsStatus, setFieldsetsStatus] = React.useState<'loading' | 'ready' | 'error'>('loading')
|
|
56
57
|
const [fieldsetAttempt, setFieldsetAttempt] = React.useState(0)
|
|
@@ -103,6 +104,10 @@ export function ActivityTypeEditor({ title, description }: { title: string; desc
|
|
|
103
104
|
}, [selected, fieldsetAttempt])
|
|
104
105
|
|
|
105
106
|
const localRow = (key: string) => rows.find((row) => row.value.toLowerCase() === key && !row.isInherited)
|
|
107
|
+
const openEditor = (item: ScopedCalendarEventType | null) => {
|
|
108
|
+
setSelectedVersion(item ? localRow(item.key)?.updatedAt ?? item.updatedAt : undefined)
|
|
109
|
+
setSelected(item)
|
|
110
|
+
}
|
|
106
111
|
const remove = async (item: ScopedCalendarEventType) => {
|
|
107
112
|
const row = localRow(item.key)
|
|
108
113
|
if (!row) return
|
|
@@ -157,6 +162,7 @@ export function ActivityTypeEditor({ title, description }: { title: string; desc
|
|
|
157
162
|
{ id: 'behavior', title: t('customers.config.activityTypes.behavior', 'Form behavior'), fields: ['baseKind', 'selectable', 'endTime', 'allDay', 'recurrence', 'location', 'people', 'priority', 'resources'] },
|
|
158
163
|
...(fieldsets.length || selected?.behavior.customFieldsetIds.length ? [{ id: 'fieldsets', fields: ['customFieldsetIds'] }] : []),
|
|
159
164
|
]
|
|
165
|
+
const formInitialValues = React.useMemo(() => initialValues(selected ?? null, selectedVersion), [selected, selectedVersion])
|
|
160
166
|
const save = async (values: FormValues) => {
|
|
161
167
|
const key = String(values.value ?? '').trim()
|
|
162
168
|
if (!calendarEventTypeKeySchema.safeParse(key).success) throw createCrudFormError(t('customers.config.activityTypes.invalidKey', 'Use a lowercase key with letters, numbers, hyphens, or underscores.'), { value: t('customers.config.activityTypes.invalidKey', 'Use a lowercase key with letters, numbers, hyphens, or underscores.') })
|
|
@@ -206,11 +212,11 @@ export function ActivityTypeEditor({ title, description }: { title: string; desc
|
|
|
206
212
|
{status === 'error' ? <div className="space-y-3"><ErrorMessage label={t('customers.config.activityTypes.loadFailed', 'Failed to load activity types.')} /><Button type="button" onClick={() => { void load() }}>{t('customers.config.activityTypes.retry', 'Retry')}</Button></div> :
|
|
207
213
|
<DataTable<ScopedCalendarEventType> embedded columns={columns} data={items} isLoading={status === 'loading'}
|
|
208
214
|
title={title} titleHeadingLevel={2} emptyState={t('customers.config.activityTypes.empty', 'No activity types available.')}
|
|
209
|
-
actions={<Button type="button" size="sm" onClick={() =>
|
|
215
|
+
actions={<Button type="button" size="sm" onClick={() => openEditor(null)}>{t('customers.config.activityTypes.new', 'New activity type')}</Button>}
|
|
210
216
|
refreshButton={{ label: t('customers.config.activityTypes.refresh', 'Refresh'), onRefresh: load, isRefreshing: status === 'loading' }}
|
|
211
217
|
rowActions={(item) => {
|
|
212
218
|
const actions: RowActionItem[] = [{ id: 'edit', label: item.adminConfigurable
|
|
213
|
-
? t('customers.config.activityTypes.configure', 'Configure') : t('customers.config.activityTypes.view', 'View'), onSelect: () =>
|
|
219
|
+
? t('customers.config.activityTypes.configure', 'Configure') : t('customers.config.activityTypes.view', 'View'), onSelect: () => openEditor(item) }]
|
|
214
220
|
if (localRow(item.key)) actions.push({ id: 'delete', label: item.source === 'dictionary'
|
|
215
221
|
? t('customers.config.activityTypes.delete', 'Delete') : t('customers.config.activityTypes.reset', 'Reset override'),
|
|
216
222
|
destructive: true, onSelect: () => { void remove(item) } })
|
|
@@ -230,7 +236,7 @@ export function ActivityTypeEditor({ title, description }: { title: string; desc
|
|
|
230
236
|
{fieldsetsStatus === 'ready' && fieldsets.length === 0 ? <p className="text-sm text-muted-foreground">{t('customers.config.activityTypes.noFieldsets', 'No custom-field fieldsets are defined yet.')}</p> : null}
|
|
231
237
|
{selected !== undefined && fieldsetsStatus === 'ready' ? <CrudForm<FormValues> key={selected?.key ?? 'new'} embedded
|
|
232
238
|
readOnly={selected?.adminConfigurable === false} fields={fields} groups={groups}
|
|
233
|
-
initialValues={
|
|
239
|
+
initialValues={formInitialValues} onSubmit={save} submitLabel={t('customers.config.activityTypes.save', 'Save')}
|
|
234
240
|
extraActions={<Button type="button" variant="outline" onClick={() => setSelected(undefined)}>{t('customers.config.dictionaries.dialog.cancel', 'Cancel')}</Button>} /> : null}
|
|
235
241
|
</DialogContent>
|
|
236
242
|
</Dialog>
|