@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Endora sp. z o.o. and the Endora Commerce contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,58 @@
1
+ <!-- Generated by `pnpm --filter backend run manifests:generate`. Delete this line to take the file over; a README without it is never regenerated. -->
2
+
3
+ # @endora-commerce/mod-settings
4
+
5
+ Per-module setting registry, admin UI, and value resolver.
6
+
7
+ ## What this is
8
+
9
+ An **Endora Commerce module package**. Its module id is `settings` — the identity of record in the platform's registries, in its migrations and in its setting, permission and translation codes.
10
+
11
+ A module is not imported by application code. The platform discovers the extension packages an instance has installed, reads the manifest on the root subpath and composes the module from it, so installing this package and starting the instance is the whole integration.
12
+
13
+ ## Entry points
14
+
15
+ | Import | Contents |
16
+ | --- | --- |
17
+ | `@endora-commerce/mod-settings` | the module manifest — its id, version, dependencies, settings and activation |
18
+ | `@endora-commerce/mod-settings/admin` | the Admin UI contribution: the screens, navigation and palette actions it adds |
19
+ | `@endora-commerce/mod-settings/backend` | the composition root the platform calls, with the entities, services, routes and workers it registers |
20
+ | `@endora-commerce/mod-settings/tailwind.css` | the Tailwind source declaration for the admin code above |
21
+
22
+ ## Depends on
23
+
24
+ Everything below is a **peer** dependency, so the application resolves exactly one copy of each — two copies of a host or of React are a runtime failure rather than a type error. An entry marked *optional* is needed only by the layers that use it.
25
+
26
+ **Endora packages**
27
+
28
+ - `@endora-commerce/admin-kit` — *optional*
29
+ - `@endora-commerce/contracts`
30
+ - `@endora-commerce/mod-credentials` — *optional*
31
+ - `@endora-commerce/platform`
32
+
33
+ **Third-party**
34
+
35
+ - `@fastify/rate-limit` ^10
36
+ - `@mikro-orm/postgresql` ^6
37
+ - `fastify` ^5
38
+ - `ioredis` ^5
39
+ - `lucide-react` ^1 — *optional*
40
+ - `react` ^19 — *optional*
41
+ - `react-router-dom` ^7 — *optional*
42
+
43
+ ## What the tarball carries
44
+
45
+ - `dist/` — the compiled JavaScript and its type declarations
46
+ - `i18n/` — the translation bundles this package ships (`en`, `pl`), loaded by the platform
47
+ - `docs/` — the package’s own pages in the Endora Commerce documentation site
48
+ - `tailwind.css` — the Tailwind source declaration
49
+
50
+ ## Install
51
+
52
+ ```bash
53
+ pnpm add @endora-commerce/mod-settings
54
+ ```
55
+
56
+ ## Licence
57
+
58
+ MIT — the text is in `LICENSE`, beside this file.
@@ -0,0 +1,47 @@
1
+ import type { CacheNamespacesResponse, ClearCacheRequest, ClearCacheResult, SearchReindexResponse, SetValueRequest, SettingDto, SettingGroupDto } from '@endora-commerce/contracts';
2
+ /**
3
+ * Typed wrapper around `/api/v1/admin/settings/*`.
4
+ * Source-of-truth schemas live in `@endora-commerce/contracts`.
5
+ */
6
+ export interface ListGroupsResponse {
7
+ groups: SettingGroupDto[];
8
+ }
9
+ export interface GroupRow {
10
+ id: string;
11
+ code: string;
12
+ name: string;
13
+ isSystemProtected: boolean;
14
+ ownerModule: string;
15
+ salesChannelCodes: string[];
16
+ settingCount: number;
17
+ updatedAt: string;
18
+ }
19
+ export interface ListGroupsOnlyResponse {
20
+ groups: GroupRow[];
21
+ }
22
+ export declare const settingsClient: {
23
+ list(filter?: {
24
+ groupCode?: string;
25
+ }): Promise<ListGroupsResponse>;
26
+ getByCode(code: string): Promise<SettingDto>;
27
+ setValue(code: string, body: SetValueRequest & {
28
+ expectedVersion?: string;
29
+ }): Promise<SettingDto>;
30
+ resetValues(code: string, channelCodes?: string[]): Promise<SettingDto>;
31
+ listGroupsOnly(): Promise<ListGroupsOnlyResponse>;
32
+ createGroup(input: {
33
+ code: string;
34
+ name: string;
35
+ salesChannelCodes?: string[];
36
+ }): Promise<GroupRow>;
37
+ updateGroup(code: string, patch: {
38
+ name?: string;
39
+ salesChannelCodes?: string[];
40
+ expectedVersion?: string;
41
+ }): Promise<GroupRow>;
42
+ deleteGroup(code: string): Promise<void>;
43
+ listCacheNamespaces(): Promise<CacheNamespacesResponse>;
44
+ clearCache(body: ClearCacheRequest): Promise<ClearCacheResult>;
45
+ reindexSearch(): Promise<SearchReindexResponse>;
46
+ };
47
+ //# sourceMappingURL=settings-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-client.d.ts","sourceRoot":"","sources":["../../../src/admin/api/settings-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAEpC;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,QAAQ,EAAE,CAAC;CACpB;AAED,eAAO,MAAM,cAAc;kBACX;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC;oBAKlD,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;mBAI7B,MAAM,QAAQ,eAAe,GAAG;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;sBAO/E,MAAM,iBAAiB,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;sBASrD,OAAO,CAAC,sBAAsB,CAAC;uBAI9B;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC9B,GAAG,OAAO,CAAC,QAAQ,CAAC;sBAKb,MAAM,SACL;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/E,OAAO,CAAC,QAAQ,CAAC;sBAOF,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;2BAIjB,OAAO,CAAC,uBAAuB,CAAC;qBAItC,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;qBAI7C,OAAO,CAAC,qBAAqB,CAAC;CAGhD,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { apiClient } from '@endora-commerce/admin-kit/lib';
2
+ export const settingsClient = {
3
+ list(filter) {
4
+ const qs = filter?.groupCode ? `?groupCode=${encodeURIComponent(filter.groupCode)}` : '';
5
+ return apiClient.get(`/api/v1/admin/settings${qs}`);
6
+ },
7
+ getByCode(code) {
8
+ return apiClient.get(`/api/v1/admin/settings/${encodeURIComponent(code)}`);
9
+ },
10
+ setValue(code, body) {
11
+ return apiClient.put(`/api/v1/admin/settings/${encodeURIComponent(code)}/value`, body);
12
+ },
13
+ resetValues(code, channelCodes) {
14
+ const qs = channelCodes && channelCodes.length > 0
15
+ ? `?salesChannelCodes=${encodeURIComponent(channelCodes.join(','))}`
16
+ : '';
17
+ return apiClient.delete(`/api/v1/admin/settings/${encodeURIComponent(code)}/values${qs}`);
18
+ },
19
+ listGroupsOnly() {
20
+ return apiClient.get('/api/v1/admin/settings/groups');
21
+ },
22
+ createGroup(input) {
23
+ return apiClient.post('/api/v1/admin/settings/groups', input);
24
+ },
25
+ updateGroup(code, patch) {
26
+ return apiClient.patch(`/api/v1/admin/settings/groups/${encodeURIComponent(code)}`, patch);
27
+ },
28
+ deleteGroup(code) {
29
+ return apiClient.delete(`/api/v1/admin/settings/groups/${encodeURIComponent(code)}`);
30
+ },
31
+ listCacheNamespaces() {
32
+ return apiClient.get('/api/v1/admin/cache/namespaces');
33
+ },
34
+ clearCache(body) {
35
+ return apiClient.post('/api/v1/admin/cache/clear', body);
36
+ },
37
+ reindexSearch() {
38
+ return apiClient.post('/api/v1/admin/search/reindex', {});
39
+ },
40
+ };
41
+ //# sourceMappingURL=settings-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-client.js","sourceRoot":"","sources":["../../../src/admin/api/settings-client.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAyB3D,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,CAAC,MAA+B;QAClC,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,cAAc,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzF,OAAO,SAAS,CAAC,GAAG,CAAqB,yBAAyB,EAAE,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,OAAO,SAAS,CAAC,GAAG,CAAa,0BAA0B,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC;IAED,QAAQ,CAAC,IAAY,EAAE,IAAoD;QACzE,OAAO,SAAS,CAAC,GAAG,CAClB,0BAA0B,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAC1D,IAAI,CACL,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,IAAY,EAAE,YAAuB;QAC/C,MAAM,EAAE,GAAG,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC;YAChD,CAAC,CAAC,sBAAsB,kBAAkB,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE;YACpE,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,SAAS,CAAC,MAAM,CACrB,0BAA0B,kBAAkB,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CACjE,CAAC;IACJ,CAAC;IAED,cAAc;QACZ,OAAO,SAAS,CAAC,GAAG,CAAyB,+BAA+B,CAAC,CAAC;IAChF,CAAC;IAED,WAAW,CAAC,KAIX;QACC,OAAO,SAAS,CAAC,IAAI,CAAW,+BAA+B,EAAE,KAAK,CAAC,CAAC;IAC1E,CAAC;IAED,WAAW,CACT,IAAY,EACZ,KAAgF;QAEhF,OAAO,SAAS,CAAC,KAAK,CACpB,iCAAiC,kBAAkB,CAAC,IAAI,CAAC,EAAE,EAC3D,KAAK,CACN,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,IAAY;QACtB,OAAO,SAAS,CAAC,MAAM,CAAO,iCAAiC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7F,CAAC;IAED,mBAAmB;QACjB,OAAO,SAAS,CAAC,GAAG,CAA0B,gCAAgC,CAAC,CAAC;IAClF,CAAC;IAED,UAAU,CAAC,IAAuB;QAChC,OAAO,SAAS,CAAC,IAAI,CAAmB,2BAA2B,EAAE,IAAI,CAAC,CAAC;IAC7E,CAAC;IAED,aAAa;QACX,OAAO,SAAS,CAAC,IAAI,CAAwB,8BAA8B,EAAE,EAAE,CAAC,CAAC;IACnF,CAAC;CACF,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { SettingDto } from '@endora-commerce/contracts';
3
+ /**
4
+ * A module's activation setting, as the Settings screen shows it after D-36a.
5
+ *
6
+ * It is no longer a control here. The single control moved to
7
+ * `/platform/modules`, whose routes are kernel-resident, so that no module owns
8
+ * the surface that toggles modules — with the control on this screen, switching
9
+ * `settings` off took the control that would switch it back on with it.
10
+ *
11
+ * The row stays visible on purpose. An operator who knows a capability by the
12
+ * name of its setting still finds it where they expect, and is told where the
13
+ * switch went; deleting the row would make the relocation look like a loss.
14
+ * It renders read-only for the same reason the batch save skips it: the
15
+ * ordinary settings write path refuses activation codes outright, so a
16
+ * saveable-looking row could only ever fail.
17
+ */
18
+ export declare function ActivationPointerRow({ setting }: {
19
+ setting: SettingDto;
20
+ }): ReactNode;
21
+ //# sourceMappingURL=ActivationPointerRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActivationPointerRow.d.ts","sourceRoot":"","sources":["../../../src/admin/components/ActivationPointerRow.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAG7D;;;;;;;;;;;;;;GAcG;AAEH,wBAAgB,oBAAoB,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,UAAU,CAAA;CAAE,GAAG,SAAS,CAwBpF"}
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import {} from 'react';
3
+ import { Link } from 'react-router-dom';
4
+ import { ExternalLink } from 'lucide-react';
5
+ import { Badge } from '@endora-commerce/admin-kit/ui';
6
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
7
+ /**
8
+ * A module's activation setting, as the Settings screen shows it after D-36a.
9
+ *
10
+ * It is no longer a control here. The single control moved to
11
+ * `/platform/modules`, whose routes are kernel-resident, so that no module owns
12
+ * the surface that toggles modules — with the control on this screen, switching
13
+ * `settings` off took the control that would switch it back on with it.
14
+ *
15
+ * The row stays visible on purpose. An operator who knows a capability by the
16
+ * name of its setting still finds it where they expect, and is told where the
17
+ * switch went; deleting the row would make the relocation look like a loss.
18
+ * It renders read-only for the same reason the batch save skips it: the
19
+ * ordinary settings write path refuses activation codes outright, so a
20
+ * saveable-looking row could only ever fail.
21
+ */
22
+ export function ActivationPointerRow({ setting }) {
23
+ const t = useTranslation('settings');
24
+ // Presence is not read here on purpose: this row states where the switch is,
25
+ // not what position it is in. The screen that owns the switch shows that.
26
+ return (_jsxs("div", { className: "space-y-2 rounded-md border border-dashed px-4 py-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium", children: setting.name }), _jsx(Badge, { variant: "outline", className: "text-[10px] text-muted-foreground", children: t('activation.title') })] }), _jsx("p", { className: "text-xs text-muted-foreground", children: t('activation.managedOnPlatformScreen') }), _jsxs(Link, { to: "/platform/modules", className: "inline-flex items-center gap-1 text-xs font-medium text-primary hover:underline", children: [_jsx(ExternalLink, { className: "size-3", "aria-hidden": "true" }), t('activation.openPlatformScreen')] })] }));
27
+ }
28
+ //# sourceMappingURL=ActivationPointerRow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActivationPointerRow.js","sourceRoot":"","sources":["../../../src/admin/components/ActivationPointerRow.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE;;;;;;;;;;;;;;GAcG;AAEH,MAAM,UAAU,oBAAoB,CAAC,EAAE,OAAO,EAA2B;IACvE,MAAM,CAAC,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IACrC,6EAA6E;IAC7E,0EAA0E;IAC1E,OAAO,CACL,eAAK,SAAS,EAAC,qDAAqD,aAClE,eAAK,SAAS,EAAC,mCAAmC,aAChD,eAAM,SAAS,EAAC,qBAAqB,YAAE,OAAO,CAAC,IAAI,GAAQ,EAC3D,KAAC,KAAK,IAAC,OAAO,EAAC,SAAS,EAAC,SAAS,EAAC,mCAAmC,YACnE,CAAC,CAAC,kBAAkB,CAAC,GAChB,IACJ,EACN,YAAG,SAAS,EAAC,+BAA+B,YACzC,CAAC,CAAC,oCAAoC,CAAC,GACtC,EACJ,MAAC,IAAI,IACH,EAAE,EAAC,mBAAmB,EACtB,SAAS,EAAC,iFAAiF,aAE3F,KAAC,YAAY,IAAC,SAAS,EAAC,QAAQ,iBAAa,MAAM,GAAG,EACrD,CAAC,CAAC,+BAA+B,CAAC,IAC9B,IACH,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { ReactNode } from 'react';
2
+ interface Props {
3
+ value: string;
4
+ onChange: (next: string) => void;
5
+ }
6
+ /**
7
+ * Settings editor for string values that store an Assets Library UUID
8
+ * (convention: code ends with `_asset_id`).
9
+ */
10
+ export declare function AssetIdSettingInput({ value, onChange }: Props): ReactNode;
11
+ export {};
12
+ //# sourceMappingURL=AssetIdSettingInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetIdSettingInput.d.ts","sourceRoot":"","sources":["../../../src/admin/components/AssetIdSettingInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,GAAG,SAAS,CAUzE"}
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { AssetFieldPicker } from '@endora-commerce/admin-kit/components';
3
+ /**
4
+ * Settings editor for string values that store an Assets Library UUID
5
+ * (convention: code ends with `_asset_id`).
6
+ */
7
+ export function AssetIdSettingInput({ value, onChange }) {
8
+ return (_jsx(AssetFieldPicker, { value: value, onChange: onChange, acceptMimePrefix: "image/", allowUpload: true, placeholder: "Select an image from the Assets Library" }));
9
+ }
10
+ //# sourceMappingURL=AssetIdSettingInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetIdSettingInput.js","sourceRoot":"","sources":["../../../src/admin/components/AssetIdSettingInput.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAMzE;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAS;IAC5D,OAAO,CACL,KAAC,gBAAgB,IACf,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAC,QAAQ,EACzB,WAAW,QACX,WAAW,EAAC,yCAAyC,GACrD,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * Settings field editor for the `credential_ref` value type (feature 058 US2).
4
+ *
5
+ * Reads the setting's `configurationType`, loads the matching configurations,
6
+ * and renders a picker (value = configuration code) plus a preview button that
7
+ * opens the read-only `ConfigurationPreviewModal` (secrets masked). Modeled on
8
+ * `ImageSettingInput`.
9
+ *
10
+ * ## Two things batch 10 changed about it, and both are seam decisions
11
+ *
12
+ * **The preview button gates on `credentials`' presence** (Z12). A statically
13
+ * imported component is filtered by nothing, and `credentials` declares an
14
+ * activation control — so with the module switched off the modal would render
15
+ * over an API that answers 503 and a picker whose list is already empty. The
16
+ * predicate is the one every other admin surface uses; this is its fourth kind
17
+ * of caller. The gate is here rather than inside the modal because only the
18
+ * consumer knows what the absence should collapse: the button and nothing else,
19
+ * so the operator keeps the stored value and the field it sits in.
20
+ *
21
+ * **Its copy is this module's** (R-1 §9.2, one surface over). The button read
22
+ * `useTranslation('credentials')` for a single label — a module id written as a
23
+ * string in a file `credentials` does not own, which
24
+ * `backend/scripts/ledgers/foreign-module-ids.ts` recorded as its
25
+ * `module-namespace:credentials` entry. The string a settings field shows
26
+ * belongs in the settings bundle, so `editor.credentialRef.preview` is a key of
27
+ * this module's and the entry retires because the coupling is **gone**, not
28
+ * because this file left the walk the check reads.
29
+ */
30
+ interface Props {
31
+ /** The configuration type the reference is constrained to (e.g. `'llm'`). */
32
+ configurationType: string | null | undefined;
33
+ /** Current value — a configuration code (may be empty ⇒ not configured). */
34
+ value: string;
35
+ onChange: (next: string) => void;
36
+ }
37
+ export declare function ConfigurationReferenceInput({ configurationType, value, onChange, }: Props): ReactNode;
38
+ export {};
39
+ //# sourceMappingURL=ConfigurationReferenceInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigurationReferenceInput.d.ts","sourceRoot":"","sources":["../../../src/admin/components/ConfigurationReferenceInput.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAsD5E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,UAAU,KAAK;IACb,6EAA6E;IAC7E,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7C,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,wBAAgB,2BAA2B,CAAC,EAC1C,iBAAiB,EACjB,KAAK,EACL,QAAQ,GACT,EAAE,KAAK,GAAG,SAAS,CAgEnB"}
@@ -0,0 +1,74 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { lazy, Suspense, useEffect, useState } from 'react';
3
+ import { apiClient, useSurfaceVisibility } from '@endora-commerce/admin-kit/lib';
4
+ import { Button, Select } from '@endora-commerce/admin-kit/ui';
5
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
6
+ /**
7
+ * Loaded lazily, and that is a **build** decision rather than a performance one
8
+ * (`specs/110-instance-repository/` T138).
9
+ *
10
+ * `credentials` is an **optional** peer of this package — `manifests:generate`
11
+ * marks a peer optional when only a UI layer reaches it — so a client's instance
12
+ * that did not install `credentials` has no such package, and a *static* named
13
+ * import of one is a bundle that does not build. Measured on the acceptance
14
+ * criterion's own scaffolded instance: Vite binds an unresolved optional peer to
15
+ * an `__vite-optional-peer-dep:` stub, and a named import off a stub is
16
+ * `"ConfigurationPreviewModal" is not exported by …` — which takes out the whole
17
+ * admin bundle, every module's screens with it, over one button.
18
+ *
19
+ * A dynamic import is not analysed that way, so the stub survives to runtime,
20
+ * where it is never reached: the render below is already gated on the module's
21
+ * presence (Z12), and a module that is not installed is never present. The gate
22
+ * was there first and answers the operator's question; this answers the
23
+ * bundler's, and neither stands in for the other.
24
+ */
25
+ const ConfigurationPreviewModal = lazy(() => import('@endora-commerce/mod-credentials/admin-ui').then((module) => ({
26
+ default: module.ConfigurationPreviewModal,
27
+ })));
28
+ /**
29
+ * List the configurations of one type (feature 091, P6).
30
+ *
31
+ * The request is built here rather than through `credentials`' own admin API
32
+ * client: that client is another module's **code**, which is what the
33
+ * cross-module ledger recorded, while `/api/v1/admin/credentials` and
34
+ * `ConfigurationListResponse` are an HTTP path and a
35
+ * `@endora-commerce/contracts` type that both sides already compile. That is
36
+ * the exit P2 established and `admin-kit-surface.md` R6 records. The reach into
37
+ * `ConfigurationPreviewModal` below is a **component** reach and is a different
38
+ * repair — D-191's `./admin-ui`, taken in batch 10 — and it is **still
39
+ * ledgered**, because Z11 keeps a published-component reach counted.
40
+ */
41
+ function listConfigurations(type) {
42
+ return apiClient
43
+ .get(`/api/v1/admin/credentials?type=${encodeURIComponent(type)}`)
44
+ .then((res) => res.configurations);
45
+ }
46
+ export function ConfigurationReferenceInput({ configurationType, value, onChange, }) {
47
+ const t = useTranslation('settings');
48
+ const isVisible = useSurfaceVisibility();
49
+ const credentialsPresent = isVisible({ module: 'credentials' });
50
+ const [options, setOptions] = useState([]);
51
+ const [preview, setPreview] = useState(null);
52
+ useEffect(() => {
53
+ let cancelled = false;
54
+ if (!configurationType) {
55
+ setOptions([]);
56
+ return;
57
+ }
58
+ void listConfigurations(configurationType)
59
+ .then((list) => {
60
+ if (!cancelled)
61
+ setOptions(list);
62
+ })
63
+ .catch(() => {
64
+ if (!cancelled)
65
+ setOptions([]);
66
+ });
67
+ return () => {
68
+ cancelled = true;
69
+ };
70
+ }, [configurationType]);
71
+ const selected = options.find((o) => o.code === value) ?? null;
72
+ return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Select, { className: "flex-1", value: value, onChange: (e) => onChange(e.target.value), children: [_jsx("option", { value: "", children: "\u2014" }), options.map((o) => (_jsxs("option", { value: o.code, children: [o.name, " (", o.code, ")"] }, o.code)))] }), credentialsPresent ? (_jsxs(_Fragment, { children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", disabled: !selected, onClick: () => setPreview(selected), children: t('editor.credentialRef.preview') }), _jsx(Suspense, { fallback: null, children: _jsx(ConfigurationPreviewModal, { open: preview !== null, configuration: preview, onClose: () => setPreview(null) }) })] })) : null] }));
73
+ }
74
+ //# sourceMappingURL=ConfigurationReferenceInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigurationReferenceInput.js","sourceRoot":"","sources":["../../../src/admin/components/ConfigurationReferenceInput.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { ReactNode } from 'react';
2
+ interface Props {
3
+ message?: string;
4
+ onRefresh: () => void;
5
+ }
6
+ /**
7
+ * Surface used when the server returns 409 VERSION_CONFLICT (someone else
8
+ * modified the setting between this client's load and save). Asks the user
9
+ * to refresh and retry — matches the pattern used in feature 003 governance.
10
+ */
11
+ export declare function ConflictBanner({ message, onRefresh }: Props): ReactNode;
12
+ export {};
13
+ //# sourceMappingURL=ConflictBanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConflictBanner.d.ts","sourceRoot":"","sources":["../../../src/admin/components/ConflictBanner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,UAAU,KAAK;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,KAAK,GAAG,SAAS,CAcvE"}
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Alert, AlertDescription, Button } from '@endora-commerce/admin-kit/ui';
3
+ /**
4
+ * Surface used when the server returns 409 VERSION_CONFLICT (someone else
5
+ * modified the setting between this client's load and save). Asks the user
6
+ * to refresh and retry — matches the pattern used in feature 003 governance.
7
+ */
8
+ export function ConflictBanner({ message, onRefresh }) {
9
+ return (_jsx(Alert, { className: "border-amber-300 bg-amber-50 text-amber-900", children: _jsxs(AlertDescription, { className: "flex items-center justify-between gap-4", children: [_jsx("span", { children: message ??
10
+ 'Someone else changed this setting since you opened it. Refresh to load the latest value, then re-apply your edit.' }), _jsx(Button, { variant: "outline", size: "sm", onClick: onRefresh, children: "Refresh" })] }) }));
11
+ }
12
+ //# sourceMappingURL=ConflictBanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConflictBanner.js","sourceRoot":"","sources":["../../../src/admin/components/ConflictBanner.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAMhF;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,OAAO,EAAE,SAAS,EAAS;IAC1D,OAAO,CACL,KAAC,KAAK,IAAC,SAAS,EAAC,6CAA6C,YAC5D,MAAC,gBAAgB,IAAC,SAAS,EAAC,yCAAyC,aACnE,yBACG,OAAO;wBACN,mHAAmH,GAChH,EACP,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,SAAS,wBAE7C,IACQ,GACb,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { type ReactNode } from 'react';
2
+ interface Props {
3
+ /** The current value — a resolvable image URL (may be empty). */
4
+ value: string;
5
+ /** Emit the new URL when the admin uploads, clears, or edits the value. */
6
+ onChange: (next: string) => void;
7
+ }
8
+ /**
9
+ * `toAbsoluteAssetUrl` is `@endora-commerce/admin-kit/lib`'s, imported above.
10
+ *
11
+ * This file carried its own copy of it, over a private
12
+ * `import.meta.env.VITE_API_BASE_URL` read with the same
13
+ * `http://localhost:3001` fallback — a ninth implementation of a function P4c
14
+ * published, invisible to that merge request because a copy in a module's own
15
+ * file is not a *cross-module* reach. The move refuses it in the compiler
16
+ * rather than in review: this package's `tsconfig.ui.json` carries no
17
+ * `vite/client` types, so `import.meta.env` does not compile here.
18
+ *
19
+ * The two things this copy did that the kit's did not — trimming, and treating
20
+ * a protocol-relative URL as already absolute — went into the kit's rather than
21
+ * being lost, so nothing this screen renders changes. That is batch 9's
22
+ * `AssetDetailDrawer` repair arriving with one extra behaviour to carry.
23
+ */
24
+ /**
25
+ * Editor for string settings that hold an image URL (e.g. the product-image
26
+ * placeholder). Instead of forcing the admin to paste a URL, it offers a
27
+ * drag-and-drop / file-picker uploader (via the Assets Library) and stores the
28
+ * resulting public asset URL as the setting value. A live preview is shown for
29
+ * the current value, and a collapsible field still allows pasting a raw URL for
30
+ * power users / externally-hosted images.
31
+ */
32
+ export declare function ImageSettingInput({ value, onChange }: Props): ReactNode;
33
+ export {};
34
+ //# sourceMappingURL=ImageSettingInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageSettingInput.d.ts","sourceRoot":"","sources":["../../../src/admin/components/ImageSettingInput.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAMjD,UAAU,KAAK;IACb,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,GAAG,SAAS,CA6CvE"}
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Button, Input } from '@endora-commerce/admin-kit/ui';
4
+ import { toAbsoluteAssetUrl } from '@endora-commerce/admin-kit/lib';
5
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
6
+ import { AssetUploader } from '@endora-commerce/admin-kit/components';
7
+ /**
8
+ * `toAbsoluteAssetUrl` is `@endora-commerce/admin-kit/lib`'s, imported above.
9
+ *
10
+ * This file carried its own copy of it, over a private
11
+ * `import.meta.env.VITE_API_BASE_URL` read with the same
12
+ * `http://localhost:3001` fallback — a ninth implementation of a function P4c
13
+ * published, invisible to that merge request because a copy in a module's own
14
+ * file is not a *cross-module* reach. The move refuses it in the compiler
15
+ * rather than in review: this package's `tsconfig.ui.json` carries no
16
+ * `vite/client` types, so `import.meta.env` does not compile here.
17
+ *
18
+ * The two things this copy did that the kit's did not — trimming, and treating
19
+ * a protocol-relative URL as already absolute — went into the kit's rather than
20
+ * being lost, so nothing this screen renders changes. That is batch 9's
21
+ * `AssetDetailDrawer` repair arriving with one extra behaviour to carry.
22
+ */
23
+ /**
24
+ * Editor for string settings that hold an image URL (e.g. the product-image
25
+ * placeholder). Instead of forcing the admin to paste a URL, it offers a
26
+ * drag-and-drop / file-picker uploader (via the Assets Library) and stores the
27
+ * resulting public asset URL as the setting value. A live preview is shown for
28
+ * the current value, and a collapsible field still allows pasting a raw URL for
29
+ * power users / externally-hosted images.
30
+ */
31
+ export function ImageSettingInput({ value, onChange }) {
32
+ const t = useTranslation('settings');
33
+ const [showUrl, setShowUrl] = useState(false);
34
+ return (_jsxs("div", { className: "space-y-2", children: [value ? (_jsxs("div", { className: "flex items-center gap-3 rounded-md border bg-muted/20 p-2", children: [_jsx("img", { src: toAbsoluteAssetUrl(value), className: "h-16 w-16 shrink-0 rounded border bg-background object-cover" }), _jsx("p", { className: "min-w-0 flex-1 truncate text-xs text-muted-foreground", children: value }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => onChange(''), children: t('editor.image.remove') })] })) : (_jsx("p", { className: "text-xs text-muted-foreground", children: t('editor.image.none') })), _jsx(AssetUploader, { acceptPrefix: "image/", defaults: { visibility: 'public' }, onUploaded: (asset) => onChange(toAbsoluteAssetUrl(asset.url)), triggerLabel: t('editor.image.upload') }), _jsx("button", { type: "button", className: "text-xs text-muted-foreground underline-offset-2 hover:underline", onClick: () => setShowUrl((s) => !s), children: t('editor.image.toggleUrl') }), showUrl ? (_jsx(Input, { value: value, onChange: (e) => onChange(e.target.value), placeholder: t('editor.image.urlPlaceholder') })) : null] }));
35
+ }
36
+ //# sourceMappingURL=ImageSettingInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageSettingInput.js","sourceRoot":"","sources":["../../../src/admin/components/ImageSettingInput.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAStE;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAS;IAC1D,MAAM,CAAC,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE9C,OAAO,CACL,eAAK,SAAS,EAAC,WAAW,aACvB,KAAK,CAAC,CAAC,CAAC,CACP,eAAK,SAAS,EAAC,2DAA2D,aAExE,cACE,GAAG,EAAE,kBAAkB,CAAC,KAAK,CAAC,EAC9B,SAAS,EAAC,8DAA8D,GACxE,EACF,YAAG,SAAS,EAAC,uDAAuD,YAAE,KAAK,GAAK,EAChF,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,GAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,YAC9E,CAAC,CAAC,qBAAqB,CAAC,GAClB,IACL,CACP,CAAC,CAAC,CAAC,CACF,YAAG,SAAS,EAAC,+BAA+B,YAAE,CAAC,CAAC,mBAAmB,CAAC,GAAK,CAC1E,EAED,KAAC,aAAa,IACZ,YAAY,EAAC,QAAQ,EACrB,QAAQ,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,EAClC,UAAU,EAAE,CAAC,KAAK,EAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EACpE,YAAY,EAAE,CAAC,CAAC,qBAAqB,CAAC,GACtC,EAEF,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,kEAAkE,EAC5E,OAAO,EAAE,GAAS,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAEzC,CAAC,CAAC,wBAAwB,CAAC,GACrB,EACR,OAAO,CAAC,CAAC,CAAC,CACT,KAAC,KAAK,IACJ,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC/C,WAAW,EAAE,CAAC,CAAC,6BAA6B,CAAC,GAC7C,CACH,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ReactNode } from 'react';
2
+ export declare function QuoteRequestsSettingsTab(): ReactNode;
3
+ //# sourceMappingURL=QuoteRequestsSettingsTab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuoteRequestsSettingsTab.d.ts","sourceRoot":"","sources":["../../../src/admin/components/QuoteRequestsSettingsTab.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAyBzE,wBAAgB,wBAAwB,IAAI,SAAS,CAgHpD"}
@@ -0,0 +1,69 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from 'react';
3
+ import { Save } from 'lucide-react';
4
+ import { apiClient, ApiError } from '@endora-commerce/admin-kit/lib';
5
+ import { Alert, AlertDescription, Button, Card, CardContent, CardHeader, CardTitle, Input, Label } from '@endora-commerce/admin-kit/ui';
6
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
7
+ const KEYS = {
8
+ expiry: 'quote_requests.expiry_days',
9
+ card: 'quote_requests.show_add_to_quote_on_card',
10
+ pdp: 'quote_requests.show_add_to_quote_on_pdp',
11
+ };
12
+ export function QuoteRequestsSettingsTab() {
13
+ const t = useTranslation('settings');
14
+ const [expiry, setExpiry] = useState('0');
15
+ const [card, setCard] = useState(true);
16
+ const [pdp, setPdp] = useState(true);
17
+ const [busy, setBusy] = useState(false);
18
+ const [error, setError] = useState(null);
19
+ const [info, setInfo] = useState(null);
20
+ const refresh = useCallback(async () => {
21
+ setError(null);
22
+ try {
23
+ const res = await apiClient.get('/api/v1/admin/settings?prefix=quote_requests.');
24
+ for (const v of res.data) {
25
+ if (v.code === KEYS.expiry && typeof v.value === 'number')
26
+ setExpiry(String(v.value));
27
+ if (v.code === KEYS.card && typeof v.value === 'boolean')
28
+ setCard(v.value);
29
+ if (v.code === KEYS.pdp && typeof v.value === 'boolean')
30
+ setPdp(v.value);
31
+ }
32
+ }
33
+ catch (err) {
34
+ setError(err instanceof ApiError ? err.envelope.error.message : t('quoteRequestsTab.error.load'));
35
+ }
36
+ }, [t]);
37
+ useEffect(() => {
38
+ void refresh();
39
+ }, [refresh]);
40
+ const save = async () => {
41
+ setBusy(true);
42
+ setError(null);
43
+ setInfo(null);
44
+ const expiryDays = Number(expiry);
45
+ if (!Number.isFinite(expiryDays) || expiryDays < 0) {
46
+ setError(t('quoteRequestsTab.error.invalidExpiry'));
47
+ setBusy(false);
48
+ return;
49
+ }
50
+ try {
51
+ await apiClient.patch('/api/v1/admin/settings', {
52
+ changes: [
53
+ { code: KEYS.expiry, value: Math.floor(expiryDays) },
54
+ { code: KEYS.card, value: card },
55
+ { code: KEYS.pdp, value: pdp },
56
+ ],
57
+ });
58
+ setInfo(t('quoteRequestsTab.saved'));
59
+ }
60
+ catch (err) {
61
+ setError(err instanceof ApiError ? err.envelope.error.message : t('quoteRequestsTab.error.save'));
62
+ }
63
+ finally {
64
+ setBusy(false);
65
+ }
66
+ };
67
+ return (_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx(CardTitle, { children: t('quoteRequestsTab.title') }) }), _jsxs(CardContent, { style: { display: 'flex', flexDirection: 'column', gap: 16 }, children: [error ? (_jsx(Alert, { variant: "destructive", children: _jsx(AlertDescription, { children: error }) })) : null, info ? (_jsx(Alert, { children: _jsx(AlertDescription, { children: info }) })) : null, _jsxs("div", { children: [_jsx(Label, { htmlFor: "expiry", children: t('quoteRequestsTab.expiry.label') }), _jsx(Input, { id: "expiry", type: "number", min: 0, value: expiry, onChange: (e) => setExpiry(e.target.value) }), _jsx("p", { style: { fontSize: 12, color: 'var(--b2b-muted)', marginTop: 4 }, children: t('quoteRequestsTab.expiry.help') })] }), _jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: 8 }, children: [_jsx("input", { type: "checkbox", checked: card, onChange: (e) => setCard(e.target.checked) }), t('quoteRequestsTab.showOnCards')] }), _jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: 8 }, children: [_jsx("input", { type: "checkbox", checked: pdp, onChange: (e) => setPdp(e.target.checked) }), t('quoteRequestsTab.showOnPdp')] }), _jsx("div", { children: _jsxs(Button, { onClick: () => void save(), disabled: busy, children: [_jsx(Save, { size: 14, style: { marginRight: 4 } }), " ", t('quoteRequestsTab.save')] }) })] })] }));
68
+ }
69
+ //# sourceMappingURL=QuoteRequestsSettingsTab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuoteRequestsSettingsTab.js","sourceRoot":"","sources":["../../../src/admin/components/QuoteRequestsSettingsTab.tsx"],"names":[],"mappings":"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"}