@feedmepos/mf-order-setting 0.0.72-test.1 → 0.0.74-dev
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/.env +1 -1
- package/README.md +7 -23
- package/dist/{KioskDevicesView-CP_cGMXE.js → KioskDevicesView-CW7nDXi2.js} +1 -1
- package/dist/KioskDevicesView.vue_vue_type_script_setup_true_lang-CPDkls2i.js +762 -0
- package/dist/{KioskSettingView-BiKYEjfe.js → KioskSettingView-DErXeFIt.js} +183 -202
- package/dist/KioskView-d1YjttbD.js +362 -0
- package/dist/OrderSettingsView-asfw4cYT.js +60012 -0
- package/dist/app-DrWO2wkv.js +20750 -0
- package/dist/app.js +3 -3
- package/dist/{dayjs.min-Bml-FvS7.js → dayjs.min-Fu6ejRAr.js} +1 -1
- package/dist/frontend/mf-order/src/api/index.d.ts +3 -1
- package/dist/frontend/mf-order/src/api/menu/index.d.ts +1 -1
- package/dist/frontend/mf-order/src/api/remoteOrder/index.d.ts +10 -3
- package/dist/frontend/mf-order/src/app.d.ts +194 -150
- package/dist/frontend/mf-order/src/components/GoogleMap.vue.d.ts +1 -1
- package/dist/frontend/mf-order/src/composables/useKioskPermission.d.ts +11 -0
- package/dist/frontend/mf-order/src/composables/useOrderSettingPermission.d.ts +13 -0
- package/dist/frontend/mf-order/src/composables/useQrOrderingEnabled.d.ts +2 -0
- package/dist/frontend/mf-order/src/helpers/menu.d.ts +1 -1
- package/dist/frontend/mf-order/src/main.d.ts +194 -150
- package/dist/frontend/mf-order/src/stores/kiosk/index.d.ts +21 -21
- package/dist/frontend/mf-order/src/stores/menu/menu.d.ts +906 -1044
- package/dist/frontend/mf-order/src/stores/order-setting/index.d.ts +39 -6
- package/dist/frontend/mf-order/src/stores/restaurant/index.d.ts +5 -2
- package/dist/frontend/mf-order/src/views/kiosk/KioskStatePanel.vue.d.ts +19 -0
- package/dist/frontend/mf-order/src/views/kiosk/devices/KioskDevicesView.vue.d.ts +7 -1
- package/dist/frontend/mf-order/src/views/order-settings/delivery/DeliverySetting.vue.d.ts +2 -2
- package/dist/frontend/mf-order/src/views/order-settings/delivery/components/TaxInput.vue.d.ts +3 -8
- package/dist/frontend/mf-order/src/views/order-settings/delivery/delivery.d.ts +3 -1
- package/dist/frontend/mf-order/src/views/order-settings/delivery/delivery.data.d.ts +5 -1
- package/dist/frontend/mf-order/src/views/order-settings/delivery/inhouse/InHouseDelivery.vue.d.ts +21 -0
- package/dist/frontend/mf-order/src/views/order-settings/delivery/integrated-delivery/ExternalSetting.vue.d.ts +2 -2
- package/dist/frontend/mf-order/src/views/order-settings/delivery/integrated-delivery/GrabfoodSetting.vue.d.ts +1 -1
- package/dist/frontend/mf-order/src/views/order-settings/delivery/integrated-delivery/IntegratedDelivery.vue.d.ts +28 -2
- package/dist/frontend/mf-order/src/views/order-settings/delivery/integrated-delivery/LinemanSetting.vue.d.ts +46 -0
- package/dist/frontend/mf-order/src/views/order-settings/delivery/integrated-delivery/TngSetting.vue.d.ts +57 -0
- package/dist/frontend/mf-order/src/views/order-settings/pickup/PickUpSettingDialogContent.vue.d.ts +23 -1
- package/dist/frontend/mf-order/src/views/order-settings/pickup/Preorder.vue.d.ts +27 -0
- package/dist/frontend/mf-order/src/views/order-settings/servicecharge/RateInput.vue.d.ts +8 -0
- package/dist/frontend/mf-order/tsconfig.app.tsbuildinfo +1 -1
- package/dist/{index-BlKeAWPk.js → index-DEKeP24S.js} +7 -7
- package/dist/index-DJLCZHNZ.js +665 -0
- package/dist/lineman-settings.dto-DS4tgxBJ.js +61259 -0
- package/dist/package/entity/_type-assert.d.ts +7 -0
- package/dist/package/entity/booking/booking.dto.d.ts +24 -24
- package/dist/package/entity/delivery/delivery.dto.d.ts +8 -8
- package/dist/package/entity/delivery/delivery.enum.d.ts +12 -0
- package/dist/package/entity/delivery/gateway/grab.dto.d.ts +2 -2
- package/dist/package/entity/delivery/gateway/kosmo.dto.d.ts +16 -16
- package/dist/package/entity/delivery/gateway/pandago.dto.d.ts +10 -10
- package/dist/package/entity/incoming-order/incoming-order-to-bill.dto.d.ts +282 -4591
- package/dist/package/entity/incoming-order/incoming-order.do.d.ts +32 -24
- package/dist/package/entity/incoming-order/incoming-order.dto.d.ts +23 -11719
- package/dist/package/entity/incoming-order/incoming-order.enum.d.ts +2 -2
- package/dist/package/entity/index.d.ts +12 -0
- package/dist/package/entity/kiosk/kiosk.do.d.ts +140 -140
- package/dist/package/entity/kiosk/kiosk.dto.d.ts +168 -168
- package/dist/package/entity/kiosk/marketing/marketing.dto.d.ts +63 -7
- package/dist/package/entity/marketing/marketing.dto.d.ts +4 -4
- package/dist/package/entity/member/member.dto.d.ts +6 -0
- package/dist/package/entity/order/dine-in/dine-in.do.d.ts +8 -8
- package/dist/package/entity/order/effects/effect.dto.d.ts +68 -16
- package/dist/package/entity/order/menu/menu.dto.d.ts +45 -8
- package/dist/package/entity/order/order-item/order-item.dto.d.ts +358 -3853
- package/dist/package/entity/order/order.do.d.ts +239 -42
- package/dist/package/entity/order/order.dto.d.ts +6497 -2236
- package/dist/package/entity/order/payment/payment.dto.d.ts +52 -12
- package/dist/package/entity/order-platform/base-integration.do.d.ts +8 -0
- package/dist/package/entity/order-platform/deliveroo/deliveroo-dto.d.ts +2 -2
- package/dist/package/entity/order-platform/deliveroo/deliveroo-order.do.d.ts +524 -524
- package/dist/package/entity/order-platform/deliveroo/deliveroo-setting.do.d.ts +2 -2
- package/dist/package/entity/order-platform/deliveroo/deliveroo.menu.dto.d.ts +58 -58
- package/dist/package/entity/order-platform/external/menu/external-master-menu.do.d.ts +212 -284
- package/dist/package/entity/order-platform/external/menu/external-menu.do.d.ts +331 -589
- package/dist/package/entity/order-platform/external/menu/external-menu.dto.d.ts +1 -1
- package/dist/package/entity/order-platform/external/order/external-order.do.d.ts +12 -12
- package/dist/package/entity/order-platform/external/order/external-order.dto.d.ts +275 -275
- package/dist/package/entity/order-platform/external/setting/external-setting.do.d.ts +3 -3
- package/dist/package/entity/order-platform/external/setting/external-setting.dto.d.ts +3 -3
- package/dist/package/entity/order-platform/foodpanda/foodpanda-menu.dto.d.ts +284 -284
- package/dist/package/entity/order-platform/foodpanda/foodpanda-order.do.d.ts +40 -40
- package/dist/package/entity/order-platform/foodpanda/foodpanda-order.dto.d.ts +16 -16
- package/dist/package/entity/order-platform/foodpanda/foodpanda-settings.do.d.ts +2 -2
- package/dist/package/entity/order-platform/foodpanda/foodpanda-settings.dto.d.ts +2 -2
- package/dist/package/entity/order-platform/gofood/gofood-order.do.d.ts +18 -18
- package/dist/package/entity/order-platform/gofood/gofood-settings.do.d.ts +2 -2
- package/dist/package/entity/order-platform/gofood/gofood-settings.dto.d.ts +2 -2
- package/dist/package/entity/order-platform/gofood/gofood.dto.d.ts +32 -32
- package/dist/package/entity/order-platform/grabfood/grabfood-edit-order.do.d.ts +12 -12
- package/dist/package/entity/order-platform/grabfood/grabfood-omni.do.d.ts +134 -115
- package/dist/package/entity/order-platform/grabfood/grabfood-order.do.d.ts +187 -165
- package/dist/package/entity/order-platform/grabfood/grabfood-settings.do.d.ts +8 -2
- package/dist/package/entity/order-platform/grabfood/grabfood-webhook.dto.d.ts +49 -42
- package/dist/package/entity/order-platform/grabfood/grabfood.dto.d.ts +67 -54
- package/dist/package/entity/order-platform/grabfood/grabfood.enum.d.ts +1 -1
- package/dist/package/entity/order-platform/lineman/lineman-settings.do.d.ts +37 -0
- package/dist/package/entity/order-platform/lineman/lineman-settings.dto.d.ts +40 -0
- package/dist/package/entity/order-platform/menu.dto.d.ts +716 -13887
- package/dist/package/entity/order-platform/order-platform.dto.d.ts +136 -2
- package/dist/package/entity/order-platform/order-platform.enum.d.ts +1 -1
- package/dist/package/entity/order-platform/shopeefood/shopeefood-order.do.d.ts +176 -176
- package/dist/package/entity/order-platform/shopeefood/shopeefood-order.dto.d.ts +62 -62
- package/dist/package/entity/order-platform/shopeefood/shopeefood-settings.do.d.ts +8 -2
- package/dist/package/entity/order-platform/shopeefood/shopeefood-settings.dto.d.ts +8 -2
- package/dist/package/entity/order-platform/tng/tng-menu.do.d.ts +1061 -0
- package/dist/package/entity/order-platform/tng/tng-order.do.d.ts +1915 -0
- package/dist/package/entity/order-platform/tng/tng-settings.do.d.ts +379 -0
- package/dist/package/entity/order-platform/tng/tng-settings.dto.d.ts +301 -0
- package/dist/package/entity/order-platform/tng/tng.dto.d.ts +1162 -0
- package/dist/package/entity/order-platform/tng/tng.enum.d.ts +29 -0
- package/dist/package/entity/order-setting/delivery/inhouse-delivery.do.d.ts +12 -0
- package/dist/package/entity/order-setting/delivery/inhouse-delivery.dto.d.ts +12 -0
- package/dist/package/entity/order-setting/dine-in/dine-in.do.d.ts +11 -0
- package/dist/package/entity/order-setting/dine-in/dine-in.dto.d.ts +9 -0
- package/dist/package/entity/order-setting/kiosk/kiosk.do.d.ts +2 -2
- package/dist/package/entity/order-setting/kiosk/kiosk.dto.d.ts +2 -2
- package/dist/package/entity/order-setting/order-setting.do.d.ts +59 -8
- package/dist/package/entity/order-setting/order-setting.dto.d.ts +118 -16
- package/dist/package/entity/order-setting/pickup/pickup.do.d.ts +12 -0
- package/dist/package/entity/order-setting/pickup/pickup.dto.d.ts +12 -0
- package/dist/package/entity/order-setting/sms/sms.do.d.ts +2 -2
- package/dist/package/entity/order-setting/sms/sms.dto.d.ts +2 -2
- package/dist/package/entity/payment/transaction.d.ts +80 -8
- package/dist/package/entity/printer/printer.do.d.ts +14 -14
- package/dist/package/entity/pubsub/ably/ably.enum.d.ts +1 -1
- package/dist/package/entity/queue/queue.do.d.ts +236 -1901
- package/dist/package/entity/queue/queue.dto.d.ts +743 -445
- package/dist/package/entity/restaurant/restaurant.dto.d.ts +27 -4
- package/dist/package/entity/websocket/websocket.dto.d.ts +10 -10
- package/dist/style.css +1 -0
- package/golar.config.ts +20 -0
- package/package.json +11 -4
- package/src/Entry.vue +2 -10
- package/src/api/index.ts +5 -2
- package/src/api/menu/index.ts +1 -1
- package/src/api/remoteOrder/index.ts +176 -110
- package/src/composables/useKioskPermission.ts +41 -0
- package/src/composables/useOrderSettingPermission.ts +34 -0
- package/src/composables/useQrOrderingEnabled.ts +66 -0
- package/src/helpers/menu.ts +1 -1
- package/src/locales/en-US.json +164 -147
- package/src/locales/ja-JP.json +1769 -1760
- package/src/locales/th-TH.json +409 -400
- package/src/locales/zh-CN.json +417 -408
- package/src/main.ts +12 -49
- package/src/router/index.ts +2 -2
- package/src/router/routes.ts +34 -5
- package/src/stores/menu/menu.ts +48 -27
- package/src/stores/restaurant/index.ts +24 -9
- package/src/utils/firebase-storage.ts +3 -13
- package/src/views/kiosk/KioskStatePanel.vue +31 -0
- package/src/views/kiosk/KioskView.vue +100 -62
- package/src/views/kiosk/devices/KioskDeviceCard.vue +4 -0
- package/src/views/kiosk/devices/KioskDevicesView.vue +42 -9
- package/src/views/kiosk/settings/KioskSettingView.vue +3 -2
- package/src/views/order-settings/OrderSettingsView.vue +39 -16
- package/src/views/order-settings/delivery/DeliverySetting.vue +223 -11
- package/src/views/order-settings/delivery/components/TaxInput.vue +1 -1
- package/src/views/order-settings/delivery/delivery.data.ts +31 -10
- package/src/views/order-settings/delivery/delivery.ts +60 -28
- package/src/views/order-settings/delivery/inhouse/InHouseDelivery.vue +40 -1
- package/src/views/order-settings/delivery/integrated-delivery/DeliverooSetting.vue +1 -1
- package/src/views/order-settings/delivery/integrated-delivery/GrabfoodSetting.vue +15 -7
- package/src/views/order-settings/delivery/integrated-delivery/IntegratedDelivery.vue +83 -27
- package/src/views/order-settings/delivery/integrated-delivery/LinemanSetting.vue +79 -0
- package/src/views/order-settings/delivery/integrated-delivery/ShopeefoodSetting.vue +2 -0
- package/src/views/order-settings/delivery/integrated-delivery/TngSetting.vue +749 -0
- package/src/views/order-settings/dine-in/DineInSetting.vue +54 -23
- package/src/views/order-settings/dine-in/PaymentType.vue +9 -12
- package/src/views/order-settings/general/GeneralSetting.vue +15 -6
- package/src/views/order-settings/pickup/PickUpSettingDialog.vue +31 -3
- package/src/views/order-settings/pickup/PickUpSettingDialogContent.vue +34 -0
- package/src/views/order-settings/pickup/Preorder.vue +13 -12
- package/src/views/order-settings/queue/QueueSetting.vue +30 -1
- package/src/views/order-settings/servicecharge/RateInput.vue +9 -7
- package/vite.config.ts +21 -18
- package/dist/KioskDevicesView.vue_vue_type_script_setup_true_lang-CiNLqFw6.js +0 -707
- package/dist/KioskView-BYxPrI7N.js +0 -343
- package/dist/OrderSettingsView-C7Y-_y5U.js +0 -32222
- package/dist/app-BN02cB5o.js +0 -18668
- package/dist/frontend/mf-order/src/api/auth/index.d.ts +0 -7
- package/dist/frontend/mf-order/src/stores/iframe/index.d.ts +0 -14
- package/dist/index-DZA8A0m4.js +0 -630
- package/dist/queue-transfer.dto-C7nRZOZH.js +0 -45618
- package/src/api/auth/index.ts +0 -20
- package/src/stores/iframe/index.ts +0 -23
|
@@ -1,58 +1,63 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="py-[1.5rem]">
|
|
3
|
-
<FmPageHead :title="t('order.kiosk')" />
|
|
4
|
-
<div class="px-[1.5rem]">
|
|
5
|
-
<FmTabs v-model:model-value="selectedMenuItem" :items="menuItems"></FmTabs>
|
|
6
|
-
<div class="pt-[1.5rem]">
|
|
7
|
-
<div class="flex flex-col gap-10">
|
|
8
|
-
<div class="flex flex-col gap-2">
|
|
9
|
-
<span class="fm-typo-en-title-sm-600"> {{ t('order.activateLocation') }} </span>
|
|
10
|
-
<span class="fm-typo-en-title-sm-400"> {{ t('order.selectRestaurant') }}: </span>
|
|
11
|
-
<FmSelect
|
|
12
|
-
class="w-1/2"
|
|
13
|
-
v-model="currentSelect"
|
|
14
|
-
:items="restaurantItems"
|
|
15
|
-
:placeholder="t('order.selectItem')"
|
|
16
|
-
@update:model-value="selectRestaurant"
|
|
17
|
-
/>
|
|
18
|
-
</div>
|
|
19
|
-
<KioskDevicesView
|
|
20
|
-
v-if="selectedMenuItem == 'device'"
|
|
21
|
-
:devices="devices"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
:
|
|
28
|
-
|
|
29
|
-
:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
</
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<div class="py-[1.5rem]">
|
|
3
|
+
<FmPageHead :title="t('order.kiosk')" />
|
|
4
|
+
<div class="px-[1.5rem]">
|
|
5
|
+
<FmTabs v-model:model-value="selectedMenuItem" :items="menuItems"></FmTabs>
|
|
6
|
+
<div class="pt-[1.5rem]">
|
|
7
|
+
<div class="flex flex-col gap-10">
|
|
8
|
+
<div class="flex flex-col gap-2">
|
|
9
|
+
<span class="fm-typo-en-title-sm-600"> {{ t('order.activateLocation') }} </span>
|
|
10
|
+
<span class="fm-typo-en-title-sm-400"> {{ t('order.selectRestaurant') }}: </span>
|
|
11
|
+
<FmSelect
|
|
12
|
+
class="w-1/2"
|
|
13
|
+
v-model="currentSelect"
|
|
14
|
+
:items="restaurantItems"
|
|
15
|
+
:placeholder="t('order.selectItem')"
|
|
16
|
+
@update:model-value="selectRestaurant"
|
|
17
|
+
/>
|
|
18
|
+
</div>
|
|
19
|
+
<KioskDevicesView
|
|
20
|
+
v-if="selectedMenuItem == 'device'"
|
|
21
|
+
:devices="devices"
|
|
22
|
+
:load-error="devicesLoadError"
|
|
23
|
+
@request-otp="requestOtp"
|
|
24
|
+
@retry="loadDevices"
|
|
25
|
+
/>
|
|
26
|
+
<KioskSettingView
|
|
27
|
+
:key="`KioskSettingView-${currentRestaurantId}`"
|
|
28
|
+
v-if="selectedMenuItem == 'setting' && canManageOrderSetting"
|
|
29
|
+
:restaurant-id="currentRestaurantId"
|
|
30
|
+
@update-kiosk-order-setting="updateKioskOrderSetting"
|
|
31
|
+
:form="OrderSettingStore.state.kiosk ?? defaultKioskOrderSetting"
|
|
32
|
+
/>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<script setup lang="ts">
|
|
40
|
+
import KioskDevicesView from '@/views/kiosk/devices/KioskDevicesView.vue'
|
|
41
|
+
import {
|
|
42
|
+
useDialog,
|
|
43
|
+
useSnackbar,
|
|
44
|
+
type FmTabProps,
|
|
45
|
+
type ISelectItem
|
|
46
|
+
} from '@feedmepos/ui-library'
|
|
47
|
+
import { ref, computed, defineAsyncComponent, watch, onMounted } from 'vue'
|
|
46
48
|
import { useKioskStore } from '@/stores/kiosk'
|
|
47
49
|
import type { MfKioskDevice } from '@/modules/kiosk/interface'
|
|
48
50
|
import KioskOtpDialog from '@/views/kiosk/devices/KioskOtpDialog.vue'
|
|
51
|
+
import { SvcCompanyApiError } from '@/api'
|
|
49
52
|
import { useCoreStore, useI18n } from '@feedmepos/mf-common'
|
|
50
53
|
import { useOrderSettings } from '@/stores/order-setting'
|
|
51
54
|
import type { MfKioskOrderSetting } from '@/modules/order-setting/kiosk/interface'
|
|
52
55
|
import { defaultKioskOrderSetting } from '@/stores/order-setting/mapper'
|
|
56
|
+
import { useOrderSettingPermission } from '@/composables/useOrderSettingPermission'
|
|
53
57
|
import { capitalCase } from 'change-case'
|
|
54
58
|
|
|
55
59
|
const { t } = useI18n()
|
|
60
|
+
const { canManageOrderSetting } = useOrderSettingPermission()
|
|
56
61
|
|
|
57
62
|
type KioskMenuItemValue = 'device' | 'setting'
|
|
58
63
|
|
|
@@ -63,12 +68,15 @@ const KioskSettingView = defineAsyncComponent(
|
|
|
63
68
|
const selectedMenuItem = ref<KioskMenuItemValue>('device')
|
|
64
69
|
const KioskStore = useKioskStore()
|
|
65
70
|
const OrderSettingStore = useOrderSettings()
|
|
66
|
-
const Dialog = useDialog()
|
|
67
|
-
const { currentRestaurant, restaurants, changeRestaurant } = useCoreStore()
|
|
68
|
-
const SnackBar = useSnackbar()
|
|
71
|
+
const Dialog = useDialog()
|
|
72
|
+
const { currentRestaurant, restaurants, changeRestaurant } = useCoreStore()
|
|
73
|
+
const SnackBar = useSnackbar()
|
|
69
74
|
|
|
70
75
|
const currentSelect = ref<string | undefined>(currentRestaurant.value?._id ?? undefined)
|
|
71
76
|
|
|
77
|
+
/** Drives the denied/error panel inside the device tab. 'forbidden' === HTTP 403. */
|
|
78
|
+
const devicesLoadError = ref<'forbidden' | 'error' | null>(null)
|
|
79
|
+
|
|
72
80
|
const restaurantItems = computed<ISelectItem[]>(() => {
|
|
73
81
|
return restaurants.value.map((r) => ({
|
|
74
82
|
label: r.profile.name,
|
|
@@ -78,7 +86,7 @@ const restaurantItems = computed<ISelectItem[]>(() => {
|
|
|
78
86
|
|
|
79
87
|
const currentRestaurantId = ref<string>(currentRestaurant.value?._id ?? '')
|
|
80
88
|
|
|
81
|
-
async function selectRestaurant(v: string) {
|
|
89
|
+
async function selectRestaurant(v: string) {
|
|
82
90
|
const restaurant = restaurants.value.find((r) => r._id == v)
|
|
83
91
|
await changeRestaurant(restaurant)
|
|
84
92
|
await loadRestaurantData()
|
|
@@ -87,27 +95,57 @@ async function selectRestaurant(v: string) {
|
|
|
87
95
|
}
|
|
88
96
|
|
|
89
97
|
async function loadRestaurantData() {
|
|
90
|
-
|
|
91
|
-
|
|
98
|
+
// Order settings are only needed for the (permission-gated) Settings tab. Skip the
|
|
99
|
+
// fetch when the user can't manage them, and never let its failure block the Device
|
|
100
|
+
// tab — the order-settings endpoint is now HRM-guarded and 403s without the subject.
|
|
101
|
+
if (canManageOrderSetting.value) {
|
|
102
|
+
try {
|
|
103
|
+
await OrderSettingStore.getSetting()
|
|
104
|
+
} catch {
|
|
105
|
+
// Settings tab surfaces its own state; don't block device loading.
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
await loadDevices()
|
|
92
109
|
}
|
|
93
110
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
value
|
|
111
|
+
// Loads the device list, mapping a 403 to the in-tab "access denied" panel and any
|
|
112
|
+
// other failure to a retryable error panel (instead of silently showing "no devices").
|
|
113
|
+
async function loadDevices() {
|
|
114
|
+
devicesLoadError.value = null
|
|
115
|
+
try {
|
|
116
|
+
await KioskStore.getDevices()
|
|
117
|
+
} catch (e) {
|
|
118
|
+
devicesLoadError.value =
|
|
119
|
+
e instanceof SvcCompanyApiError && e.status === 403 ? 'forbidden' : 'error'
|
|
102
120
|
}
|
|
103
|
-
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const menuItems = computed<FmTabProps[]>(() => {
|
|
124
|
+
const items: FmTabProps[] = [{ label: t('order.deviceBinding'), value: 'device' }]
|
|
125
|
+
// The Settings tab is order settings — only show it to users who can manage them.
|
|
126
|
+
if (canManageOrderSetting.value) {
|
|
127
|
+
items.push({ label: t('order.settings'), value: 'setting' })
|
|
128
|
+
}
|
|
129
|
+
return items
|
|
130
|
+
})
|
|
104
131
|
|
|
105
132
|
const devices = computed<MfKioskDevice[]>(() => {
|
|
106
133
|
return KioskStore.state.devices
|
|
107
134
|
})
|
|
108
135
|
|
|
109
136
|
async function requestOtp() {
|
|
110
|
-
|
|
137
|
+
try {
|
|
138
|
+
await KioskStore.requestOtp()
|
|
139
|
+
} catch (e) {
|
|
140
|
+
SnackBar.open({
|
|
141
|
+
title:
|
|
142
|
+
e instanceof SvcCompanyApiError && e.status === 403
|
|
143
|
+
? t('order.bindDevicePermissionDenied')
|
|
144
|
+
: t('order.bindDeviceFailed'),
|
|
145
|
+
type: 'error'
|
|
146
|
+
})
|
|
147
|
+
return
|
|
148
|
+
}
|
|
111
149
|
Dialog.open({
|
|
112
150
|
title: capitalCase(t('order.bindDevice')),
|
|
113
151
|
contentComponent: KioskOtpDialog,
|
|
@@ -116,7 +154,7 @@ async function requestOtp() {
|
|
|
116
154
|
}
|
|
117
155
|
}).onClose(async () => {
|
|
118
156
|
// Refresh devices after dialog closes (in case a device was bound)
|
|
119
|
-
await
|
|
157
|
+
await loadDevices()
|
|
120
158
|
})
|
|
121
159
|
}
|
|
122
160
|
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
</div>
|
|
81
81
|
|
|
82
82
|
<FmButton
|
|
83
|
+
v-if="canManageDevices"
|
|
83
84
|
class="w-full"
|
|
84
85
|
variant="primary"
|
|
85
86
|
:label="device?.pinInfo ? t('order.resetDevicePin') : t('order.setDevicePin')"
|
|
@@ -139,6 +140,7 @@
|
|
|
139
140
|
</div>
|
|
140
141
|
</FmSideSheet>
|
|
141
142
|
<FmButton
|
|
143
|
+
v-if="canBindDevice"
|
|
142
144
|
variant="plain"
|
|
143
145
|
icon="link_off"
|
|
144
146
|
class="text-fm-color-system-error-300"
|
|
@@ -213,9 +215,11 @@ import dayjs from 'dayjs'
|
|
|
213
215
|
import relativeTime from 'dayjs/plugin/relativeTime'
|
|
214
216
|
import { computed, ref, watch } from 'vue'
|
|
215
217
|
import KioskUnbindConfirm from './KioskUnbindConfirm.vue'
|
|
218
|
+
import { useKioskPermission } from '@/composables/useKioskPermission'
|
|
216
219
|
dayjs.extend(relativeTime)
|
|
217
220
|
|
|
218
221
|
const { t } = useI18n()
|
|
222
|
+
const { canManageDevices, canBindDevice } = useKioskPermission()
|
|
219
223
|
|
|
220
224
|
const Dialog = useDialog()
|
|
221
225
|
const Snackbar = useSnackbar()
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
<span class="fm-typo-en-body-md-400 block"> {{ t('order.kioskDisplayDescription') }} </span>
|
|
8
8
|
</div>
|
|
9
9
|
<FmButton
|
|
10
|
+
v-if="canBindDevice"
|
|
10
11
|
variant="primary"
|
|
11
12
|
:label="t('order.bindDevice')"
|
|
12
13
|
size="md"
|
|
@@ -15,6 +16,31 @@
|
|
|
15
16
|
/>
|
|
16
17
|
</div>
|
|
17
18
|
|
|
19
|
+
<!-- Permission denied (e.g. the user reached this tab via the bind-only -->
|
|
20
|
+
<!-- coverSubject, but GET /devices requires the device-management subject). -->
|
|
21
|
+
<KioskStatePanel
|
|
22
|
+
v-if="loadError === 'forbidden'"
|
|
23
|
+
icon="lock"
|
|
24
|
+
:title="t('order.deviceAccessDeniedTitle')"
|
|
25
|
+
:message="t('order.deviceAccessDeniedMessage')"
|
|
26
|
+
/>
|
|
27
|
+
|
|
28
|
+
<!-- Any other load failure -->
|
|
29
|
+
<KioskStatePanel
|
|
30
|
+
v-else-if="loadError === 'error'"
|
|
31
|
+
icon="error"
|
|
32
|
+
:title="t('order.deviceLoadErrorTitle')"
|
|
33
|
+
:message="t('order.deviceLoadErrorMessage')"
|
|
34
|
+
>
|
|
35
|
+
<FmButton
|
|
36
|
+
variant="secondary"
|
|
37
|
+
:label="t('order.retry')"
|
|
38
|
+
prepend-icon="refresh"
|
|
39
|
+
@click="$emit('retry')"
|
|
40
|
+
/>
|
|
41
|
+
</KioskStatePanel>
|
|
42
|
+
|
|
43
|
+
<template v-else>
|
|
18
44
|
<!-- Search and Filter Bar -->
|
|
19
45
|
<div class="flex items-center gap-3 flex-wrap">
|
|
20
46
|
<FmSearch
|
|
@@ -72,6 +98,7 @@
|
|
|
72
98
|
{{ t('order.noDevicesBound') }}
|
|
73
99
|
</div>
|
|
74
100
|
</div>
|
|
101
|
+
</template>
|
|
75
102
|
</div>
|
|
76
103
|
</div>
|
|
77
104
|
</template>
|
|
@@ -80,16 +107,22 @@ import type { MfKioskDevice } from '@/modules/kiosk/interface'
|
|
|
80
107
|
import { useI18n } from '@feedmepos/mf-common'
|
|
81
108
|
import { computed, ref } from 'vue'
|
|
82
109
|
import KioskDeviceCard from './KioskDeviceCard.vue'
|
|
110
|
+
import KioskStatePanel from '@/views/kiosk/KioskStatePanel.vue'
|
|
111
|
+
import { useKioskPermission } from '@/composables/useKioskPermission'
|
|
83
112
|
|
|
84
113
|
const { t } = useI18n()
|
|
114
|
+
const { canBindDevice } = useKioskPermission()
|
|
85
115
|
|
|
86
116
|
interface Props {
|
|
87
117
|
devices: MfKioskDevice[]
|
|
118
|
+
/** Why the device list failed to load, if at all. 'forbidden' === HTTP 403. */
|
|
119
|
+
loadError?: 'forbidden' | 'error' | null
|
|
88
120
|
}
|
|
89
121
|
|
|
90
|
-
const props = defineProps<Props>()
|
|
122
|
+
const props = withDefaults(defineProps<Props>(), { loadError: null })
|
|
91
123
|
defineEmits<{
|
|
92
124
|
(e: 'requestOtp'): void
|
|
125
|
+
(e: 'retry'): void
|
|
93
126
|
}>()
|
|
94
127
|
|
|
95
128
|
const searchQuery = ref('')
|
|
@@ -119,14 +152,14 @@ const filteredDevices = computed(() => {
|
|
|
119
152
|
// Apply search filter
|
|
120
153
|
const query = searchQuery.value.toLowerCase().trim()
|
|
121
154
|
if (query) {
|
|
122
|
-
result = result.filter((d) => {
|
|
123
|
-
const name = d.name?.toLowerCase() || ''
|
|
124
|
-
const machineId = d.machineId?.toLowerCase() || ''
|
|
125
|
-
const slot = d.slotInfo?.toLowerCase() || ''
|
|
126
|
-
const remark = d.remarkInfo?.toLowerCase() || ''
|
|
127
|
-
return name.includes(query) || machineId.includes(query) || slot.includes(query) || remark.includes(query)
|
|
128
|
-
})
|
|
129
|
-
}
|
|
155
|
+
result = result.filter((d) => {
|
|
156
|
+
const name = d.name?.toLowerCase() || ''
|
|
157
|
+
const machineId = d.machineId?.toLowerCase() || ''
|
|
158
|
+
const slot = d.slotInfo?.toLowerCase() || ''
|
|
159
|
+
const remark = d.remarkInfo?.toLowerCase() || ''
|
|
160
|
+
return name.includes(query) || machineId.includes(query) || slot.includes(query) || remark.includes(query)
|
|
161
|
+
})
|
|
162
|
+
}
|
|
130
163
|
|
|
131
164
|
// Sort tablets by slot, kiosks by name
|
|
132
165
|
return result.sort((a, b) => {
|
|
@@ -337,13 +337,14 @@ const validKioskOrderSetting = computed<MfKioskOrderSetting | null>(() => {
|
|
|
337
337
|
if (!ePayment) return null
|
|
338
338
|
|
|
339
339
|
const hasCard = ePayment.card?.terminal || ePayment.card?.nfc
|
|
340
|
-
|
|
340
|
+
const hasWallet =
|
|
341
341
|
ePayment.eWallet?.qrPay ||
|
|
342
342
|
ePayment.eWallet?.scanPay ||
|
|
343
343
|
ePayment.eWallet?.terminalScanPay ||
|
|
344
344
|
ePayment.eWallet?.terminalQrPay
|
|
345
|
+
const hasTerminal = ePayment.terminal
|
|
345
346
|
|
|
346
|
-
if (!hasCard && !hasWallet) return null
|
|
347
|
+
if (!hasCard && !hasWallet && !hasTerminal) return null
|
|
347
348
|
}
|
|
348
349
|
|
|
349
350
|
// Return the form as-is if valid, with display stand disabled when dineIn is disabled
|
|
@@ -30,11 +30,13 @@ import QueueSetting from './queue/QueueSetting.vue'
|
|
|
30
30
|
import { useI18n, useCoreStore } from '@feedmepos/mf-common'
|
|
31
31
|
import { useMenuStore } from '@/stores/menu/menu'
|
|
32
32
|
import { useSnackbarFunctions } from '@/components/snackbar'
|
|
33
|
+
import { useQrOrderingEnabled } from '@/composables/useQrOrderingEnabled'
|
|
33
34
|
|
|
34
35
|
const { t } = useI18n()
|
|
35
36
|
const { currentRestaurant } = useCoreStore()
|
|
36
37
|
const menuStore = useMenuStore()
|
|
37
38
|
const { showError } = useSnackbarFunctions()
|
|
39
|
+
const qrEnabled = useQrOrderingEnabled()
|
|
38
40
|
type OrderSettingMenuItemValue =
|
|
39
41
|
| 'delivery'
|
|
40
42
|
| 'pickup'
|
|
@@ -47,17 +49,33 @@ type OrderSettingMenuItemValue =
|
|
|
47
49
|
| 'queue'
|
|
48
50
|
const selectedOrderSetting = ref<OrderSettingMenuItemValue>('delivery')
|
|
49
51
|
|
|
50
|
-
const settingItem = computed<FmTabProps[]>(() =>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
52
|
+
const settingItem = computed<FmTabProps[]>(() => {
|
|
53
|
+
// QR ordering off -> expose only the Delivery tab (Local delivery company).
|
|
54
|
+
if (!qrEnabled.value) {
|
|
55
|
+
return [{ label: t('order.delivery'), value: 'delivery' }]
|
|
56
|
+
}
|
|
57
|
+
return [
|
|
58
|
+
{ label: t('order.delivery'), value: 'delivery' },
|
|
59
|
+
{ label: t('order.pickup'), value: 'pickup' },
|
|
60
|
+
{ label: t('order.dineIn'), value: 'dinein' },
|
|
61
|
+
{ label: t('order.driveThru'), value: 'driveThru' },
|
|
62
|
+
// { label: t('order.serviceCharge'), value: 'servicecharge' },
|
|
63
|
+
// { label: t('order.discountRule.title'), value: 'discountRule' },
|
|
64
|
+
{ label: t('order.sms'), value: 'sms' },
|
|
65
|
+
{ label: t('order.general'), value: 'general' },
|
|
66
|
+
{ label: t('order.queue'), value: 'queue' }
|
|
67
|
+
]
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
// When QR ordering is off, keep selection on the only visible tab so a
|
|
71
|
+
// previously-selected (now hidden) tab can't stay active.
|
|
72
|
+
watch(
|
|
73
|
+
qrEnabled,
|
|
74
|
+
(enabled) => {
|
|
75
|
+
if (!enabled) selectedOrderSetting.value = 'delivery'
|
|
76
|
+
},
|
|
77
|
+
{ immediate: true }
|
|
78
|
+
)
|
|
61
79
|
|
|
62
80
|
const currentComponent = computed(() => {
|
|
63
81
|
switch (selectedOrderSetting.value) {
|
|
@@ -79,6 +97,8 @@ const currentComponent = computed(() => {
|
|
|
79
97
|
return GeneralSetting
|
|
80
98
|
case 'queue':
|
|
81
99
|
return QueueSetting
|
|
100
|
+
default:
|
|
101
|
+
return DeliverySetting
|
|
82
102
|
}
|
|
83
103
|
})
|
|
84
104
|
|
|
@@ -88,11 +108,14 @@ onMounted(async () => {
|
|
|
88
108
|
}
|
|
89
109
|
})
|
|
90
110
|
|
|
91
|
-
watch(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
111
|
+
watch(
|
|
112
|
+
() => currentRestaurant.value,
|
|
113
|
+
async (newRestaurant) => {
|
|
114
|
+
if (newRestaurant?._id) {
|
|
115
|
+
await menuStore.loadCatalogOptions(newRestaurant._id)
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
)
|
|
96
119
|
|
|
97
120
|
watch(
|
|
98
121
|
() => menuStore.catalogOptionsError,
|