@feedmepos/mf-miniprogram-v2 0.2.5 → 0.2.6-dev.0
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/{App-qAELeU_7.js → App-B8Qhgf0V.js} +2 -2
- package/dist/{BrandFontPicker-BZyGrK3D.js → BrandFontPicker-BzsoYtYG.js} +1 -1
- package/dist/{BrandKitView-CzefaEEN.js → BrandKitView-HqIYrYNt.js} +2 -2
- package/dist/{ControlPlaneView-DmXe1Avx.js → ControlPlaneView-BGKGx1gE.js} +7436 -7242
- package/dist/{EcosystemView-C-y5cPOp.js → EcosystemView-BG3Gba74.js} +3 -3
- package/dist/{LegacyWorkspaceEntry-CADRpDkg.js → LegacyWorkspaceEntry-lEMtmdIe.js} +1 -1
- package/dist/MobileProjectDialog-mNUZfDy7.js +389 -0
- package/dist/MobileProjectsView-DW2BNTNc.js +224 -0
- package/dist/{ModuleCenterView-B08oZqQw.js → ModuleCenterView-BBaQu0Pm.js} +1 -1
- package/dist/{ModuleDetailView-lROTkaR7.js → ModuleDetailView-ChrsLmJa.js} +1 -1
- package/dist/{PagesView-DOG8RSen.js → PagesView-CPYtQtsx.js} +1 -1
- package/dist/{PortalSettingsView-BK6kRgtf.js → PortalSettingsView-C60zqwk0.js} +4 -4
- package/dist/{TemplateCenterView-niXTXw9y.js → TemplateCenterView-Da9HzssA.js} +1 -1
- package/dist/{WorkspaceEntryView-DzR8DQC5.js → WorkspaceEntryView-DE82gwZH.js} +1 -1
- package/dist/{adminAccess-CDxAuQ-M.js → adminAccess-Cy0P9Hg-.js} +1 -1
- package/dist/app.js +11 -11
- package/dist/{controlPlane-DT3t_ftg.js → controlPlane-CDopeXyb.js} +17 -17
- package/dist/package.json +1 -1
- package/dist/{portalContext-B2pXdNtB.js → portalContext-IOgByqvZ.js} +1 -1
- package/dist/style.css +1 -1
- package/dist/{useBrandKit-CQv08nyY.js → useBrandKit-C3CGmni1.js} +2 -2
- package/dist/{useModuleCatalog-B9HXHA-e.js → useModuleCatalog-B_6PWpER.js} +1 -1
- package/package.json +1 -1
- package/dist/AppTemplatePicker.vue_vue_type_script_setup_true_lang-LE_aKvfg.js +0 -198
- package/dist/MobileProjectsView-BCXdpVTc.js +0 -331
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import { defineComponent as M, computed as k, openBlock as s, createElementBlock as d, createStaticVNode as F, createCommentVNode as b, createElementVNode as r, createVNode as w, toDisplayString as _, Fragment as L, renderList as q, normalizeClass as E, ref as v, onMounted as X, resolveComponent as S, createBlock as I, withCtx as U, createTextVNode as z, unref as Z } from "vue";
|
|
2
|
+
import { m as ee } from "./index-CIJWcl_6.js";
|
|
3
|
+
import { c as $, e as P, i as te } from "./controlPlane-CDopeXyb.js";
|
|
4
|
+
import { a as C } from "./routes-CeuodIgg.js";
|
|
5
|
+
import { _ as re } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
6
|
+
function Pe(e) {
|
|
7
|
+
return e === "active" ? "success" : e === "needs_attention" ? "warning" : "neutral";
|
|
8
|
+
}
|
|
9
|
+
function Be(e) {
|
|
10
|
+
return e === "active" ? "Active" : e === "needs_attention" ? "Needs attention" : "Archived";
|
|
11
|
+
}
|
|
12
|
+
function Le(e) {
|
|
13
|
+
return e === "succeeded" ? "success" : e === "failed" ? "error" : e === "queued" || e === "running" ? "info" : "neutral";
|
|
14
|
+
}
|
|
15
|
+
function Me(e) {
|
|
16
|
+
switch (e) {
|
|
17
|
+
case "queued":
|
|
18
|
+
return "Queued";
|
|
19
|
+
case "running":
|
|
20
|
+
return "Running";
|
|
21
|
+
case "succeeded":
|
|
22
|
+
return "Built";
|
|
23
|
+
case "failed":
|
|
24
|
+
return "Build failed";
|
|
25
|
+
default:
|
|
26
|
+
return "No build yet";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function Re(e) {
|
|
30
|
+
switch (e) {
|
|
31
|
+
case "ready":
|
|
32
|
+
return "Ready";
|
|
33
|
+
case "provisioning":
|
|
34
|
+
return "Setting up";
|
|
35
|
+
case "failed":
|
|
36
|
+
return "Setup failed";
|
|
37
|
+
default:
|
|
38
|
+
return "Not set up";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const ae = ["preview", "published", "rolled_back"];
|
|
42
|
+
function Oe(e) {
|
|
43
|
+
return ae.includes(e.status);
|
|
44
|
+
}
|
|
45
|
+
function De(e) {
|
|
46
|
+
return e.is_live === 1 ? "Live" : e.build_status === "queued" || e.build_status === "running" ? "Building" : e.build_status === "failed" ? "Failed" : e.build_status === "succeeded" ? "Ready" : "Draft";
|
|
47
|
+
}
|
|
48
|
+
function qe(e) {
|
|
49
|
+
return e.is_live === 1 ? "primary" : e.build_status === "succeeded" ? "success" : e.build_status === "queued" || e.build_status === "running" ? "info" : e.build_status === "failed" ? "error" : "neutral";
|
|
50
|
+
}
|
|
51
|
+
function Ue(e, f) {
|
|
52
|
+
return `${C.project(e, f)}/ota`;
|
|
53
|
+
}
|
|
54
|
+
function B(e) {
|
|
55
|
+
const f = e.trim();
|
|
56
|
+
return f.length <= 32 && /^\d+\.\d+\.\d+$/.test(f);
|
|
57
|
+
}
|
|
58
|
+
const le = {
|
|
59
|
+
key: 0,
|
|
60
|
+
viewBox: "0 0 56 96",
|
|
61
|
+
class: "h-[72px] w-[42px] shrink-0 rounded-[6px] border border-portal-border-default bg-portal-bg-default",
|
|
62
|
+
"aria-hidden": "true",
|
|
63
|
+
focusable: "false"
|
|
64
|
+
}, se = {
|
|
65
|
+
key: 0,
|
|
66
|
+
fill: "currentColor",
|
|
67
|
+
class: "text-fm-color-neutral-gray-300"
|
|
68
|
+
}, oe = {
|
|
69
|
+
key: 1,
|
|
70
|
+
fill: "currentColor",
|
|
71
|
+
class: "text-fm-color-neutral-gray-300"
|
|
72
|
+
}, ne = {
|
|
73
|
+
key: 2,
|
|
74
|
+
fill: "currentColor",
|
|
75
|
+
class: "text-fm-color-neutral-gray-300"
|
|
76
|
+
}, H = /* @__PURE__ */ M({
|
|
77
|
+
__name: "AppTemplateThumbnail",
|
|
78
|
+
props: {
|
|
79
|
+
restaurantStyle: {}
|
|
80
|
+
},
|
|
81
|
+
setup(e) {
|
|
82
|
+
const f = e, o = k(
|
|
83
|
+
() => f.restaurantStyle === "qsr" || f.restaurantStyle === "coffee" || f.restaurantStyle === "tea"
|
|
84
|
+
);
|
|
85
|
+
return (V, u) => o.value ? (s(), d("svg", le, [
|
|
86
|
+
e.restaurantStyle === "qsr" ? (s(), d("g", se, [...u[0] || (u[0] = [
|
|
87
|
+
F('<rect x="6" y="7" width="44" height="6" rx="3"></rect><rect x="6" y="18" width="19" height="18" rx="2"></rect><rect x="31" y="18" width="19" height="18" rx="2"></rect><rect x="6" y="40" width="19" height="18" rx="2"></rect><rect x="31" y="40" width="19" height="18" rx="2"></rect><rect x="6" y="62" width="19" height="18" rx="2"></rect><rect x="31" y="62" width="19" height="18" rx="2"></rect><rect x="6" y="85" width="44" height="7" rx="3.5" class="text-fm-color-neutral-gray-400"></rect>', 8)
|
|
88
|
+
])])) : e.restaurantStyle === "coffee" ? (s(), d("g", oe, [...u[1] || (u[1] = [
|
|
89
|
+
F('<rect x="6" y="7" width="44" height="30" rx="3"></rect><rect x="6" y="43" width="26" height="4" rx="2"></rect><rect x="6" y="53" width="44" height="12" rx="2"></rect><rect x="6" y="69" width="44" height="12" rx="2"></rect><rect x="6" y="87" width="18" height="4" rx="2"></rect>', 5)
|
|
90
|
+
])])) : (s(), d("g", ne, [...u[2] || (u[2] = [
|
|
91
|
+
F('<rect x="6" y="7" width="44" height="5" rx="2.5"></rect><rect x="6" y="17" width="44" height="9" rx="2"></rect><rect x="6" y="28" width="9" height="4" rx="2" class="text-fm-color-neutral-gray-400"></rect><rect x="18" y="28" width="9" height="4" rx="2" class="text-fm-color-neutral-gray-400"></rect><rect x="30" y="28" width="9" height="4" rx="2" class="text-fm-color-neutral-gray-400"></rect><rect x="6" y="38" width="44" height="9" rx="2"></rect><rect x="6" y="49" width="9" height="4" rx="2" class="text-fm-color-neutral-gray-400"></rect><rect x="18" y="49" width="9" height="4" rx="2" class="text-fm-color-neutral-gray-400"></rect><rect x="6" y="59" width="44" height="9" rx="2"></rect><rect x="6" y="70" width="9" height="4" rx="2" class="text-fm-color-neutral-gray-400"></rect><rect x="18" y="70" width="9" height="4" rx="2" class="text-fm-color-neutral-gray-400"></rect><rect x="30" y="70" width="9" height="4" rx="2" class="text-fm-color-neutral-gray-400"></rect><rect x="6" y="80" width="44" height="9" rx="2"></rect>', 13)
|
|
92
|
+
])]))
|
|
93
|
+
])) : b("", !0);
|
|
94
|
+
}
|
|
95
|
+
}), ie = {
|
|
96
|
+
key: 0,
|
|
97
|
+
class: "rounded-lg border border-portal-border-default bg-portal-bg-default p-16"
|
|
98
|
+
}, ue = { class: "mt-12 flex items-start gap-12" }, de = { class: "min-w-0 max-w-[640px] flex-1" }, ce = { class: "m-0 fm-typo-en-body-md-600 text-portal-text-primary" }, me = { class: "m-0 mt-4 fm-typo-en-body-sm-400 text-portal-text-muted" }, pe = {
|
|
99
|
+
key: 1,
|
|
100
|
+
class: "rounded-lg border border-portal-border-default bg-portal-bg-default p-16"
|
|
101
|
+
}, fe = { class: "mt-12 max-w-[640px]" }, ye = {
|
|
102
|
+
key: 0,
|
|
103
|
+
class: "m-0 mb-8 fm-typo-en-body-sm-600 uppercase tracking-wide text-portal-text-muted"
|
|
104
|
+
}, he = { class: "flex flex-col gap-8" }, ve = ["aria-checked", "disabled", "onClick"], be = {
|
|
105
|
+
key: 0,
|
|
106
|
+
class: "h-[6px] w-[6px] rounded-full bg-portal-bg-default"
|
|
107
|
+
}, ge = { class: "min-w-0 max-w-[640px] flex-1" }, xe = { class: "flex flex-wrap items-center gap-8" }, we = { class: "fm-typo-en-body-md-600 text-portal-text-primary" }, _e = {
|
|
108
|
+
key: 0,
|
|
109
|
+
class: "rounded-full bg-portal-bg-canvas px-8 py-[2px] fm-typo-en-body-sm-400 text-portal-text-muted"
|
|
110
|
+
}, ke = { class: "mt-4 block fm-typo-en-body-sm-400 text-portal-text-muted" }, Ve = /* @__PURE__ */ M({
|
|
111
|
+
__name: "AppTemplatePicker",
|
|
112
|
+
props: {
|
|
113
|
+
templates: {},
|
|
114
|
+
modelValue: {},
|
|
115
|
+
disabled: { type: Boolean }
|
|
116
|
+
},
|
|
117
|
+
emits: ["update:modelValue"],
|
|
118
|
+
setup(e, { emit: f }) {
|
|
119
|
+
const o = e, V = f, u = k(() => o.templates.length > 1), y = k(() => o.templates.length === 1 ? o.templates[0] : null), j = k(() => {
|
|
120
|
+
const i = [], n = /* @__PURE__ */ new Map();
|
|
121
|
+
for (const a of o.templates) {
|
|
122
|
+
if (!a.industries.length) {
|
|
123
|
+
i.push(a);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
for (const p of a.industries) {
|
|
127
|
+
const t = n.get(p) ?? [];
|
|
128
|
+
t.push(a), n.set(p, t);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return [
|
|
132
|
+
...i.length ? [{ label: null, templates: i }] : [],
|
|
133
|
+
...[...n.entries()].sort(([a], [p]) => a.localeCompare(p)).map(([a, p]) => ({ label: a, templates: p }))
|
|
134
|
+
];
|
|
135
|
+
});
|
|
136
|
+
function x(i) {
|
|
137
|
+
o.disabled || V("update:modelValue", i);
|
|
138
|
+
}
|
|
139
|
+
return (i, n) => y.value ? (s(), d("section", ie, [
|
|
140
|
+
n[0] || (n[0] = r("p", { class: "m-0 fm-typo-en-body-md-600 text-portal-text-primary" }, "App template", -1)),
|
|
141
|
+
r("div", ue, [
|
|
142
|
+
w(H, {
|
|
143
|
+
"restaurant-style": y.value.restaurantStyle
|
|
144
|
+
}, null, 8, ["restaurant-style"]),
|
|
145
|
+
r("div", de, [
|
|
146
|
+
r("p", ce, _(y.value.label), 1),
|
|
147
|
+
r("p", me, _(y.value.description), 1)
|
|
148
|
+
])
|
|
149
|
+
])
|
|
150
|
+
])) : u.value ? (s(), d("section", pe, [
|
|
151
|
+
n[1] || (n[1] = r("p", { class: "m-0 fm-typo-en-body-md-600 text-portal-text-primary" }, "App template", -1)),
|
|
152
|
+
n[2] || (n[2] = r("p", { class: "m-0 mt-4 fm-typo-en-body-sm-400 text-portal-text-muted" }, " Choose how this app looks and works for your customers. This cannot be changed after setup. ", -1)),
|
|
153
|
+
r("div", fe, [
|
|
154
|
+
(s(!0), d(L, null, q(j.value, (a, p) => (s(), d("div", {
|
|
155
|
+
key: a.label ?? "__general",
|
|
156
|
+
role: "radiogroup",
|
|
157
|
+
"aria-label": "App template",
|
|
158
|
+
class: E(p === 0 ? "" : "mt-16")
|
|
159
|
+
}, [
|
|
160
|
+
a.label ? (s(), d("p", ye, _(a.label), 1)) : b("", !0),
|
|
161
|
+
r("div", he, [
|
|
162
|
+
(s(!0), d(L, null, q(a.templates, (t) => (s(), d("button", {
|
|
163
|
+
key: t.id,
|
|
164
|
+
type: "button",
|
|
165
|
+
role: "radio",
|
|
166
|
+
"aria-checked": e.modelValue === t.id,
|
|
167
|
+
disabled: e.disabled,
|
|
168
|
+
class: E([
|
|
169
|
+
"flex w-full cursor-pointer items-start gap-12 rounded-lg border p-12 text-left transition disabled:cursor-not-allowed disabled:opacity-60",
|
|
170
|
+
e.modelValue === t.id ? "border-fm-color-primary bg-fm-color-primary-50" : "border-fm-color-neutral-gray-200 bg-fm-color-neutral-white hover:border-fm-color-neutral-gray-300"
|
|
171
|
+
]),
|
|
172
|
+
onClick: (g) => x(t.id)
|
|
173
|
+
}, [
|
|
174
|
+
r("span", {
|
|
175
|
+
class: E([
|
|
176
|
+
"mt-[2px] flex h-16 w-16 shrink-0 items-center justify-center rounded-full border",
|
|
177
|
+
e.modelValue === t.id ? "border-fm-color-primary bg-fm-color-primary" : "border-fm-color-neutral-gray-300 bg-fm-color-neutral-white"
|
|
178
|
+
])
|
|
179
|
+
}, [
|
|
180
|
+
e.modelValue === t.id ? (s(), d("span", be)) : b("", !0)
|
|
181
|
+
], 2),
|
|
182
|
+
w(H, {
|
|
183
|
+
"restaurant-style": t.restaurantStyle
|
|
184
|
+
}, null, 8, ["restaurant-style"]),
|
|
185
|
+
r("span", ge, [
|
|
186
|
+
r("span", xe, [
|
|
187
|
+
r("span", we, _(t.label), 1),
|
|
188
|
+
t.default ? (s(), d("span", _e, " Default ")) : b("", !0)
|
|
189
|
+
]),
|
|
190
|
+
r("span", ke, _(t.description), 1)
|
|
191
|
+
])
|
|
192
|
+
], 10, ve))), 128))
|
|
193
|
+
])
|
|
194
|
+
], 2))), 128))
|
|
195
|
+
])
|
|
196
|
+
])) : b("", !0);
|
|
197
|
+
}
|
|
198
|
+
}), je = { class: "project-dialog__body" }, Se = {
|
|
199
|
+
key: 0,
|
|
200
|
+
class: "project-dialog__ota"
|
|
201
|
+
}, Ie = {
|
|
202
|
+
key: 0,
|
|
203
|
+
role: "status"
|
|
204
|
+
}, Ce = {
|
|
205
|
+
key: 2,
|
|
206
|
+
class: "portal-error",
|
|
207
|
+
role: "alert"
|
|
208
|
+
}, Te = /* @__PURE__ */ M({
|
|
209
|
+
__name: "MobileProjectDialog",
|
|
210
|
+
props: {
|
|
211
|
+
businessId: {},
|
|
212
|
+
projectId: {},
|
|
213
|
+
initialName: {}
|
|
214
|
+
},
|
|
215
|
+
emits: ["saved", "close"],
|
|
216
|
+
setup(e, { emit: f }) {
|
|
217
|
+
const o = e, V = f, u = v(o.initialName ?? ""), y = v(null), j = v([]), x = !o.projectId, i = v(x), n = v(!1), a = v(""), p = v(!o.projectId), t = v(!1), g = v(""), N = v(!1), R = v(""), J = k(
|
|
218
|
+
() => t.value ? [(m) => B(m) || "Enter a native version in x.y.z format"] : []
|
|
219
|
+
), Q = k(() => {
|
|
220
|
+
const m = t.value ? g.value.trim() : null, l = N.value ? R.value.trim() : null;
|
|
221
|
+
return t.value !== N.value || m !== l;
|
|
222
|
+
}), W = ee();
|
|
223
|
+
async function O() {
|
|
224
|
+
var m, l;
|
|
225
|
+
i.value = !0, a.value = "";
|
|
226
|
+
try {
|
|
227
|
+
const c = await $(C.appTemplates());
|
|
228
|
+
j.value = c.templates, y.value = ((m = c.templates.find((A) => A.default)) == null ? void 0 : m.id) ?? ((l = c.templates[0]) == null ? void 0 : l.id) ?? null;
|
|
229
|
+
} catch (c) {
|
|
230
|
+
a.value = P(c);
|
|
231
|
+
} finally {
|
|
232
|
+
i.value = !1;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
async function Y() {
|
|
236
|
+
if (!(n.value || i.value || o.projectId && !p.value || !u.value.trim() || u.value.trim().length > 120 || x && !y.value || t.value && !B(g.value))) {
|
|
237
|
+
n.value = !0, a.value = "";
|
|
238
|
+
try {
|
|
239
|
+
const m = await $(
|
|
240
|
+
o.projectId ? C.project(o.businessId, o.projectId) : C.projects(o.businessId),
|
|
241
|
+
{
|
|
242
|
+
method: o.projectId ? "PATCH" : "POST",
|
|
243
|
+
body: JSON.stringify({
|
|
244
|
+
...o.projectId ? {
|
|
245
|
+
name: u.value.trim(),
|
|
246
|
+
...Q.value ? {
|
|
247
|
+
settings: {
|
|
248
|
+
ota: {
|
|
249
|
+
enabled: t.value,
|
|
250
|
+
minNativeVersion: t.value ? g.value.trim() : null
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
} : {}
|
|
254
|
+
} : {
|
|
255
|
+
name: u.value.trim(),
|
|
256
|
+
projectId: W,
|
|
257
|
+
kind: "mobile",
|
|
258
|
+
appTemplate: y.value,
|
|
259
|
+
country: te()
|
|
260
|
+
}
|
|
261
|
+
})
|
|
262
|
+
}
|
|
263
|
+
);
|
|
264
|
+
V("saved", m);
|
|
265
|
+
} catch (m) {
|
|
266
|
+
a.value = P(m);
|
|
267
|
+
} finally {
|
|
268
|
+
n.value = !1;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
async function D() {
|
|
273
|
+
var m;
|
|
274
|
+
i.value = !0, a.value = "";
|
|
275
|
+
try {
|
|
276
|
+
const c = (m = (await $(C.project(o.businessId, o.projectId))).settings) == null ? void 0 : m.ota;
|
|
277
|
+
t.value = (c == null ? void 0 : c.enabled) === !0, g.value = (c == null ? void 0 : c.minNativeVersion) ?? "", N.value = t.value, R.value = g.value, p.value = !0;
|
|
278
|
+
} catch (l) {
|
|
279
|
+
a.value = P(l);
|
|
280
|
+
} finally {
|
|
281
|
+
i.value = !1;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return X(() => {
|
|
285
|
+
x ? O() : D();
|
|
286
|
+
}), (m, l) => {
|
|
287
|
+
const c = S("FmTextField"), A = S("FmSwitch"), T = S("FmButton"), G = S("FmCard"), K = S("FmForm");
|
|
288
|
+
return s(), I(K, { onValidationSuccess: Y }, {
|
|
289
|
+
default: U(() => [
|
|
290
|
+
w(G, { class: "project-dialog" }, {
|
|
291
|
+
default: U(() => [
|
|
292
|
+
r("h2", null, _(e.projectId ? "Project settings" : "New Mobile project"), 1),
|
|
293
|
+
r("div", je, [
|
|
294
|
+
w(c, {
|
|
295
|
+
modelValue: u.value,
|
|
296
|
+
"onUpdate:modelValue": l[0] || (l[0] = (h) => u.value = h),
|
|
297
|
+
label: "Project name",
|
|
298
|
+
placeholder: "e.g. Summer ordering",
|
|
299
|
+
disabled: n.value,
|
|
300
|
+
rules: [(h) => h.trim().length > 0 && h.trim().length <= 120 || "Enter a name up to 120 characters"]
|
|
301
|
+
}, null, 8, ["modelValue", "disabled", "rules"]),
|
|
302
|
+
e.projectId ? (s(), d("section", Se, [
|
|
303
|
+
l[5] || (l[5] = r("div", null, [
|
|
304
|
+
r("h3", null, "Over-the-air updates"),
|
|
305
|
+
r("p", null, "Let compatible app builds receive release updates without a native app update."),
|
|
306
|
+
r("p", { class: "project-dialog__note" }, [
|
|
307
|
+
z("After a successful mount, the web app must call "),
|
|
308
|
+
r("code", null, "FeedMeNative.call('NativeApp', 'ready')"),
|
|
309
|
+
z(" or the native shell may roll back the OTA update.")
|
|
310
|
+
])
|
|
311
|
+
], -1)),
|
|
312
|
+
w(A, {
|
|
313
|
+
modelValue: t.value,
|
|
314
|
+
"onUpdate:modelValue": l[1] || (l[1] = (h) => t.value = h),
|
|
315
|
+
label: "Enable OTA updates",
|
|
316
|
+
sublabel: "OTA is off by default",
|
|
317
|
+
disabled: n.value || i.value
|
|
318
|
+
}, null, 8, ["modelValue", "disabled"]),
|
|
319
|
+
t.value ? (s(), I(c, {
|
|
320
|
+
key: 0,
|
|
321
|
+
modelValue: g.value,
|
|
322
|
+
"onUpdate:modelValue": l[2] || (l[2] = (h) => g.value = h),
|
|
323
|
+
label: "Minimum native version",
|
|
324
|
+
placeholder: "e.g. 1.2.3",
|
|
325
|
+
"helper-text": "Applies to future releases. Existing OTA packages keep their original minimum version.",
|
|
326
|
+
disabled: n.value || i.value,
|
|
327
|
+
rules: J.value
|
|
328
|
+
}, null, 8, ["modelValue", "disabled", "rules"])) : b("", !0)
|
|
329
|
+
])) : b("", !0),
|
|
330
|
+
x ? (s(), d(L, { key: 1 }, [
|
|
331
|
+
i.value ? (s(), d("p", Ie, "Loading templates…")) : (s(), I(Ve, {
|
|
332
|
+
key: 1,
|
|
333
|
+
templates: j.value,
|
|
334
|
+
modelValue: y.value,
|
|
335
|
+
"onUpdate:modelValue": l[3] || (l[3] = (h) => y.value = h),
|
|
336
|
+
disabled: n.value
|
|
337
|
+
}, null, 8, ["templates", "modelValue", "disabled"])),
|
|
338
|
+
l[6] || (l[6] = r("p", { class: "project-dialog__note" }, "Start a separate app from a template. Your live app stays as it is.", -1))
|
|
339
|
+
], 64)) : b("", !0),
|
|
340
|
+
a.value ? (s(), d("p", Ce, _(a.value), 1)) : b("", !0),
|
|
341
|
+
e.projectId && !p.value && !i.value ? (s(), I(T, {
|
|
342
|
+
key: 3,
|
|
343
|
+
label: "Retry loading project settings",
|
|
344
|
+
variant: "secondary",
|
|
345
|
+
onClick: D
|
|
346
|
+
})) : b("", !0),
|
|
347
|
+
x && !j.value.length && !i.value ? (s(), I(T, {
|
|
348
|
+
key: 4,
|
|
349
|
+
label: "Retry loading templates",
|
|
350
|
+
variant: "secondary",
|
|
351
|
+
onClick: O
|
|
352
|
+
})) : b("", !0)
|
|
353
|
+
]),
|
|
354
|
+
r("footer", null, [
|
|
355
|
+
w(T, {
|
|
356
|
+
label: "Cancel",
|
|
357
|
+
variant: "tertiary",
|
|
358
|
+
disabled: n.value,
|
|
359
|
+
onClick: l[4] || (l[4] = (h) => V("close"))
|
|
360
|
+
}, null, 8, ["disabled"]),
|
|
361
|
+
w(T, {
|
|
362
|
+
label: e.projectId ? "Save" : "Create project",
|
|
363
|
+
type: "submit",
|
|
364
|
+
loading: n.value,
|
|
365
|
+
disabled: i.value || e.projectId && !p.value || !u.value.trim() || u.value.trim().length > 120 || x && !y.value || t.value && !Z(B)(g.value)
|
|
366
|
+
}, null, 8, ["label", "loading", "disabled"])
|
|
367
|
+
])
|
|
368
|
+
]),
|
|
369
|
+
_: 1
|
|
370
|
+
})
|
|
371
|
+
]),
|
|
372
|
+
_: 1
|
|
373
|
+
});
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
}), ze = /* @__PURE__ */ re(Te, [["__scopeId", "data-v-2b2e037d"]]);
|
|
377
|
+
export {
|
|
378
|
+
ze as M,
|
|
379
|
+
Ve as _,
|
|
380
|
+
qe as a,
|
|
381
|
+
De as b,
|
|
382
|
+
Be as c,
|
|
383
|
+
Le as d,
|
|
384
|
+
Me as e,
|
|
385
|
+
Ue as o,
|
|
386
|
+
Re as p,
|
|
387
|
+
Oe as r,
|
|
388
|
+
Pe as s
|
|
389
|
+
};
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { defineComponent as V, ref as w, computed as C, h as o, withModifiers as j, onMounted as q, onScopeDispose as B, resolveComponent as S, openBlock as r, createElementBlock as n, createElementVNode as a, createTextVNode as I, toDisplayString as M, createCommentVNode as P, createBlock as D, createVNode as _, unref as h } from "vue";
|
|
2
|
+
import { useRoute as R, useRouter as A } from "vue-router";
|
|
3
|
+
import { components as T, useDialog as $ } from "@feedmepos/ui-library";
|
|
4
|
+
import { a as E } from "./routes-CeuodIgg.js";
|
|
5
|
+
import { c as O, e as U } from "./controlPlane-CDopeXyb.js";
|
|
6
|
+
import { u as Y } from "./portalContext-IOgByqvZ.js";
|
|
7
|
+
import { w as u } from "./portalNavigation-DKCfwTH8.js";
|
|
8
|
+
import { p as G, M as H } from "./MobileProjectDialog-mNUZfDy7.js";
|
|
9
|
+
import { _ as k } from "./StatusBadge.vue_vue_type_script_setup_true_lang-CMgQ0bd_.js";
|
|
10
|
+
import { _ as J } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
11
|
+
const K = { class: "portal-page" }, Q = { class: "portal-page-inner" }, W = { class: "portal-page-heading" }, X = {
|
|
12
|
+
key: 0,
|
|
13
|
+
class: "mobile-projects__count"
|
|
14
|
+
}, Z = {
|
|
15
|
+
key: 0,
|
|
16
|
+
class: "portal-error",
|
|
17
|
+
role: "alert"
|
|
18
|
+
}, ee = {
|
|
19
|
+
key: 1,
|
|
20
|
+
role: "status"
|
|
21
|
+
}, te = {
|
|
22
|
+
key: 2,
|
|
23
|
+
class: "portal-empty"
|
|
24
|
+
}, oe = {
|
|
25
|
+
key: 3,
|
|
26
|
+
class: "rounded-2xl border border-portal-border-default bg-portal-bg-default",
|
|
27
|
+
"aria-label": "Mobile projects"
|
|
28
|
+
}, re = /* @__PURE__ */ V({
|
|
29
|
+
__name: "MobileProjectsView",
|
|
30
|
+
setup(ae) {
|
|
31
|
+
const { FmButton: m } = T, x = Y(), s = R(), i = A(), v = $(), l = w([]), p = w(!0), c = w(""), f = new AbortController();
|
|
32
|
+
async function g() {
|
|
33
|
+
p.value = !0, c.value = "";
|
|
34
|
+
try {
|
|
35
|
+
const t = await O(E.projects(x.businessId.value), {
|
|
36
|
+
signal: f.signal
|
|
37
|
+
});
|
|
38
|
+
l.value = t.projects;
|
|
39
|
+
} catch (t) {
|
|
40
|
+
f.signal.aborted || (c.value = U(t));
|
|
41
|
+
} finally {
|
|
42
|
+
p.value = !1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function d(t) {
|
|
46
|
+
v.open({
|
|
47
|
+
title: t ? "Project settings" : "New Mobile project",
|
|
48
|
+
dialogComponent: H,
|
|
49
|
+
dialogComponentProps: {
|
|
50
|
+
businessId: x.businessId.value,
|
|
51
|
+
projectId: t == null ? void 0 : t.projectId,
|
|
52
|
+
initialName: t == null ? void 0 : t.name,
|
|
53
|
+
onClose: () => v.close(),
|
|
54
|
+
onSaved: (e) => {
|
|
55
|
+
v.close(), t ? g() : i.push(u(e.projectId, "workspace", { ...s.query, setup: "1" }));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function z(t) {
|
|
61
|
+
return new Intl.DateTimeFormat(void 0, { dateStyle: "medium", timeStyle: "short" }).format(new Date(t));
|
|
62
|
+
}
|
|
63
|
+
const N = C(() => [
|
|
64
|
+
{
|
|
65
|
+
id: "project",
|
|
66
|
+
header: () => "Project",
|
|
67
|
+
cell: (t) => {
|
|
68
|
+
const e = t.row.original;
|
|
69
|
+
return o("div", { class: "flex min-w-0 flex-col gap-2" }, [
|
|
70
|
+
o("span", { class: "truncate fm-typo-en-body-md-600 text-portal-text-primary" }, e.name),
|
|
71
|
+
o(
|
|
72
|
+
"span",
|
|
73
|
+
{ class: "fm-typo-en-body-sm-400 text-portal-text-muted", title: e.projectId },
|
|
74
|
+
`…${e.projectId.slice(-6)}`
|
|
75
|
+
)
|
|
76
|
+
]);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: "setup",
|
|
81
|
+
header: () => "Setup",
|
|
82
|
+
size: 130,
|
|
83
|
+
enableSorting: !1,
|
|
84
|
+
cell: (t) => o(
|
|
85
|
+
k,
|
|
86
|
+
{ variant: t.row.original.provisioningStatus === "failed" ? "error" : "neutral", size: "sm" },
|
|
87
|
+
() => G(t.row.original.provisioningStatus)
|
|
88
|
+
)
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: "live",
|
|
92
|
+
header: () => "Live",
|
|
93
|
+
size: 200,
|
|
94
|
+
enableSorting: !1,
|
|
95
|
+
// Badges only. The muted sentence this replaces ("Unpublished release
|
|
96
|
+
// available") was the one thing in the row set in prose, and prose in a 200px
|
|
97
|
+
// column wraps — which is what made the cell look crowded. The state it
|
|
98
|
+
// carried is worth keeping, so it becomes a second tag rather than going away:
|
|
99
|
+
// it is the only place in this list that shows a merchant they have work built
|
|
100
|
+
// and waiting to go live.
|
|
101
|
+
//
|
|
102
|
+
// Nothing is rendered for a project with no pending release. That is the
|
|
103
|
+
// resting state of most rows, and a tag saying so would be back to filling the
|
|
104
|
+
// column with "nothing happened".
|
|
105
|
+
cell: (t) => {
|
|
106
|
+
const e = t.row.original;
|
|
107
|
+
return o("div", { class: "flex flex-wrap items-center gap-4" }, [
|
|
108
|
+
// "Live project" in a column headed Live said the word twice, and cost the
|
|
109
|
+
// width that made the line below it wrap.
|
|
110
|
+
o(
|
|
111
|
+
k,
|
|
112
|
+
{ variant: e.isLive ? "success" : "neutral", size: "sm" },
|
|
113
|
+
() => e.isLive ? "Live" : "Not live"
|
|
114
|
+
),
|
|
115
|
+
// `=== true` rather than truthiness: the field is optional in the contract,
|
|
116
|
+
// and an absent value means the state is unknown, not that it is false.
|
|
117
|
+
// This endpoint always sends a boolean, so that is a contract-level
|
|
118
|
+
// possibility rather than one a merchant meets.
|
|
119
|
+
e.hasUnpublishedRelease === !0 ? o(
|
|
120
|
+
k,
|
|
121
|
+
{ variant: "warning", size: "sm", title: "A release is built and waiting to be published" },
|
|
122
|
+
() => "Unpublished"
|
|
123
|
+
) : null
|
|
124
|
+
]);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: "updatedAt",
|
|
129
|
+
header: () => "Last edited",
|
|
130
|
+
size: 170,
|
|
131
|
+
enableSorting: !1,
|
|
132
|
+
cell: (t) => o("span", { class: "fm-typo-en-body-sm-400 text-portal-text-muted" }, z(t.row.original.updatedAt))
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: "actions",
|
|
136
|
+
header: () => "",
|
|
137
|
+
size: 340,
|
|
138
|
+
enableSorting: !1,
|
|
139
|
+
cell: (t) => {
|
|
140
|
+
const e = t.row.original;
|
|
141
|
+
return o("div", { class: "flex flex-wrap items-center justify-end gap-4" }, [
|
|
142
|
+
e.provisioningStatus === "ready" ? o(m, {
|
|
143
|
+
icon: "deployed_code",
|
|
144
|
+
variant: "tertiary",
|
|
145
|
+
title: "View releases",
|
|
146
|
+
onClick: j(
|
|
147
|
+
() => i.push(u(e.projectId, "releases", s.query)),
|
|
148
|
+
["stop"]
|
|
149
|
+
)
|
|
150
|
+
}) : null,
|
|
151
|
+
o(m, {
|
|
152
|
+
label: "Rename",
|
|
153
|
+
variant: "tertiary",
|
|
154
|
+
onClick: j(() => d(e), ["stop"])
|
|
155
|
+
}),
|
|
156
|
+
o(m, {
|
|
157
|
+
label: e.provisioningStatus === "ready" ? "Open editor" : "Continue setup",
|
|
158
|
+
variant: "secondary",
|
|
159
|
+
onClick: j(
|
|
160
|
+
() => i.push(u(e.projectId, "workspace", s.query)),
|
|
161
|
+
["stop"]
|
|
162
|
+
)
|
|
163
|
+
})
|
|
164
|
+
]);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
]), F = C(() => !p.value && l.value.length > 0);
|
|
168
|
+
return q(() => {
|
|
169
|
+
if (g(), s.query.create === "1") {
|
|
170
|
+
const { create: t, ...e } = s.query;
|
|
171
|
+
i.replace({ query: e }), d();
|
|
172
|
+
}
|
|
173
|
+
}), B(() => f.abort()), (t, e) => {
|
|
174
|
+
const b = S("FmButton"), L = S("FmTable");
|
|
175
|
+
return r(), n("div", K, [
|
|
176
|
+
a("div", Q, [
|
|
177
|
+
a("header", W, [
|
|
178
|
+
a("div", null, [
|
|
179
|
+
e[4] || (e[4] = a("p", { class: "portal-eyebrow" }, "Mobile Ordering", -1)),
|
|
180
|
+
a("h1", null, [
|
|
181
|
+
e[3] || (e[3] = I("Projects ", -1)),
|
|
182
|
+
p.value ? P("", !0) : (r(), n("span", X, M(l.value.length), 1))
|
|
183
|
+
])
|
|
184
|
+
]),
|
|
185
|
+
F.value ? (r(), D(b, {
|
|
186
|
+
key: 0,
|
|
187
|
+
label: "New project",
|
|
188
|
+
icon: "add",
|
|
189
|
+
onClick: e[0] || (e[0] = (y) => d())
|
|
190
|
+
})) : P("", !0)
|
|
191
|
+
]),
|
|
192
|
+
c.value ? (r(), n("p", Z, [
|
|
193
|
+
I(M(c.value) + " ", 1),
|
|
194
|
+
_(b, {
|
|
195
|
+
label: "Retry",
|
|
196
|
+
variant: "tertiary",
|
|
197
|
+
onClick: g
|
|
198
|
+
})
|
|
199
|
+
])) : p.value ? (r(), n("p", ee, "Loading projects…")) : l.value.length ? (r(), n("section", oe, [
|
|
200
|
+
_(L, {
|
|
201
|
+
"column-defs": N.value,
|
|
202
|
+
"row-data": l.value,
|
|
203
|
+
"page-size": l.value.length,
|
|
204
|
+
"hide-footer": "",
|
|
205
|
+
"pin-header-row": "",
|
|
206
|
+
onRowClick: e[2] || (e[2] = (y) => h(i).push(h(u)(y.original.projectId, "workspace", h(s).query)))
|
|
207
|
+
}, null, 8, ["column-defs", "row-data", "page-size"])
|
|
208
|
+
])) : (r(), n("section", te, [
|
|
209
|
+
e[5] || (e[5] = a("h2", null, "Your first Mobile project", -1)),
|
|
210
|
+
e[6] || (e[6] = a("p", null, "Create an app from a template to start editing.", -1)),
|
|
211
|
+
_(b, {
|
|
212
|
+
label: "New project",
|
|
213
|
+
icon: "add",
|
|
214
|
+
onClick: e[1] || (e[1] = (y) => d())
|
|
215
|
+
})
|
|
216
|
+
]))
|
|
217
|
+
])
|
|
218
|
+
]);
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
}), fe = /* @__PURE__ */ J(re, [["__scopeId", "data-v-cda36ac2"]]);
|
|
222
|
+
export {
|
|
223
|
+
fe as default
|
|
224
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineComponent as F, openBlock as e, createElementBlock as n, createElementVNode as o, toDisplayString as d, createCommentVNode as k, ref as w, computed as m, onMounted as q, resolveComponent as f, createVNode as p, unref as i, Fragment as v, renderList as b, normalizeClass as A, createBlock as y, withCtx as R } from "vue";
|
|
2
2
|
import { useRoute as z } from "vue-router";
|
|
3
3
|
import { _ as T } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
4
|
-
import { u as D, c as G, f as K, _ as h, t as O } from "./useModuleCatalog-
|
|
4
|
+
import { u as D, c as G, f as K, _ as h, t as O } from "./useModuleCatalog-B_6PWpER.js";
|
|
5
5
|
const P = { class: "card" }, U = { class: "card__head" }, j = { class: "card__name fm-typo-en-body-md-600 text-portal-text-primary" }, H = { class: "card__version fm-typo-en-body-sm-400 text-portal-text-muted" }, J = { class: "card__description fm-typo-en-body-sm-400 text-portal-text-muted" }, Q = { class: "card__tags" }, W = { class: "card__tag card__tag--tier fm-typo-en-body-sm-600" }, X = {
|
|
6
6
|
key: 0,
|
|
7
7
|
class: "card__tag card__tag--slot fm-typo-en-body-sm-400"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineComponent as C, ref as M, computed as u, watch as T, resolveComponent as g, openBlock as n, createElementBlock as l, createElementVNode as e, toDisplayString as i, createCommentVNode as _, Fragment as I, renderList as S, createVNode as k, onMounted as B, unref as d, withCtx as L, createBlock as v } from "vue";
|
|
2
2
|
import { useRoute as N, useRouter as P } from "vue-router";
|
|
3
|
-
import { m as q, i as A, u as F, _ as w } from "./useModuleCatalog-
|
|
3
|
+
import { m as q, i as A, u as F, _ as w } from "./useModuleCatalog-B_6PWpER.js";
|
|
4
4
|
import { useDialog as V } from "@feedmepos/ui-library";
|
|
5
5
|
import { _ as E } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
6
6
|
const R = { class: "detail" }, j = { class: "detail__head" }, z = { class: "detail__name fm-typo-en-title-sm-600 text-portal-text-primary" }, K = { class: "detail__version fm-typo-en-body-md-400 text-portal-text-muted" }, O = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineComponent as p, resolveComponent as i, openBlock as l, createElementBlock as m, createElementVNode as o, createVNode as r, unref as t, withCtx as u, createTextVNode as c } from "vue";
|
|
2
2
|
import { useRoute as d } from "vue-router";
|
|
3
|
-
import { u as g } from "./portalContext-
|
|
3
|
+
import { u as g } from "./portalContext-IOgByqvZ.js";
|
|
4
4
|
import { w as f } from "./portalNavigation-DKCfwTH8.js";
|
|
5
5
|
import { P as k } from "./PortalIcon-DO0VrIoY.js";
|
|
6
6
|
const w = { class: "portal-page" }, y = { class: "portal-page-inner" }, b = { class: "portal-section portal-empty" }, E = /* @__PURE__ */ p({
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { defineComponent as k, computed as p, ref as l, onMounted as P, onScopeDispose as S, resolveComponent as x, openBlock as o, createElementBlock as n, createElementVNode as s, toDisplayString as d, createCommentVNode as h, Fragment as I, createVNode as A, unref as M } from "vue";
|
|
2
2
|
import { useRoute as N } from "vue-router";
|
|
3
3
|
import { e as _, a as $ } from "./index-CIJWcl_6.js";
|
|
4
|
-
import { l as B, e as E } from "./controlPlane-
|
|
4
|
+
import { l as B, e as E } from "./controlPlane-CDopeXyb.js";
|
|
5
5
|
import { useCoreStore as F } from "@feedmepos/mf-common";
|
|
6
|
-
import { u as U } from "./portalContext-
|
|
6
|
+
import { u as U } from "./portalContext-IOgByqvZ.js";
|
|
7
7
|
import { l as V } from "./portalNavigation-DKCfwTH8.js";
|
|
8
8
|
import { _ as q } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
9
9
|
const L = { class: "portal-page" }, R = { class: "portal-page-inner settings-page" }, T = { class: "portal-page-heading" }, D = ["href"], H = {
|
|
@@ -23,10 +23,10 @@ const L = { class: "portal-page" }, R = { class: "portal-page-inner settings-pag
|
|
|
23
23
|
country: c.currentCountry.value ?? null,
|
|
24
24
|
restaurantId: ((t = c.currentRestaurant.value) == null ? void 0 : t._id) ?? null
|
|
25
25
|
}),
|
|
26
|
-
_("fmmf:
|
|
26
|
+
_("fmmf:dev") === "dev" ? "https://portal.feedmedev.cc" : "https://portal.feedme.cc"
|
|
27
27
|
).href;
|
|
28
28
|
}
|
|
29
|
-
), m = l(null), g = l(!0), r = l(null), v = l(!1), f = $(_("fmmf:
|
|
29
|
+
), m = l(null), g = l(!0), r = l(null), v = l(!1), f = $(_("fmmf:dev")).apiOrigin, C = p(() => `${f}/metadata/${a.businessId.value}/pwa-512x512.png`), b = p(() => {
|
|
30
30
|
var t;
|
|
31
31
|
return (t = B()) == null ? void 0 : t.thumbnail;
|
|
32
32
|
}), i = new AbortController();
|