@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.
- package/LICENSE +21 -0
- package/README.md +58 -0
- package/dist/admin/api/settings-client.d.ts +47 -0
- package/dist/admin/api/settings-client.d.ts.map +1 -0
- package/dist/admin/api/settings-client.js +41 -0
- package/dist/admin/api/settings-client.js.map +1 -0
- package/dist/admin/components/ActivationPointerRow.d.ts +21 -0
- package/dist/admin/components/ActivationPointerRow.d.ts.map +1 -0
- package/dist/admin/components/ActivationPointerRow.js +28 -0
- package/dist/admin/components/ActivationPointerRow.js.map +1 -0
- package/dist/admin/components/AssetIdSettingInput.d.ts +12 -0
- package/dist/admin/components/AssetIdSettingInput.d.ts.map +1 -0
- package/dist/admin/components/AssetIdSettingInput.js +10 -0
- package/dist/admin/components/AssetIdSettingInput.js.map +1 -0
- package/dist/admin/components/ConfigurationReferenceInput.d.ts +39 -0
- package/dist/admin/components/ConfigurationReferenceInput.d.ts.map +1 -0
- package/dist/admin/components/ConfigurationReferenceInput.js +74 -0
- package/dist/admin/components/ConfigurationReferenceInput.js.map +1 -0
- package/dist/admin/components/ConflictBanner.d.ts +13 -0
- package/dist/admin/components/ConflictBanner.d.ts.map +1 -0
- package/dist/admin/components/ConflictBanner.js +12 -0
- package/dist/admin/components/ConflictBanner.js.map +1 -0
- package/dist/admin/components/ImageSettingInput.d.ts +34 -0
- package/dist/admin/components/ImageSettingInput.d.ts.map +1 -0
- package/dist/admin/components/ImageSettingInput.js +36 -0
- package/dist/admin/components/ImageSettingInput.js.map +1 -0
- package/dist/admin/components/QuoteRequestsSettingsTab.d.ts +3 -0
- package/dist/admin/components/QuoteRequestsSettingsTab.d.ts.map +1 -0
- package/dist/admin/components/QuoteRequestsSettingsTab.js +69 -0
- package/dist/admin/components/QuoteRequestsSettingsTab.js.map +1 -0
- package/dist/admin/components/SellerCompanyDataInput.d.ts +22 -0
- package/dist/admin/components/SellerCompanyDataInput.d.ts.map +1 -0
- package/dist/admin/components/SellerCompanyDataInput.js +53 -0
- package/dist/admin/components/SellerCompanyDataInput.js.map +1 -0
- package/dist/admin/components/SettingRowEditor.d.ts +55 -0
- package/dist/admin/components/SettingRowEditor.d.ts.map +1 -0
- package/dist/admin/components/SettingRowEditor.js +160 -0
- package/dist/admin/components/SettingRowEditor.js.map +1 -0
- package/dist/admin/index.d.ts +39 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +87 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/CachePage.d.ts +14 -0
- package/dist/admin/pages/CachePage.d.ts.map +1 -0
- package/dist/admin/pages/CachePage.js +124 -0
- package/dist/admin/pages/CachePage.js.map +1 -0
- package/dist/admin/pages/GroupsPage.d.ts +17 -0
- package/dist/admin/pages/GroupsPage.d.ts.map +1 -0
- package/dist/admin/pages/GroupsPage.js +84 -0
- package/dist/admin/pages/GroupsPage.js.map +1 -0
- package/dist/admin/pages/SettingsPage.d.ts +20 -0
- package/dist/admin/pages/SettingsPage.d.ts.map +1 -0
- package/dist/admin/pages/SettingsPage.js +453 -0
- package/dist/admin/pages/SettingsPage.js.map +1 -0
- package/dist/backend/cli/cache-clear.d.ts +23 -0
- package/dist/backend/cli/cache-clear.d.ts.map +1 -0
- package/dist/backend/cli/cache-clear.js +37 -0
- package/dist/backend/cli/cache-clear.js.map +1 -0
- package/dist/backend/index.d.ts +100 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +125 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/routes.admin.d.ts +308 -0
- package/dist/backend/routes.admin.d.ts.map +1 -0
- package/dist/backend/routes.admin.js +188 -0
- package/dist/backend/routes.admin.js.map +1 -0
- package/dist/backend/routes.cache.d.ts +20 -0
- package/dist/backend/routes.cache.d.ts.map +1 -0
- package/dist/backend/routes.cache.js +22 -0
- package/dist/backend/routes.cache.js.map +1 -0
- package/dist/backend/routes.homepage.d.ts +15 -0
- package/dist/backend/routes.homepage.d.ts.map +1 -0
- package/dist/backend/routes.homepage.js +20 -0
- package/dist/backend/routes.homepage.js.map +1 -0
- package/dist/backend/routes.product-card-buttons.d.ts +15 -0
- package/dist/backend/routes.product-card-buttons.d.ts.map +1 -0
- package/dist/backend/routes.product-card-buttons.js +21 -0
- package/dist/backend/routes.product-card-buttons.js.map +1 -0
- package/dist/backend/routes.speculation-rules.d.ts +16 -0
- package/dist/backend/routes.speculation-rules.d.ts.map +1 -0
- package/dist/backend/routes.speculation-rules.js +21 -0
- package/dist/backend/routes.speculation-rules.js.map +1 -0
- package/dist/backend/routes.storefront.d.ts +15 -0
- package/dist/backend/routes.storefront.d.ts.map +1 -0
- package/dist/backend/routes.storefront.js +20 -0
- package/dist/backend/routes.storefront.js.map +1 -0
- package/dist/backend/services/cache-admin.service.d.ts +83 -0
- package/dist/backend/services/cache-admin.service.d.ts.map +1 -0
- package/dist/backend/services/cache-admin.service.js +148 -0
- package/dist/backend/services/cache-admin.service.js.map +1 -0
- package/dist/backend/services/homepage-resolver.d.ts +25 -0
- package/dist/backend/services/homepage-resolver.d.ts.map +1 -0
- package/dist/backend/services/homepage-resolver.js +31 -0
- package/dist/backend/services/homepage-resolver.js.map +1 -0
- package/dist/backend/services/product-card-buttons-resolver.d.ts +25 -0
- package/dist/backend/services/product-card-buttons-resolver.d.ts.map +1 -0
- package/dist/backend/services/product-card-buttons-resolver.js +37 -0
- package/dist/backend/services/product-card-buttons-resolver.js.map +1 -0
- package/dist/backend/services/registered-settings-manifests.d.ts +45 -0
- package/dist/backend/services/registered-settings-manifests.d.ts.map +1 -0
- package/dist/backend/services/registered-settings-manifests.js +55 -0
- package/dist/backend/services/registered-settings-manifests.js.map +1 -0
- package/dist/backend/services/setting-write-validators.d.ts +43 -0
- package/dist/backend/services/setting-write-validators.d.ts.map +1 -0
- package/dist/backend/services/setting-write-validators.js +43 -0
- package/dist/backend/services/setting-write-validators.js.map +1 -0
- package/dist/backend/services/settings-admin.service.d.ts +206 -0
- package/dist/backend/services/settings-admin.service.d.ts.map +1 -0
- package/dist/backend/services/settings-admin.service.js +642 -0
- package/dist/backend/services/settings-admin.service.js.map +1 -0
- package/dist/backend/services/shop-info-resolver.d.ts +15 -0
- package/dist/backend/services/shop-info-resolver.d.ts.map +1 -0
- package/dist/backend/services/shop-info-resolver.js +44 -0
- package/dist/backend/services/shop-info-resolver.js.map +1 -0
- package/dist/backend/services/speculation-rules-resolver.d.ts +28 -0
- package/dist/backend/services/speculation-rules-resolver.d.ts.map +1 -0
- package/dist/backend/services/speculation-rules-resolver.js +39 -0
- package/dist/backend/services/speculation-rules-resolver.js.map +1 -0
- package/dist/manifest.d.ts +194 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +379 -0
- package/dist/manifest.js.map +1 -0
- package/docs/settings/index.md +171 -0
- package/i18n/en.json +167 -0
- package/i18n/pl.json +167 -0
- package/package.json +96 -0
- 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 @@
|
|
|
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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"}
|