@feedmepos/mf-order-setting 0.0.83 → 0.0.84
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/{DisplaySystemView-BXy_OnbY.js → DisplaySystemView-4Bz8p26A.js} +1 -1
- package/dist/{KioskDevicesView-D3YR1e6K.js → KioskDevicesView-DdwFuenU.js} +1 -1
- package/dist/{KioskDevicesView.vue_vue_type_script_setup_true_lang-CuhL_Q5C.js → KioskDevicesView.vue_vue_type_script_setup_true_lang-CxtLm_oh.js} +3 -3
- package/dist/{KioskSettingView-C3L9_8ag.js → KioskSettingView-D57KtQ-t.js} +289 -240
- package/dist/{KioskView-Cs6VBCj5.js → KioskView-fwBwUGCQ.js} +113 -103
- package/dist/{OrderSettingsView-BdaHRXda.js → OrderSettingsView-RhlyZmzs.js} +1772 -1766
- package/dist/{app-CP6AFTEu.js → app-ClOkRxOZ.js} +26 -6
- package/dist/app.js +1 -1
- package/dist/common/util/index.d.ts +9 -0
- package/dist/frontend/mf-order/src/app.d.ts +20 -0
- package/dist/frontend/mf-order/src/main.d.ts +20 -0
- package/dist/frontend/mf-order/src/modules/order-setting/kiosk/interface.d.ts +2 -0
- package/dist/frontend/mf-order/src/modules/order-setting/kiosk/languages.d.ts +7 -0
- package/dist/frontend/mf-order/src/stores/order-setting/index.d.ts +6 -0
- package/dist/frontend/mf-order/src/views/order-settings/delivery/integrated-delivery/ExternalSetting.vue.d.ts +8 -0
- package/dist/frontend/mf-order/src/views/order-settings/delivery/integrated-delivery/IntegratedDelivery.vue.d.ts +9 -0
- package/dist/frontend/mf-order/tsconfig.app.tsbuildinfo +1 -1
- package/dist/{index-LCS8oexE.js → index-5k7kGCpJ.js} +2 -2
- package/dist/{index-BckeUsPc.js → index-CKEbr9Es.js} +1 -1
- package/dist/{index-DoJzzpyh.js → index-I2YGevce.js} +1 -1
- package/dist/{order.dto-Bm04C1sQ.js → order.dto-Dbn-hRrm.js} +3294 -3235
- package/dist/package/entity/alert/alert-base.dto.d.ts +306 -0
- package/dist/package/entity/alert/alert.dto.d.ts +956 -0
- package/dist/package/entity/alert/alert.enum.d.ts +7 -0
- package/dist/package/entity/alert/categories/integration.d.ts +333 -0
- package/dist/package/entity/alert/categories/kiosk.d.ts +297 -0
- package/dist/package/entity/alert/categories/mini-program.d.ts +297 -0
- package/dist/package/entity/alert/investigation.dto.d.ts +86 -0
- package/dist/package/entity/alert/lark-callback.dto.d.ts +106 -0
- package/dist/package/entity/alert/suggestion.dto.d.ts +31 -0
- package/dist/package/entity/alert/suggestion.enum.d.ts +7 -0
- package/dist/package/entity/incoming-order/incoming-order-to-bill.dto.d.ts +80 -0
- package/dist/package/entity/incoming-order/incoming-order.dto.d.ts +575 -0
- package/dist/package/entity/index.d.ts +12 -0
- package/dist/package/entity/index.frontend.d.ts +1 -0
- package/dist/package/entity/member/member.dto.d.ts +2 -1
- package/dist/package/entity/order/order.do.d.ts +64 -7
- package/dist/package/entity/order/order.dto.d.ts +85 -67
- package/dist/package/entity/order/payment/payment.dto.d.ts +36 -28
- package/dist/package/entity/order-platform/external/auth/external-auth.dto.d.ts +9 -15
- package/dist/package/entity/order-platform/external/menu/external-master-menu.do.d.ts +33 -0
- package/dist/package/entity/order-platform/external/menu/external-menu.do.d.ts +1185 -23
- package/dist/package/entity/order-platform/external/order/external-order.do.d.ts +1104 -52
- package/dist/package/entity/order-platform/external/order/external-order.dto.d.ts +2914 -88
- package/dist/package/entity/order-platform/external/setting/external-setting.do.d.ts +38 -0
- package/dist/package/entity/order-platform/external/setting/external-setting.dto.d.ts +26 -0
- package/dist/package/entity/order-platform/foodpanda/foodpanda-availability.dto.d.ts +75 -0
- package/dist/package/entity/order-platform/foodpanda/foodpanda-order.do.d.ts +9 -0
- package/dist/package/entity/order-platform/foodpanda/foodpanda-settings.do.d.ts +13 -0
- package/dist/package/entity/order-platform/foodpanda/foodpanda-settings.dto.d.ts +3 -0
- package/dist/package/entity/order-platform/shopeefood/shopeefood.enum.d.ts +6 -0
- package/dist/package/entity/order-platform/tng/tng-order.do.d.ts +6 -6
- package/dist/package/entity/order-platform/tng/tng.dto.d.ts +2 -2
- package/dist/package/entity/order-setting/kiosk/kiosk.do.d.ts +3 -0
- package/dist/package/entity/order-setting/kiosk/kiosk.dto.d.ts +3 -0
- package/dist/package/entity/order-setting/kiosk/kiosk.enum.d.ts +12 -0
- package/dist/package/entity/order-setting/order-setting.do.d.ts +5 -0
- package/dist/package/entity/order-setting/order-setting.dto.d.ts +10 -0
- package/dist/package/entity/payment/payment.dto.d.ts +2 -2
- package/dist/package/entity/payment/transaction.d.ts +115 -30
- package/dist/package/entity/queue/queue.dto.d.ts +13 -11
- package/dist/package/entity/restaurant/restaurant.dto.d.ts +5 -0
- package/dist/package/entity/websocket/websocket.dto.d.ts +12 -0
- package/package.json +1 -1
- package/src/locales/en-US.json +5 -0
- package/src/locales/ja-JP.json +5 -0
- package/src/locales/th-TH.json +5 -0
- package/src/locales/zh-CN.json +5 -0
- package/src/modules/order-setting/kiosk/interface.ts +8 -0
- package/src/modules/order-setting/kiosk/languages.ts +29 -0
- package/src/stores/order-setting/mapper.spec.ts +44 -0
- package/src/stores/order-setting/mapper.ts +9 -2
- package/src/views/kiosk/settings/KioskSettingView.vue +63 -0
- package/src/views/order-settings/delivery/integrated-delivery/IntegratedDelivery.vue +6 -1
- package/src/views/order-settings/delivery/integrated-delivery/LinemanSetting.vue +2 -1
|
@@ -493,6 +493,7 @@ export declare const WebSocketEventDto: z.ZodDiscriminatedUnion<"type", z.Primit
|
|
|
493
493
|
otaChannel: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
494
494
|
autoCloseBill: z.ZodNullable<z.ZodOptional<z.ZodBoolean>>;
|
|
495
495
|
printReceiptAfterClose: z.ZodNullable<z.ZodOptional<z.ZodBoolean>>;
|
|
496
|
+
languages: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
496
497
|
}, "strip", z.ZodTypeAny, {
|
|
497
498
|
autoCloseBill?: boolean | null | undefined;
|
|
498
499
|
printReceiptAfterClose?: boolean | null | undefined;
|
|
@@ -554,6 +555,7 @@ export declare const WebSocketEventDto: z.ZodDiscriminatedUnion<"type", z.Primit
|
|
|
554
555
|
coverImageLandscape?: string | null | undefined;
|
|
555
556
|
coverImagePortrait?: string | null | undefined;
|
|
556
557
|
otaChannel?: string | null | undefined;
|
|
558
|
+
languages?: string[] | null | undefined;
|
|
557
559
|
}, {
|
|
558
560
|
autoCloseBill?: boolean | null | undefined;
|
|
559
561
|
printReceiptAfterClose?: boolean | null | undefined;
|
|
@@ -615,6 +617,7 @@ export declare const WebSocketEventDto: z.ZodDiscriminatedUnion<"type", z.Primit
|
|
|
615
617
|
coverImageLandscape?: string | null | undefined;
|
|
616
618
|
coverImagePortrait?: string | null | undefined;
|
|
617
619
|
otaChannel?: string | null | undefined;
|
|
620
|
+
languages?: string[] | null | undefined;
|
|
618
621
|
}>>;
|
|
619
622
|
}>, "strip", z.ZodTypeAny, {
|
|
620
623
|
data: {
|
|
@@ -678,6 +681,7 @@ export declare const WebSocketEventDto: z.ZodDiscriminatedUnion<"type", z.Primit
|
|
|
678
681
|
coverImageLandscape?: string | null | undefined;
|
|
679
682
|
coverImagePortrait?: string | null | undefined;
|
|
680
683
|
otaChannel?: string | null | undefined;
|
|
684
|
+
languages?: string[] | null | undefined;
|
|
681
685
|
};
|
|
682
686
|
type: "KIOSK:UPDATE_SETTING";
|
|
683
687
|
}, {
|
|
@@ -742,6 +746,7 @@ export declare const WebSocketEventDto: z.ZodDiscriminatedUnion<"type", z.Primit
|
|
|
742
746
|
coverImageLandscape?: string | null | undefined;
|
|
743
747
|
coverImagePortrait?: string | null | undefined;
|
|
744
748
|
otaChannel?: string | null | undefined;
|
|
749
|
+
languages?: string[] | null | undefined;
|
|
745
750
|
} | undefined;
|
|
746
751
|
type: "KIOSK:UPDATE_SETTING";
|
|
747
752
|
}>>;
|
|
@@ -1204,6 +1209,7 @@ export declare const WebSocketReqDto: z.ZodObject<{
|
|
|
1204
1209
|
otaChannel: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
1205
1210
|
autoCloseBill: z.ZodNullable<z.ZodOptional<z.ZodBoolean>>;
|
|
1206
1211
|
printReceiptAfterClose: z.ZodNullable<z.ZodOptional<z.ZodBoolean>>;
|
|
1212
|
+
languages: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
1207
1213
|
}, "strip", z.ZodTypeAny, {
|
|
1208
1214
|
autoCloseBill?: boolean | null | undefined;
|
|
1209
1215
|
printReceiptAfterClose?: boolean | null | undefined;
|
|
@@ -1265,6 +1271,7 @@ export declare const WebSocketReqDto: z.ZodObject<{
|
|
|
1265
1271
|
coverImageLandscape?: string | null | undefined;
|
|
1266
1272
|
coverImagePortrait?: string | null | undefined;
|
|
1267
1273
|
otaChannel?: string | null | undefined;
|
|
1274
|
+
languages?: string[] | null | undefined;
|
|
1268
1275
|
}, {
|
|
1269
1276
|
autoCloseBill?: boolean | null | undefined;
|
|
1270
1277
|
printReceiptAfterClose?: boolean | null | undefined;
|
|
@@ -1326,6 +1333,7 @@ export declare const WebSocketReqDto: z.ZodObject<{
|
|
|
1326
1333
|
coverImageLandscape?: string | null | undefined;
|
|
1327
1334
|
coverImagePortrait?: string | null | undefined;
|
|
1328
1335
|
otaChannel?: string | null | undefined;
|
|
1336
|
+
languages?: string[] | null | undefined;
|
|
1329
1337
|
}>>;
|
|
1330
1338
|
}>, "strip", z.ZodTypeAny, {
|
|
1331
1339
|
data: {
|
|
@@ -1389,6 +1397,7 @@ export declare const WebSocketReqDto: z.ZodObject<{
|
|
|
1389
1397
|
coverImageLandscape?: string | null | undefined;
|
|
1390
1398
|
coverImagePortrait?: string | null | undefined;
|
|
1391
1399
|
otaChannel?: string | null | undefined;
|
|
1400
|
+
languages?: string[] | null | undefined;
|
|
1392
1401
|
};
|
|
1393
1402
|
type: "KIOSK:UPDATE_SETTING";
|
|
1394
1403
|
}, {
|
|
@@ -1453,6 +1462,7 @@ export declare const WebSocketReqDto: z.ZodObject<{
|
|
|
1453
1462
|
coverImageLandscape?: string | null | undefined;
|
|
1454
1463
|
coverImagePortrait?: string | null | undefined;
|
|
1455
1464
|
otaChannel?: string | null | undefined;
|
|
1465
|
+
languages?: string[] | null | undefined;
|
|
1456
1466
|
} | undefined;
|
|
1457
1467
|
type: "KIOSK:UPDATE_SETTING";
|
|
1458
1468
|
}>>;
|
|
@@ -1565,6 +1575,7 @@ export declare const WebSocketReqDto: z.ZodObject<{
|
|
|
1565
1575
|
coverImageLandscape?: string | null | undefined;
|
|
1566
1576
|
coverImagePortrait?: string | null | undefined;
|
|
1567
1577
|
otaChannel?: string | null | undefined;
|
|
1578
|
+
languages?: string[] | null | undefined;
|
|
1568
1579
|
};
|
|
1569
1580
|
type: "KIOSK:UPDATE_SETTING";
|
|
1570
1581
|
};
|
|
@@ -1678,6 +1689,7 @@ export declare const WebSocketReqDto: z.ZodObject<{
|
|
|
1678
1689
|
coverImageLandscape?: string | null | undefined;
|
|
1679
1690
|
coverImagePortrait?: string | null | undefined;
|
|
1680
1691
|
otaChannel?: string | null | undefined;
|
|
1692
|
+
languages?: string[] | null | undefined;
|
|
1681
1693
|
} | undefined;
|
|
1682
1694
|
type: "KIOSK:UPDATE_SETTING";
|
|
1683
1695
|
};
|
package/package.json
CHANGED
package/src/locales/en-US.json
CHANGED
|
@@ -313,6 +313,11 @@
|
|
|
313
313
|
"kioskDevices": "Kiosk devices",
|
|
314
314
|
"kioskDisplay": "Kiosk Display",
|
|
315
315
|
"kioskDisplayDescription": "Click \"Bind device\" to receive a special code for device binding.",
|
|
316
|
+
"kioskLanguage": "Language",
|
|
317
|
+
"kioskLanguageAtLeastOne": "Select at least one language, or turn the limit off.",
|
|
318
|
+
"kioskLanguageHint": "Choose which languages customers can pick from on the kiosk. By default the kiosk offers every language it supports.",
|
|
319
|
+
"kioskLanguageRestrict": "Limit the languages shown",
|
|
320
|
+
"kioskLanguageRestrictSublabel": "Off: show every supported language. On: show only the ones ticked below.",
|
|
316
321
|
"kioskOnly": "Kiosk Only",
|
|
317
322
|
"kioskSettingFailed": "Failed to update kiosk order setting",
|
|
318
323
|
"kioskSettingSuccess": "Kiosk order setting updated",
|
package/src/locales/ja-JP.json
CHANGED
|
@@ -399,6 +399,11 @@
|
|
|
399
399
|
"searchDevices": "スロット、マシンID、名前で検索...",
|
|
400
400
|
"allTypes": "すべてのタイプ",
|
|
401
401
|
"tabletOnly": "タブレットのみ",
|
|
402
|
+
"kioskLanguage": "言語",
|
|
403
|
+
"kioskLanguageAtLeastOne": "言語を1つ以上選択するか、制限をオフにしてください。",
|
|
404
|
+
"kioskLanguageHint": "キオスクでお客様が選べる言語を設定します。既定では対応するすべての言語を表示します。",
|
|
405
|
+
"kioskLanguageRestrict": "表示する言語を制限する",
|
|
406
|
+
"kioskLanguageRestrictSublabel": "オフ:対応するすべての言語を表示。オン:下でチェックした言語のみ表示。",
|
|
402
407
|
"kioskOnly": "キオスクのみ",
|
|
403
408
|
"showingDevices": "{count} / {total} 件表示",
|
|
404
409
|
"noDevicesMatch": "検索条件に一致するデバイスはありません",
|
package/src/locales/th-TH.json
CHANGED
|
@@ -494,6 +494,11 @@
|
|
|
494
494
|
"searchDevices": "ค้นหาตามสล็อต, ID เครื่อง หรือชื่อ...",
|
|
495
495
|
"allTypes": "ทุกประเภท",
|
|
496
496
|
"tabletOnly": "แท็บเล็ตเท่านั้น",
|
|
497
|
+
"kioskLanguage": "ภาษา",
|
|
498
|
+
"kioskLanguageAtLeastOne": "เลือกอย่างน้อยหนึ่งภาษา หรือปิดการจำกัด",
|
|
499
|
+
"kioskLanguageHint": "เลือกภาษาที่ลูกค้าเลือกใช้ได้บนตู้คีออส ค่าเริ่มต้นคือแสดงทุกภาษาที่รองรับ",
|
|
500
|
+
"kioskLanguageRestrict": "จำกัดภาษาที่แสดง",
|
|
501
|
+
"kioskLanguageRestrictSublabel": "ปิด: แสดงทุกภาษาที่รองรับ เปิด: แสดงเฉพาะภาษาที่เลือกด้านล่าง",
|
|
497
502
|
"kioskOnly": "คีออสก์เท่านั้น",
|
|
498
503
|
"showingDevices": "แสดง {count} จาก {total}",
|
|
499
504
|
"noDevicesMatch": "ไม่มีอุปกรณ์ตรงกับเกณฑ์การค้นหาของคุณ",
|
package/src/locales/zh-CN.json
CHANGED
|
@@ -499,6 +499,11 @@
|
|
|
499
499
|
"searchDevices": "按槽位、设备ID或名称搜索...",
|
|
500
500
|
"allTypes": "全部类型",
|
|
501
501
|
"tabletOnly": "仅平板",
|
|
502
|
+
"kioskLanguage": "语言",
|
|
503
|
+
"kioskLanguageAtLeastOne": "请至少选择一种语言,或关闭限制。",
|
|
504
|
+
"kioskLanguageHint": "选择顾客可以在自助点餐机上使用的语言。默认显示所有支持的语言。",
|
|
505
|
+
"kioskLanguageRestrict": "限制显示的语言",
|
|
506
|
+
"kioskLanguageRestrictSublabel": "关闭:显示所有支持的语言。开启:只显示下面勾选的语言。",
|
|
502
507
|
"kioskOnly": "仅自助终端",
|
|
503
508
|
"showingDevices": "显示 {count} / {total}",
|
|
504
509
|
"noDevicesMatch": "没有设备符合您的搜索条件",
|
|
@@ -88,6 +88,10 @@ export interface MfKioskOrderSetting {
|
|
|
88
88
|
// kiosk field would persist `false` and silently kill inheritance.
|
|
89
89
|
autoCloseBill: boolean | null,
|
|
90
90
|
printReceiptAfterClose: boolean | null,
|
|
91
|
+
// Locales the kiosk may offer the customer. null or [] = no restriction,
|
|
92
|
+
// i.e. the kiosk shows every language it ships. Anything else is the exact
|
|
93
|
+
// allowed set.
|
|
94
|
+
languages: string[] | null,
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
export interface MfKioskOrderSettingMenuItemForm {
|
|
@@ -107,6 +111,10 @@ export interface MfKioskOrderSettingForm {
|
|
|
107
111
|
// kiosk field would persist `false` and silently kill inheritance.
|
|
108
112
|
autoCloseBill: boolean | null,
|
|
109
113
|
printReceiptAfterClose: boolean | null,
|
|
114
|
+
// Locales the kiosk may offer the customer. null or [] = no restriction,
|
|
115
|
+
// i.e. the kiosk shows every language it ships. Anything else is the exact
|
|
116
|
+
// allowed set.
|
|
117
|
+
languages: string[] | null,
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
export type KioskPickAtCounterSettingForm = MfKioskPickAtCounterSetting;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { KIOSK_LOCALES, type KioskLocale } from '@entity'
|
|
2
|
+
|
|
3
|
+
export interface KioskLanguageOption {
|
|
4
|
+
code: KioskLocale
|
|
5
|
+
/** Endonym — the language's own name, so a merchant recognises it on sight. */
|
|
6
|
+
label: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Labels for the locales the kiosk app ships (`KIOSK_LOCALES` in the entity
|
|
11
|
+
* package). Written as endonyms and NOT translated: the merchant is choosing
|
|
12
|
+
* which languages their customers will see, so "中文" must read as "中文" even
|
|
13
|
+
* when the portal itself is in English.
|
|
14
|
+
*/
|
|
15
|
+
const LABELS: Record<KioskLocale, string> = {
|
|
16
|
+
'en-US': 'English',
|
|
17
|
+
'zh-CN': '中文',
|
|
18
|
+
'th-TH': 'ไทย',
|
|
19
|
+
'vi-VN': 'Tiếng Việt',
|
|
20
|
+
'id-ID': 'Bahasa Indonesia',
|
|
21
|
+
'ko-KR': '한국어',
|
|
22
|
+
'ja-JP': '日本語',
|
|
23
|
+
'ar-SA': 'العربية'
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const KIOSK_LANGUAGE_OPTIONS: KioskLanguageOption[] = KIOSK_LOCALES.map((code) => ({
|
|
27
|
+
code,
|
|
28
|
+
label: LABELS[code]
|
|
29
|
+
}))
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { OrderSettingMapper, defaultKioskOrderSetting } from './mapper'
|
|
3
|
+
import type { MfKioskOrderSetting } from '@/modules/order-setting/kiosk/interface'
|
|
4
|
+
import type { OrderSettingsDto } from '@entity'
|
|
5
|
+
|
|
6
|
+
function toKioskForm(kioskSettings: unknown) {
|
|
7
|
+
return OrderSettingMapper.convertOrderSettingDto({
|
|
8
|
+
_id: 'r1',
|
|
9
|
+
kioskSettings
|
|
10
|
+
} as OrderSettingsDto).kiosk
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function saved(kiosk: MfKioskOrderSetting) {
|
|
14
|
+
return OrderSettingMapper.toOrderKioskSettingsDto(kiosk).kioskSettings
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe('kiosk languages round-trip', () => {
|
|
18
|
+
it('reads an unset restriction as null', () => {
|
|
19
|
+
expect(toKioskForm({}).languages).toBeNull()
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('reads a stored empty list as null — [] already means "all languages"', () => {
|
|
23
|
+
expect(toKioskForm({ languages: [] }).languages).toBeNull()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('reads a stored restriction as-is', () => {
|
|
27
|
+
expect(toKioskForm({ languages: ['en-US', 'zh-CN'] }).languages).toEqual(['en-US', 'zh-CN'])
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('omits the field entirely when the merchant restricts nothing', () => {
|
|
31
|
+
expect(saved({ ...defaultKioskOrderSetting, languages: null }).languages).toBeUndefined()
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('omits the field rather than saving an empty restriction', () => {
|
|
35
|
+
expect(saved({ ...defaultKioskOrderSetting, languages: [] }).languages).toBeUndefined()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('saves the chosen restriction', () => {
|
|
39
|
+
expect(saved({ ...defaultKioskOrderSetting, languages: ['en-US', 'th-TH'] }).languages).toEqual([
|
|
40
|
+
'en-US',
|
|
41
|
+
'th-TH'
|
|
42
|
+
])
|
|
43
|
+
})
|
|
44
|
+
})
|
|
@@ -82,7 +82,8 @@ export const defaultKioskOrderSetting: MfKioskOrderSettingForm = {
|
|
|
82
82
|
coverImagePortrait: null,
|
|
83
83
|
otaChannel: '',
|
|
84
84
|
autoCloseBill: null,
|
|
85
|
-
printReceiptAfterClose: null
|
|
85
|
+
printReceiptAfterClose: null,
|
|
86
|
+
languages: null
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
export const defaultSubmitOrderInstruction: MfKioskSubmitOrderInstruction = {
|
|
@@ -143,7 +144,10 @@ const toKiosk = (
|
|
|
143
144
|
// Preserve "unset" as null — collapsing to a boolean here is what let an
|
|
144
145
|
// unrelated save overwrite the inherited dineInSettings value.
|
|
145
146
|
autoCloseBill: kioskOrderSettings?.autoCloseBill ?? null,
|
|
146
|
-
printReceiptAfterClose: kioskOrderSettings?.printReceiptAfterClose ?? null
|
|
147
|
+
printReceiptAfterClose: kioskOrderSettings?.printReceiptAfterClose ?? null,
|
|
148
|
+
// Stored [] means the same thing as unset ("all languages"), so collapse it
|
|
149
|
+
// to null here — the form only ever has to reason about null vs a real set.
|
|
150
|
+
languages: kioskOrderSettings?.languages?.length ? [...kioskOrderSettings.languages] : null
|
|
147
151
|
}
|
|
148
152
|
}
|
|
149
153
|
|
|
@@ -239,6 +243,9 @@ const toOrderKioskSettingsDto = (
|
|
|
239
243
|
// still applies — sending `false` here would pin it off for good.
|
|
240
244
|
autoCloseBill: kioskSetting.autoCloseBill ?? undefined,
|
|
241
245
|
printReceiptAfterClose: kioskSetting.printReceiptAfterClose ?? undefined,
|
|
246
|
+
// Omit rather than send [] when the merchant restricts nothing, so the
|
|
247
|
+
// saved document stays free of a field that means "all languages" anyway.
|
|
248
|
+
languages: kioskSetting.languages?.length ? kioskSetting.languages : undefined,
|
|
242
249
|
paymentSetting: createPaymentSettings(kioskSetting.paymentSetting),
|
|
243
250
|
takeaway: kioskSetting.takeaway.submitOrderInstruction
|
|
244
251
|
? {
|
|
@@ -155,6 +155,39 @@
|
|
|
155
155
|
/>
|
|
156
156
|
</div>
|
|
157
157
|
|
|
158
|
+
<!-- Language Section -->
|
|
159
|
+
<div class="flex flex-col gap-2">
|
|
160
|
+
<span class="fm-typo-en-title-sm-600">{{ t('order.kioskLanguage') }}</span>
|
|
161
|
+
<span class="fm-typo-en-body-sm-400 text-fm-color-typo-secondary">
|
|
162
|
+
{{ t('order.kioskLanguageHint') }}
|
|
163
|
+
</span>
|
|
164
|
+
<div class="border p-[1.5rem] fm-corner-radius-lg flex flex-col gap-4 my-5 w-11/12">
|
|
165
|
+
<FmSwitch
|
|
166
|
+
:model-value="restrictLanguages"
|
|
167
|
+
:label="t('order.kioskLanguageRestrict')"
|
|
168
|
+
:sublabel="t('order.kioskLanguageRestrictSublabel')"
|
|
169
|
+
label-placement="right"
|
|
170
|
+
@update:model-value="onRestrictLanguagesChange"
|
|
171
|
+
/>
|
|
172
|
+
<div v-show="restrictLanguages" class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
|
173
|
+
<FmCheckbox
|
|
174
|
+
v-for="option in languageOptions"
|
|
175
|
+
:key="option.code"
|
|
176
|
+
:model-value="selectedLanguages.includes(option.code)"
|
|
177
|
+
:value="option.code"
|
|
178
|
+
:label="option.label"
|
|
179
|
+
@update:model-value="(v: boolean) => toggleLanguage(option.code, v)"
|
|
180
|
+
/>
|
|
181
|
+
</div>
|
|
182
|
+
<span
|
|
183
|
+
v-if="restrictLanguages && selectedLanguages.length === 0"
|
|
184
|
+
class="fm-typo-en-body-sm-400 text-fm-color-system-error-300"
|
|
185
|
+
>
|
|
186
|
+
{{ t('order.kioskLanguageAtLeastOne') }}
|
|
187
|
+
</span>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
|
|
158
191
|
<!-- Cover Image Section -->
|
|
159
192
|
<div class="flex flex-col gap-2">
|
|
160
193
|
<span class="fm-typo-en-title-sm-600">{{ t('order.coverImage') }}</span>
|
|
@@ -299,6 +332,10 @@ import type {
|
|
|
299
332
|
MfKioskOrderSettingForm,
|
|
300
333
|
KioskPaymentTypesForm
|
|
301
334
|
} from '@/modules/order-setting/kiosk/interface'
|
|
335
|
+
import {
|
|
336
|
+
KIOSK_LANGUAGE_OPTIONS,
|
|
337
|
+
type KioskLanguageOption
|
|
338
|
+
} from '@/modules/order-setting/kiosk/languages'
|
|
302
339
|
import { useLoading } from '@/composables/loading'
|
|
303
340
|
import { useSnackbar } from '@feedmepos/ui-library'
|
|
304
341
|
import { useCoreStore, useI18n } from '@feedmepos/mf-common'
|
|
@@ -336,6 +373,28 @@ const onAutoCloseBillChange = (value: boolean) => {
|
|
|
336
373
|
}
|
|
337
374
|
}
|
|
338
375
|
|
|
376
|
+
const languageOptions: KioskLanguageOption[] = KIOSK_LANGUAGE_OPTIONS
|
|
377
|
+
|
|
378
|
+
// `languages: null` is "no restriction" — the kiosk shows everything it ships.
|
|
379
|
+
// The switch is therefore derived from the saved value, not a separate flag, so
|
|
380
|
+
// a merchant who turns the restriction off leaves nothing behind in the record.
|
|
381
|
+
const restrictLanguages = computed(() => kioskOrderSettingForm.value.languages != null)
|
|
382
|
+
|
|
383
|
+
const selectedLanguages = computed<string[]>(() => kioskOrderSettingForm.value.languages ?? [])
|
|
384
|
+
|
|
385
|
+
function onRestrictLanguagesChange(value: boolean) {
|
|
386
|
+
// Seed with English rather than an empty list: an empty list is indistinguishable
|
|
387
|
+
// from "no restriction" once saved, and the form would open on an error state.
|
|
388
|
+
kioskOrderSettingForm.value.languages = value ? ['en-US'] : null
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function toggleLanguage(code: string, selected: boolean) {
|
|
392
|
+
const current = kioskOrderSettingForm.value.languages ?? []
|
|
393
|
+
kioskOrderSettingForm.value.languages = selected
|
|
394
|
+
? languageOptions.filter((o) => o.code === code || current.includes(o.code)).map((o) => o.code)
|
|
395
|
+
: current.filter((c) => c !== code)
|
|
396
|
+
}
|
|
397
|
+
|
|
339
398
|
// Validation rules
|
|
340
399
|
const nonNegativeRule = (val: any) => {
|
|
341
400
|
if (val < 0) return t('order.nonNegativeRule')
|
|
@@ -370,6 +429,10 @@ const validKioskOrderSetting = computed<MfKioskOrderSetting | null>(() => {
|
|
|
370
429
|
if (!isValid) return null
|
|
371
430
|
}
|
|
372
431
|
|
|
432
|
+
// A restriction that allows no language would leave the kiosk with nothing to
|
|
433
|
+
// render. Saving it would also be a no-op, since [] round-trips as null.
|
|
434
|
+
if (f.languages != null && f.languages.length === 0) return null
|
|
435
|
+
|
|
373
436
|
// Validate payment settings
|
|
374
437
|
const payment = f.paymentSetting
|
|
375
438
|
if (payment?.paymentTypes?.includes(F_ORDER_PAYMENT_TYPE.enum.ePayment)) {
|
|
@@ -61,6 +61,10 @@ const props = defineProps({
|
|
|
61
61
|
integrationIdReadOnly: {
|
|
62
62
|
type: Boolean,
|
|
63
63
|
default: false
|
|
64
|
+
},
|
|
65
|
+
syncMenuLoading: {
|
|
66
|
+
type: Boolean,
|
|
67
|
+
default: false
|
|
64
68
|
}
|
|
65
69
|
})
|
|
66
70
|
|
|
@@ -402,7 +406,8 @@ const formattedMenuSyncError = computed(() => {
|
|
|
402
406
|
variant="primary"
|
|
403
407
|
:label="t('order.syncMenu')"
|
|
404
408
|
@click="emits('syncMenu')"
|
|
405
|
-
:
|
|
409
|
+
:loading="syncMenuLoading"
|
|
410
|
+
:disabled="!canEdit || syncMenuLoading"
|
|
406
411
|
/>
|
|
407
412
|
|
|
408
413
|
<div
|
|
@@ -85,7 +85,7 @@ function updateVatExclude(vatExclude: boolean) {
|
|
|
85
85
|
const { t } = useI18n()
|
|
86
86
|
const { currentRestaurant } = useCoreStore()
|
|
87
87
|
const { showSuccess, showError } = useSnackbarFunctions()
|
|
88
|
-
const { startAsyncCallWithErr } = useLoading()
|
|
88
|
+
const { isLoading, startAsyncCallWithErr } = useLoading()
|
|
89
89
|
|
|
90
90
|
async function syncMenu() {
|
|
91
91
|
await startAsyncCallWithErr(async () => {
|
|
@@ -111,6 +111,7 @@ async function syncMenu() {
|
|
|
111
111
|
:company="company"
|
|
112
112
|
:can-use-auto-delivery-integration="canUseAutoDeliveryIntegration"
|
|
113
113
|
:show-test-order-actions="false"
|
|
114
|
+
:sync-menu-loading="isLoading"
|
|
114
115
|
@update:model-value="updateDataPass"
|
|
115
116
|
@sync-menu="syncMenu"
|
|
116
117
|
>
|