@endora-commerce/mod-quick-order 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/quick-order-client.d.ts +76 -0
- package/dist/admin/api/quick-order-client.d.ts.map +1 -0
- package/dist/admin/api/quick-order-client.js +18 -0
- package/dist/admin/api/quick-order-client.js.map +1 -0
- package/dist/admin/components/DefaultPreferencesPanel.d.ts +44 -0
- package/dist/admin/components/DefaultPreferencesPanel.d.ts.map +1 -0
- package/dist/admin/components/DefaultPreferencesPanel.js +107 -0
- package/dist/admin/components/DefaultPreferencesPanel.js.map +1 -0
- package/dist/admin/index.d.ts +48 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +120 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/QuickOrderOnBehalfPage.d.ts +16 -0
- package/dist/admin/pages/QuickOrderOnBehalfPage.d.ts.map +1 -0
- package/dist/admin/pages/QuickOrderOnBehalfPage.js +85 -0
- package/dist/admin/pages/QuickOrderOnBehalfPage.js.map +1 -0
- package/dist/admin/zones/CustomerDefaults.d.ts +27 -0
- package/dist/admin/zones/CustomerDefaults.d.ts.map +1 -0
- package/dist/admin/zones/CustomerDefaults.js +11 -0
- package/dist/admin/zones/CustomerDefaults.js.map +1 -0
- package/dist/admin/zones/OrderEntryQuickTab.d.ts +21 -0
- package/dist/admin/zones/OrderEntryQuickTab.d.ts.map +1 -0
- package/dist/admin/zones/OrderEntryQuickTab.js +26 -0
- package/dist/admin/zones/OrderEntryQuickTab.js.map +1 -0
- package/dist/admin/zones/OrganizationDefaults.d.ts +30 -0
- package/dist/admin/zones/OrganizationDefaults.d.ts.map +1 -0
- package/dist/admin/zones/OrganizationDefaults.js +11 -0
- package/dist/admin/zones/OrganizationDefaults.js.map +1 -0
- package/dist/backend/entities/quick-order-default-preference.entity.d.ts +22 -0
- package/dist/backend/entities/quick-order-default-preference.entity.d.ts.map +1 -0
- package/dist/backend/entities/quick-order-default-preference.entity.js +76 -0
- package/dist/backend/entities/quick-order-default-preference.entity.js.map +1 -0
- package/dist/backend/index.d.ts +88 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +235 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/routes.admin.d.ts +35 -0
- package/dist/backend/routes.admin.d.ts.map +1 -0
- package/dist/backend/routes.admin.js +64 -0
- package/dist/backend/routes.admin.js.map +1 -0
- package/dist/backend/routes.d.ts +35 -0
- package/dist/backend/routes.d.ts.map +1 -0
- package/dist/backend/routes.js +77 -0
- package/dist/backend/routes.js.map +1 -0
- package/dist/backend/routes.one-click.d.ts +22 -0
- package/dist/backend/routes.one-click.d.ts.map +1 -0
- package/dist/backend/routes.one-click.js +35 -0
- package/dist/backend/routes.one-click.js.map +1 -0
- package/dist/backend/routes.preferences.admin.d.ts +23 -0
- package/dist/backend/routes.preferences.admin.d.ts.map +1 -0
- package/dist/backend/routes.preferences.admin.js +40 -0
- package/dist/backend/routes.preferences.admin.js.map +1 -0
- package/dist/backend/routes.preferences.d.ts +21 -0
- package/dist/backend/routes.preferences.d.ts.map +1 -0
- package/dist/backend/routes.preferences.js +42 -0
- package/dist/backend/routes.preferences.js.map +1 -0
- package/dist/backend/services/catalog-lookup.d.ts +39 -0
- package/dist/backend/services/catalog-lookup.d.ts.map +1 -0
- package/dist/backend/services/catalog-lookup.js +104 -0
- package/dist/backend/services/catalog-lookup.js.map +1 -0
- package/dist/backend/services/default-preference-authz.d.ts +31 -0
- package/dist/backend/services/default-preference-authz.d.ts.map +1 -0
- package/dist/backend/services/default-preference-authz.js +26 -0
- package/dist/backend/services/default-preference-authz.js.map +1 -0
- package/dist/backend/services/default-preference-resolver.d.ts +28 -0
- package/dist/backend/services/default-preference-resolver.d.ts.map +1 -0
- package/dist/backend/services/default-preference-resolver.js +27 -0
- package/dist/backend/services/default-preference-resolver.js.map +1 -0
- package/dist/backend/services/default-preference-service.d.ts +63 -0
- package/dist/backend/services/default-preference-service.d.ts.map +1 -0
- package/dist/backend/services/default-preference-service.js +176 -0
- package/dist/backend/services/default-preference-service.js.map +1 -0
- package/dist/backend/services/excel-importer.d.ts +11 -0
- package/dist/backend/services/excel-importer.d.ts.map +1 -0
- package/dist/backend/services/excel-importer.js +47 -0
- package/dist/backend/services/excel-importer.js.map +1 -0
- package/dist/backend/services/import-from-request.d.ts +9 -0
- package/dist/backend/services/import-from-request.d.ts.map +1 -0
- package/dist/backend/services/import-from-request.js +17 -0
- package/dist/backend/services/import-from-request.js.map +1 -0
- package/dist/backend/services/import-pipeline.d.ts +89 -0
- package/dist/backend/services/import-pipeline.d.ts.map +1 -0
- package/dist/backend/services/import-pipeline.js +188 -0
- package/dist/backend/services/import-pipeline.js.map +1 -0
- package/dist/backend/services/import-rows.d.ts +43 -0
- package/dist/backend/services/import-rows.d.ts.map +1 -0
- package/dist/backend/services/import-rows.js +102 -0
- package/dist/backend/services/import-rows.js.map +1 -0
- package/dist/backend/services/one-click-service.d.ts +50 -0
- package/dist/backend/services/one-click-service.d.ts.map +1 -0
- package/dist/backend/services/one-click-service.js +83 -0
- package/dist/backend/services/one-click-service.js.map +1 -0
- package/dist/backend/services/quick-order-build-service.d.ts +35 -0
- package/dist/backend/services/quick-order-build-service.d.ts.map +1 -0
- package/dist/backend/services/quick-order-build-service.js +61 -0
- package/dist/backend/services/quick-order-build-service.js.map +1 -0
- package/dist/backend/services/variant-resolver.d.ts +40 -0
- package/dist/backend/services/variant-resolver.d.ts.map +1 -0
- package/dist/backend/services/variant-resolver.js +47 -0
- package/dist/backend/services/variant-resolver.js.map +1 -0
- package/dist/manifest.d.ts +190 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +129 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260611T140359_quick_order_default_preferences.d.ts +15 -0
- package/dist/migrations/20260611T140359_quick_order_default_preferences.d.ts.map +1 -0
- package/dist/migrations/20260611T140359_quick_order_default_preferences.js +53 -0
- package/dist/migrations/20260611T140359_quick_order_default_preferences.js.map +1 -0
- package/dist/migrations/index.d.ts +27 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +29 -0
- package/dist/migrations/index.js.map +1 -0
- package/docs/quick_order.md +98 -0
- package/i18n/en.json +47 -0
- package/i18n/pl.json +47 -0
- package/package.json +91 -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-quick-order
|
|
4
|
+
|
|
5
|
+
Bulk Cart / Quote Request import (CSV + Excel, with variants), quick product search, reorder, default ordering preferences, and one-click buy.
|
|
6
|
+
|
|
7
|
+
## What this is
|
|
8
|
+
|
|
9
|
+
An **Endora Commerce module package**. Its module id is `quick_order` — 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-quick-order` | the module manifest — its id, version, dependencies, settings and activation |
|
|
18
|
+
| `@endora-commerce/mod-quick-order/admin` | the Admin UI contribution: the screens, navigation and palette actions it adds |
|
|
19
|
+
| `@endora-commerce/mod-quick-order/backend` | the composition root the platform calls, with the entities, services, routes and workers it registers |
|
|
20
|
+
| `@endora-commerce/mod-quick-order/migrations` | the module’s own schema migrations, in the order the platform runs them |
|
|
21
|
+
| `@endora-commerce/mod-quick-order/tailwind.css` | the Tailwind source declaration for the admin code above |
|
|
22
|
+
|
|
23
|
+
## Depends on
|
|
24
|
+
|
|
25
|
+
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.
|
|
26
|
+
|
|
27
|
+
**Endora packages**
|
|
28
|
+
|
|
29
|
+
- `@endora-commerce/admin-kit` — *optional*
|
|
30
|
+
- `@endora-commerce/contracts`
|
|
31
|
+
- `@endora-commerce/platform`
|
|
32
|
+
|
|
33
|
+
**Third-party**
|
|
34
|
+
|
|
35
|
+
- `@mikro-orm/core` ^6
|
|
36
|
+
- `@mikro-orm/migrations` ^6
|
|
37
|
+
- `@mikro-orm/postgresql` ^6
|
|
38
|
+
- `exceljs` ^4
|
|
39
|
+
- `fastify` ^5
|
|
40
|
+
- `react` ^19 — *optional*
|
|
41
|
+
- `zod` ^4
|
|
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-quick-order
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Licence
|
|
57
|
+
|
|
58
|
+
MIT — the text is in `LICENSE`, beside this file.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin quick-order bindings (feature 039). Wraps the `/api/v1/admin/quick-order`
|
|
3
|
+
* endpoints; the operator acts on behalf of a customer + organization.
|
|
4
|
+
*/
|
|
5
|
+
export type QuickOrderRejectionReason = 'sku_missing' | 'quantity_invalid' | 'product_not_found' | 'product_archived' | 'malformed_row' | 'variant_not_resolved' | 'variant_ambiguous' | 'row_limit_exceeded';
|
|
6
|
+
export interface RecognizedQuickOrderItem {
|
|
7
|
+
line: number;
|
|
8
|
+
sku: string;
|
|
9
|
+
productId: string;
|
|
10
|
+
variantId: string | null;
|
|
11
|
+
resolvedVariantSku?: string | null;
|
|
12
|
+
quantity: number;
|
|
13
|
+
mergedFromLines?: number[];
|
|
14
|
+
}
|
|
15
|
+
export interface RejectedQuickOrderItem {
|
|
16
|
+
line: number;
|
|
17
|
+
raw: string;
|
|
18
|
+
reason: QuickOrderRejectionReason;
|
|
19
|
+
}
|
|
20
|
+
export interface QuickOrderImportResponse {
|
|
21
|
+
recognized: RecognizedQuickOrderItem[];
|
|
22
|
+
rejected: RejectedQuickOrderItem[];
|
|
23
|
+
summary: {
|
|
24
|
+
recognizedCount: number;
|
|
25
|
+
rejectedCount: number;
|
|
26
|
+
mergedCount: number;
|
|
27
|
+
truncated: boolean;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export type QuickOrderTarget = 'cart' | 'quote_request';
|
|
31
|
+
export interface QuickOrderBuildResponse {
|
|
32
|
+
target: QuickOrderTarget;
|
|
33
|
+
cartId?: string;
|
|
34
|
+
checkoutUrl?: string;
|
|
35
|
+
quoteRequestId?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface OnBehalfOf {
|
|
38
|
+
customerAccountId: string;
|
|
39
|
+
organizationId: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function adminQuickOrderImport(input: {
|
|
42
|
+
csv?: string;
|
|
43
|
+
file?: {
|
|
44
|
+
filename: string;
|
|
45
|
+
contentBase64: string;
|
|
46
|
+
};
|
|
47
|
+
}): Promise<QuickOrderImportResponse>;
|
|
48
|
+
export declare function adminQuickOrderBuild(input: {
|
|
49
|
+
target: QuickOrderTarget;
|
|
50
|
+
items: Array<{
|
|
51
|
+
productId: string;
|
|
52
|
+
variantId?: string | null;
|
|
53
|
+
quantity: number;
|
|
54
|
+
}>;
|
|
55
|
+
onBehalfOf: OnBehalfOf;
|
|
56
|
+
}): Promise<QuickOrderBuildResponse>;
|
|
57
|
+
export type PreferenceScope = 'organization' | 'customer';
|
|
58
|
+
export interface QuickOrderPreference {
|
|
59
|
+
scope: PreferenceScope;
|
|
60
|
+
scopeId: string;
|
|
61
|
+
defaultPaymentMethodId: string | null;
|
|
62
|
+
defaultDeliveryMethodId: string | null;
|
|
63
|
+
defaultBillingAddressId: string | null;
|
|
64
|
+
defaultShippingAddressId: string | null;
|
|
65
|
+
}
|
|
66
|
+
export interface QuickOrderPreferenceUpsert {
|
|
67
|
+
scope: PreferenceScope;
|
|
68
|
+
scopeId: string;
|
|
69
|
+
defaultPaymentMethodId?: string | null;
|
|
70
|
+
defaultDeliveryMethodId?: string | null;
|
|
71
|
+
defaultBillingAddressId?: string | null;
|
|
72
|
+
defaultShippingAddressId?: string | null;
|
|
73
|
+
}
|
|
74
|
+
export declare function adminGetPreference(scope: PreferenceScope, scopeId: string): Promise<QuickOrderPreference | null>;
|
|
75
|
+
export declare function adminUpsertPreference(body: QuickOrderPreferenceUpsert): Promise<QuickOrderPreference>;
|
|
76
|
+
//# sourceMappingURL=quick-order-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quick-order-client.d.ts","sourceRoot":"","sources":["../../../src/admin/api/quick-order-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { apiClient } from '@endora-commerce/admin-kit/lib';
|
|
2
|
+
export async function adminQuickOrderImport(input) {
|
|
3
|
+
const res = await apiClient.post('/api/v1/admin/quick-order/import', input);
|
|
4
|
+
return res.data;
|
|
5
|
+
}
|
|
6
|
+
export async function adminQuickOrderBuild(input) {
|
|
7
|
+
const res = await apiClient.post('/api/v1/admin/quick-order/build', input);
|
|
8
|
+
return res.data;
|
|
9
|
+
}
|
|
10
|
+
export async function adminGetPreference(scope, scopeId) {
|
|
11
|
+
const res = await apiClient.get(`/api/v1/admin/quick-order/preferences?scope=${scope}&scopeId=${encodeURIComponent(scopeId)}`);
|
|
12
|
+
return res.data;
|
|
13
|
+
}
|
|
14
|
+
export async function adminUpsertPreference(body) {
|
|
15
|
+
const res = await apiClient.put('/api/v1/admin/quick-order/preferences', body);
|
|
16
|
+
return res.data;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=quick-order-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quick-order-client.js","sourceRoot":"","sources":["../../../src/admin/api/quick-order-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAwD3D,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAG3C;IACC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,IAAI,CAC9B,kCAAkC,EAClC,KAAK,CACN,CAAC;IACF,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAI1C;IACC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,IAAI,CAC9B,iCAAiC,EACjC,KAAK,CACN,CAAC;IACF,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AAsBD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAsB,EACtB,OAAe;IAEf,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAC7B,+CAA+C,KAAK,YAAY,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAC9F,CAAC;IACF,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAAgC;IAEhC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAC7B,uCAAuC,EACvC,IAAI,CACL,CAAC;IACF,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* DefaultPreferencesPanel — feature 039 (US2 / FR-018).
|
|
4
|
+
*
|
|
5
|
+
* Embedded editor for an organization's or customer's default ordering
|
|
6
|
+
* preferences (payment / delivery method + billing / shipping address). It is
|
|
7
|
+
* mounted on the Customer and Organization edit pages so the configuration
|
|
8
|
+
* lives next to the entity it belongs to — the standalone admin page was
|
|
9
|
+
* removed in favour of this panel.
|
|
10
|
+
*
|
|
11
|
+
* Scope + scopeId are fixed by the host page; the four values are picked from
|
|
12
|
+
* dropdowns populated with the real methods / addresses available for that
|
|
13
|
+
* scope. For the customer scope an empty value means "inherit the
|
|
14
|
+
* organization default"; for the organization scope it means "no default".
|
|
15
|
+
*
|
|
16
|
+
* ## Why the calls are rebuilt rather than the client moved (feature 091, P7b)
|
|
17
|
+
*
|
|
18
|
+
* The file used to live at `admin/src/modules/quick_order/`, imported by path
|
|
19
|
+
* from `organizations`' and `customers`' detail screens — the two
|
|
20
|
+
* `DefaultPreferencesPanel` keys of the boundary ledger, one in each shard. It
|
|
21
|
+
* is this module's panel, so it lives in this module's package and reaches both
|
|
22
|
+
* screens as `organization.detail.after` and `customer.detail.after`
|
|
23
|
+
* contributions instead.
|
|
24
|
+
*
|
|
25
|
+
* `admin/src/modules/quick_order/api/quick-order-client.ts` did **not** travel
|
|
26
|
+
* with it: `QuickOrderOnBehalfPage` still imports that file, and moving it here
|
|
27
|
+
* would leave a package reaching back into the admin application. Its two
|
|
28
|
+
* preference bindings are HTTP paths over a payload this file already declares,
|
|
29
|
+
* so they are rebuilt from the published `apiClient` (P2's exit) — twelve lines
|
|
30
|
+
* against a reach.
|
|
31
|
+
*
|
|
32
|
+
* The copy stays in the `core` namespace rather than moving to this module's
|
|
33
|
+
* own, on P7a's reading of `contracts/admin-component-contribution.md` §9.2:
|
|
34
|
+
* that population is 62 files wide and no P7 row is the merge request that
|
|
35
|
+
* answers it.
|
|
36
|
+
*/
|
|
37
|
+
/** Which entity the defaults belong to. */
|
|
38
|
+
export type PreferenceScope = 'organization' | 'customer';
|
|
39
|
+
export interface DefaultPreferencesPanelProps {
|
|
40
|
+
scope: PreferenceScope;
|
|
41
|
+
scopeId: string;
|
|
42
|
+
}
|
|
43
|
+
export declare function DefaultPreferencesPanel(props: DefaultPreferencesPanelProps): ReactNode;
|
|
44
|
+
//# sourceMappingURL=DefaultPreferencesPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DefaultPreferencesPanel.d.ts","sourceRoot":"","sources":["../../../src/admin/components/DefaultPreferencesPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAezE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,2CAA2C;AAC3C,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,UAAU,CAAC;AAoD1D,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAWD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,GAAG,SAAS,CA+JtF"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
3
|
+
import { ApiError, apiClient } from '@endora-commerce/admin-kit/lib';
|
|
4
|
+
import { Alert, AlertDescription, Button, Card, CardContent, CardHeader, CardTitle, Label, Select, } from '@endora-commerce/admin-kit/ui';
|
|
5
|
+
import { useTranslation } from '@endora-commerce/admin-kit/i18n';
|
|
6
|
+
async function readPreference(scope, scopeId) {
|
|
7
|
+
const res = await apiClient.get(`/api/v1/admin/quick-order/preferences?scope=${scope}&scopeId=${encodeURIComponent(scopeId)}`);
|
|
8
|
+
return res.data;
|
|
9
|
+
}
|
|
10
|
+
async function writePreference(body) {
|
|
11
|
+
await apiClient.put('/api/v1/admin/quick-order/preferences', body);
|
|
12
|
+
}
|
|
13
|
+
function pickLabel(name, fallback) {
|
|
14
|
+
if (!name)
|
|
15
|
+
return fallback;
|
|
16
|
+
return name['en'] ?? name['pl'] ?? Object.values(name)[0] ?? fallback;
|
|
17
|
+
}
|
|
18
|
+
function addressLabel(a) {
|
|
19
|
+
return `${a.recipientName} — ${a.street}, ${a.postalCode} ${a.city}`;
|
|
20
|
+
}
|
|
21
|
+
export function DefaultPreferencesPanel(props) {
|
|
22
|
+
const { scope, scopeId } = props;
|
|
23
|
+
const t = useTranslation('core');
|
|
24
|
+
const [paymentMethods, setPaymentMethods] = useState([]);
|
|
25
|
+
const [deliveryMethods, setDeliveryMethods] = useState([]);
|
|
26
|
+
const [addresses, setAddresses] = useState([]);
|
|
27
|
+
const [payment, setPayment] = useState('');
|
|
28
|
+
const [delivery, setDelivery] = useState('');
|
|
29
|
+
const [billing, setBilling] = useState('');
|
|
30
|
+
const [shipping, setShipping] = useState('');
|
|
31
|
+
const [loading, setLoading] = useState(true);
|
|
32
|
+
const [busy, setBusy] = useState(false);
|
|
33
|
+
const [error, setError] = useState(null);
|
|
34
|
+
const [info, setInfo] = useState(null);
|
|
35
|
+
const loadAll = useCallback(async () => {
|
|
36
|
+
setLoading(true);
|
|
37
|
+
setError(null);
|
|
38
|
+
setInfo(null);
|
|
39
|
+
try {
|
|
40
|
+
const addressesReq = scope === 'customer'
|
|
41
|
+
? apiClient
|
|
42
|
+
.get(`/api/v1/admin/customers/${scopeId}/addresses`)
|
|
43
|
+
.then((res) => [...res.data.personal, ...res.data.organization])
|
|
44
|
+
: apiClient
|
|
45
|
+
.get(`/api/v1/admin/organizations/${scopeId}/addresses`)
|
|
46
|
+
.then((res) => res.data);
|
|
47
|
+
const [pms, dms, addrRows, current] = await Promise.all([
|
|
48
|
+
apiClient.get('/api/v1/admin/payment-methods?pageSize=200'),
|
|
49
|
+
apiClient.get('/api/v1/admin/delivery-methods?pageSize=200'),
|
|
50
|
+
addressesReq,
|
|
51
|
+
readPreference(scope, scopeId),
|
|
52
|
+
]);
|
|
53
|
+
setPaymentMethods((pms.data ?? []).map((m) => ({ id: m.id, label: pickLabel(m.name, m.code) })));
|
|
54
|
+
setDeliveryMethods((dms.data ?? []).map((m) => ({ id: m.id, label: pickLabel(m.name, m.code) })));
|
|
55
|
+
setAddresses((addrRows ?? []).map((a) => ({ id: a.id, kind: a.kind, label: addressLabel(a) })));
|
|
56
|
+
setPayment(current?.defaultPaymentMethodId ?? '');
|
|
57
|
+
setDelivery(current?.defaultDeliveryMethodId ?? '');
|
|
58
|
+
setBilling(current?.defaultBillingAddressId ?? '');
|
|
59
|
+
setShipping(current?.defaultShippingAddressId ?? '');
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
setError(err instanceof ApiError ? err.envelope.error.message : t('defaultPreferences.loadError'));
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
setLoading(false);
|
|
66
|
+
}
|
|
67
|
+
}, [scope, scopeId, t]);
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
void loadAll();
|
|
70
|
+
}, [loadAll]);
|
|
71
|
+
const save = useCallback(async () => {
|
|
72
|
+
if (busy)
|
|
73
|
+
return;
|
|
74
|
+
setBusy(true);
|
|
75
|
+
setError(null);
|
|
76
|
+
setInfo(null);
|
|
77
|
+
try {
|
|
78
|
+
await writePreference({
|
|
79
|
+
scope,
|
|
80
|
+
scopeId,
|
|
81
|
+
defaultPaymentMethodId: payment || null,
|
|
82
|
+
defaultDeliveryMethodId: delivery || null,
|
|
83
|
+
defaultBillingAddressId: billing || null,
|
|
84
|
+
defaultShippingAddressId: shipping || null,
|
|
85
|
+
});
|
|
86
|
+
setInfo(t('defaultPreferences.saved'));
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
setError(err instanceof ApiError ? err.envelope.error.message : t('defaultPreferences.saveError'));
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
setBusy(false);
|
|
93
|
+
}
|
|
94
|
+
}, [busy, scope, scopeId, payment, delivery, billing, shipping, t]);
|
|
95
|
+
const emptyLabel = scope === 'customer' ? t('defaultPreferences.inherit') : t('defaultPreferences.none');
|
|
96
|
+
const billingAddresses = addresses.filter((a) => a.kind === 'billing');
|
|
97
|
+
const shippingAddresses = addresses.filter((a) => a.kind === 'delivery');
|
|
98
|
+
return (_jsxs(Card, { className: "mb-4", children: [_jsx(CardHeader, { children: _jsx(CardTitle, { children: t('defaultPreferences.title') }) }), _jsxs(CardContent, { className: "space-y-4", children: [_jsx("p", { className: "text-xs text-muted-foreground", children: t('defaultPreferences.description') }), error ? (_jsx(Alert, { variant: "destructive", children: _jsx(AlertDescription, { children: error }) })) : null, info ? (_jsx(Alert, { variant: "success", children: _jsx(AlertDescription, { children: info }) })) : null, loading ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('common.state.loading') })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [_jsx(PrefSelect, { id: "pref-payment", label: t('defaultPreferences.paymentMethod'), emptyLabel: emptyLabel, value: payment, options: paymentMethods, onChange: setPayment }), _jsx(PrefSelect, { id: "pref-delivery", label: t('defaultPreferences.deliveryMethod'), emptyLabel: emptyLabel, value: delivery, options: deliveryMethods, onChange: setDelivery }), _jsx(PrefSelect, { id: "pref-billing", label: t('defaultPreferences.billingAddress'), emptyLabel: emptyLabel, value: billing, options: billingAddresses, onChange: setBilling }), _jsx(PrefSelect, { id: "pref-shipping", label: t('defaultPreferences.shippingAddress'), emptyLabel: emptyLabel, value: shipping, options: shippingAddresses, onChange: setShipping })] }), _jsx("div", { className: "flex justify-end", children: _jsx(Button, { onClick: () => void save(), disabled: busy, children: t('defaultPreferences.save') }) })] }))] })] }));
|
|
99
|
+
}
|
|
100
|
+
function PrefSelect(props) {
|
|
101
|
+
// Keep the stored value selectable even when it is no longer in the
|
|
102
|
+
// available list (e.g. an address that was since deleted, or a method the
|
|
103
|
+
// caller cannot see) so saving does not silently drop it.
|
|
104
|
+
const known = props.options.some((o) => o.id === props.value);
|
|
105
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: props.id, children: props.label }), _jsxs(Select, { id: props.id, value: props.value, onChange: (e) => props.onChange(e.target.value), children: [_jsx("option", { value: "", children: props.emptyLabel }), props.options.map((o) => (_jsx("option", { value: o.id, children: o.label }, o.id))), props.value && !known ? _jsx("option", { value: props.value, children: props.value }) : null] })] }));
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=DefaultPreferencesPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DefaultPreferencesPanel.js","sourceRoot":"","sources":["../../../src/admin/components/DefaultPreferencesPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `quick_order`'s admin surface — one route, no sidebar entry and three zone
|
|
3
|
+
* contributions (feature 091, P7b and P4d for the zones, Phase 4 batch 13 for
|
|
4
|
+
* the route;
|
|
5
|
+
* `specs/091-module-owned-admin-surfaces/contracts/admin-component-contribution.md`
|
|
6
|
+
* §10).
|
|
7
|
+
*
|
|
8
|
+
* **No sidebar entry, and it is not an omission.** `AppShell.tsx`'s own
|
|
9
|
+
* comment records why, in the *Sales* section this module never had a row in:
|
|
10
|
+
* quick order *"is not a second destination — it is the other way of getting
|
|
11
|
+
* lines into the same order, so it lives behind a tab on the order-entry page
|
|
12
|
+
* rather than on its own sidebar row"*. That tab is the
|
|
13
|
+
* `order.entry.tabs` contribution below, which P4d declared. So this module's
|
|
14
|
+
* `{ routes: 1, nav: 0 }` entry leaves the ratchet like any other: a zero that
|
|
15
|
+
* stays zero is a passing assertion, not a missing one, and `plan.md`'s Ruling
|
|
16
|
+
* 1 puts the off-state proof on the **route**, which is what an operator
|
|
17
|
+
* following a stale deep link meets.
|
|
18
|
+
*
|
|
19
|
+
* **The zones came first, and that is the property the batch rests on.** P7b
|
|
20
|
+
* and P4d declared the three contributions below while this screen was still
|
|
21
|
+
* `admin/src/App.tsx`'s, because `check:admin-registrations` counts routes and
|
|
22
|
+
* nav entries and a zone is neither.
|
|
23
|
+
*
|
|
24
|
+
* **What it drains**: both `DefaultPreferencesPanel` keys of the boundary
|
|
25
|
+
* ledger — the whole of
|
|
26
|
+
* `backend/scripts/ledgers/cross-module-imports/customers.ts`, which is
|
|
27
|
+
* deleted, and one of the three in `organizations.ts`. Each entry's recorded
|
|
28
|
+
* retiring condition is *"the owner declaring an admin contribution zone"*, and
|
|
29
|
+
* this is that declaration.
|
|
30
|
+
*
|
|
31
|
+
* **And, with P4d, one of the last two keys of
|
|
32
|
+
* `backend/scripts/ledgers/admin-surface.ts`**:
|
|
33
|
+
* `admin/src/modules/quick_order/QuickOrderOnBehalfPage.tsx` importing
|
|
34
|
+
* `OrderEntryTabs` out of `admin/src/components/`. `orders` drains the other
|
|
35
|
+
* with the twin tab, and with the pair gone that ledger is empty.
|
|
36
|
+
*
|
|
37
|
+
* **Zone and not a published component**, decided from the signature read off
|
|
38
|
+
* the file in this merge request (§9.3): `({ scope, scopeId })` — two
|
|
39
|
+
* identifiers in, nothing back, no `value`/`onChange` pair, and the panel owns
|
|
40
|
+
* its own `PUT`. That is Z1 question 2, an addition this module makes because
|
|
41
|
+
* this module is installed.
|
|
42
|
+
*
|
|
43
|
+
* **This entry exports data and nothing else** (R2); every component is a
|
|
44
|
+
* dynamic-import factory (R6).
|
|
45
|
+
*/
|
|
46
|
+
import { type AdminContributions } from '@endora-commerce/admin-kit/contributions';
|
|
47
|
+
export declare const contributions: AdminContributions;
|
|
48
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,0CAA0C,CAAC;AAiClD,eAAO,MAAM,aAAa,EAAE,kBA2C3B,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `quick_order`'s admin surface — one route, no sidebar entry and three zone
|
|
3
|
+
* contributions (feature 091, P7b and P4d for the zones, Phase 4 batch 13 for
|
|
4
|
+
* the route;
|
|
5
|
+
* `specs/091-module-owned-admin-surfaces/contracts/admin-component-contribution.md`
|
|
6
|
+
* §10).
|
|
7
|
+
*
|
|
8
|
+
* **No sidebar entry, and it is not an omission.** `AppShell.tsx`'s own
|
|
9
|
+
* comment records why, in the *Sales* section this module never had a row in:
|
|
10
|
+
* quick order *"is not a second destination — it is the other way of getting
|
|
11
|
+
* lines into the same order, so it lives behind a tab on the order-entry page
|
|
12
|
+
* rather than on its own sidebar row"*. That tab is the
|
|
13
|
+
* `order.entry.tabs` contribution below, which P4d declared. So this module's
|
|
14
|
+
* `{ routes: 1, nav: 0 }` entry leaves the ratchet like any other: a zero that
|
|
15
|
+
* stays zero is a passing assertion, not a missing one, and `plan.md`'s Ruling
|
|
16
|
+
* 1 puts the off-state proof on the **route**, which is what an operator
|
|
17
|
+
* following a stale deep link meets.
|
|
18
|
+
*
|
|
19
|
+
* **The zones came first, and that is the property the batch rests on.** P7b
|
|
20
|
+
* and P4d declared the three contributions below while this screen was still
|
|
21
|
+
* `admin/src/App.tsx`'s, because `check:admin-registrations` counts routes and
|
|
22
|
+
* nav entries and a zone is neither.
|
|
23
|
+
*
|
|
24
|
+
* **What it drains**: both `DefaultPreferencesPanel` keys of the boundary
|
|
25
|
+
* ledger — the whole of
|
|
26
|
+
* `backend/scripts/ledgers/cross-module-imports/customers.ts`, which is
|
|
27
|
+
* deleted, and one of the three in `organizations.ts`. Each entry's recorded
|
|
28
|
+
* retiring condition is *"the owner declaring an admin contribution zone"*, and
|
|
29
|
+
* this is that declaration.
|
|
30
|
+
*
|
|
31
|
+
* **And, with P4d, one of the last two keys of
|
|
32
|
+
* `backend/scripts/ledgers/admin-surface.ts`**:
|
|
33
|
+
* `admin/src/modules/quick_order/QuickOrderOnBehalfPage.tsx` importing
|
|
34
|
+
* `OrderEntryTabs` out of `admin/src/components/`. `orders` drains the other
|
|
35
|
+
* with the twin tab, and with the pair gone that ledger is empty.
|
|
36
|
+
*
|
|
37
|
+
* **Zone and not a published component**, decided from the signature read off
|
|
38
|
+
* the file in this merge request (§9.3): `({ scope, scopeId })` — two
|
|
39
|
+
* identifiers in, nothing back, no `value`/`onChange` pair, and the panel owns
|
|
40
|
+
* its own `PUT`. That is Z1 question 2, an addition this module makes because
|
|
41
|
+
* this module is installed.
|
|
42
|
+
*
|
|
43
|
+
* **This entry exports data and nothing else** (R2); every component is a
|
|
44
|
+
* dynamic-import factory (R6).
|
|
45
|
+
*/
|
|
46
|
+
import { zoneComponent, } from '@endora-commerce/admin-kit/contributions';
|
|
47
|
+
/**
|
|
48
|
+
* The code that opens both contributed surfaces — and it is **not**
|
|
49
|
+
* `quick_order:read`, which §10.6 named and which exists nowhere.
|
|
50
|
+
*
|
|
51
|
+
* Read off the routes in this merge request, as §10.6's own instruction for the
|
|
52
|
+
* sibling row requires: `packages/modules/quick_order/src/backend/routes.preferences.admin.ts`
|
|
53
|
+
* gates `GET` and `PUT /api/v1/admin/quick-order/preferences` with
|
|
54
|
+
* `requireAdmin('orders:write')`, and every other admin route this module owns
|
|
55
|
+
* takes the same code — the manifest's own palette action says so in place.
|
|
56
|
+
* There is no `quick_order:*` permission in the platform at all, so declaring
|
|
57
|
+
* one would not merely advertise a 403: no role could ever hold it, and the
|
|
58
|
+
* panel would be invisible to every operator including the one who can use it.
|
|
59
|
+
*
|
|
60
|
+
* It is a **write** code for a surface that also reads, which is honest here
|
|
61
|
+
* rather than a compromise: the panel is an editor, its `GET` is gated on the
|
|
62
|
+
* same code as its `PUT`, and an operator holding `orders:write` can do both.
|
|
63
|
+
*/
|
|
64
|
+
const PREFERENCES_PERMISSION = 'orders:write';
|
|
65
|
+
/**
|
|
66
|
+
* The module's only route: placing an order on a customer's behalf.
|
|
67
|
+
*
|
|
68
|
+
* It sits under `/orders/` rather than at a path of its own, which is the
|
|
69
|
+
* placement the host table had and this declaration keeps: `orders` declares
|
|
70
|
+
* `/orders`, `/orders/new`, `/orders/statuses` and `/orders/:id`, and
|
|
71
|
+
* `<Routes>` ranks by specificity, so the static `quick-order` segment wins
|
|
72
|
+
* over `orders`' parametric detail route whatever order the registry composes
|
|
73
|
+
* them in.
|
|
74
|
+
*/
|
|
75
|
+
const ROUTE_PATH = '/orders/quick-order';
|
|
76
|
+
export const contributions = {
|
|
77
|
+
routes: [
|
|
78
|
+
{
|
|
79
|
+
path: ROUTE_PATH,
|
|
80
|
+
component: () => import('./pages/QuickOrderOnBehalfPage.js'),
|
|
81
|
+
// The same `orders:write` the zones declare, and for the same reason
|
|
82
|
+
// read off the routes rather than guessed: the two `POST`s behind this
|
|
83
|
+
// screen (`src/backend/routes.admin.ts`) carry it, and there is no
|
|
84
|
+
// `quick_order:*` code in the platform at all.
|
|
85
|
+
requiredPermission: PREFERENCES_PERMISSION,
|
|
86
|
+
index: true,
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
zones: [
|
|
90
|
+
// Weight 300 of four contributors to the organization detail's zone:
|
|
91
|
+
// `sales_channels` at 100, `price_lists` at 200, this panel, then `carts`
|
|
92
|
+
// at 400. That is the order the operator saw when the panels were
|
|
93
|
+
// scattered through `OrganizationDetail.tsx`, preserved rather than
|
|
94
|
+
// re-chosen.
|
|
95
|
+
zoneComponent('organization.detail.after', () => import('./zones/OrganizationDefaults.js'), {
|
|
96
|
+
weight: 300,
|
|
97
|
+
requiredPermission: PREFERENCES_PERMISSION,
|
|
98
|
+
}),
|
|
99
|
+
// The only contribution to the customer detail's zone, so the weight
|
|
100
|
+
// orders nothing today. Declared rather than defaulted so a second
|
|
101
|
+
// contributor arrives beside it rather than ahead of it by accident.
|
|
102
|
+
zoneComponent('customer.detail.after', () => import('./zones/CustomerDefaults.js'), {
|
|
103
|
+
weight: 100,
|
|
104
|
+
requiredPermission: PREFERENCES_PERMISSION,
|
|
105
|
+
}),
|
|
106
|
+
// Weight 200 of the two tabs in the order-entry strip: `orders`' standard
|
|
107
|
+
// tab at 100, then this one. That is the order the operator has seen since
|
|
108
|
+
// the strip existed, preserved rather than re-chosen.
|
|
109
|
+
//
|
|
110
|
+
// The same `orders:write`, and for the same reason one level down: the two
|
|
111
|
+
// `POST`s behind `/orders/quick-order`
|
|
112
|
+
// (`src/backend/routes.admin.ts`) carry it, and there is no
|
|
113
|
+
// `quick_order:*` code in the platform at all.
|
|
114
|
+
zoneComponent('order.entry.tabs', () => import('./zones/OrderEntryQuickTab.js'), {
|
|
115
|
+
weight: 200,
|
|
116
|
+
requiredPermission: PREFERENCES_PERMISSION,
|
|
117
|
+
}),
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,OAAO,EACL,aAAa,GAEd,MAAM,0CAA0C,CAAC;AAElD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,sBAAsB,GAAG,cAAc,CAAC;AAE9C;;;;;;;;;GASG;AACH,MAAM,UAAU,GAAG,qBAAqB,CAAC;AAEzC,MAAM,CAAC,MAAM,aAAa,GAAuB;IAC/C,MAAM,EAAE;QACN;YACE,IAAI,EAAE,UAAU;YAChB,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,mCAAmC,CAAC;YAC5D,qEAAqE;YACrE,uEAAuE;YACvE,mEAAmE;YACnE,+CAA+C;YAC/C,kBAAkB,EAAE,sBAAsB;YAC1C,KAAK,EAAE,IAAI;SACZ;KACF;IACD,KAAK,EAAE;QACL,qEAAqE;QACrE,0EAA0E;QAC1E,kEAAkE;QAClE,oEAAoE;QACpE,aAAa;QACb,aAAa,CAAC,2BAA2B,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,iCAAiC,CAAC,EAAE;YAC1F,MAAM,EAAE,GAAG;YACX,kBAAkB,EAAE,sBAAsB;SAC3C,CAAC;QACF,qEAAqE;QACrE,mEAAmE;QACnE,qEAAqE;QACrE,aAAa,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,6BAA6B,CAAC,EAAE;YAClF,MAAM,EAAE,GAAG;YACX,kBAAkB,EAAE,sBAAsB;SAC3C,CAAC;QACF,0EAA0E;QAC1E,2EAA2E;QAC3E,sDAAsD;QACtD,EAAE;QACF,2EAA2E;QAC3E,uCAAuC;QACvC,4DAA4D;QAC5D,+CAA+C;QAC/C,aAAa,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,+BAA+B,CAAC,EAAE;YAC/E,MAAM,EAAE,GAAG;YACX,kBAAkB,EAAE,sBAAsB;SAC3C,CAAC;KACH;CACF,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* QuickOrderOnBehalfPage — feature 039 (US1 / FR-008).
|
|
4
|
+
*
|
|
5
|
+
* Lets an operator import a CSV / Excel file (or paste CSV) and build a Cart
|
|
6
|
+
* or Quote Request on behalf of a chosen customer + organization. Identifier
|
|
7
|
+
* fields are entered directly, matching the existing OrderCreatePage approach.
|
|
8
|
+
*/
|
|
9
|
+
export declare function QuickOrderOnBehalfPage(): ReactNode;
|
|
10
|
+
/**
|
|
11
|
+
* The registry loads a route component through a dynamic-import factory and
|
|
12
|
+
* reads its default export (feature 091, FR-013). The named export stays: it is
|
|
13
|
+
* the spelling this module's own code and its tests use.
|
|
14
|
+
*/
|
|
15
|
+
export default QuickOrderOnBehalfPage;
|
|
16
|
+
//# sourceMappingURL=QuickOrderOnBehalfPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuickOrderOnBehalfPage.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/QuickOrderOnBehalfPage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAcjD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI,SAAS,CAsNlD;AAED;;;;GAIG;AACH,eAAe,sBAAsB,CAAC"}
|