@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.
Files changed (186) hide show
  1. package/.env +1 -1
  2. package/README.md +7 -23
  3. package/dist/{KioskDevicesView-CP_cGMXE.js → KioskDevicesView-CW7nDXi2.js} +1 -1
  4. package/dist/KioskDevicesView.vue_vue_type_script_setup_true_lang-CPDkls2i.js +762 -0
  5. package/dist/{KioskSettingView-BiKYEjfe.js → KioskSettingView-DErXeFIt.js} +183 -202
  6. package/dist/KioskView-d1YjttbD.js +362 -0
  7. package/dist/OrderSettingsView-asfw4cYT.js +60012 -0
  8. package/dist/app-DrWO2wkv.js +20750 -0
  9. package/dist/app.js +3 -3
  10. package/dist/{dayjs.min-Bml-FvS7.js → dayjs.min-Fu6ejRAr.js} +1 -1
  11. package/dist/frontend/mf-order/src/api/index.d.ts +3 -1
  12. package/dist/frontend/mf-order/src/api/menu/index.d.ts +1 -1
  13. package/dist/frontend/mf-order/src/api/remoteOrder/index.d.ts +10 -3
  14. package/dist/frontend/mf-order/src/app.d.ts +194 -150
  15. package/dist/frontend/mf-order/src/components/GoogleMap.vue.d.ts +1 -1
  16. package/dist/frontend/mf-order/src/composables/useKioskPermission.d.ts +11 -0
  17. package/dist/frontend/mf-order/src/composables/useOrderSettingPermission.d.ts +13 -0
  18. package/dist/frontend/mf-order/src/composables/useQrOrderingEnabled.d.ts +2 -0
  19. package/dist/frontend/mf-order/src/helpers/menu.d.ts +1 -1
  20. package/dist/frontend/mf-order/src/main.d.ts +194 -150
  21. package/dist/frontend/mf-order/src/stores/kiosk/index.d.ts +21 -21
  22. package/dist/frontend/mf-order/src/stores/menu/menu.d.ts +906 -1044
  23. package/dist/frontend/mf-order/src/stores/order-setting/index.d.ts +39 -6
  24. package/dist/frontend/mf-order/src/stores/restaurant/index.d.ts +5 -2
  25. package/dist/frontend/mf-order/src/views/kiosk/KioskStatePanel.vue.d.ts +19 -0
  26. package/dist/frontend/mf-order/src/views/kiosk/devices/KioskDevicesView.vue.d.ts +7 -1
  27. package/dist/frontend/mf-order/src/views/order-settings/delivery/DeliverySetting.vue.d.ts +2 -2
  28. package/dist/frontend/mf-order/src/views/order-settings/delivery/components/TaxInput.vue.d.ts +3 -8
  29. package/dist/frontend/mf-order/src/views/order-settings/delivery/delivery.d.ts +3 -1
  30. package/dist/frontend/mf-order/src/views/order-settings/delivery/delivery.data.d.ts +5 -1
  31. package/dist/frontend/mf-order/src/views/order-settings/delivery/inhouse/InHouseDelivery.vue.d.ts +21 -0
  32. package/dist/frontend/mf-order/src/views/order-settings/delivery/integrated-delivery/ExternalSetting.vue.d.ts +2 -2
  33. package/dist/frontend/mf-order/src/views/order-settings/delivery/integrated-delivery/GrabfoodSetting.vue.d.ts +1 -1
  34. package/dist/frontend/mf-order/src/views/order-settings/delivery/integrated-delivery/IntegratedDelivery.vue.d.ts +28 -2
  35. package/dist/frontend/mf-order/src/views/order-settings/delivery/integrated-delivery/LinemanSetting.vue.d.ts +46 -0
  36. package/dist/frontend/mf-order/src/views/order-settings/delivery/integrated-delivery/TngSetting.vue.d.ts +57 -0
  37. package/dist/frontend/mf-order/src/views/order-settings/pickup/PickUpSettingDialogContent.vue.d.ts +23 -1
  38. package/dist/frontend/mf-order/src/views/order-settings/pickup/Preorder.vue.d.ts +27 -0
  39. package/dist/frontend/mf-order/src/views/order-settings/servicecharge/RateInput.vue.d.ts +8 -0
  40. package/dist/frontend/mf-order/tsconfig.app.tsbuildinfo +1 -1
  41. package/dist/{index-BlKeAWPk.js → index-DEKeP24S.js} +7 -7
  42. package/dist/index-DJLCZHNZ.js +665 -0
  43. package/dist/lineman-settings.dto-DS4tgxBJ.js +61259 -0
  44. package/dist/package/entity/_type-assert.d.ts +7 -0
  45. package/dist/package/entity/booking/booking.dto.d.ts +24 -24
  46. package/dist/package/entity/delivery/delivery.dto.d.ts +8 -8
  47. package/dist/package/entity/delivery/delivery.enum.d.ts +12 -0
  48. package/dist/package/entity/delivery/gateway/grab.dto.d.ts +2 -2
  49. package/dist/package/entity/delivery/gateway/kosmo.dto.d.ts +16 -16
  50. package/dist/package/entity/delivery/gateway/pandago.dto.d.ts +10 -10
  51. package/dist/package/entity/incoming-order/incoming-order-to-bill.dto.d.ts +282 -4591
  52. package/dist/package/entity/incoming-order/incoming-order.do.d.ts +32 -24
  53. package/dist/package/entity/incoming-order/incoming-order.dto.d.ts +23 -11719
  54. package/dist/package/entity/incoming-order/incoming-order.enum.d.ts +2 -2
  55. package/dist/package/entity/index.d.ts +12 -0
  56. package/dist/package/entity/kiosk/kiosk.do.d.ts +140 -140
  57. package/dist/package/entity/kiosk/kiosk.dto.d.ts +168 -168
  58. package/dist/package/entity/kiosk/marketing/marketing.dto.d.ts +63 -7
  59. package/dist/package/entity/marketing/marketing.dto.d.ts +4 -4
  60. package/dist/package/entity/member/member.dto.d.ts +6 -0
  61. package/dist/package/entity/order/dine-in/dine-in.do.d.ts +8 -8
  62. package/dist/package/entity/order/effects/effect.dto.d.ts +68 -16
  63. package/dist/package/entity/order/menu/menu.dto.d.ts +45 -8
  64. package/dist/package/entity/order/order-item/order-item.dto.d.ts +358 -3853
  65. package/dist/package/entity/order/order.do.d.ts +239 -42
  66. package/dist/package/entity/order/order.dto.d.ts +6497 -2236
  67. package/dist/package/entity/order/payment/payment.dto.d.ts +52 -12
  68. package/dist/package/entity/order-platform/base-integration.do.d.ts +8 -0
  69. package/dist/package/entity/order-platform/deliveroo/deliveroo-dto.d.ts +2 -2
  70. package/dist/package/entity/order-platform/deliveroo/deliveroo-order.do.d.ts +524 -524
  71. package/dist/package/entity/order-platform/deliveroo/deliveroo-setting.do.d.ts +2 -2
  72. package/dist/package/entity/order-platform/deliveroo/deliveroo.menu.dto.d.ts +58 -58
  73. package/dist/package/entity/order-platform/external/menu/external-master-menu.do.d.ts +212 -284
  74. package/dist/package/entity/order-platform/external/menu/external-menu.do.d.ts +331 -589
  75. package/dist/package/entity/order-platform/external/menu/external-menu.dto.d.ts +1 -1
  76. package/dist/package/entity/order-platform/external/order/external-order.do.d.ts +12 -12
  77. package/dist/package/entity/order-platform/external/order/external-order.dto.d.ts +275 -275
  78. package/dist/package/entity/order-platform/external/setting/external-setting.do.d.ts +3 -3
  79. package/dist/package/entity/order-platform/external/setting/external-setting.dto.d.ts +3 -3
  80. package/dist/package/entity/order-platform/foodpanda/foodpanda-menu.dto.d.ts +284 -284
  81. package/dist/package/entity/order-platform/foodpanda/foodpanda-order.do.d.ts +40 -40
  82. package/dist/package/entity/order-platform/foodpanda/foodpanda-order.dto.d.ts +16 -16
  83. package/dist/package/entity/order-platform/foodpanda/foodpanda-settings.do.d.ts +2 -2
  84. package/dist/package/entity/order-platform/foodpanda/foodpanda-settings.dto.d.ts +2 -2
  85. package/dist/package/entity/order-platform/gofood/gofood-order.do.d.ts +18 -18
  86. package/dist/package/entity/order-platform/gofood/gofood-settings.do.d.ts +2 -2
  87. package/dist/package/entity/order-platform/gofood/gofood-settings.dto.d.ts +2 -2
  88. package/dist/package/entity/order-platform/gofood/gofood.dto.d.ts +32 -32
  89. package/dist/package/entity/order-platform/grabfood/grabfood-edit-order.do.d.ts +12 -12
  90. package/dist/package/entity/order-platform/grabfood/grabfood-omni.do.d.ts +134 -115
  91. package/dist/package/entity/order-platform/grabfood/grabfood-order.do.d.ts +187 -165
  92. package/dist/package/entity/order-platform/grabfood/grabfood-settings.do.d.ts +8 -2
  93. package/dist/package/entity/order-platform/grabfood/grabfood-webhook.dto.d.ts +49 -42
  94. package/dist/package/entity/order-platform/grabfood/grabfood.dto.d.ts +67 -54
  95. package/dist/package/entity/order-platform/grabfood/grabfood.enum.d.ts +1 -1
  96. package/dist/package/entity/order-platform/lineman/lineman-settings.do.d.ts +37 -0
  97. package/dist/package/entity/order-platform/lineman/lineman-settings.dto.d.ts +40 -0
  98. package/dist/package/entity/order-platform/menu.dto.d.ts +716 -13887
  99. package/dist/package/entity/order-platform/order-platform.dto.d.ts +136 -2
  100. package/dist/package/entity/order-platform/order-platform.enum.d.ts +1 -1
  101. package/dist/package/entity/order-platform/shopeefood/shopeefood-order.do.d.ts +176 -176
  102. package/dist/package/entity/order-platform/shopeefood/shopeefood-order.dto.d.ts +62 -62
  103. package/dist/package/entity/order-platform/shopeefood/shopeefood-settings.do.d.ts +8 -2
  104. package/dist/package/entity/order-platform/shopeefood/shopeefood-settings.dto.d.ts +8 -2
  105. package/dist/package/entity/order-platform/tng/tng-menu.do.d.ts +1061 -0
  106. package/dist/package/entity/order-platform/tng/tng-order.do.d.ts +1915 -0
  107. package/dist/package/entity/order-platform/tng/tng-settings.do.d.ts +379 -0
  108. package/dist/package/entity/order-platform/tng/tng-settings.dto.d.ts +301 -0
  109. package/dist/package/entity/order-platform/tng/tng.dto.d.ts +1162 -0
  110. package/dist/package/entity/order-platform/tng/tng.enum.d.ts +29 -0
  111. package/dist/package/entity/order-setting/delivery/inhouse-delivery.do.d.ts +12 -0
  112. package/dist/package/entity/order-setting/delivery/inhouse-delivery.dto.d.ts +12 -0
  113. package/dist/package/entity/order-setting/dine-in/dine-in.do.d.ts +11 -0
  114. package/dist/package/entity/order-setting/dine-in/dine-in.dto.d.ts +9 -0
  115. package/dist/package/entity/order-setting/kiosk/kiosk.do.d.ts +2 -2
  116. package/dist/package/entity/order-setting/kiosk/kiosk.dto.d.ts +2 -2
  117. package/dist/package/entity/order-setting/order-setting.do.d.ts +59 -8
  118. package/dist/package/entity/order-setting/order-setting.dto.d.ts +118 -16
  119. package/dist/package/entity/order-setting/pickup/pickup.do.d.ts +12 -0
  120. package/dist/package/entity/order-setting/pickup/pickup.dto.d.ts +12 -0
  121. package/dist/package/entity/order-setting/sms/sms.do.d.ts +2 -2
  122. package/dist/package/entity/order-setting/sms/sms.dto.d.ts +2 -2
  123. package/dist/package/entity/payment/transaction.d.ts +80 -8
  124. package/dist/package/entity/printer/printer.do.d.ts +14 -14
  125. package/dist/package/entity/pubsub/ably/ably.enum.d.ts +1 -1
  126. package/dist/package/entity/queue/queue.do.d.ts +236 -1901
  127. package/dist/package/entity/queue/queue.dto.d.ts +743 -445
  128. package/dist/package/entity/restaurant/restaurant.dto.d.ts +27 -4
  129. package/dist/package/entity/websocket/websocket.dto.d.ts +10 -10
  130. package/dist/style.css +1 -0
  131. package/golar.config.ts +20 -0
  132. package/package.json +11 -4
  133. package/src/Entry.vue +2 -10
  134. package/src/api/index.ts +5 -2
  135. package/src/api/menu/index.ts +1 -1
  136. package/src/api/remoteOrder/index.ts +176 -110
  137. package/src/composables/useKioskPermission.ts +41 -0
  138. package/src/composables/useOrderSettingPermission.ts +34 -0
  139. package/src/composables/useQrOrderingEnabled.ts +66 -0
  140. package/src/helpers/menu.ts +1 -1
  141. package/src/locales/en-US.json +164 -147
  142. package/src/locales/ja-JP.json +1769 -1760
  143. package/src/locales/th-TH.json +409 -400
  144. package/src/locales/zh-CN.json +417 -408
  145. package/src/main.ts +12 -49
  146. package/src/router/index.ts +2 -2
  147. package/src/router/routes.ts +34 -5
  148. package/src/stores/menu/menu.ts +48 -27
  149. package/src/stores/restaurant/index.ts +24 -9
  150. package/src/utils/firebase-storage.ts +3 -13
  151. package/src/views/kiosk/KioskStatePanel.vue +31 -0
  152. package/src/views/kiosk/KioskView.vue +100 -62
  153. package/src/views/kiosk/devices/KioskDeviceCard.vue +4 -0
  154. package/src/views/kiosk/devices/KioskDevicesView.vue +42 -9
  155. package/src/views/kiosk/settings/KioskSettingView.vue +3 -2
  156. package/src/views/order-settings/OrderSettingsView.vue +39 -16
  157. package/src/views/order-settings/delivery/DeliverySetting.vue +223 -11
  158. package/src/views/order-settings/delivery/components/TaxInput.vue +1 -1
  159. package/src/views/order-settings/delivery/delivery.data.ts +31 -10
  160. package/src/views/order-settings/delivery/delivery.ts +60 -28
  161. package/src/views/order-settings/delivery/inhouse/InHouseDelivery.vue +40 -1
  162. package/src/views/order-settings/delivery/integrated-delivery/DeliverooSetting.vue +1 -1
  163. package/src/views/order-settings/delivery/integrated-delivery/GrabfoodSetting.vue +15 -7
  164. package/src/views/order-settings/delivery/integrated-delivery/IntegratedDelivery.vue +83 -27
  165. package/src/views/order-settings/delivery/integrated-delivery/LinemanSetting.vue +79 -0
  166. package/src/views/order-settings/delivery/integrated-delivery/ShopeefoodSetting.vue +2 -0
  167. package/src/views/order-settings/delivery/integrated-delivery/TngSetting.vue +749 -0
  168. package/src/views/order-settings/dine-in/DineInSetting.vue +54 -23
  169. package/src/views/order-settings/dine-in/PaymentType.vue +9 -12
  170. package/src/views/order-settings/general/GeneralSetting.vue +15 -6
  171. package/src/views/order-settings/pickup/PickUpSettingDialog.vue +31 -3
  172. package/src/views/order-settings/pickup/PickUpSettingDialogContent.vue +34 -0
  173. package/src/views/order-settings/pickup/Preorder.vue +13 -12
  174. package/src/views/order-settings/queue/QueueSetting.vue +30 -1
  175. package/src/views/order-settings/servicecharge/RateInput.vue +9 -7
  176. package/vite.config.ts +21 -18
  177. package/dist/KioskDevicesView.vue_vue_type_script_setup_true_lang-CiNLqFw6.js +0 -707
  178. package/dist/KioskView-BYxPrI7N.js +0 -343
  179. package/dist/OrderSettingsView-C7Y-_y5U.js +0 -32222
  180. package/dist/app-BN02cB5o.js +0 -18668
  181. package/dist/frontend/mf-order/src/api/auth/index.d.ts +0 -7
  182. package/dist/frontend/mf-order/src/stores/iframe/index.d.ts +0 -14
  183. package/dist/index-DZA8A0m4.js +0 -630
  184. package/dist/queue-transfer.dto-C7nRZOZH.js +0 -45618
  185. package/src/api/auth/index.ts +0 -20
  186. package/src/stores/iframe/index.ts +0 -23
package/src/main.ts CHANGED
@@ -1,22 +1,17 @@
1
1
  import './assets/main.css'
2
2
 
3
- import { computed, createApp } from 'vue'
3
+ import { createApp, type Plugin } from 'vue'
4
4
  import { createPinia } from 'pinia'
5
5
  import Entry from './Entry.vue'
6
6
  import { router } from './router'
7
7
  import { initialize, useCoreStore } from '@feedmepos/mf-common'
8
8
  import { FeedMeUI } from '@feedmepos/ui-library';
9
- import { AuthApi } from './api/auth'
10
- import { signInWithCustomToken } from 'firebase/auth'
11
- import { useIframeStore } from './stores/iframe'
12
9
  import { createFeedMeI18n, type I18n, detectLocale } from "@feedmepos/mf-common"
13
10
  import enUS from "./locales/en-US.json"
14
11
  import zhCN from "./locales/zh-CN.json"
15
12
  import thTH from "./locales/th-TH.json"
16
13
  import jaJP from "./locales/ja-JP.json"
17
14
 
18
- import { getFirebaseAuth } from '@/utils/firebase-app'
19
-
20
15
  export const i18nMessages = {
21
16
  "en-US": enUS,
22
17
  "zh-CN": zhCN,
@@ -35,53 +30,21 @@ function initI18n(): I18n {
35
30
 
36
31
  const app = createApp(Entry)
37
32
 
33
+ // mf-common's createFeedMeI18n returns vue-i18n's I18n instance, which is a valid
34
+ // Vue plugin at runtime but doesn't structurally match vue's tightened Plugin type
35
+ // after the mf-common bump — cast at the install site.
36
+ app.use(initI18n() as unknown as Plugin)
37
+ app.use(createPinia())
38
+ app.use(router)
39
+
40
+
38
41
  app.use(FeedMeUI, {
39
42
  locale: detectLocale(),
40
43
  })
41
44
 
42
- app.use(createPinia() as any)
43
- app.use(router)
44
- app.use(initI18n() as any)
45
-
46
-
47
45
  const CoreStore = useCoreStore();
48
- const iframeMode = computed(() => {
49
- return new URLSearchParams(window.location.search).get('iframe') === 'true';
50
- });
51
-
52
- useIframeStore().init(iframeMode.value);
53
-
54
- const firebaseAuth = getFirebaseAuth()
55
-
56
- async function signInWithToken(token: string) {
57
- const customToken = await AuthApi.getCustomToken(token);
58
- const { user } = await signInWithCustomToken(firebaseAuth, customToken);
59
- await CoreStore.signInWithToken({ ...user, id: user.uid }, await user.getIdToken());
60
- }
61
-
62
- async function init() {
63
- if (iframeMode.value) {
64
- router.beforeEach((to, from, next) => {
65
- window.addEventListener('message', async (event: MessageEvent<{ event: string, data: any }>) => {
66
- switch (event.data.event) {
67
- case 'init':
68
- await signInWithToken(event.data.data.token);
69
- await CoreStore.changeCountry(event.data.data.country);
70
- await CoreStore.changeBusiness(event.data.data.business);
71
- CoreStore.changeRestaurant(event.data.data.restaurant);
72
- break;
73
- default:
74
- break;
75
- }
76
- });
77
- next();
78
- });
79
- }
80
- if (!iframeMode.value || import.meta.env.VITE_DEBUG_MODE === 'true') {
81
- initialize(import.meta.env.VITE_AUTH_CLIENT_ID);
82
- CoreStore.setNamespace(import.meta.env.DEV ? 'dev' : 'prod');
83
- }
84
- }
85
46
 
47
+ initialize(import.meta.env.VITE_AUTH_CLIENT_ID);
48
+ CoreStore.setNamespace(import.meta.env.DEV ? 'dev' : 'prod');
86
49
 
87
- init().then(() => app.mount('#app'))
50
+ app.mount('#app')
@@ -3,8 +3,8 @@ import { routes } from './routes'
3
3
 
4
4
  const router = createRouter({
5
5
  history: createWebHistory(),
6
- routes,
6
+ routes
7
7
  })
8
8
 
9
9
  export { router }
10
- export default router;
10
+ export default router
@@ -1,26 +1,55 @@
1
- import { type RouteRecordRaw } from 'vue-router'
1
+ import { type RouteRecordRaw, type RouteMeta } from 'vue-router'
2
+ import { defineAsyncComponent } from 'vue'
3
+ import { Permission, type CaslPermission } from '@feedmepos/hrm-permission'
4
+ import { withPermission } from '@feedmepos/hrm-permission/components'
5
+ import { kioskPermission } from '@/composables/useKioskPermission'
6
+ import { orderSettingPermission } from '@/composables/useOrderSettingPermission'
2
7
  import { PortalRoute } from '@/utils/constants/route';
3
8
 
9
+ /** Wrap CASL permissions into a route meta the withPermission HOC validates. */
10
+ const permissionMeta = (permissions: CaslPermission[]): RouteMeta =>
11
+ ({
12
+ validationManifest: { requiredCaslPermissions: permissions }
13
+ }) as unknown as RouteMeta;
14
+
15
+ const manageDevices = kioskPermission(Permission.Action.manage, 'deviceManagement');
16
+ const bindDevices = kioskPermission(Permission.Action.manage, 'deviceBinding');
17
+ const manageOrderSetting = orderSettingPermission(Permission.Action.manage);
18
+
4
19
  const routes: RouteRecordRaw[] = [
5
20
  {
21
+ // Main Kiosk view hosts both the device-binding and management tabs, so
22
+ // allow access via either subject (coverSubject = OR fallback).
6
23
  path: PortalRoute.KioskRoute,
7
24
  name: 'Kiosk',
8
- component: () => import('@/views/kiosk/KioskView.vue')
25
+ component: withPermission(defineAsyncComponent(() => import('@/views/kiosk/KioskView.vue'))),
26
+ meta: permissionMeta([{ ...manageDevices, coverSubject: bindDevices.subject }]),
9
27
  },
10
28
  {
11
29
  path: PortalRoute.KioskDeviceRoute,
12
30
  name: 'Kiosk Device',
13
- component: () => import('@/views/kiosk/devices/KioskDevicesView.vue')
31
+ component: withPermission(
32
+ defineAsyncComponent(() => import('@/views/kiosk/devices/KioskDevicesView.vue')),
33
+ ),
34
+ meta: permissionMeta([manageDevices]),
14
35
  },
15
36
  {
37
+ // The Kiosk "Settings" tab is order settings, so it is governed by the
38
+ // order-setting subject (a kiosk permission is still required to reach /kiosk).
16
39
  path: PortalRoute.KioskOrderSettingRoute,
17
40
  name: 'Kiosk Order Setting',
18
- component: () => import('@/views/kiosk/settings/KioskSettingView.vue')
41
+ component: withPermission(
42
+ defineAsyncComponent(() => import('@/views/kiosk/settings/KioskSettingView.vue')),
43
+ ),
44
+ meta: permissionMeta([manageOrderSetting]),
19
45
  },
20
46
  {
21
47
  path: PortalRoute.OrderSettingView,
22
48
  name: 'Order Setting View',
23
- component: () => import('@/views/order-settings/OrderSettingsView.vue')
49
+ component: withPermission(
50
+ defineAsyncComponent(() => import('@/views/order-settings/OrderSettingsView.vue')),
51
+ ),
52
+ meta: permissionMeta([manageOrderSetting]),
24
53
  },
25
54
  ];
26
55
 
@@ -1,5 +1,5 @@
1
1
  import { generator, overrideMenu } from '@feedmepos/menu';
2
- import { F_MENU_VERSION, FdoHasPosition, FdoItemOverriderV4, FdoItemVariant, FdoMenuV4, FdoMenuV4Catalog, FdoMenuV4Category, FdoMenuV4Item, FdoMenuV4VariantGroup, FdtoRestaurantWithMenuV4 } from '@feedmepos/menu/entity';
2
+ import { F_MENU_VERSION, FdoHasPosition, FdoItemOverriderV4, FdoItemVariant, FdoMenuV4, FdoMenuV4Catalog, FdoMenuV4Category, FdoMenuV4Item, FdoMenuV4VariantGroup, FdtoRestaurantWithMenuV4 } from '@feedmepos/entity';
3
3
 
4
4
  import { defineStore } from 'pinia';
5
5
  import { menuApi } from '@/api/menu';
@@ -10,10 +10,10 @@ import { useCoreStore } from '@feedmepos/mf-common';
10
10
 
11
11
  interface MenuState {
12
12
  restaurants: FdtoRestaurantWithMenuV4[];
13
- menu: { _rev: string } & FdoMenuV4;
13
+ menu: { _rev: string; } & FdoMenuV4;
14
14
  currentCatalogId: string | null;
15
15
  currentSchedulerId: string;
16
- catalogOptions: { label: string; value: string | null }[];
16
+ catalogOptions: { label: string; value: string | null; }[];
17
17
  loadingCatalogOptions: boolean;
18
18
  catalogOptionsError: string | null;
19
19
  }
@@ -35,7 +35,7 @@ export function sortPosition<T extends FdoHasPosition>(
35
35
  elseIf: keyof T | ((v: T) => string),
36
36
  ) {
37
37
  const cloned = arr;
38
- const result = cloned.reduce<{ hasPosition: T[], noPosition: T[] }>((pv, v) => {
38
+ const result = cloned.reduce<{ hasPosition: T[], noPosition: T[]; }>((pv, v) => {
39
39
  if (v.position == null) {
40
40
  pv.noPosition.push(v);
41
41
  } else {
@@ -53,8 +53,8 @@ export function sortPosition<T extends FdoHasPosition>(
53
53
  type Item = Omit<FdoMenuV4Item, 'variant'> & {
54
54
  codeName: string;
55
55
  variant?: Omit<FdoItemVariant, 'variantCombinations'> & {
56
- variantCombinations: (VariantItem & { codeName: string })[]
57
- }
56
+ variantCombinations: (VariantItem & { codeName: string; })[];
57
+ };
58
58
  };
59
59
 
60
60
  interface VariantItem extends FdoItemOverriderV4 {
@@ -63,10 +63,10 @@ interface VariantItem extends FdoItemOverriderV4 {
63
63
 
64
64
 
65
65
  export function categorizedItems(
66
- categories: (Omit<FdoMenuV4Category, '_id'> & { _id: string | null })[],
66
+ categories: (Omit<FdoMenuV4Category, '_id'> & { _id: string | null; })[],
67
67
  items: FdoMenuV4Item[],
68
68
  ): CategorizedItem[] {
69
- const mapped = items.reduce<{ [key: string]: Item[] }>((pv, p) => {
69
+ const mapped = items.reduce<{ [key: string]: Item[]; }>((pv, p) => {
70
70
  const key = p.category || '';
71
71
  const combinations = mapVariant(p.variant?.variantGroupIds);
72
72
  const i = {
@@ -105,28 +105,23 @@ export const useMenuStore = defineStore('menu', {
105
105
  version() {
106
106
  return (useCoreStore().currentBusiness?.value?.menuVersion || F_MENU_VERSION.enum.v3) as F_MENU_VERSION;
107
107
  },
108
-
109
108
  mergedMenu(): FdoMenuV4 {
110
109
  const res = overrideMenu({
111
110
  menu: this.menu as FdoMenuV4,
112
111
  catalogId: this.currentCatalogId,
113
-
114
112
  });
115
-
116
-
117
113
  return res;
118
-
119
114
  },
120
115
  catalogs(): FdoMenuV4Catalog[] {
121
116
  const catalogs = this.menu.modules.catalog;
122
- return catalogs
117
+ return catalogs;
123
118
  },
124
119
  currentCatalog: (state): FdoMenuV4Catalog | undefined => {
125
120
  return state.menu.modules.catalog.find(
126
121
  (catalog) => catalog._id === state.currentCatalogId
127
122
  );
128
123
  },
129
- categories(): (Omit<FdoMenuV4Category, '_id'> & { _id: string | null })[] {
124
+ categories(): (Omit<FdoMenuV4Category, '_id'> & { _id: string | null; })[] {
130
125
  const categories = this.mergedMenu.modules.category;
131
126
  return [
132
127
  ...this.rules.item.addon ? [{ _id: this.currentCatalogId ? '' : null, name: 'Addon', position: 0 }] : [],
@@ -137,17 +132,17 @@ export const useMenuStore = defineStore('menu', {
137
132
  const items = this.mergedMenu.modules.item;
138
133
  return sortPosition(items, (item) => item.code || item.name);
139
134
  },
140
- sortedItems(): { [key: string]: number } {
135
+ sortedItems(): { [key: string]: number; } {
141
136
  const category = this.menu.modules.category;
142
137
  const sorted = sortPosition(category, (c) => c.name)
143
- .reduce<{ [key: string]: number }>((pv, c, index) => {
138
+ .reduce<{ [key: string]: number; }>((pv, c, index) => {
144
139
  pv[c._id] = index;
145
140
  return pv;
146
141
  }, { ['']: 0 });
147
142
 
148
143
  const items = this.menu.modules.item;
149
144
  return sortPosition(items, (item) => item.code || item.name)
150
- .reduce<{ [key: string]: number }>((pv, item, index) => {
145
+ .reduce<{ [key: string]: number; }>((pv, item, index) => {
151
146
  pv[item._id] = index + sorted[item.category || ''];
152
147
  return pv;
153
148
  }, {});
@@ -160,6 +155,32 @@ export const useMenuStore = defineStore('menu', {
160
155
  categorizedItems(): CategorizedItem[] {
161
156
  return categorizedItems(this.categories, this.items);
162
157
  },
158
+ rawCategorizedItems(): CategorizedItem[] {
159
+ const grouped = this.menu.modules.item.reduce<Record<string, Item[]>>((acc, p) => {
160
+ const key = p.category || '';
161
+ const i: Item = {
162
+ ...p,
163
+ codeName: [p.code, p.name].filter(Boolean).join(' '),
164
+ variant: {
165
+ variantGroupIds: p.variant?.variantGroupIds ?? [],
166
+ variantCombinations: (p.variant?.variantCombinations ?? []).map((vc) => ({
167
+ ...vc,
168
+ codeName: [vc.code, vc.name].filter(Boolean).join(' ').trim() || '-',
169
+ })),
170
+ },
171
+ };
172
+ acc[key] = acc[key] ? [...acc[key], i] : [i];
173
+ return acc;
174
+ }, {});
175
+
176
+ const res = sortPosition(this.menu.modules.category, (c) => c.name).map((category) => ({
177
+ id: category._id,
178
+ name: category.name,
179
+ items: grouped[category._id] ?? [],
180
+ }));
181
+
182
+ return res
183
+ },
163
184
  rules(): MenuRules {
164
185
  const isDefault = this.currentCatalogId == undefined;
165
186
  const isV4 = this.version === F_MENU_VERSION.enum.v4;
@@ -247,24 +268,24 @@ export const useMenuStore = defineStore('menu', {
247
268
  async loadCatalogOptions(restaurantId: string) {
248
269
  this.loadingCatalogOptions = true;
249
270
  this.catalogOptionsError = null;
250
- const options: {label:string, value: string | null}[] = [{
271
+ const options: { label: string, value: string | null; }[] = [{
251
272
  label: 'Main',
252
273
  value: null,
253
274
  }];
254
275
 
255
276
  try {
256
- const resp = await menuApi.readCatalogOptions(restaurantId);
257
- const restaurntCatalogOptions = resp[restaurantId] ?? [];
258
- for (let index = 0; index < restaurntCatalogOptions.length; index++) {
259
- const opt = restaurntCatalogOptions[index];
277
+ const resp = await menuApi.readCatalogOptions(restaurantId);
278
+ const restaurntCatalogOptions = resp[restaurantId] ?? [];
279
+ for (let index = 0; index < restaurntCatalogOptions.length; index++) {
280
+ const opt = restaurntCatalogOptions[index];
260
281
  options.push({
261
282
  label: opt.name,
262
283
  value: opt._id
263
- })
264
- }
265
- this.catalogOptions = options;
284
+ });
285
+ }
286
+ this.catalogOptions = options;
266
287
  } catch (error) {
267
- console.error('Failed to load catalog options:', error)
288
+ console.error('Failed to load catalog options:', error);
268
289
  this.catalogOptionsError = 'order.failedToLoadCatalogOptions';
269
290
  } finally {
270
291
  this.loadingCatalogOptions = false;
@@ -20,6 +20,7 @@ import {
20
20
  FdoGrabfoodSettings,
21
21
  FdoExternalSetting,
22
22
  FdoFoodpandaSettings,
23
+ FdoLinemanSettings,
23
24
  FdoGoFoodSettings,
24
25
  FdoShopeeFoodSettings
25
26
  } from '@entity'
@@ -29,7 +30,6 @@ import { remoteOrderApi } from '@/api/remoteOrder'
29
30
  import { useI18n, useCoreStore } from '@feedmepos/mf-common'
30
31
  import { computed, ref, watch } from 'vue'
31
32
 
32
-
33
33
  export interface Profile extends FdoProfile {
34
34
  address: Address
35
35
  }
@@ -65,7 +65,9 @@ function initRestaurantState(): RestaurantState {
65
65
  export const useRestaurantStore = defineStore('restaurant', () => {
66
66
  const CoreStore = useCoreStore()
67
67
  const state = ref(initRestaurantState())
68
- const currentRestaurantSetting = computed<RestaurantSettingDoc | undefined>(() => state.value.restaurantSettings[CoreStore.currentRestaurant.value?._id || ''])
68
+ const currentRestaurantSetting = computed<RestaurantSettingDoc | undefined>(
69
+ () => state.value.restaurantSettings[CoreStore.currentRestaurant.value?._id || '']
70
+ )
69
71
 
70
72
  async function readRestaurantSetting(restaurantId: string) {
71
73
  const restaurantSetting = await restaurantApi.readRestaurantSetting(restaurantId)
@@ -104,20 +106,32 @@ export const useRestaurantStore = defineStore('restaurant', () => {
104
106
  async function updateFeedmeDelivery(restaurantId: string, dto: FdoRestaurantFeedmeDelivery) {
105
107
  return await remoteOrderApi.integratedDelivery.updateFeedme(restaurantId, dto)
106
108
  }
107
- async function updateIntegratedFoodpandaDelivery(restaurantId: string, dto: FdoFoodpandaSettings) {
109
+ async function updateIntegratedFoodpandaDelivery(
110
+ restaurantId: string,
111
+ dto: FdoFoodpandaSettings
112
+ ) {
108
113
  await remoteOrderApi.integratedDelivery.updateFoodpanda(restaurantId, dto)
109
114
  }
110
115
  async function updateIntegratedGrabfoodDelivery(restaurantId: string, dto: FdoGrabfoodSettings) {
111
116
  await remoteOrderApi.integratedDelivery.updateGrabfood(restaurantId, dto)
112
117
  }
113
- async function updateIntegratedShopeefoodDelivery(restaurantId: string, dto: FdoShopeeFoodSettings) {
118
+ async function updateIntegratedLinemanDelivery(restaurantId: string, dto: FdoLinemanSettings) {
119
+ await remoteOrderApi.integratedDelivery.updateLineman(restaurantId, dto)
120
+ }
121
+ async function updateIntegratedShopeefoodDelivery(
122
+ restaurantId: string,
123
+ dto: FdoShopeeFoodSettings
124
+ ) {
114
125
  await remoteOrderApi.integratedDelivery.updateShopeefood(restaurantId, dto)
115
126
  }
116
127
  async function updateIntegratedGofoodDelivery(restaurantId: string, dto: FdoGoFoodSettings) {
117
128
  await remoteOrderApi.integratedDelivery.updateGofood(restaurantId, dto)
118
129
  }
119
130
 
120
- async function updateIntegratedDeliverooDelivery(restaurantId: string, dto: FdoDeliverooSettings) {
131
+ async function updateIntegratedDeliverooDelivery(
132
+ restaurantId: string,
133
+ dto: FdoDeliverooSettings
134
+ ) {
121
135
  await remoteOrderApi.integratedDelivery.updateDeliveroo(restaurantId, dto)
122
136
  }
123
137
  async function updateExternalDelivery(restaurantId: string, dto: FdoExternalSetting) {
@@ -127,10 +141,10 @@ export const useRestaurantStore = defineStore('restaurant', () => {
127
141
  function getRestaurantEPayment(): true | string {
128
142
  const { t } = useI18n()
129
143
  if (!CoreStore.currentRestaurant.value) {
130
- return 'getRestaurantEPayment - Invalid restaurant ';
144
+ return 'getRestaurantEPayment - Invalid restaurant '
131
145
  }
132
- const payoutAccount = CoreStore.currentRestaurant.value.payoutAccount;
133
- const posVersion = CoreStore.currentRestaurant.value.posVersion;
146
+ const payoutAccount = CoreStore.currentRestaurant.value.payoutAccount
147
+ const posVersion = CoreStore.currentRestaurant.value.posVersion
134
148
 
135
149
  const validPosVersion =
136
150
  !!posVersion &&
@@ -163,10 +177,11 @@ export const useRestaurantStore = defineStore('restaurant', () => {
163
177
  updateFeedmeDelivery,
164
178
  updateIntegratedFoodpandaDelivery,
165
179
  updateIntegratedGrabfoodDelivery,
180
+ updateIntegratedLinemanDelivery,
166
181
  updateIntegratedShopeefoodDelivery,
167
182
  updateIntegratedGofoodDelivery,
168
183
  updateIntegratedDeliverooDelivery,
169
184
  updateExternalDelivery,
170
- getRestaurantEPayment,
185
+ getRestaurantEPayment
171
186
  }
172
187
  })
@@ -1,5 +1,4 @@
1
- import { AuthApi } from '@/api/auth'
2
- import { SvcConfig } from '@/api'
1
+ import { FeedMeAuth } from '@feedmepos/mf-common'
3
2
  import { signInWithCustomToken, signOut } from 'firebase/auth'
4
3
  import { ref, uploadBytes } from 'firebase/storage'
5
4
  import { getFirebaseAuth, getFirebaseStorage } from './firebase-app'
@@ -45,12 +44,7 @@ async function ensureFirebaseAuth(): Promise<void> {
45
44
 
46
45
  if (!pendingFirebaseSignIn) {
47
46
  pendingFirebaseSignIn = (async () => {
48
- const idToken = SvcConfig.getIdToken()
49
- if (!idToken) {
50
- throw new Error('Missing session token for Firebase authentication')
51
- }
52
-
53
- const customToken = await AuthApi.getCustomToken(idToken)
47
+ const customToken = await FeedMeAuth.getCustomToken()
54
48
  await signInWithCustomToken(auth, customToken)
55
49
  })().finally(() => {
56
50
  pendingFirebaseSignIn = null
@@ -65,16 +59,12 @@ async function ensureFirebaseAuth(): Promise<void> {
65
59
 
66
60
  async function forceRefreshFirebaseAuth(): Promise<void> {
67
61
  const auth = getFirebaseAuth()
68
- const idToken = SvcConfig.getIdToken()
69
- if (!idToken) {
70
- throw new Error('Missing session token for Firebase authentication')
71
- }
72
62
 
73
63
  if (auth.currentUser) {
74
64
  await signOut(auth)
75
65
  }
76
66
 
77
- const customToken = await AuthApi.getCustomToken(idToken)
67
+ const customToken = await FeedMeAuth.getCustomToken()
78
68
  await signInWithCustomToken(auth, customToken)
79
69
  }
80
70
 
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <div class="flex flex-col items-center justify-center gap-3 py-16 text-center col-span-2">
3
+ <div
4
+ class="flex items-center justify-center w-16 h-16 rounded-full bg-fm-color-surface-secondary"
5
+ >
6
+ <FmIcon :name="icon" size="xl" class="text-fm-color-typo-tertiary" />
7
+ </div>
8
+ <span class="fm-typo-en-title-sm-600 block">{{ title }}</span>
9
+ <span class="fm-typo-en-body-md-400 block text-fm-color-typo-tertiary max-w-[360px]">
10
+ {{ message }}
11
+ </span>
12
+ <div v-if="$slots.default" class="pt-2">
13
+ <slot />
14
+ </div>
15
+ </div>
16
+ </template>
17
+
18
+ <script setup lang="ts">
19
+ // Lightweight, self-contained state panel for the kiosk surface (e.g. permission
20
+ // denied / load error). Kept local because @feedmepos/hrm-permission only exposes
21
+ // its NoPermission illustration via the route-level withPermission HOC, not as a
22
+ // standalone component we can render on an API 403.
23
+ withDefaults(
24
+ defineProps<{
25
+ title: string
26
+ message: string
27
+ icon?: string
28
+ }>(),
29
+ { icon: 'info' }
30
+ )
31
+ </script>