@endora-commerce/mod-settings 0.100.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.
Files changed (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +58 -0
  3. package/dist/admin/api/settings-client.d.ts +47 -0
  4. package/dist/admin/api/settings-client.d.ts.map +1 -0
  5. package/dist/admin/api/settings-client.js +41 -0
  6. package/dist/admin/api/settings-client.js.map +1 -0
  7. package/dist/admin/components/ActivationPointerRow.d.ts +21 -0
  8. package/dist/admin/components/ActivationPointerRow.d.ts.map +1 -0
  9. package/dist/admin/components/ActivationPointerRow.js +28 -0
  10. package/dist/admin/components/ActivationPointerRow.js.map +1 -0
  11. package/dist/admin/components/AssetIdSettingInput.d.ts +12 -0
  12. package/dist/admin/components/AssetIdSettingInput.d.ts.map +1 -0
  13. package/dist/admin/components/AssetIdSettingInput.js +10 -0
  14. package/dist/admin/components/AssetIdSettingInput.js.map +1 -0
  15. package/dist/admin/components/ConfigurationReferenceInput.d.ts +39 -0
  16. package/dist/admin/components/ConfigurationReferenceInput.d.ts.map +1 -0
  17. package/dist/admin/components/ConfigurationReferenceInput.js +74 -0
  18. package/dist/admin/components/ConfigurationReferenceInput.js.map +1 -0
  19. package/dist/admin/components/ConflictBanner.d.ts +13 -0
  20. package/dist/admin/components/ConflictBanner.d.ts.map +1 -0
  21. package/dist/admin/components/ConflictBanner.js +12 -0
  22. package/dist/admin/components/ConflictBanner.js.map +1 -0
  23. package/dist/admin/components/ImageSettingInput.d.ts +34 -0
  24. package/dist/admin/components/ImageSettingInput.d.ts.map +1 -0
  25. package/dist/admin/components/ImageSettingInput.js +36 -0
  26. package/dist/admin/components/ImageSettingInput.js.map +1 -0
  27. package/dist/admin/components/QuoteRequestsSettingsTab.d.ts +3 -0
  28. package/dist/admin/components/QuoteRequestsSettingsTab.d.ts.map +1 -0
  29. package/dist/admin/components/QuoteRequestsSettingsTab.js +69 -0
  30. package/dist/admin/components/QuoteRequestsSettingsTab.js.map +1 -0
  31. package/dist/admin/components/SellerCompanyDataInput.d.ts +22 -0
  32. package/dist/admin/components/SellerCompanyDataInput.d.ts.map +1 -0
  33. package/dist/admin/components/SellerCompanyDataInput.js +53 -0
  34. package/dist/admin/components/SellerCompanyDataInput.js.map +1 -0
  35. package/dist/admin/components/SettingRowEditor.d.ts +55 -0
  36. package/dist/admin/components/SettingRowEditor.d.ts.map +1 -0
  37. package/dist/admin/components/SettingRowEditor.js +160 -0
  38. package/dist/admin/components/SettingRowEditor.js.map +1 -0
  39. package/dist/admin/index.d.ts +39 -0
  40. package/dist/admin/index.d.ts.map +1 -0
  41. package/dist/admin/index.js +87 -0
  42. package/dist/admin/index.js.map +1 -0
  43. package/dist/admin/pages/CachePage.d.ts +14 -0
  44. package/dist/admin/pages/CachePage.d.ts.map +1 -0
  45. package/dist/admin/pages/CachePage.js +124 -0
  46. package/dist/admin/pages/CachePage.js.map +1 -0
  47. package/dist/admin/pages/GroupsPage.d.ts +17 -0
  48. package/dist/admin/pages/GroupsPage.d.ts.map +1 -0
  49. package/dist/admin/pages/GroupsPage.js +84 -0
  50. package/dist/admin/pages/GroupsPage.js.map +1 -0
  51. package/dist/admin/pages/SettingsPage.d.ts +20 -0
  52. package/dist/admin/pages/SettingsPage.d.ts.map +1 -0
  53. package/dist/admin/pages/SettingsPage.js +453 -0
  54. package/dist/admin/pages/SettingsPage.js.map +1 -0
  55. package/dist/backend/cli/cache-clear.d.ts +23 -0
  56. package/dist/backend/cli/cache-clear.d.ts.map +1 -0
  57. package/dist/backend/cli/cache-clear.js +37 -0
  58. package/dist/backend/cli/cache-clear.js.map +1 -0
  59. package/dist/backend/index.d.ts +100 -0
  60. package/dist/backend/index.d.ts.map +1 -0
  61. package/dist/backend/index.js +125 -0
  62. package/dist/backend/index.js.map +1 -0
  63. package/dist/backend/routes.admin.d.ts +308 -0
  64. package/dist/backend/routes.admin.d.ts.map +1 -0
  65. package/dist/backend/routes.admin.js +188 -0
  66. package/dist/backend/routes.admin.js.map +1 -0
  67. package/dist/backend/routes.cache.d.ts +20 -0
  68. package/dist/backend/routes.cache.d.ts.map +1 -0
  69. package/dist/backend/routes.cache.js +22 -0
  70. package/dist/backend/routes.cache.js.map +1 -0
  71. package/dist/backend/routes.homepage.d.ts +15 -0
  72. package/dist/backend/routes.homepage.d.ts.map +1 -0
  73. package/dist/backend/routes.homepage.js +20 -0
  74. package/dist/backend/routes.homepage.js.map +1 -0
  75. package/dist/backend/routes.product-card-buttons.d.ts +15 -0
  76. package/dist/backend/routes.product-card-buttons.d.ts.map +1 -0
  77. package/dist/backend/routes.product-card-buttons.js +21 -0
  78. package/dist/backend/routes.product-card-buttons.js.map +1 -0
  79. package/dist/backend/routes.speculation-rules.d.ts +16 -0
  80. package/dist/backend/routes.speculation-rules.d.ts.map +1 -0
  81. package/dist/backend/routes.speculation-rules.js +21 -0
  82. package/dist/backend/routes.speculation-rules.js.map +1 -0
  83. package/dist/backend/routes.storefront.d.ts +15 -0
  84. package/dist/backend/routes.storefront.d.ts.map +1 -0
  85. package/dist/backend/routes.storefront.js +20 -0
  86. package/dist/backend/routes.storefront.js.map +1 -0
  87. package/dist/backend/services/cache-admin.service.d.ts +83 -0
  88. package/dist/backend/services/cache-admin.service.d.ts.map +1 -0
  89. package/dist/backend/services/cache-admin.service.js +148 -0
  90. package/dist/backend/services/cache-admin.service.js.map +1 -0
  91. package/dist/backend/services/homepage-resolver.d.ts +25 -0
  92. package/dist/backend/services/homepage-resolver.d.ts.map +1 -0
  93. package/dist/backend/services/homepage-resolver.js +31 -0
  94. package/dist/backend/services/homepage-resolver.js.map +1 -0
  95. package/dist/backend/services/product-card-buttons-resolver.d.ts +25 -0
  96. package/dist/backend/services/product-card-buttons-resolver.d.ts.map +1 -0
  97. package/dist/backend/services/product-card-buttons-resolver.js +37 -0
  98. package/dist/backend/services/product-card-buttons-resolver.js.map +1 -0
  99. package/dist/backend/services/registered-settings-manifests.d.ts +45 -0
  100. package/dist/backend/services/registered-settings-manifests.d.ts.map +1 -0
  101. package/dist/backend/services/registered-settings-manifests.js +55 -0
  102. package/dist/backend/services/registered-settings-manifests.js.map +1 -0
  103. package/dist/backend/services/setting-write-validators.d.ts +43 -0
  104. package/dist/backend/services/setting-write-validators.d.ts.map +1 -0
  105. package/dist/backend/services/setting-write-validators.js +43 -0
  106. package/dist/backend/services/setting-write-validators.js.map +1 -0
  107. package/dist/backend/services/settings-admin.service.d.ts +206 -0
  108. package/dist/backend/services/settings-admin.service.d.ts.map +1 -0
  109. package/dist/backend/services/settings-admin.service.js +642 -0
  110. package/dist/backend/services/settings-admin.service.js.map +1 -0
  111. package/dist/backend/services/shop-info-resolver.d.ts +15 -0
  112. package/dist/backend/services/shop-info-resolver.d.ts.map +1 -0
  113. package/dist/backend/services/shop-info-resolver.js +44 -0
  114. package/dist/backend/services/shop-info-resolver.js.map +1 -0
  115. package/dist/backend/services/speculation-rules-resolver.d.ts +28 -0
  116. package/dist/backend/services/speculation-rules-resolver.d.ts.map +1 -0
  117. package/dist/backend/services/speculation-rules-resolver.js +39 -0
  118. package/dist/backend/services/speculation-rules-resolver.js.map +1 -0
  119. package/dist/manifest.d.ts +194 -0
  120. package/dist/manifest.d.ts.map +1 -0
  121. package/dist/manifest.js +379 -0
  122. package/dist/manifest.js.map +1 -0
  123. package/docs/settings/index.md +171 -0
  124. package/i18n/en.json +167 -0
  125. package/i18n/pl.json +167 -0
  126. package/package.json +96 -0
  127. package/tailwind.css +14 -0
@@ -0,0 +1,17 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * Settings groups page — feature 004 / US2.
4
+ *
5
+ * Manage logical sections used to organise settings in the Admin UI.
6
+ * `general` is system-protected: the server refuses deletion (T032 contract).
7
+ * Deleting any other group reassigns its settings to `general` and preserves
8
+ * their per-channel values (T033 integration).
9
+ */
10
+ export declare function GroupsPage(): ReactNode;
11
+ /**
12
+ * The registry loads a route component through a dynamic-import factory and
13
+ * reads its default export (feature 091, FR-013). The named export stays: it is
14
+ * the spelling this module's own code and its tests use.
15
+ */
16
+ export default GroupsPage;
17
+ //# sourceMappingURL=GroupsPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GroupsPage.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/GroupsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAKf;;;;;;;GAOG;AACH,wBAAgB,UAAU,IAAI,SAAS,CA2JtC;AAED;;;;GAIG;AACH,eAAe,UAAU,CAAC"}
@@ -0,0 +1,84 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState, } from 'react';
3
+ import { ApiError } from '@endora-commerce/admin-kit/lib';
4
+ import { Alert, AlertDescription, Button, Card, CardContent, CardHeader, CardTitle, Input, PageHeader, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@endora-commerce/admin-kit/ui';
5
+ import { settingsClient } from '../api/settings-client.js';
6
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
7
+ /**
8
+ * Settings groups page — feature 004 / US2.
9
+ *
10
+ * Manage logical sections used to organise settings in the Admin UI.
11
+ * `general` is system-protected: the server refuses deletion (T032 contract).
12
+ * Deleting any other group reassigns its settings to `general` and preserves
13
+ * their per-channel values (T033 integration).
14
+ */
15
+ export function GroupsPage() {
16
+ const t = useTranslation('settings');
17
+ const [rows, setRows] = useState([]);
18
+ const [loading, setLoading] = useState(true);
19
+ const [error, setError] = useState(null);
20
+ const [draftCode, setDraftCode] = useState('');
21
+ const [draftName, setDraftName] = useState('');
22
+ const refresh = useCallback(async () => {
23
+ setLoading(true);
24
+ setError(null);
25
+ try {
26
+ const res = await settingsClient.listGroupsOnly();
27
+ setRows(res.groups);
28
+ }
29
+ catch (err) {
30
+ setError(err instanceof ApiError ? err.envelope.error.message : 'Failed to load groups.');
31
+ }
32
+ finally {
33
+ setLoading(false);
34
+ }
35
+ }, []);
36
+ useEffect(() => {
37
+ void refresh();
38
+ }, [refresh]);
39
+ const onCreate = useCallback(async (e) => {
40
+ e.preventDefault();
41
+ if (!draftCode.trim() || !draftName.trim())
42
+ return;
43
+ try {
44
+ await settingsClient.createGroup({ code: draftCode, name: draftName });
45
+ setDraftCode('');
46
+ setDraftName('');
47
+ await refresh();
48
+ }
49
+ catch (err) {
50
+ setError(err instanceof ApiError ? err.envelope.error.message : 'Create failed.');
51
+ }
52
+ }, [draftCode, draftName, refresh]);
53
+ const onRename = useCallback(async (code) => {
54
+ const name = prompt(`Rename group "${code}" to:`);
55
+ if (!name || !name.trim())
56
+ return;
57
+ try {
58
+ await settingsClient.updateGroup(code, { name: name.trim() });
59
+ await refresh();
60
+ }
61
+ catch (err) {
62
+ setError(err instanceof ApiError ? err.envelope.error.message : 'Rename failed.');
63
+ }
64
+ }, [refresh]);
65
+ const onDelete = useCallback(async (code) => {
66
+ if (!confirm(`Delete group "${code}"? Its settings will be reassigned to "general"; their values are preserved.`))
67
+ return;
68
+ try {
69
+ await settingsClient.deleteGroup(code);
70
+ await refresh();
71
+ }
72
+ catch (err) {
73
+ setError(err instanceof ApiError ? err.envelope.error.message : 'Delete failed.');
74
+ }
75
+ }, [refresh]);
76
+ return (_jsxs(_Fragment, { children: [_jsx(PageHeader, { title: t('groups.page.title'), description: t('groups.page.description') }), error && (_jsx(Alert, { variant: "destructive", className: "mb-4", children: _jsx(AlertDescription, { children: error }) })), _jsxs(Card, { className: "mb-4", children: [_jsx(CardHeader, { children: _jsx(CardTitle, { className: "text-base", children: t('groups.newGroup.title') }) }), _jsx(CardContent, { children: _jsxs("form", { className: "grid gap-3 md:grid-cols-[1fr_2fr_auto]", onSubmit: onCreate, children: [_jsx(Input, { placeholder: t('groups.newGroup.codePlaceholder'), value: draftCode, onChange: (e) => setDraftCode(e.target.value) }), _jsx(Input, { placeholder: t('groups.newGroup.namePlaceholder'), value: draftName, onChange: (e) => setDraftName(e.target.value) }), _jsx(Button, { type: "submit", children: t('groups.newGroup.create') })] }) })] }), _jsx(Card, { children: _jsx(CardContent, { className: "pt-6", children: loading ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('groups.loading') })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: t('groups.column.code') }), _jsx(TableHead, { children: t('groups.column.name') }), _jsx(TableHead, { children: t('groups.column.ownerModule') }), _jsx(TableHead, { children: t('groups.column.settings') }), _jsx(TableHead, { className: "w-44 text-right", children: t('groups.column.actions') })] }) }), _jsx(TableBody, { children: rows.map((g) => (_jsxs(TableRow, { children: [_jsx(TableCell, { className: "font-mono text-xs", children: g.code }), _jsx(TableCell, { children: g.name }), _jsx(TableCell, { className: "text-xs", children: g.ownerModule }), _jsx(TableCell, { children: g.settingCount }), _jsxs(TableCell, { className: "text-right", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => void onRename(g.code), disabled: g.isSystemProtected, children: t('groups.action.rename') }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => void onDelete(g.code), disabled: g.isSystemProtected, children: t('groups.action.delete') })] })] }, g.code))) })] })) }) })] }));
77
+ }
78
+ /**
79
+ * The registry loads a route component through a dynamic-import factory and
80
+ * reads its default export (feature 091, FR-013). The named export stays: it is
81
+ * the spelling this module's own code and its tests use.
82
+ */
83
+ export default GroupsPage;
84
+ //# sourceMappingURL=GroupsPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GroupsPage.js","sourceRoot":"","sources":["../../../src/admin/pages/GroupsPage.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * Settings page — feature 004 / US2.
4
+ *
5
+ * The page is driven by a single "Editing for" channel context picked at the
6
+ * top: `null` = All channels (default), otherwise a specific sales-channel
7
+ * code. Every row's value input reflects the value for that context (the
8
+ * channel's override, or the default when none exists). Save sends the
9
+ * batch as either `scope: 'all'` or `scope: 'subset', salesChannelCodes: […]`
10
+ * depending on the picker. Edits accumulate in `drafts` and a sticky bottom
11
+ * bar flushes them all at once.
12
+ */
13
+ export declare function SettingsPage(): ReactNode;
14
+ /**
15
+ * The registry loads a route component through a dynamic-import factory and
16
+ * reads its default export (feature 091, FR-013). The named export stays: it is
17
+ * the spelling this module's own code and its tests use.
18
+ */
19
+ export default SettingsPage;
20
+ //# sourceMappingURL=SettingsPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettingsPage.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/SettingsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AA0Cf;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAwgBxC;AA4GD;;;;GAIG;AACH,eAAe,YAAY,CAAC"}
@@ -0,0 +1,453 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
3
+ import { ChevronDown, ChevronRight, Search } from 'lucide-react';
4
+ import { apiClient, ApiError, cn, normalize } from '@endora-commerce/admin-kit/lib';
5
+ import { Alert, AlertDescription, Button, Card, CardContent, CardHeader, CardTitle, Input, Label, PageHeader, Select } from '@endora-commerce/admin-kit/ui';
6
+ import { settingsClient } from '../api/settings-client.js';
7
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
8
+ import { ConflictBanner } from '../components/ConflictBanner.js';
9
+ import { ActivationPointerRow } from '../components/ActivationPointerRow.js';
10
+ import { SettingRowEditor, computeVersion, deriveDisplayValue, isDraftDirty, parseValue, } from '../components/SettingRowEditor.js';
11
+ /**
12
+ * List sales channels (feature 091, P6).
13
+ *
14
+ * The request is built here rather than through `sales_channels`' own admin
15
+ * API client: that client is another module's **code**, which is what the
16
+ * cross-module ledger recorded, while `/api/v1/admin/sales-channels` and
17
+ * `SalesChannelListResponse` are an HTTP path and a
18
+ * `@endora-commerce/contracts` type that both sides already compile. That is
19
+ * the exit P2 established and `admin-kit-surface.md` R6 records — one `GET`
20
+ * out of that client's ten methods, and no dependency on the owner's code.
21
+ */
22
+ function listSalesChannels(activeOnly, pageSize) {
23
+ const qs = new URLSearchParams();
24
+ qs.set('activeOnly', String(activeOnly));
25
+ qs.set('pageSize', String(pageSize));
26
+ return apiClient.get(`/api/v1/admin/sales-channels?${qs.toString()}`);
27
+ }
28
+ /**
29
+ * Settings page — feature 004 / US2.
30
+ *
31
+ * The page is driven by a single "Editing for" channel context picked at the
32
+ * top: `null` = All channels (default), otherwise a specific sales-channel
33
+ * code. Every row's value input reflects the value for that context (the
34
+ * channel's override, or the default when none exists). Save sends the
35
+ * batch as either `scope: 'all'` or `scope: 'subset', salesChannelCodes: […]`
36
+ * depending on the picker. Edits accumulate in `drafts` and a sticky bottom
37
+ * bar flushes them all at once.
38
+ */
39
+ export function SettingsPage() {
40
+ const t = useTranslation('settings');
41
+ const [groups, setGroups] = useState([]);
42
+ const [allChannels, setAllChannels] = useState([]);
43
+ const [loading, setLoading] = useState(true);
44
+ const [error, setError] = useState(null);
45
+ const [info, setInfo] = useState(null);
46
+ const [conflicts, setConflicts] = useState({});
47
+ const [saving, setSaving] = useState(false);
48
+ const [resettingCode, setResettingCode] = useState(null);
49
+ const [search, setSearch] = useState('');
50
+ const searchRef = useRef(null);
51
+ const [collapsed, setCollapsed] = useState({});
52
+ const [copiedCode, setCopiedCode] = useState(null);
53
+ const [drafts, setDrafts] = useState({});
54
+ const [channelContext, setChannelContext] = useState(null);
55
+ const refresh = useCallback(async (contextOverride) => {
56
+ const contextForRefresh = contextOverride === undefined ? channelContext : contextOverride;
57
+ setLoading(true);
58
+ setError(null);
59
+ try {
60
+ const list = await settingsClient.list();
61
+ setGroups(list.groups);
62
+ setDrafts((prev) => mergeDrafts(prev, list.groups, contextForRefresh));
63
+ // Fetch sales channels separately so a permission/connectivity issue
64
+ // here surfaces in the UI instead of silently emptying the dropdown.
65
+ try {
66
+ const channels = await listSalesChannels(false, 100);
67
+ setAllChannels(channels.items);
68
+ }
69
+ catch (err) {
70
+ setAllChannels([]);
71
+ setError(err instanceof ApiError
72
+ ? `Failed to load sales channels: ${err.envelope.error.message}`
73
+ : 'Failed to load sales channels.');
74
+ }
75
+ }
76
+ catch (err) {
77
+ setError(err instanceof ApiError ? err.envelope.error.message : 'Failed to load settings.');
78
+ }
79
+ finally {
80
+ setLoading(false);
81
+ }
82
+ }, [channelContext]);
83
+ useEffect(() => {
84
+ void refresh();
85
+ // We intentionally only refresh on mount; switchChannelContext drives
86
+ // subsequent refreshes when the context changes.
87
+ // eslint-disable-next-line react-hooks/exhaustive-deps
88
+ }, []);
89
+ // Ctrl/⌘+Shift+K jumps to the settings filter from anywhere on the page —
90
+ // the settings list is long enough that reaching for the mouse is the slow
91
+ // path. Shift distinguishes it from the global ⌘K palette, which skips the
92
+ // shifted chord (see AppShell's keydown handler).
93
+ useEffect(() => {
94
+ const onKey = (e) => {
95
+ if (!(e.metaKey || e.ctrlKey) || !e.shiftKey)
96
+ return;
97
+ if (e.key.toLowerCase() !== 'k')
98
+ return;
99
+ e.preventDefault();
100
+ const input = searchRef.current;
101
+ if (!input)
102
+ return;
103
+ input.focus();
104
+ // Select what's already typed so the next keystroke replaces the
105
+ // previous query instead of appending to it.
106
+ input.select();
107
+ };
108
+ window.addEventListener('keydown', onKey);
109
+ return () => window.removeEventListener('keydown', onKey);
110
+ }, []);
111
+ const filteredGroups = useMemo(() => filterGroupsForContext(groups, search, channelContext), [groups, search, channelContext]);
112
+ // `/settings?group=<code>` scrolls to that group and expands it — module
113
+ // pages link here to point an operator at their own settings (e.g. the KSeF
114
+ // page's "Open module settings"). Runs once the groups have rendered; an
115
+ // unknown code is a no-op rather than an error, since the group may belong
116
+ // to a module that is currently disabled.
117
+ const requestedGroup = new URLSearchParams(location.search).get('group');
118
+ useEffect(() => {
119
+ if (!requestedGroup || loading)
120
+ return;
121
+ const card = document.getElementById(`settings-group-${requestedGroup}`);
122
+ if (!card)
123
+ return;
124
+ setCollapsed((prev) => ({ ...prev, [requestedGroup]: false }));
125
+ card.scrollIntoView({ behavior: 'smooth', block: 'start' });
126
+ }, [requestedGroup, loading]);
127
+ const channelOptions = useMemo(() => {
128
+ const byCode = new Map();
129
+ for (const c of allChannels) {
130
+ byCode.set(c.code, { code: c.code, label: channelLabel(c) });
131
+ }
132
+ for (const g of groups) {
133
+ for (const c of g.salesChannelCodes) {
134
+ if (!byCode.has(c))
135
+ byCode.set(c, { code: c, label: c });
136
+ }
137
+ for (const s of g.settings) {
138
+ for (const c of s.salesChannelCodes) {
139
+ if (!byCode.has(c))
140
+ byCode.set(c, { code: c, label: c });
141
+ }
142
+ for (const v of s.valuesByChannel) {
143
+ if (!byCode.has(v.salesChannelCode)) {
144
+ byCode.set(v.salesChannelCode, { code: v.salesChannelCode, label: v.salesChannelCode });
145
+ }
146
+ }
147
+ }
148
+ }
149
+ return Array.from(byCode.values()).sort((a, b) => a.code.localeCompare(b.code));
150
+ }, [allChannels, groups]);
151
+ const allCollapsed = useMemo(() => filteredGroups.length > 0 && filteredGroups.every((g) => collapsed[g.code]), [collapsed, filteredGroups]);
152
+ const toggleGroup = (code) => {
153
+ setCollapsed((prev) => ({ ...prev, [code]: !prev[code] }));
154
+ };
155
+ const toggleAll = () => {
156
+ const next = !allCollapsed;
157
+ setCollapsed((prev) => {
158
+ const out = { ...prev };
159
+ for (const g of filteredGroups)
160
+ out[g.code] = next;
161
+ return out;
162
+ });
163
+ };
164
+ const patchDraft = useCallback((code, patch) => {
165
+ setDrafts((prev) => {
166
+ const current = prev[code];
167
+ if (!current)
168
+ return prev;
169
+ return { ...prev, [code]: { ...current, ...patch } };
170
+ });
171
+ }, []);
172
+ const onCopyCode = useCallback(async (code) => {
173
+ try {
174
+ await navigator.clipboard.writeText(code);
175
+ setCopiedCode(code);
176
+ window.setTimeout(() => {
177
+ setCopiedCode((current) => (current === code ? null : current));
178
+ }, 1500);
179
+ }
180
+ catch {
181
+ setError('Failed to copy to clipboard.');
182
+ }
183
+ }, []);
184
+ const dirtyCountFor = useCallback((group) => {
185
+ let n = 0;
186
+ for (const s of group.settings) {
187
+ if (!isSaveable(s))
188
+ continue;
189
+ const d = drafts[s.code];
190
+ if (d && isDraftDirty(d))
191
+ n += 1;
192
+ }
193
+ return n;
194
+ }, [drafts]);
195
+ const allDirtySettings = useMemo(() => {
196
+ const out = [];
197
+ for (const g of groups) {
198
+ for (const s of g.settings) {
199
+ // Feature 073: a row belonging to a switched-off module, and a module's
200
+ // activation control, are both excluded from the batch — the first
201
+ // because the server refuses it, the second because it has its own
202
+ // audited endpoint. Counting them would put a "save 1 change" bar on
203
+ // screen for a write that can never happen.
204
+ if (!isSaveable(s))
205
+ continue;
206
+ const d = drafts[s.code];
207
+ if (d && isDraftDirty(d))
208
+ out.push(s);
209
+ }
210
+ }
211
+ return out;
212
+ }, [drafts, groups]);
213
+ const totalDirtyCount = allDirtySettings.length;
214
+ const discardAll = useCallback(() => {
215
+ setDrafts(() => {
216
+ const out = {};
217
+ for (const g of groups) {
218
+ for (const s of g.settings) {
219
+ out[s.code] = baselineDraft(s, channelContext);
220
+ }
221
+ }
222
+ return out;
223
+ });
224
+ setConflicts({});
225
+ }, [groups, channelContext]);
226
+ const switchChannelContext = useCallback((next) => {
227
+ if (next === channelContext)
228
+ return;
229
+ if (totalDirtyCount > 0) {
230
+ const ok = window.confirm(t('context.discardOnSwitch'));
231
+ if (!ok)
232
+ return;
233
+ }
234
+ setChannelContext(next);
235
+ setConflicts({});
236
+ // Re-baseline every draft for the new context.
237
+ setDrafts(() => {
238
+ const out = {};
239
+ for (const g of groups) {
240
+ for (const s of g.settings)
241
+ out[s.code] = baselineDraft(s, next);
242
+ }
243
+ return out;
244
+ });
245
+ }, [channelContext, groups, t, totalDirtyCount]);
246
+ const findSetting = useCallback((code) => {
247
+ for (const g of groups) {
248
+ for (const s of g.settings)
249
+ if (s.code === code)
250
+ return s;
251
+ }
252
+ return undefined;
253
+ }, [groups]);
254
+ const saveAll = useCallback(async () => {
255
+ if (allDirtySettings.length === 0)
256
+ return;
257
+ setSaving(true);
258
+ setError(null);
259
+ setInfo(null);
260
+ const newConflicts = {};
261
+ const savedCodes = new Set();
262
+ for (const s of allDirtySettings) {
263
+ const draft = drafts[s.code];
264
+ if (!draft)
265
+ continue;
266
+ try {
267
+ const value = parseValue(s.valueType, draft.text);
268
+ const expectedVersion = computeVersion(s);
269
+ if (channelContext === null) {
270
+ await settingsClient.setValue(s.code, {
271
+ scope: 'all',
272
+ value,
273
+ expectedVersion,
274
+ });
275
+ }
276
+ else {
277
+ await settingsClient.setValue(s.code, {
278
+ scope: 'subset',
279
+ salesChannelCodes: [channelContext],
280
+ value,
281
+ expectedVersion,
282
+ });
283
+ }
284
+ savedCodes.add(s.code);
285
+ }
286
+ catch (err) {
287
+ if (err instanceof ApiError && err.envelope.error.code === 'VERSION_CONFLICT') {
288
+ newConflicts[s.code] = err.envelope.error.message;
289
+ }
290
+ else {
291
+ newConflicts[s.code] =
292
+ err instanceof ApiError ? err.envelope.error.message : 'Save failed.';
293
+ }
294
+ }
295
+ }
296
+ if (savedCodes.size > 0) {
297
+ setDrafts((prev) => {
298
+ const out = { ...prev };
299
+ for (const code of savedCodes)
300
+ delete out[code];
301
+ return out;
302
+ });
303
+ }
304
+ setConflicts((prev) => ({ ...prev, ...newConflicts }));
305
+ if (savedCodes.size > 0) {
306
+ setInfo(t('editor.savedNotice', { count: savedCodes.size }));
307
+ }
308
+ await refresh();
309
+ setSaving(false);
310
+ }, [allDirtySettings, channelContext, drafts, refresh, t]);
311
+ const resetSetting = useCallback(async (code) => {
312
+ const setting = findSetting(code);
313
+ if (!setting)
314
+ return;
315
+ const isChannelMode = channelContext !== null;
316
+ const confirmMsg = isChannelMode
317
+ ? `Reset "${code}" override for channel "${channelContext}"?`
318
+ : `Reset all per-channel values for "${code}"?`;
319
+ if (!confirm(confirmMsg))
320
+ return;
321
+ setResettingCode(code);
322
+ setError(null);
323
+ try {
324
+ await settingsClient.resetValues(code, isChannelMode ? [channelContext] : undefined);
325
+ await refresh();
326
+ }
327
+ catch (err) {
328
+ setError(err instanceof ApiError ? err.envelope.error.message : 'Reset failed.');
329
+ }
330
+ finally {
331
+ setResettingCode(null);
332
+ }
333
+ }, [channelContext, findSetting, refresh]);
334
+ return (_jsxs(_Fragment, { children: [_jsx(PageHeader, { title: t('page.title'), description: t('page.description') }), error && (_jsx(Alert, { variant: "destructive", className: "mb-4", children: _jsx(AlertDescription, { children: error }) })), info && (_jsx(Alert, { className: "mb-4", children: _jsx(AlertDescription, { children: info }) })), _jsx(Card, { className: "mb-4", children: _jsxs(CardContent, { className: "flex flex-col gap-2 py-4 sm:flex-row sm:items-center sm:gap-4", children: [_jsxs(Label, { htmlFor: "settings-channel-context", className: "shrink-0 text-sm font-medium", children: [t('context.label'), ":"] }), _jsxs(Select, { id: "settings-channel-context", className: "sm:max-w-sm", value: channelContext ?? '', onChange: (e) => switchChannelContext(e.target.value === '' ? null : e.target.value), children: [_jsx("option", { value: "", children: t('context.allChannels') }), channelOptions.map((c) => (_jsx("option", { value: c.code, children: c.label }, c.code)))] })] }) }), _jsxs("div", { className: "mb-4 flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [_jsxs("div", { className: "relative w-full sm:max-w-sm", children: [_jsx(Search, { "aria-hidden": "true", className: "pointer-events-none absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { ref: searchRef, type: "search", value: search, onChange: (e) => setSearch(e.target.value), placeholder: t('search.placeholder'), "aria-keyshortcuts": "Control+Shift+K Meta+Shift+K", className: "pl-8 pr-16" }), _jsx("kbd", { "aria-hidden": "true", className: "pointer-events-none absolute right-2 top-1/2 hidden -translate-y-1/2 rounded border bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground sm:inline-block", children: t('search.shortcut') })] }), filteredGroups.length > 0 && (_jsx(Button, { variant: "outline", size: "sm", onClick: toggleAll, children: allCollapsed ? t('groups.expandAll') : t('groups.collapseAll') }))] }), _jsxs("div", { className: cn('space-y-4', totalDirtyCount > 0 && 'pb-24'), children: [loading && (_jsx("p", { className: "text-sm text-muted-foreground", children: t('state.loading') })), !loading && filteredGroups.length === 0 && search && (_jsx("p", { className: "text-sm text-muted-foreground", children: t('search.noResults') })), !loading && filteredGroups.length === 0 && !search && channelContext !== null && (_jsx("p", { className: "text-sm text-muted-foreground", children: t('context.empty') })), !loading &&
335
+ filteredGroups.map((group) => {
336
+ const isCollapsed = !!collapsed[group.code];
337
+ const dirtyCount = dirtyCountFor(group);
338
+ return (_jsxs(Card, { id: `settings-group-${group.code}`, children: [_jsx(CardHeader, { children: _jsxs("button", { type: "button", onClick: () => toggleGroup(group.code), className: "flex w-full items-center gap-2 text-left", "aria-expanded": !isCollapsed, children: [isCollapsed ? (_jsx(ChevronRight, { className: "h-4 w-4 text-muted-foreground" })) : (_jsx(ChevronDown, { className: "h-4 w-4 text-muted-foreground" })), _jsxs(CardTitle, { className: "flex items-center gap-2", children: [group.name, group.isSystemProtected && (_jsx("span", { className: "rounded bg-muted px-2 py-0.5 text-xs", children: "system" })), _jsxs("span", { className: "text-xs font-normal text-muted-foreground", children: ["(", group.settings.length, ")"] }), dirtyCount > 0 && (_jsx("span", { className: "rounded bg-amber-100 px-2 py-0.5 text-xs text-amber-900", children: t('actions.saveChanges', { count: dirtyCount }) }))] })] }) }), !isCollapsed && (_jsx(CardContent, { children: group.settings.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('groups.empty') })) : (_jsx("div", { className: "space-y-3", children: group.settings.map((s) => {
339
+ const draft = drafts[s.code] ?? baselineDraft(s, channelContext);
340
+ const conflict = conflicts[s.code];
341
+ return (_jsxs("div", { className: "space-y-2", children: [conflict && (_jsx(ConflictBanner, { message: conflict, onRefresh: () => {
342
+ setConflicts((prev) => {
343
+ const out = { ...prev };
344
+ delete out[s.code];
345
+ return out;
346
+ });
347
+ void refresh();
348
+ } })), s.activationControl === true ? (
349
+ // D-36a: the control itself lives on
350
+ // `/platform/modules`. What stays here is the
351
+ // row an operator looks for by name, pointing
352
+ // at the one surface that can flip it.
353
+ _jsx(ActivationPointerRow, { setting: s })) : (_jsx(SettingRowEditor, { setting: s, draft: draft, channelContext: channelContext, isCopied: copiedCode === s.code, resetting: resettingCode === s.code, readOnly: s.editable === false, onChange: (patch) => patchDraft(s.code, patch), onCopyCode: () => void onCopyCode(s.code), onReset: () => void resetSetting(s.code) }))] }, s.code));
354
+ }) })) }))] }, group.code));
355
+ })] }), totalDirtyCount > 0 && (_jsxs("div", { role: "region", "aria-label": t('actions.saveChanges', { count: totalDirtyCount }), className: "fixed inset-x-0 bottom-0 z-40 flex items-center justify-end gap-3 border-t bg-background/95 px-4 py-3 shadow-lg backdrop-blur sm:px-6 lg:px-8", children: [_jsx("span", { className: "mr-auto text-sm text-muted-foreground", children: channelContext !== null
356
+ ? `${t('context.channelOverride', { code: channelContext })} · ${t('actions.saveChanges', { count: totalDirtyCount })}`
357
+ : t('actions.saveChanges', { count: totalDirtyCount }) }), _jsx(Button, { variant: "outline", size: "sm", onClick: discardAll, disabled: saving, children: t('actions.discard') }), _jsx(Button, { size: "sm", onClick: () => void saveAll(), disabled: saving, children: saving
358
+ ? t('actions.saveAll') + '…'
359
+ : t('actions.saveChanges', { count: totalDirtyCount }) })] }))] }));
360
+ }
361
+ /**
362
+ * Feature 073 — can the generic batch save touch this row?
363
+ *
364
+ * Two rows it must not: one whose module is switched off (the server refuses
365
+ * it, FR-033) and a module's activation control (the audited Command owns it,
366
+ * FR-009). `editable`/`activationControl` are optional on the wire so an older
367
+ * backend keeps working; absent means "ordinary setting", which is the
368
+ * pre-073 behaviour.
369
+ */
370
+ function isSaveable(setting) {
371
+ return setting.editable !== false && setting.activationControl !== true;
372
+ }
373
+ function baselineDraft(setting, channelContext) {
374
+ const text = deriveDisplayValue(setting, channelContext);
375
+ return { text, initialText: text };
376
+ }
377
+ /**
378
+ * Re-baseline drafts against the current channel context after a refresh.
379
+ * Dirty drafts keep their `text` so unsaved edits aren't blown away; their
380
+ * `initialText` is rebound to whatever the server now reports for the active
381
+ * context.
382
+ */
383
+ function mergeDrafts(prev, groups, channelContext) {
384
+ const out = {};
385
+ for (const g of groups) {
386
+ for (const s of g.settings) {
387
+ const existing = prev[s.code];
388
+ const base = baselineDraft(s, channelContext);
389
+ if (existing && isDraftDirty(existing)) {
390
+ out[s.code] = {
391
+ ...existing,
392
+ initialText: base.initialText,
393
+ };
394
+ }
395
+ else {
396
+ out[s.code] = base;
397
+ }
398
+ }
399
+ }
400
+ return out;
401
+ }
402
+ function filterGroupsForContext(groups, search, channelContext) {
403
+ const q = normalize(search);
404
+ const out = [];
405
+ for (const g of groups) {
406
+ if (channelContext !== null &&
407
+ g.salesChannelCodes.length > 0 &&
408
+ !g.salesChannelCodes.includes(channelContext)) {
409
+ continue;
410
+ }
411
+ // A query may match the section (group) title itself — e.g. "assistant"
412
+ // matching "Prompt actions (AI assistant)". When it does, surface every
413
+ // channel-passing setting in the group rather than requiring a per-setting
414
+ // match.
415
+ const groupMatches = q !== '' && (normalize(g.name).includes(q) || normalize(g.code).includes(q));
416
+ const filtered = g.settings.filter((s) => {
417
+ if (channelContext !== null &&
418
+ s.salesChannelCodes.length > 0 &&
419
+ !s.salesChannelCodes.includes(channelContext)) {
420
+ return false;
421
+ }
422
+ if (groupMatches)
423
+ return true;
424
+ if (q && !settingMatches(s, q))
425
+ return false;
426
+ return true;
427
+ });
428
+ if (filtered.length === 0 && (q || channelContext !== null))
429
+ continue;
430
+ out.push({ ...g, settings: filtered });
431
+ }
432
+ return out;
433
+ }
434
+ function settingMatches(s, q) {
435
+ if (normalize(s.name).includes(q))
436
+ return true;
437
+ if (normalize(s.code).includes(q))
438
+ return true;
439
+ if (s.description && normalize(s.description).includes(q))
440
+ return true;
441
+ return false;
442
+ }
443
+ function channelLabel(channel) {
444
+ const name = channel.name['en-US'] ?? Object.values(channel.name)[0] ?? channel.code;
445
+ return `${name} (${channel.code})`;
446
+ }
447
+ /**
448
+ * The registry loads a route component through a dynamic-import factory and
449
+ * reads its default export (feature 091, FR-013). The named export stays: it is
450
+ * the spelling this module's own code and its tests use.
451
+ */
452
+ export default SettingsPage;
453
+ //# sourceMappingURL=SettingsPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettingsPage.js","sourceRoot":"","sources":["../../../src/admin/pages/SettingsPage.tsx"],"names":[],"mappings":"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"}