@feedmepos/mf-order-setting 0.0.92 → 0.0.94
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-Doh1JUoe.js +8891 -0
- package/dist/{KioskDevicesView-d2WLB0-w.js → KioskDevicesView-DvUq9eFa.js} +1 -1
- package/dist/{KioskDevicesView.vue_vue_type_script_setup_true_lang-rs-hNWUW.js → KioskDevicesView.vue_vue_type_script_setup_true_lang-Ce-CHsOK.js} +3 -3
- package/dist/{KioskSettingView-DFE3_u5c.js → KioskSettingView-Ba1sLolg.js} +3 -3
- package/dist/{KioskView-C3Pi3lWW.js → KioskView-CeKSWYbI.js} +5 -5
- package/dist/{OrderSettingsView-Dxg9RjSd.js → OrderSettingsView-CdxkPS_V.js} +22200 -22918
- package/dist/{app-BFlQtcsd.js → app-BQ0W0_dt.js} +2536 -1818
- package/dist/app.js +1 -1
- package/dist/featureFlag-C4gAe_F4.js +846 -0
- package/dist/frontend/mf-order/src/api/brandkit/index.d.ts +3 -0
- package/dist/frontend/mf-order/src/api/native-app/index.d.ts +2 -0
- package/dist/frontend/mf-order/src/app.d.ts +716 -0
- package/dist/frontend/mf-order/src/composables/featureFlag.d.ts +7 -0
- package/dist/frontend/mf-order/src/composables/useBusinessFeatureFlag.d.ts +4 -0
- package/dist/frontend/mf-order/src/composables/useLegacyOdsAccess.d.ts +4 -0
- package/dist/frontend/mf-order/src/composables/useMiniProgramPermission.d.ts +5 -0
- package/dist/frontend/mf-order/src/main.d.ts +716 -0
- package/dist/frontend/mf-order/src/modules/display-system/legacy-ods/interface.d.ts +80 -0
- package/dist/frontend/mf-order/src/views/display-system/legacy-ods/ColorOverrideDialog.vue.d.ts +26 -0
- package/dist/frontend/mf-order/src/views/display-system/legacy-ods/ColorSelection.vue.d.ts +15 -0
- package/dist/frontend/mf-order/src/views/display-system/legacy-ods/LegacyOdsEditorDialog.vue.d.ts +24 -0
- package/dist/frontend/mf-order/src/views/display-system/legacy-ods/LegacyOdsTemplateList.vue.d.ts +4 -0
- package/dist/frontend/mf-order/src/views/display-system/view-selection.d.ts +18 -0
- package/dist/frontend/mf-order/src/views/order-settings/components/push-availability.d.ts +13 -0
- package/dist/frontend/mf-order/tsconfig.app.tsbuildinfo +1 -1
- package/dist/{index-ByiTrmdq.js → index-BFJ4YEfL.js} +2 -2
- package/dist/{index-CaO7aaaT.js → index-CGiJXVU3.js} +1 -1
- package/dist/{index-s2kWGMtz.js → index-DSB009Br.js} +1 -1
- package/dist/{order.dto-C829lA69.js → order.dto-CUp8zhQC.js} +18 -18
- package/dist/package/entity/order-platform/tng/tng-menu.do.d.ts +74 -74
- package/dist/style.css +1 -1
- package/env.d.ts +2 -0
- package/package.json +2 -1
- package/src/api/brandkit/index.ts +24 -0
- package/src/api/native-app/index.ts +26 -0
- package/src/api/native-app/native-app.spec.ts +42 -0
- package/src/composables/featureFlag.ts +22 -0
- package/src/composables/useBusinessFeatureFlag.ts +44 -0
- package/src/composables/useLegacyOdsAccess.ts +35 -0
- package/src/composables/useMiniProgramPermission.ts +19 -0
- package/src/composables/useQrOrderingEnabled.ts +1 -21
- package/src/locales/en-US.json +179 -0
- package/src/locales/ja-JP.json +179 -0
- package/src/locales/th-TH.json +179 -0
- package/src/locales/zh-CN.json +179 -0
- package/src/modules/display-system/legacy-ods/interface.ts +108 -0
- package/src/router/routes.ts +1 -1
- package/src/views/display-system/DisplaySystemView.vue +82 -11
- package/src/views/display-system/legacy-ods/ColorOverrideDialog.vue +223 -0
- package/src/views/display-system/legacy-ods/ColorSelection.vue +67 -0
- package/src/views/display-system/legacy-ods/LegacyOdsEditorDialog.spec.ts +185 -0
- package/src/views/display-system/legacy-ods/LegacyOdsEditorDialog.vue +1677 -0
- package/src/views/display-system/legacy-ods/LegacyOdsTemplateList.spec.ts +124 -0
- package/src/views/display-system/legacy-ods/LegacyOdsTemplateList.vue +297 -0
- package/src/views/display-system/legacy-ods/brandkit.spec.ts +67 -0
- package/src/views/display-system/view-selection.spec.ts +93 -0
- package/src/views/display-system/view-selection.ts +54 -0
- package/src/views/order-settings/components/NotifyChannelEditor.spec.ts +184 -0
- package/src/views/order-settings/components/NotifyChannelEditor.vue +84 -5
- package/src/views/order-settings/components/push-availability.spec.ts +59 -0
- package/src/views/order-settings/components/push-availability.ts +78 -0
- package/src/views/order-settings/queue/QueueSetting.vue +7 -0
- package/src/views/order-settings/sms/SmsSetting.vue +11 -0
- package/dist/DisplaySystemView-DZS7EVfk.js +0 -6564
- package/dist/_plugin-vue_export-helper-CHgC5LLL.js +0 -9
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
|
+
import { mount, type VueWrapper } from '@vue/test-utils'
|
|
4
|
+
import { ref } from 'vue'
|
|
5
|
+
import type { OdsConfigEntry } from '@/modules/display-system/legacy-ods/interface'
|
|
6
|
+
|
|
7
|
+
const access = {
|
|
8
|
+
canAccessOdsTemplateSettings: ref(true),
|
|
9
|
+
isAdvancedCustomizationEnabled: ref(false)
|
|
10
|
+
}
|
|
11
|
+
vi.mock('@/composables/useLegacyOdsAccess', () => ({ useLegacyOdsAccess: () => access }))
|
|
12
|
+
vi.mock('@feedmepos/media-picker', () => ({
|
|
13
|
+
MediaPickerModal: {
|
|
14
|
+
name: 'MediaPickerModal',
|
|
15
|
+
props: ['open', 'businessId', 'kinds', 'zIndex'],
|
|
16
|
+
template: '<div />'
|
|
17
|
+
}
|
|
18
|
+
}))
|
|
19
|
+
vi.mock('@feedmepos/mf-common', () => ({
|
|
20
|
+
RestaurantSelector: { name: 'RestaurantSelector', template: '<div />' },
|
|
21
|
+
useCoreStore: () => ({ currentBusiness: ref({ _id: 'business' }), namespace: ref('dev') }),
|
|
22
|
+
useI18n: () => ({ t: (key: string) => key })
|
|
23
|
+
}))
|
|
24
|
+
vi.mock('./ColorOverrideDialog.vue', () => ({ default: { template: '<div />' } }))
|
|
25
|
+
import Editor from './LegacyOdsEditorDialog.vue'
|
|
26
|
+
|
|
27
|
+
const wrappers: VueWrapper[] = []
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
access.canAccessOdsTemplateSettings.value = true
|
|
30
|
+
access.isAdvancedCustomizationEnabled.value = false
|
|
31
|
+
vi.stubGlobal(
|
|
32
|
+
'ResizeObserver',
|
|
33
|
+
class {
|
|
34
|
+
observe() {}
|
|
35
|
+
disconnect() {}
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
})
|
|
39
|
+
afterEach(() => {
|
|
40
|
+
wrappers.forEach((wrapper) => wrapper.unmount())
|
|
41
|
+
wrappers.length = 0
|
|
42
|
+
vi.unstubAllGlobals()
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
async function editor(entry: OdsConfigEntry = { isDefault: true, label: '默认 🍵' }) {
|
|
46
|
+
const wrapper = mount(Editor, {
|
|
47
|
+
props: {
|
|
48
|
+
modelValue: false,
|
|
49
|
+
entry,
|
|
50
|
+
editingIndex: 0,
|
|
51
|
+
allEntries: [entry],
|
|
52
|
+
brandkit: { colors: { primary: '#123456' } } as never,
|
|
53
|
+
colorFields: []
|
|
54
|
+
},
|
|
55
|
+
global: {
|
|
56
|
+
stubs: {
|
|
57
|
+
Teleport: true,
|
|
58
|
+
FmButton: {
|
|
59
|
+
props: ['label', 'disabled'],
|
|
60
|
+
template: '<button :disabled="disabled">{{ label }}</button>'
|
|
61
|
+
},
|
|
62
|
+
FmIcon: true,
|
|
63
|
+
FmTextField: true,
|
|
64
|
+
FmSwitch: true,
|
|
65
|
+
FmButtonGroup: true,
|
|
66
|
+
FmStepperField: true,
|
|
67
|
+
FmRadio: true
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
wrappers.push(wrapper)
|
|
72
|
+
await wrapper.setProps({ modelValue: true })
|
|
73
|
+
return wrapper
|
|
74
|
+
}
|
|
75
|
+
async function confirm(wrapper: VueWrapper) {
|
|
76
|
+
await wrapper
|
|
77
|
+
.findAll('button')
|
|
78
|
+
.find((button) => button.text().endsWith('.confirm'))!
|
|
79
|
+
.trigger('click')
|
|
80
|
+
// The list closes the editor only once the save has landed.
|
|
81
|
+
expect(wrapper.emitted('update:modelValue')).toBeUndefined()
|
|
82
|
+
return wrapper.emitted('save')![0][0] as OdsConfigEntry
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function previewBrandKit(wrapper: VueWrapper) {
|
|
86
|
+
const url = new URL(wrapper.get('iframe').attributes('src'))
|
|
87
|
+
expect(url.origin).toBe('https://v2-dev.feedme-ods.pages.dev')
|
|
88
|
+
expect(url.searchParams.get('preview')).toBe('1')
|
|
89
|
+
return JSON.parse(Buffer.from(url.searchParams.get('brandKit')!, 'base64url').toString('utf8'))
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
describe('legacy ODS editor', () => {
|
|
93
|
+
it('keeps collected-order hiding across preset changes and previews the draft as default', async () => {
|
|
94
|
+
const wrapper = await editor({
|
|
95
|
+
isDefault: false,
|
|
96
|
+
label: '默认 🍵',
|
|
97
|
+
restaurantIds: ['outlet'],
|
|
98
|
+
display: { hideCompletedOrders: true } as never
|
|
99
|
+
})
|
|
100
|
+
const presets = wrapper.findAllComponents({ name: 'FmButtonGroup' })[0]
|
|
101
|
+
presets.vm.$emit('update:modelValue', { value: 'preset2' })
|
|
102
|
+
await wrapper.vm.$nextTick()
|
|
103
|
+
const preview = previewBrandKit(wrapper)
|
|
104
|
+
expect(preview.colors.primary).toBe('#123456')
|
|
105
|
+
expect(preview.ods[0]).toMatchObject({
|
|
106
|
+
isDefault: true,
|
|
107
|
+
layout: { background: null, sidePanel: { url: '/images/feedme-side.png' } },
|
|
108
|
+
display: { groupBy: 'status', hideCompletedOrders: true }
|
|
109
|
+
})
|
|
110
|
+
const saved = await confirm(wrapper)
|
|
111
|
+
expect(saved.label).toBe('默认 🍵')
|
|
112
|
+
expect(saved.restaurantIds).toEqual(['outlet'])
|
|
113
|
+
expect(saved.isDefault).toBe(false)
|
|
114
|
+
expect(saved.display?.hideCompletedOrders).toBe(true)
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it('leaves metadata, outlet selection and presets editable without the template flag', async () => {
|
|
118
|
+
access.canAccessOdsTemplateSettings.value = false
|
|
119
|
+
const wrapper = await editor({ isDefault: false, label: 'Existing', restaurantIds: ['outlet'] })
|
|
120
|
+
const label = wrapper.findComponent({ name: 'FmTextField' })
|
|
121
|
+
expect(label.attributes('disabled')).toBeUndefined()
|
|
122
|
+
label.vm.$emit('update:modelValue', 'Renamed')
|
|
123
|
+
const selector = wrapper.findComponent({ name: 'RestaurantSelector' })
|
|
124
|
+
expect(selector.attributes('disabled')).toBeUndefined()
|
|
125
|
+
expect(selector.attributes('managable-only')).toBe('false')
|
|
126
|
+
selector.vm.$emit('update:modelValue', ['other-outlet'])
|
|
127
|
+
const defaultSwitch = wrapper
|
|
128
|
+
.findAllComponents({ name: 'FmSwitch' })
|
|
129
|
+
.find((item) => item.attributes('label')?.endsWith('.defaultConfiguration'))!
|
|
130
|
+
expect(defaultSwitch.attributes('disabled')).toBeUndefined()
|
|
131
|
+
defaultSwitch.vm.$emit('update:modelValue', true)
|
|
132
|
+
const presets = wrapper.findComponent({ name: 'FmButtonGroup' })
|
|
133
|
+
expect(presets.attributes('disabled')).toBeUndefined()
|
|
134
|
+
presets.vm.$emit('update:modelValue', { value: 'preset2' })
|
|
135
|
+
const hide = wrapper
|
|
136
|
+
.findAllComponents({ name: 'FmSwitch' })
|
|
137
|
+
.find((item) => item.attributes('label')?.endsWith('.hideCollectedOrders'))!
|
|
138
|
+
hide.vm.$emit('update:modelValue', true)
|
|
139
|
+
const saved = await confirm(wrapper)
|
|
140
|
+
expect(saved).toMatchObject({
|
|
141
|
+
label: 'Renamed',
|
|
142
|
+
isDefault: true,
|
|
143
|
+
restaurantIds: ['other-outlet'],
|
|
144
|
+
layout: { background: null, sidePanel: { url: '/images/feedme-side.png' } },
|
|
145
|
+
display: { groupBy: 'status', hideCompletedOrders: true }
|
|
146
|
+
})
|
|
147
|
+
expect(wrapper.text()).not.toContain('order.displaySystem.legacyOds.displaySettingsDescription')
|
|
148
|
+
expect(wrapper.text()).not.toContain('order.displaySystem.legacyOds.layoutSettingsDescription')
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
it('replaces a custom image with one picked from the media library', async () => {
|
|
152
|
+
const media = 'https://image.feedmedev.vip/media-image/business/asset/a1/main'
|
|
153
|
+
const wrapper = await editor({
|
|
154
|
+
isDefault: true,
|
|
155
|
+
layout: {
|
|
156
|
+
background: { url: 'https://image.feedmedev.vip/business/business/ods/background/old.png' },
|
|
157
|
+
sidePanel: null
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
const picker = () => wrapper.findComponent({ name: 'MediaPickerModal' })
|
|
161
|
+
expect(picker().props()).toMatchObject({ open: false, businessId: 'business', kinds: ['image'] })
|
|
162
|
+
await wrapper
|
|
163
|
+
.findAll('button')
|
|
164
|
+
.find((button) => button.text().endsWith('.changeImage'))!
|
|
165
|
+
.trigger('click')
|
|
166
|
+
expect(picker().props('open')).toBe(true)
|
|
167
|
+
picker().vm.$emit('select', { url: media, kind: 'image' })
|
|
168
|
+
await wrapper.vm.$nextTick()
|
|
169
|
+
expect(picker().props('open')).toBe(false)
|
|
170
|
+
const saved = await confirm(wrapper)
|
|
171
|
+
expect(saved.layout?.background).toMatchObject({
|
|
172
|
+
url: media,
|
|
173
|
+
size: 'cover',
|
|
174
|
+
position: 'center'
|
|
175
|
+
})
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
it('shows advanced controls only when the advanced flag is enabled', async () => {
|
|
179
|
+
const wrapper = await editor()
|
|
180
|
+
expect(wrapper.text()).not.toContain('order.displaySystem.legacyOds.footerModeDescription')
|
|
181
|
+
access.isAdvancedCustomizationEnabled.value = true
|
|
182
|
+
await wrapper.vm.$nextTick()
|
|
183
|
+
expect(wrapper.text()).toContain('order.displaySystem.legacyOds.footerModeDescription')
|
|
184
|
+
})
|
|
185
|
+
})
|