@pancake-pos/ui-extensions 2026.1.3 → 2026.1.5
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/dist/elements.generated.d.ts +76 -0
- package/dist/page.js +21 -13
- package/dist/types.d.ts +72 -16
- package/package.json +1 -1
|
@@ -59,6 +59,29 @@ export interface PosButtonElement extends PosButtonProps {
|
|
|
59
59
|
focus(): void;
|
|
60
60
|
scrollIntoView(): void;
|
|
61
61
|
}
|
|
62
|
+
/** Thuộc tính của `<pos-chart>`. */
|
|
63
|
+
export interface PosChartProps {
|
|
64
|
+
type?: "line" | "bar" | "area" | "pie";
|
|
65
|
+
data?: (Record<string, string | number | null>)[];
|
|
66
|
+
xKey?: string;
|
|
67
|
+
series?: ({
|
|
68
|
+
key: string;
|
|
69
|
+
label: string;
|
|
70
|
+
format?: "number" | "money";
|
|
71
|
+
})[];
|
|
72
|
+
stacked?: boolean;
|
|
73
|
+
height?: number;
|
|
74
|
+
loading?: boolean;
|
|
75
|
+
emptyText?: string;
|
|
76
|
+
}
|
|
77
|
+
/** Sự kiện của `<pos-chart>` → kiểu `event.detail`. */
|
|
78
|
+
export interface PosChartEvents {
|
|
79
|
+
}
|
|
80
|
+
export interface PosChartAttributes extends PosChartProps, PosBaseAttributes {
|
|
81
|
+
}
|
|
82
|
+
export interface PosChartElement extends PosChartProps {
|
|
83
|
+
scrollIntoView(): void;
|
|
84
|
+
}
|
|
62
85
|
/** Thuộc tính của `<pos-checkbox>`. */
|
|
63
86
|
export interface PosCheckboxProps {
|
|
64
87
|
label?: string;
|
|
@@ -116,6 +139,17 @@ export interface PosDividerAttributes extends PosDividerProps, PosBaseAttributes
|
|
|
116
139
|
export interface PosDividerElement extends PosDividerProps {
|
|
117
140
|
scrollIntoView(): void;
|
|
118
141
|
}
|
|
142
|
+
/** Thuộc tính của `<pos-filter-bar>`. */
|
|
143
|
+
export interface PosFilterBarProps {
|
|
144
|
+
}
|
|
145
|
+
/** Sự kiện của `<pos-filter-bar>` → kiểu `event.detail`. */
|
|
146
|
+
export interface PosFilterBarEvents {
|
|
147
|
+
}
|
|
148
|
+
export interface PosFilterBarAttributes extends PosFilterBarProps, PosBaseAttributes {
|
|
149
|
+
}
|
|
150
|
+
export interface PosFilterBarElement extends PosFilterBarProps {
|
|
151
|
+
scrollIntoView(): void;
|
|
152
|
+
}
|
|
119
153
|
/** Thuộc tính của `<pos-grid>`. */
|
|
120
154
|
export interface PosGridProps {
|
|
121
155
|
columns?: number;
|
|
@@ -227,6 +261,20 @@ export interface PosNumberFieldElement extends PosNumberFieldProps {
|
|
|
227
261
|
focus(): void;
|
|
228
262
|
scrollIntoView(): void;
|
|
229
263
|
}
|
|
264
|
+
/** Thuộc tính của `<pos-page>`. */
|
|
265
|
+
export interface PosPageProps {
|
|
266
|
+
heading?: string;
|
|
267
|
+
description?: string;
|
|
268
|
+
width?: "narrow" | "default" | "full";
|
|
269
|
+
}
|
|
270
|
+
/** Sự kiện của `<pos-page>` → kiểu `event.detail`. */
|
|
271
|
+
export interface PosPageEvents {
|
|
272
|
+
}
|
|
273
|
+
export interface PosPageAttributes extends PosPageProps, PosBaseAttributes {
|
|
274
|
+
}
|
|
275
|
+
export interface PosPageElement extends PosPageProps {
|
|
276
|
+
scrollIntoView(): void;
|
|
277
|
+
}
|
|
230
278
|
/** Thuộc tính của `<pos-section>`. */
|
|
231
279
|
export interface PosSectionProps {
|
|
232
280
|
heading?: string;
|
|
@@ -332,6 +380,26 @@ export interface PosTableAttributes extends PosTableProps, PosBaseAttributes {
|
|
|
332
380
|
export interface PosTableElement extends PosTableProps {
|
|
333
381
|
scrollIntoView(): void;
|
|
334
382
|
}
|
|
383
|
+
/** Thuộc tính của `<pos-tabs>`. */
|
|
384
|
+
export interface PosTabsProps {
|
|
385
|
+
tabs?: {
|
|
386
|
+
id: string;
|
|
387
|
+
label: string;
|
|
388
|
+
badge?: number;
|
|
389
|
+
disabled?: boolean;
|
|
390
|
+
}[];
|
|
391
|
+
selected?: string;
|
|
392
|
+
}
|
|
393
|
+
/** Sự kiện của `<pos-tabs>` → kiểu `event.detail`. */
|
|
394
|
+
export interface PosTabsEvents {
|
|
395
|
+
change: string;
|
|
396
|
+
}
|
|
397
|
+
export interface PosTabsAttributes extends PosTabsProps, PosBaseAttributes {
|
|
398
|
+
onChange?: (event: PosEvent<PosTabsEvents["change"]>) => void;
|
|
399
|
+
}
|
|
400
|
+
export interface PosTabsElement extends PosTabsProps {
|
|
401
|
+
scrollIntoView(): void;
|
|
402
|
+
}
|
|
335
403
|
/** Thuộc tính của `<pos-text>`. */
|
|
336
404
|
export interface PosTextProps {
|
|
337
405
|
tone?: "default" | "subdued" | "success" | "warning" | "critical";
|
|
@@ -376,9 +444,11 @@ export interface PosIntrinsicElements {
|
|
|
376
444
|
"pos-badge": PosBadgeAttributes;
|
|
377
445
|
"pos-banner": PosBannerAttributes;
|
|
378
446
|
"pos-button": PosButtonAttributes;
|
|
447
|
+
"pos-chart": PosChartAttributes;
|
|
379
448
|
"pos-checkbox": PosCheckboxAttributes;
|
|
380
449
|
"pos-date-picker": PosDatePickerAttributes;
|
|
381
450
|
"pos-divider": PosDividerAttributes;
|
|
451
|
+
"pos-filter-bar": PosFilterBarAttributes;
|
|
382
452
|
"pos-grid": PosGridAttributes;
|
|
383
453
|
"pos-heading": PosHeadingAttributes;
|
|
384
454
|
"pos-image": PosImageAttributes;
|
|
@@ -386,11 +456,13 @@ export interface PosIntrinsicElements {
|
|
|
386
456
|
"pos-modal": PosModalAttributes;
|
|
387
457
|
"pos-money": PosMoneyAttributes;
|
|
388
458
|
"pos-number-field": PosNumberFieldAttributes;
|
|
459
|
+
"pos-page": PosPageAttributes;
|
|
389
460
|
"pos-section": PosSectionAttributes;
|
|
390
461
|
"pos-select": PosSelectAttributes;
|
|
391
462
|
"pos-spinner": PosSpinnerAttributes;
|
|
392
463
|
"pos-stack": PosStackAttributes;
|
|
393
464
|
"pos-table": PosTableAttributes;
|
|
465
|
+
"pos-tabs": PosTabsAttributes;
|
|
394
466
|
"pos-text": PosTextAttributes;
|
|
395
467
|
"pos-text-field": PosTextFieldAttributes;
|
|
396
468
|
}
|
|
@@ -399,9 +471,11 @@ export interface PosHTMLElementTagNameMap {
|
|
|
399
471
|
"pos-badge": Omit<HTMLElement, keyof PosBadgeElement> & PosBadgeElement;
|
|
400
472
|
"pos-banner": Omit<HTMLElement, keyof PosBannerElement> & PosBannerElement;
|
|
401
473
|
"pos-button": Omit<HTMLElement, keyof PosButtonElement> & PosButtonElement;
|
|
474
|
+
"pos-chart": Omit<HTMLElement, keyof PosChartElement> & PosChartElement;
|
|
402
475
|
"pos-checkbox": Omit<HTMLElement, keyof PosCheckboxElement> & PosCheckboxElement;
|
|
403
476
|
"pos-date-picker": Omit<HTMLElement, keyof PosDatePickerElement> & PosDatePickerElement;
|
|
404
477
|
"pos-divider": Omit<HTMLElement, keyof PosDividerElement> & PosDividerElement;
|
|
478
|
+
"pos-filter-bar": Omit<HTMLElement, keyof PosFilterBarElement> & PosFilterBarElement;
|
|
405
479
|
"pos-grid": Omit<HTMLElement, keyof PosGridElement> & PosGridElement;
|
|
406
480
|
"pos-heading": Omit<HTMLElement, keyof PosHeadingElement> & PosHeadingElement;
|
|
407
481
|
"pos-image": Omit<HTMLElement, keyof PosImageElement> & PosImageElement;
|
|
@@ -409,11 +483,13 @@ export interface PosHTMLElementTagNameMap {
|
|
|
409
483
|
"pos-modal": Omit<HTMLElement, keyof PosModalElement> & PosModalElement;
|
|
410
484
|
"pos-money": Omit<HTMLElement, keyof PosMoneyElement> & PosMoneyElement;
|
|
411
485
|
"pos-number-field": Omit<HTMLElement, keyof PosNumberFieldElement> & PosNumberFieldElement;
|
|
486
|
+
"pos-page": Omit<HTMLElement, keyof PosPageElement> & PosPageElement;
|
|
412
487
|
"pos-section": Omit<HTMLElement, keyof PosSectionElement> & PosSectionElement;
|
|
413
488
|
"pos-select": Omit<HTMLElement, keyof PosSelectElement> & PosSelectElement;
|
|
414
489
|
"pos-spinner": Omit<HTMLElement, keyof PosSpinnerElement> & PosSpinnerElement;
|
|
415
490
|
"pos-stack": Omit<HTMLElement, keyof PosStackElement> & PosStackElement;
|
|
416
491
|
"pos-table": Omit<HTMLElement, keyof PosTableElement> & PosTableElement;
|
|
492
|
+
"pos-tabs": Omit<HTMLElement, keyof PosTabsElement> & PosTabsElement;
|
|
417
493
|
"pos-text": Omit<HTMLElement, keyof PosTextElement> & PosTextElement;
|
|
418
494
|
"pos-text-field": Omit<HTMLElement, keyof PosTextFieldElement> & PosTextFieldElement;
|
|
419
495
|
}
|
package/dist/page.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// ../app-protocol/src/protocol.ts
|
|
2
2
|
var PROTOCOL_VERSION = 1;
|
|
3
|
+
function hostEvents(context) {
|
|
4
|
+
return context === "page" ? ["primary-action"] : [];
|
|
5
|
+
}
|
|
3
6
|
function extensionContext(kind, target) {
|
|
4
7
|
if (kind === "hook") return "hook";
|
|
5
8
|
if (kind === "headless") return "action-headless";
|
|
@@ -45,6 +48,9 @@ var PosApiError = class extends Error {
|
|
|
45
48
|
this.name = "PosApiError";
|
|
46
49
|
}
|
|
47
50
|
};
|
|
51
|
+
function withData(value) {
|
|
52
|
+
return Object.defineProperties({}, Object.getOwnPropertyDescriptors(value));
|
|
53
|
+
}
|
|
48
54
|
function buildQuery(query) {
|
|
49
55
|
if (!query) return "";
|
|
50
56
|
const params = new URLSearchParams();
|
|
@@ -60,6 +66,7 @@ function createPos(deps) {
|
|
|
60
66
|
const { init } = deps;
|
|
61
67
|
const now = deps.now ?? Date.now;
|
|
62
68
|
const context = extensionContext(init.kind, init.target);
|
|
69
|
+
const events = hostEvents(context);
|
|
63
70
|
const listeners = /* @__PURE__ */ new Map();
|
|
64
71
|
let data = init.data;
|
|
65
72
|
let token = { ...init.token };
|
|
@@ -179,18 +186,28 @@ function createPos(deps) {
|
|
|
179
186
|
},
|
|
180
187
|
on(event, handler) {
|
|
181
188
|
if (event === "data-change") require2("data-change", "pos.on('data-change')");
|
|
182
|
-
else if (!
|
|
189
|
+
else if (!events.includes(event)) throw new PosRuntimeError("unavailable", `event ${event} is not available in ${init.target}`);
|
|
183
190
|
let set = listeners.get(event);
|
|
184
191
|
if (!set) listeners.set(event, set = /* @__PURE__ */ new Set());
|
|
185
192
|
set.add(handler);
|
|
186
193
|
return () => set.delete(handler);
|
|
187
194
|
}
|
|
188
195
|
};
|
|
196
|
+
const page = Object.freeze({
|
|
197
|
+
setTitle(title) {
|
|
198
|
+
void callHost("page.setTitle", [String(title).slice(0, 200)], "pos.page.setTitle");
|
|
199
|
+
},
|
|
200
|
+
setPrimaryAction(action) {
|
|
201
|
+
const value = action ? { label: String(action.label).slice(0, 50), disabled: !!action.disabled, loading: !!action.loading } : null;
|
|
202
|
+
void callHost("page.setPrimaryAction", [value], "pos.page.setPrimaryAction");
|
|
203
|
+
}
|
|
204
|
+
});
|
|
189
205
|
const emit = (event, payload) => {
|
|
206
|
+
if (event !== "data-change" && !events.includes(event)) return;
|
|
190
207
|
for (const handler of [...listeners.get(event) ?? []]) handler(payload);
|
|
191
208
|
};
|
|
192
209
|
return {
|
|
193
|
-
pos: Object.freeze(pos),
|
|
210
|
+
pos: Object.freeze(context === "page" ? Object.defineProperty(withData(pos), "page", { value: page, enumerable: true }) : pos),
|
|
194
211
|
setData(next) {
|
|
195
212
|
data = next;
|
|
196
213
|
emit("data-change", next);
|
|
@@ -257,7 +274,6 @@ function start(port, init) {
|
|
|
257
274
|
});
|
|
258
275
|
const runtime = createPos({
|
|
259
276
|
init: { ...init, kind: "ui", data: currentLocation() },
|
|
260
|
-
events: ["primary-action"],
|
|
261
277
|
call,
|
|
262
278
|
fetch: window.fetch.bind(window)
|
|
263
279
|
});
|
|
@@ -314,16 +330,8 @@ function start(port, init) {
|
|
|
314
330
|
};
|
|
315
331
|
window.addEventListener("error", (event) => reportError(event.error ?? event.message));
|
|
316
332
|
window.addEventListener("unhandledrejection", (event) => reportError(event.reason));
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
void call("page.setTitle", [String(title).slice(0, 200)]);
|
|
320
|
-
},
|
|
321
|
-
setPrimaryAction(action) {
|
|
322
|
-
void call("page.setPrimaryAction", [action ? { label: String(action.label).slice(0, 50), disabled: !!action.disabled, loading: !!action.loading } : null]);
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
const pos = Object.defineProperties({}, { ...Object.getOwnPropertyDescriptors(runtime.pos), page: { value: page, enumerable: true } });
|
|
326
|
-
return Object.freeze(pos);
|
|
333
|
+
const pos = runtime.pos;
|
|
334
|
+
return pos;
|
|
327
335
|
}
|
|
328
336
|
export {
|
|
329
337
|
PosApiError2 as PosApiError,
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export type Resource = 'order' | 'product' | 'purchase' | 'export' | 'warehouse_transfer';
|
|
2
|
+
/** Resource có danh sách và action: 5 resource có form chi tiết và khách hàng (`customer.*`). */
|
|
3
|
+
export type ListResource = Resource | 'customer';
|
|
2
4
|
export type OrderRef = {
|
|
3
5
|
/** Mã đơn hiển thị (mã tuỳ chỉnh nếu shop dùng, ngược lại là mã hệ thống). */
|
|
4
6
|
id: string | number;
|
|
@@ -104,12 +106,23 @@ export type WarehouseTransferDraft = {
|
|
|
104
106
|
quantity: number;
|
|
105
107
|
}[];
|
|
106
108
|
};
|
|
109
|
+
/** Khách hàng (`customer.*`). `id` dùng với Open API: `/shops/{shop_id}/customers/{id}`. */
|
|
110
|
+
export type CustomerRef = {
|
|
111
|
+
id: string;
|
|
112
|
+
name: string;
|
|
113
|
+
phone_numbers: string[];
|
|
114
|
+
tags: (number | string)[];
|
|
115
|
+
level_id: string | null;
|
|
116
|
+
assigned_user_id: string | null;
|
|
117
|
+
updated_at: string | null;
|
|
118
|
+
};
|
|
107
119
|
interface Refs {
|
|
108
120
|
order: OrderRef;
|
|
109
121
|
product: ProductRef;
|
|
110
122
|
purchase: PurchaseRef;
|
|
111
123
|
export: ExportRef;
|
|
112
124
|
warehouse_transfer: WarehouseTransferRef;
|
|
125
|
+
customer: CustomerRef;
|
|
113
126
|
}
|
|
114
127
|
interface Drafts {
|
|
115
128
|
order: OrderDraft;
|
|
@@ -118,7 +131,7 @@ interface Drafts {
|
|
|
118
131
|
export: ExportDraft;
|
|
119
132
|
warehouse_transfer: WarehouseTransferDraft;
|
|
120
133
|
}
|
|
121
|
-
export type RefOf<R extends
|
|
134
|
+
export type RefOf<R extends ListResource> = Refs[R];
|
|
122
135
|
export type DraftOf<R extends Resource> = Drafts[R];
|
|
123
136
|
/** Form chi tiết: `*.details.action`, `*.details.block`, `*.before_submit`. */
|
|
124
137
|
export type DetailsData<R extends Resource = Resource> = {
|
|
@@ -130,12 +143,12 @@ export type DetailsData<R extends Resource = Resource> = {
|
|
|
130
143
|
draft: DraftOf<R>;
|
|
131
144
|
};
|
|
132
145
|
/** Một dòng của danh sách: `*.index.action`. */
|
|
133
|
-
export type IndexData<R extends
|
|
146
|
+
export type IndexData<R extends ListResource = ListResource> = {
|
|
134
147
|
resource: R;
|
|
135
148
|
record: RefOf<R>;
|
|
136
149
|
};
|
|
137
150
|
/** Thanh thao tác hàng loạt: `*.index.selection-action` (tối đa 500 bản ghi). */
|
|
138
|
-
export type SelectionData<R extends
|
|
151
|
+
export type SelectionData<R extends ListResource = ListResource> = {
|
|
139
152
|
resource: R;
|
|
140
153
|
records: RefOf<R>[];
|
|
141
154
|
};
|
|
@@ -145,13 +158,51 @@ export type AfterSaveInput<R extends Resource = Resource> = {
|
|
|
145
158
|
record: RefOf<R>;
|
|
146
159
|
};
|
|
147
160
|
export type BeforeSubmitInput<R extends Resource = Resource> = DetailsData<R>;
|
|
161
|
+
/**
|
|
162
|
+
* Thay đổi app muốn áp vào bản ghi trước khi lưu (`before_submit`): `note` ghi đè ghi chú (≤ 2000 ký tự),
|
|
163
|
+
* `add_tags` thêm thẻ theo mã thẻ của shop (≤ 20). Resource không có trường đó thì bị bỏ qua.
|
|
164
|
+
*/
|
|
165
|
+
export type BeforeSubmitChanges = {
|
|
166
|
+
note?: string;
|
|
167
|
+
add_tags?: (number | string)[];
|
|
168
|
+
};
|
|
148
169
|
/** `message` tối đa 200 ký tự, hiện cho người dùng. */
|
|
149
170
|
export type BeforeSubmitResult = {
|
|
150
171
|
ok: true;
|
|
172
|
+
changes?: BeforeSubmitChanges;
|
|
151
173
|
} | {
|
|
152
174
|
ok: false;
|
|
153
175
|
message: string;
|
|
154
176
|
};
|
|
177
|
+
/** Hồ sơ khách hàng: `customer.details.block`, `customer.details.action` (cùng dạng `IndexData<'customer'>`). */
|
|
178
|
+
export type CustomerData = {
|
|
179
|
+
resource: 'customer';
|
|
180
|
+
record: CustomerRef;
|
|
181
|
+
};
|
|
182
|
+
/** Resource có mẫu in của app (`<resource>.print-action`); sản phẩm chỉ in mã vạch nên không có. */
|
|
183
|
+
export type PrintResource = 'order' | 'purchase' | 'export' | 'warehouse_transfer';
|
|
184
|
+
/** Bản ghi được chọn để in: `<resource>.print-action` (1–500 bản ghi). */
|
|
185
|
+
export type PrintData<R extends PrintResource = PrintResource> = {
|
|
186
|
+
resource: R;
|
|
187
|
+
records: RefOf<R>[];
|
|
188
|
+
};
|
|
189
|
+
/** HTML của bản in (≤ 2 MB). POS lọc bỏ script, chỉ giữ ảnh hợp lệ rồi in. */
|
|
190
|
+
export type PrintResult = {
|
|
191
|
+
html: string;
|
|
192
|
+
title?: string;
|
|
193
|
+
};
|
|
194
|
+
/** Bản ghi đang hiển thị trên trang danh sách: `<resource>.index.column` (tối đa 500). */
|
|
195
|
+
export type ColumnData<R extends ListResource = ListResource> = {
|
|
196
|
+
resource: R;
|
|
197
|
+
records: RefOf<R>[];
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Giá trị của ô theo mã bản ghi: `system_id` với đơn, `id` với resource khác (chuỗi tối đa 200 ký tự). Bản ghi không
|
|
201
|
+
* có trong `values` để trống.
|
|
202
|
+
*/
|
|
203
|
+
export type ColumnResult = {
|
|
204
|
+
values: Record<string, string | number | null>;
|
|
205
|
+
};
|
|
155
206
|
export type HeadlessActionResult = {
|
|
156
207
|
message?: string;
|
|
157
208
|
refresh?: boolean;
|
|
@@ -162,12 +213,13 @@ export type PageData = {
|
|
|
162
213
|
query: Record<string, string>;
|
|
163
214
|
};
|
|
164
215
|
export type DetailsTarget<R extends Resource = Resource> = `${R}.details.action` | `${R}.details.block`;
|
|
165
|
-
export type Target = 'app.page' | DetailsTarget | `${
|
|
166
|
-
type ResourceOf<T extends string> = T extends `${infer R extends
|
|
216
|
+
export type Target = 'app.page' | DetailsTarget | `${ListResource}.index.action` | `${ListResource}.index.selection-action` | `${Resource}.before_submit` | `${Resource}.after_save` | `${ListResource}.index.column` | `${PrintResource}.print-action` | 'customer.details.block' | 'customer.details.action';
|
|
217
|
+
type ResourceOf<T extends string> = T extends `${infer R extends ListResource}.${string}` ? R : never;
|
|
218
|
+
type FormResourceOf<T extends string> = Extract<ResourceOf<T>, Resource>;
|
|
167
219
|
/** `pos.data` và tham số của module theo target. */
|
|
168
|
-
export type DataOf<T extends Target> = T extends 'app.page' ? PageData : T extends `${string}.index.selection-action` ? SelectionData<ResourceOf<T>> : T extends `${string}.index.action` ? IndexData<ResourceOf<T>> : T extends `${string}.after_save` ? AfterSaveInput<
|
|
220
|
+
export type DataOf<T extends Target> = T extends 'app.page' ? PageData : T extends 'customer.details.block' | 'customer.details.action' ? CustomerData : T extends `${infer R extends PrintResource}.print-action` ? PrintData<R> : T extends `${string}.index.column` ? ColumnData<ResourceOf<T>> : T extends `${string}.index.selection-action` ? SelectionData<ResourceOf<T>> : T extends `${string}.index.action` ? IndexData<ResourceOf<T>> : T extends `${string}.after_save` ? AfterSaveInput<FormResourceOf<T>> : DetailsData<FormResourceOf<T>>;
|
|
169
221
|
/** Giá trị module trả về theo target (action có giao diện và block tự render, không trả gì). */
|
|
170
|
-
export type ResultOf<T extends Target> = T extends `${string}.before_submit` ? BeforeSubmitResult : T extends `${string}.after_save` | `${string}.details.block` | 'app.page' ? void : HeadlessActionResult;
|
|
222
|
+
export type ResultOf<T extends Target> = T extends `${string}.print-action` ? PrintResult : T extends `${string}.index.column` ? ColumnResult : T extends `${string}.before_submit` ? BeforeSubmitResult : T extends `${string}.after_save` | `${string}.details.block` | 'app.page' ? void : HeadlessActionResult;
|
|
171
223
|
export type ToastOptions = {
|
|
172
224
|
tone?: 'success' | 'error' | 'info' | 'warning';
|
|
173
225
|
duration?: number;
|
|
@@ -204,6 +256,15 @@ export interface PosApi {
|
|
|
204
256
|
delete<T = any>(path: string, options?: RequestOptions): Promise<T>;
|
|
205
257
|
}
|
|
206
258
|
export type PosEventName = 'data-change' | 'primary-action';
|
|
259
|
+
/** Thanh tiêu đề của POS trên trang `app.page` (iframe và Worker UI). */
|
|
260
|
+
export interface PosPageApi {
|
|
261
|
+
setTitle(title: string): void;
|
|
262
|
+
setPrimaryAction(action: {
|
|
263
|
+
label: string;
|
|
264
|
+
disabled?: boolean;
|
|
265
|
+
loading?: boolean;
|
|
266
|
+
} | null): void;
|
|
267
|
+
}
|
|
207
268
|
export interface Pos<D = any> {
|
|
208
269
|
readonly apiVersion: string;
|
|
209
270
|
readonly target: string;
|
|
@@ -245,17 +306,12 @@ export interface Pos<D = any> {
|
|
|
245
306
|
close(): void;
|
|
246
307
|
on(event: 'data-change', handler: (data: D) => void): () => void;
|
|
247
308
|
on(event: PosEventName, handler: (payload: any) => void): () => void;
|
|
309
|
+
/** Chỉ có ở `app.page` (iframe và Worker UI). */
|
|
310
|
+
readonly page?: PosPageApi;
|
|
248
311
|
}
|
|
249
|
-
/** `pos` của trang iframe:
|
|
312
|
+
/** `pos` của trang (`connect()` ở trang iframe, biến `pos` của trang Worker UI): luôn có `pos.page`. */
|
|
250
313
|
export interface PosPage extends Pos<PageData> {
|
|
251
|
-
readonly page:
|
|
252
|
-
setTitle(title: string): void;
|
|
253
|
-
setPrimaryAction(action: {
|
|
254
|
-
label: string;
|
|
255
|
-
disabled?: boolean;
|
|
256
|
-
loading?: boolean;
|
|
257
|
-
} | null): void;
|
|
258
|
-
};
|
|
314
|
+
readonly page: PosPageApi;
|
|
259
315
|
}
|
|
260
316
|
/** Lỗi khi gọi `pos.api`; dùng `error.name === 'PosApiError'` hoặc kiểm `status`. */
|
|
261
317
|
export interface PosApiError extends Error {
|
package/package.json
CHANGED