@feedmepos/mf-miniprogram-v2 0.2.2-dev.19 → 0.2.2-dev.20
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-BWnR2QQN.js +213 -0
- package/dist/{BrandFontPicker-BFjp8k2W.js → BrandFontPicker-kQKWf1hL.js} +1 -1
- package/dist/{BrandKitView-DUbIT3c8.js → BrandKitView-RaUWE69b.js} +2 -2
- package/dist/{ControlPlaneView-DZ-hNfCQ.js → ControlPlaneView-H-hlL2ND.js} +7825 -7554
- package/dist/{EcosystemView-B359jaNI.js → EcosystemView-MvrxhO3T.js} +4 -4
- package/dist/{LegacyWorkspaceEntry-opz_kWz9.js → LegacyWorkspaceEntry-lEMtmdIe.js} +1 -1
- package/dist/{MobileProjectsView-lV5bkuns.js → MobileProjectsView-BfFS_47C.js} +4 -4
- package/dist/{ModuleCenterView-DyMr3iWV.js → ModuleCenterView-ujyL9wW3.js} +1 -1
- package/dist/{ModuleDetailView-BeXK89Cs.js → ModuleDetailView-DFXFxSIN.js} +1 -1
- package/dist/{PagesView-VqFkmYxN.js → PagesView-DOSrArQb.js} +1 -1
- package/dist/{PortalSettingsView-BmmMJ5Zm.js → PortalSettingsView-DjFh8IRa.js} +3 -3
- package/dist/TemplateCenterView-BOS6FDQ0.js +475 -0
- package/dist/{WorkspaceEntryView-BTYo51RE.js → WorkspaceEntryView-CkTnQH9g.js} +1 -1
- package/dist/app.js +21 -10
- package/dist/{controlPlane-CoEgf9BA.js → controlPlane-sXaC6pAh.js} +1 -1
- package/dist/{index-D5qXvcfE.js → index-CIJWcl_6.js} +10 -9
- package/dist/package.json +1 -1
- package/dist/{portalContext-C4HL_0kl.js → portalContext-6164Gyod.js} +2 -2
- package/dist/routes-Cay_S88s.js +75 -0
- package/dist/style.css +1 -1
- package/dist/templatePickerFlag-nLdZY-yh.js +59 -0
- package/dist/{useBrandKit-BlKlqpo2.js → useBrandKit-CkdPQRE-.js} +2 -2
- package/dist/{useModuleCatalog-DqECds3F.js → useModuleCatalog-Cd13YPg6.js} +2 -2
- package/package.json +1 -1
- package/dist/App-Dj20Jl8B.js +0 -197
- package/dist/localPreference-DneUpUrQ.js +0 -34
- package/dist/routes-Boz_WlNM.js +0 -54
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
import { defineComponent as G, ref as n, computed as D, resolveComponent as f, openBlock as u, createBlock as x, withCtx as q, createElementVNode as o, createElementBlock as y, Fragment as z, createTextVNode as V, toDisplayString as h, createVNode as s, unref as ae, createCommentVNode as P, onMounted as ie, onScopeDispose as re, renderList as de } from "vue";
|
|
2
|
+
import { a as I } from "./routes-Cay_S88s.js";
|
|
3
|
+
import { useDialog as ue } from "@feedmepos/ui-library";
|
|
4
|
+
import { useRouter as pe } from "vue-router";
|
|
5
|
+
import { c as L, e as U } from "./controlPlane-sXaC6pAh.js";
|
|
6
|
+
import { _ as H } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
7
|
+
import { _ as me } from "./StatusBadge.vue_vue_type_script_setup_true_lang-CMgQ0bd_.js";
|
|
8
|
+
const ce = ["qsr", "coffee", "tea"], ve = ["miniprogram-vue"], N = [
|
|
9
|
+
// `label` and `description` are MERCHANT-FACING: the portal's picker renders
|
|
10
|
+
// them, and they are the only thing a merchant chooses on. Say what the app does
|
|
11
|
+
// for their customers, never which package it is built from — the SDK is real and
|
|
12
|
+
// load-bearing and means nothing to the person making this decision.
|
|
13
|
+
{
|
|
14
|
+
id: "miniprogram-vue",
|
|
15
|
+
label: "Phone ordering app",
|
|
16
|
+
description: "Menu browsing, cart and checkout, membership and rewards, and order history — for customers ordering on their own phone.",
|
|
17
|
+
industries: [],
|
|
18
|
+
environments: ["dev", "prod"],
|
|
19
|
+
default: !0
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "miniprogram-vue-v2",
|
|
23
|
+
label: "Phone, kiosk and tablet",
|
|
24
|
+
description: "Everything in the phone app, plus self-order kiosk and in-store tablet surfaces sharing the same menu, cart and membership.",
|
|
25
|
+
industries: [],
|
|
26
|
+
// Dev only, deliberately. It has never been provisioned end-to-end: the
|
|
27
|
+
// preview proxy, the component-library unpack and the release build have
|
|
28
|
+
// only been exercised locally. Add 'prod' after a real merchant has run
|
|
29
|
+
// through all three.
|
|
30
|
+
environments: ["dev"]
|
|
31
|
+
},
|
|
32
|
+
// Forked from miniprogram-vue-v2 (2026-09): the coffee and tea styles used
|
|
33
|
+
// to be `restaurantStyle` choices sharing that one directory, which meant
|
|
34
|
+
// editing one style's components risked changing what the other two
|
|
35
|
+
// rendered. Each now has its own independent directory; only
|
|
36
|
+
// `templates/block-library/` is still shared across all three.
|
|
37
|
+
{
|
|
38
|
+
id: "miniprogram-vue-v2-coffee",
|
|
39
|
+
label: "Phone, kiosk and tablet — coffee house",
|
|
40
|
+
description: "Everything in the phone app, plus self-order kiosk and in-store tablet surfaces, in a calm, image-led layout for habitual pickup and considered customisation.",
|
|
41
|
+
industries: ["Food & beverage"],
|
|
42
|
+
environments: ["dev"]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "miniprogram-vue-v2-tea",
|
|
46
|
+
label: "Phone, kiosk and tablet — tea & beverage",
|
|
47
|
+
description: "Everything in the phone app, plus self-order kiosk and in-store tablet surfaces, in a light, compact, option-forward layout for repeat beverage orders.",
|
|
48
|
+
industries: ["Food & beverage"],
|
|
49
|
+
environments: ["dev"]
|
|
50
|
+
}
|
|
51
|
+
], be = ["href"], he = {
|
|
52
|
+
key: 0,
|
|
53
|
+
class: "portal-error",
|
|
54
|
+
role: "alert"
|
|
55
|
+
}, ge = /* @__PURE__ */ G({
|
|
56
|
+
__name: "ForkTemplateDialog",
|
|
57
|
+
emits: ["close"],
|
|
58
|
+
setup(R, { emit: $ }) {
|
|
59
|
+
var t;
|
|
60
|
+
const r = $, E = N.map((a) => ({ label: a.label, value: a.id })), _ = n(((t = N.find((a) => a.id === "miniprogram-vue-v2")) == null ? void 0 : t.id) ?? ""), c = n(""), g = n(""), v = n(""), d = n(!1), k = n(""), T = n(""), w = n(0), F = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/, p = D(
|
|
61
|
+
() => !d.value && _.value.length > 0 && F.test(c.value.trim()) && g.value.trim().length > 0 && v.value.trim().length > 0
|
|
62
|
+
);
|
|
63
|
+
async function A() {
|
|
64
|
+
if (p.value) {
|
|
65
|
+
d.value = !0, k.value = "";
|
|
66
|
+
try {
|
|
67
|
+
const a = await L(I.forkAppTemplate(), {
|
|
68
|
+
method: "POST",
|
|
69
|
+
body: JSON.stringify({
|
|
70
|
+
sourceAppTemplateId: _.value,
|
|
71
|
+
newAppTemplateId: c.value.trim(),
|
|
72
|
+
label: g.value.trim(),
|
|
73
|
+
description: v.value.trim()
|
|
74
|
+
})
|
|
75
|
+
});
|
|
76
|
+
T.value = a.pullRequestUrl, w.value = a.fileCount;
|
|
77
|
+
} catch (a) {
|
|
78
|
+
k.value = U(a);
|
|
79
|
+
} finally {
|
|
80
|
+
d.value = !1;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return (a, e) => {
|
|
85
|
+
const l = f("FmButton"), S = f("FmSelect"), B = f("FmTextField"), O = f("FmTextarea"), j = f("FmCard");
|
|
86
|
+
return u(), x(j, { class: "fork-template-dialog" }, {
|
|
87
|
+
default: q(() => [
|
|
88
|
+
e[9] || (e[9] = o("h2", null, "Fork template", -1)),
|
|
89
|
+
T.value ? (u(), y(z, { key: 0 }, [
|
|
90
|
+
o("p", null, [
|
|
91
|
+
e[6] || (e[6] = V(" Opened a ", -1)),
|
|
92
|
+
o("a", {
|
|
93
|
+
href: T.value,
|
|
94
|
+
target: "_blank",
|
|
95
|
+
rel: "noopener"
|
|
96
|
+
}, "pull request", 8, be),
|
|
97
|
+
V(" copying " + h(w.value) + " file(s) into a brand-new ", 1),
|
|
98
|
+
o("code", null, "templates/" + h(c.value) + "/", 1),
|
|
99
|
+
e[7] || (e[7] = V(' directory, and registering it in the template catalog. It needs human review and merge — once merged, a workflow syncs it to its own GitHub template repository automatically. A Template Center choice pointing at it can then be created from "New choice". ', -1))
|
|
100
|
+
]),
|
|
101
|
+
o("footer", null, [
|
|
102
|
+
s(l, {
|
|
103
|
+
label: "Done",
|
|
104
|
+
onClick: e[0] || (e[0] = (b) => r("close"))
|
|
105
|
+
})
|
|
106
|
+
])
|
|
107
|
+
], 64)) : (u(), y(z, { key: 1 }, [
|
|
108
|
+
e[8] || (e[8] = o("p", { class: "fork-template-dialog__note" }, " Copies an existing physical template's whole directory into a brand-new, independent one — editing the new one can never affect the source or any other template. Use this to start a new restaurant style rather than editing a style that other merchants already share. ", -1)),
|
|
109
|
+
s(S, {
|
|
110
|
+
modelValue: _.value,
|
|
111
|
+
"onUpdate:modelValue": e[1] || (e[1] = (b) => _.value = b),
|
|
112
|
+
label: "Fork from",
|
|
113
|
+
items: ae(E),
|
|
114
|
+
disabled: d.value
|
|
115
|
+
}, null, 8, ["modelValue", "items", "disabled"]),
|
|
116
|
+
s(B, {
|
|
117
|
+
modelValue: c.value,
|
|
118
|
+
"onUpdate:modelValue": e[2] || (e[2] = (b) => c.value = b),
|
|
119
|
+
label: "New template id",
|
|
120
|
+
placeholder: "e.g. miniprogram-vue-v2-bakery",
|
|
121
|
+
"helper-text": "Lowercase, kebab-case. Also becomes the directory name and GitHub repository name.",
|
|
122
|
+
disabled: d.value,
|
|
123
|
+
rules: [(b) => F.test(b.trim()) || "Lowercase kebab-case, e.g. miniprogram-vue-v2-bakery"]
|
|
124
|
+
}, null, 8, ["modelValue", "disabled", "rules"]),
|
|
125
|
+
s(B, {
|
|
126
|
+
modelValue: g.value,
|
|
127
|
+
"onUpdate:modelValue": e[3] || (e[3] = (b) => g.value = b),
|
|
128
|
+
label: "Label",
|
|
129
|
+
placeholder: "Shown to merchants in the picker",
|
|
130
|
+
disabled: d.value
|
|
131
|
+
}, null, 8, ["modelValue", "disabled"]),
|
|
132
|
+
s(O, {
|
|
133
|
+
modelValue: v.value,
|
|
134
|
+
"onUpdate:modelValue": e[4] || (e[4] = (b) => v.value = b),
|
|
135
|
+
label: "Description",
|
|
136
|
+
placeholder: "One or two sentences on what the merchant gets",
|
|
137
|
+
disabled: d.value
|
|
138
|
+
}, null, 8, ["modelValue", "disabled"]),
|
|
139
|
+
k.value ? (u(), y("p", he, h(k.value), 1)) : P("", !0),
|
|
140
|
+
o("footer", null, [
|
|
141
|
+
s(l, {
|
|
142
|
+
label: "Cancel",
|
|
143
|
+
variant: "tertiary",
|
|
144
|
+
disabled: d.value,
|
|
145
|
+
onClick: e[5] || (e[5] = (b) => r("close"))
|
|
146
|
+
}, null, 8, ["disabled"]),
|
|
147
|
+
s(l, {
|
|
148
|
+
label: "Open pull request",
|
|
149
|
+
loading: d.value,
|
|
150
|
+
disabled: !p.value,
|
|
151
|
+
onClick: A
|
|
152
|
+
}, null, 8, ["loading", "disabled"])
|
|
153
|
+
])
|
|
154
|
+
], 64))
|
|
155
|
+
]),
|
|
156
|
+
_: 1
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}), fe = /* @__PURE__ */ H(ge, [["__scopeId", "data-v-41bb02b7"]]), ye = {
|
|
161
|
+
key: 2,
|
|
162
|
+
class: "portal-error",
|
|
163
|
+
role: "alert"
|
|
164
|
+
}, _e = /* @__PURE__ */ G({
|
|
165
|
+
__name: "TemplateChoiceDialog",
|
|
166
|
+
props: {
|
|
167
|
+
choice: {}
|
|
168
|
+
},
|
|
169
|
+
emits: ["saved", "close"],
|
|
170
|
+
setup(R, { emit: $ }) {
|
|
171
|
+
var O, j, b, J, Y, K, W, Q, X;
|
|
172
|
+
const r = R, E = $, _ = N.filter((C) => !ve.includes(C.id)), c = ((O = _[0]) == null ? void 0 : O.id) ?? ((j = N[0]) == null ? void 0 : j.id) ?? "", g = n(((b = r.choice) == null ? void 0 : b.id) ?? ""), v = n(((J = r.choice) == null ? void 0 : J.appTemplateId) ?? c), d = n(((Y = r.choice) == null ? void 0 : Y.restaurantStyle) ?? "qsr"), k = n(((K = r.choice) == null ? void 0 : K.label) ?? ""), T = n(((W = r.choice) == null ? void 0 : W.description) ?? ""), w = n((((Q = r.choice) == null ? void 0 : Q.industries) ?? []).join(", ")), F = n(((X = r.choice) == null ? void 0 : X.default) ?? !1), p = n(!1), A = n(""), t = D(() => !!r.choice), a = D(
|
|
173
|
+
() => (t.value ? N : _).map((C) => ({
|
|
174
|
+
label: C.label,
|
|
175
|
+
value: C.id
|
|
176
|
+
}))
|
|
177
|
+
), e = D(() => v.value === "miniprogram-vue-v2"), l = ce.map((C) => ({ label: C, value: C })), S = D(
|
|
178
|
+
() => !p.value && k.value.trim().length > 0 && T.value.trim().length > 0 && (t.value ? !0 : /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(g.value.trim()))
|
|
179
|
+
);
|
|
180
|
+
async function B() {
|
|
181
|
+
if (!S.value) return;
|
|
182
|
+
p.value = !0, A.value = "";
|
|
183
|
+
const C = {
|
|
184
|
+
...t.value ? {} : { id: g.value.trim() },
|
|
185
|
+
appTemplateId: v.value,
|
|
186
|
+
label: k.value.trim(),
|
|
187
|
+
description: T.value.trim(),
|
|
188
|
+
industries: w.value.split(",").map((i) => i.trim()).filter(Boolean),
|
|
189
|
+
default: F.value,
|
|
190
|
+
...e.value ? { restaurantStyle: d.value } : {}
|
|
191
|
+
};
|
|
192
|
+
try {
|
|
193
|
+
await L(
|
|
194
|
+
t.value ? I.appTemplateChoice(r.choice.id) : I.appTemplateChoices(),
|
|
195
|
+
{ method: t.value ? "PATCH" : "POST", body: JSON.stringify(C) }
|
|
196
|
+
), E("saved");
|
|
197
|
+
} catch (i) {
|
|
198
|
+
A.value = U(i);
|
|
199
|
+
} finally {
|
|
200
|
+
p.value = !1;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return (C, i) => {
|
|
204
|
+
const M = f("FmTextField"), Z = f("FmSelect"), le = f("FmTextarea"), oe = f("FmSwitch"), ee = f("FmButton"), ne = f("FmCard"), se = f("FmForm");
|
|
205
|
+
return u(), x(se, { onValidationSuccess: B }, {
|
|
206
|
+
default: q(() => [
|
|
207
|
+
s(ne, { class: "template-choice-dialog" }, {
|
|
208
|
+
default: q(() => {
|
|
209
|
+
var te;
|
|
210
|
+
return [
|
|
211
|
+
o("h2", null, h(t.value ? `Edit ${(te = R.choice) == null ? void 0 : te.label}` : "New template choice"), 1),
|
|
212
|
+
t.value ? P("", !0) : (u(), x(M, {
|
|
213
|
+
key: 0,
|
|
214
|
+
modelValue: g.value,
|
|
215
|
+
"onUpdate:modelValue": i[0] || (i[0] = (m) => g.value = m),
|
|
216
|
+
label: "Choice id",
|
|
217
|
+
placeholder: "e.g. miniprogram-vue-v2-bakery",
|
|
218
|
+
"helper-text": "Lowercase, kebab-case. Cannot be changed after creation.",
|
|
219
|
+
disabled: p.value,
|
|
220
|
+
rules: [(m) => /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(m.trim()) || "Lowercase kebab-case, e.g. miniprogram-vue-v2-bakery"]
|
|
221
|
+
}, null, 8, ["modelValue", "disabled", "rules"])),
|
|
222
|
+
s(Z, {
|
|
223
|
+
modelValue: v.value,
|
|
224
|
+
"onUpdate:modelValue": i[1] || (i[1] = (m) => v.value = m),
|
|
225
|
+
label: "Physical template",
|
|
226
|
+
items: a.value,
|
|
227
|
+
disabled: p.value || t.value || a.value.length <= 1
|
|
228
|
+
}, null, 8, ["modelValue", "items", "disabled"]),
|
|
229
|
+
e.value ? (u(), x(Z, {
|
|
230
|
+
key: 1,
|
|
231
|
+
modelValue: d.value,
|
|
232
|
+
"onUpdate:modelValue": i[2] || (i[2] = (m) => d.value = m),
|
|
233
|
+
label: "Restaurant style",
|
|
234
|
+
"helper-text": "Only styles templates/miniprogram-vue-v2/src/brand/recipes.ts already implements.",
|
|
235
|
+
items: ae(l),
|
|
236
|
+
disabled: p.value
|
|
237
|
+
}, null, 8, ["modelValue", "items", "disabled"])) : P("", !0),
|
|
238
|
+
s(M, {
|
|
239
|
+
modelValue: k.value,
|
|
240
|
+
"onUpdate:modelValue": i[3] || (i[3] = (m) => k.value = m),
|
|
241
|
+
label: "Label",
|
|
242
|
+
placeholder: "Shown to merchants in the picker",
|
|
243
|
+
disabled: p.value
|
|
244
|
+
}, null, 8, ["modelValue", "disabled"]),
|
|
245
|
+
s(le, {
|
|
246
|
+
modelValue: T.value,
|
|
247
|
+
"onUpdate:modelValue": i[4] || (i[4] = (m) => T.value = m),
|
|
248
|
+
label: "Description",
|
|
249
|
+
placeholder: "One or two sentences on what the merchant gets",
|
|
250
|
+
disabled: p.value
|
|
251
|
+
}, null, 8, ["modelValue", "disabled"]),
|
|
252
|
+
s(M, {
|
|
253
|
+
modelValue: w.value,
|
|
254
|
+
"onUpdate:modelValue": i[5] || (i[5] = (m) => w.value = m),
|
|
255
|
+
label: "Industries (comma-separated)",
|
|
256
|
+
placeholder: "e.g. Food & beverage",
|
|
257
|
+
disabled: p.value
|
|
258
|
+
}, null, 8, ["modelValue", "disabled"]),
|
|
259
|
+
s(oe, {
|
|
260
|
+
modelValue: F.value,
|
|
261
|
+
"onUpdate:modelValue": i[6] || (i[6] = (m) => F.value = m),
|
|
262
|
+
label: "Default choice",
|
|
263
|
+
sublabel: "Used when a provision request names none",
|
|
264
|
+
disabled: p.value
|
|
265
|
+
}, null, 8, ["modelValue", "disabled"]),
|
|
266
|
+
A.value ? (u(), y("p", ye, h(A.value), 1)) : P("", !0),
|
|
267
|
+
o("footer", null, [
|
|
268
|
+
s(ee, {
|
|
269
|
+
label: "Cancel",
|
|
270
|
+
variant: "tertiary",
|
|
271
|
+
disabled: p.value,
|
|
272
|
+
onClick: i[7] || (i[7] = (m) => E("close"))
|
|
273
|
+
}, null, 8, ["disabled"]),
|
|
274
|
+
s(ee, {
|
|
275
|
+
label: t.value ? "Save" : "Create",
|
|
276
|
+
type: "submit",
|
|
277
|
+
loading: p.value,
|
|
278
|
+
disabled: !S.value
|
|
279
|
+
}, null, 8, ["label", "loading", "disabled"])
|
|
280
|
+
])
|
|
281
|
+
];
|
|
282
|
+
}),
|
|
283
|
+
_: 1
|
|
284
|
+
})
|
|
285
|
+
]),
|
|
286
|
+
_: 1
|
|
287
|
+
});
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
}), ke = /* @__PURE__ */ H(_e, [["__scopeId", "data-v-776c1a00"]]), Te = { class: "portal-page" }, Ce = { class: "portal-page-inner" }, we = { class: "portal-page-heading" }, Fe = { class: "portal-page-heading__actions" }, Ve = {
|
|
291
|
+
key: 0,
|
|
292
|
+
class: "portal-error",
|
|
293
|
+
role: "alert"
|
|
294
|
+
}, Ae = {
|
|
295
|
+
key: 1,
|
|
296
|
+
role: "status"
|
|
297
|
+
}, Se = {
|
|
298
|
+
key: 2,
|
|
299
|
+
class: "template-choices__list",
|
|
300
|
+
"aria-label": "Template choices"
|
|
301
|
+
}, Ee = { class: "template-choices__name" }, Ie = { class: "template-choices__label" }, Pe = { key: 0 }, xe = { class: "template-choices__id" }, $e = { class: "template-choices__meta" }, De = ["datetime"], Le = { class: "template-choices__actions" }, Ue = /* @__PURE__ */ G({
|
|
302
|
+
__name: "TemplateCenterView",
|
|
303
|
+
setup(R) {
|
|
304
|
+
const $ = pe(), r = ue(), E = n([]), _ = n(!0), c = n(""), g = new AbortController(), v = n(null);
|
|
305
|
+
async function d() {
|
|
306
|
+
_.value = !0, c.value = "";
|
|
307
|
+
try {
|
|
308
|
+
const t = await L(I.appTemplateChoices(), {
|
|
309
|
+
signal: g.signal
|
|
310
|
+
});
|
|
311
|
+
E.value = t.choices;
|
|
312
|
+
} catch (t) {
|
|
313
|
+
g.signal.aborted || (c.value = U(t));
|
|
314
|
+
} finally {
|
|
315
|
+
_.value = !1;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function k() {
|
|
319
|
+
r.open({
|
|
320
|
+
title: "Fork template",
|
|
321
|
+
dialogComponent: fe,
|
|
322
|
+
dialogComponentProps: { onClose: () => r.close() }
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
async function T(t) {
|
|
326
|
+
if (!v.value) {
|
|
327
|
+
v.value = t, c.value = "";
|
|
328
|
+
try {
|
|
329
|
+
const a = await L(
|
|
330
|
+
I.appTemplateEditingProject(t),
|
|
331
|
+
{ method: "POST" }
|
|
332
|
+
);
|
|
333
|
+
await $.push({
|
|
334
|
+
name: "miniprogram-v2-project",
|
|
335
|
+
params: { projectId: a.projectId, view: "workspace" },
|
|
336
|
+
query: { tpl: "1" }
|
|
337
|
+
});
|
|
338
|
+
} catch (a) {
|
|
339
|
+
c.value = U(a);
|
|
340
|
+
} finally {
|
|
341
|
+
v.value = null;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function w(t) {
|
|
346
|
+
r.open({
|
|
347
|
+
title: t ? `Edit ${t.label}` : "New template choice",
|
|
348
|
+
dialogComponent: ke,
|
|
349
|
+
dialogComponentProps: {
|
|
350
|
+
choice: t,
|
|
351
|
+
onClose: () => r.close(),
|
|
352
|
+
onSaved: () => {
|
|
353
|
+
r.close(), d();
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
async function F(t, a) {
|
|
359
|
+
try {
|
|
360
|
+
await L(
|
|
361
|
+
a === "archived" ? I.appTemplateChoiceArchive(t.id) : I.appTemplateChoiceRestore(t.id),
|
|
362
|
+
{ method: "POST" }
|
|
363
|
+
), await d();
|
|
364
|
+
} catch (e) {
|
|
365
|
+
c.value = U(e);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
function p(t) {
|
|
369
|
+
r.open({
|
|
370
|
+
title: `Archive ${t.label}?`,
|
|
371
|
+
message: "It stops appearing for new projects. Merchants already provisioned from it are unaffected — it is never consulted again after provisioning.",
|
|
372
|
+
primaryActions: { text: "Archive", close: !0, variant: "primary" },
|
|
373
|
+
secondaryActions: { text: "Cancel", close: !0, variant: "tertiary" }
|
|
374
|
+
}).onPrimary(() => void F(t, "archived"));
|
|
375
|
+
}
|
|
376
|
+
function A(t) {
|
|
377
|
+
return new Intl.DateTimeFormat(void 0, { dateStyle: "medium", timeStyle: "short" }).format(new Date(t));
|
|
378
|
+
}
|
|
379
|
+
return ie(() => void d()), re(() => g.abort()), (t, a) => {
|
|
380
|
+
const e = f("FmButton");
|
|
381
|
+
return u(), y("div", Te, [
|
|
382
|
+
o("div", Ce, [
|
|
383
|
+
o("header", we, [
|
|
384
|
+
a[2] || (a[2] = o("div", null, [
|
|
385
|
+
o("p", { class: "portal-eyebrow" }, "Internal"),
|
|
386
|
+
o("h1", null, "Template library")
|
|
387
|
+
], -1)),
|
|
388
|
+
o("div", Fe, [
|
|
389
|
+
s(e, {
|
|
390
|
+
label: "Fork template",
|
|
391
|
+
variant: "secondary",
|
|
392
|
+
onClick: a[0] || (a[0] = (l) => k())
|
|
393
|
+
}),
|
|
394
|
+
s(e, {
|
|
395
|
+
label: "New choice",
|
|
396
|
+
icon: "add",
|
|
397
|
+
onClick: a[1] || (a[1] = (l) => w())
|
|
398
|
+
})
|
|
399
|
+
])
|
|
400
|
+
]),
|
|
401
|
+
c.value ? (u(), y("p", Ve, [
|
|
402
|
+
V(h(c.value) + " ", 1),
|
|
403
|
+
s(e, {
|
|
404
|
+
label: "Retry",
|
|
405
|
+
variant: "tertiary",
|
|
406
|
+
onClick: d
|
|
407
|
+
})
|
|
408
|
+
])) : P("", !0),
|
|
409
|
+
a[3] || (a[3] = o("h2", { class: "template-section-title" }, "Template choices", -1)),
|
|
410
|
+
a[4] || (a[4] = o("p", { class: "template-section-note" }, ' "Edit code" opens the physical template a choice provisions from directly — the same chat + live preview a merchant project gets, saving straight to a pull request against this repo instead of a merchant repo. More than one choice can point at the same physical template; editing either reaches the same session. ', -1)),
|
|
411
|
+
_.value ? (u(), y("p", Ae, "Loading template choices…")) : (u(), y("section", Se, [
|
|
412
|
+
(u(!0), y(z, null, de(E.value, (l) => (u(), y("article", {
|
|
413
|
+
key: l.id,
|
|
414
|
+
class: "template-choices__row"
|
|
415
|
+
}, [
|
|
416
|
+
o("div", Ee, [
|
|
417
|
+
o("span", Ie, [
|
|
418
|
+
V(h(l.label), 1),
|
|
419
|
+
l.default ? (u(), y("span", Pe, " · Default")) : P("", !0)
|
|
420
|
+
]),
|
|
421
|
+
o("span", xe, h(l.id), 1),
|
|
422
|
+
o("span", $e, [
|
|
423
|
+
V(h(l.appTemplateId), 1),
|
|
424
|
+
l.restaurantStyle ? (u(), y(z, { key: 0 }, [
|
|
425
|
+
V(" · " + h(l.restaurantStyle), 1)
|
|
426
|
+
], 64)) : P("", !0),
|
|
427
|
+
V(" · " + h(l.industries.join(", ") || "General-purpose") + " · " + h((l.environments ?? []).join(", ")), 1)
|
|
428
|
+
])
|
|
429
|
+
]),
|
|
430
|
+
s(me, {
|
|
431
|
+
variant: l.status === "active" ? "success" : "neutral"
|
|
432
|
+
}, {
|
|
433
|
+
default: q(() => [
|
|
434
|
+
V(h(l.status === "active" ? "Active" : "Archived"), 1)
|
|
435
|
+
]),
|
|
436
|
+
_: 2
|
|
437
|
+
}, 1032, ["variant"]),
|
|
438
|
+
o("time", {
|
|
439
|
+
datetime: l.updatedAt
|
|
440
|
+
}, h(A(l.updatedAt)), 9, De),
|
|
441
|
+
o("div", Le, [
|
|
442
|
+
s(e, {
|
|
443
|
+
label: "Edit code",
|
|
444
|
+
variant: "secondary",
|
|
445
|
+
loading: v.value === l.appTemplateId,
|
|
446
|
+
disabled: v.value !== null,
|
|
447
|
+
onClick: (S) => T(l.appTemplateId)
|
|
448
|
+
}, null, 8, ["loading", "disabled", "onClick"]),
|
|
449
|
+
s(e, {
|
|
450
|
+
label: "Edit details",
|
|
451
|
+
variant: "secondary",
|
|
452
|
+
onClick: (S) => w(l)
|
|
453
|
+
}, null, 8, ["onClick"]),
|
|
454
|
+
l.status === "active" ? (u(), x(e, {
|
|
455
|
+
key: 0,
|
|
456
|
+
label: "Archive",
|
|
457
|
+
variant: "tertiary",
|
|
458
|
+
onClick: (S) => p(l)
|
|
459
|
+
}, null, 8, ["onClick"])) : (u(), x(e, {
|
|
460
|
+
key: 1,
|
|
461
|
+
label: "Restore",
|
|
462
|
+
variant: "tertiary",
|
|
463
|
+
onClick: (S) => F(l, "active")
|
|
464
|
+
}, null, 8, ["onClick"]))
|
|
465
|
+
])
|
|
466
|
+
]))), 128))
|
|
467
|
+
]))
|
|
468
|
+
])
|
|
469
|
+
]);
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
}), Me = /* @__PURE__ */ H(Ue, [["__scopeId", "data-v-de284b8c"]]);
|
|
473
|
+
export {
|
|
474
|
+
Me as default
|
|
475
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineComponent as s, watchEffect as a, openBlock as n, createElementBlock as p } from "vue";
|
|
2
2
|
import { useRoute as u, useRouter as i } from "vue-router";
|
|
3
|
-
import { u as l } from "./portalContext-
|
|
3
|
+
import { u as l } from "./portalContext-6164Gyod.js";
|
|
4
4
|
import { w as m, a as f } from "./portalNavigation-DKCfwTH8.js";
|
|
5
5
|
const _ = {
|
|
6
6
|
class: "portal-loading",
|
package/dist/app.js
CHANGED
|
@@ -4,42 +4,42 @@ const o = [
|
|
|
4
4
|
path: "/platforms/mobile",
|
|
5
5
|
name: "miniprogram-v2-mobile-projects",
|
|
6
6
|
meta: { title: "Mobile" },
|
|
7
|
-
component: () => import("./MobileProjectsView-
|
|
7
|
+
component: () => import("./MobileProjectsView-BfFS_47C.js")
|
|
8
8
|
},
|
|
9
9
|
{
|
|
10
10
|
path: "/",
|
|
11
11
|
name: "miniprogram-v2-ecosystem",
|
|
12
12
|
meta: { title: "Ecosystem" },
|
|
13
13
|
beforeEnter: (e) => ["workspace", "releases", "sessions"].includes(String(e.query.view)) ? { name: "miniprogram-v2-control", query: e.query } : !0,
|
|
14
|
-
component: () => import("./EcosystemView-
|
|
14
|
+
component: () => import("./EcosystemView-MvrxhO3T.js")
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
17
|
path: "/workspace",
|
|
18
18
|
name: "miniprogram-v2-control",
|
|
19
|
-
component: () => import("./WorkspaceEntryView-
|
|
19
|
+
component: () => import("./WorkspaceEntryView-CkTnQH9g.js")
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
path: "/p/:projectId/:view(workspace|releases|sessions)?",
|
|
23
23
|
name: "miniprogram-v2-project",
|
|
24
|
-
component: () => import("./ControlPlaneView-
|
|
24
|
+
component: () => import("./ControlPlaneView-H-hlL2ND.js")
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
path: "/brand-kit",
|
|
28
28
|
name: "miniprogram-v2-brand-kit",
|
|
29
29
|
meta: { title: "Brand Kit" },
|
|
30
|
-
component: () => import("./BrandKitView-
|
|
30
|
+
component: () => import("./BrandKitView-RaUWE69b.js")
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
path: "/pages",
|
|
34
34
|
name: "miniprogram-v2-pages",
|
|
35
35
|
meta: { title: "Pages" },
|
|
36
|
-
component: () => import("./PagesView-
|
|
36
|
+
component: () => import("./PagesView-DOSrArQb.js")
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
path: "/settings",
|
|
40
40
|
name: "miniprogram-v2-settings",
|
|
41
41
|
meta: { title: "Settings" },
|
|
42
|
-
component: () => import("./PortalSettingsView-
|
|
42
|
+
component: () => import("./PortalSettingsView-DjFh8IRa.js")
|
|
43
43
|
},
|
|
44
44
|
...["tablet", "kiosk"].map((e) => ({
|
|
45
45
|
path: `/platforms/${e}`,
|
|
@@ -53,7 +53,7 @@ const o = [
|
|
|
53
53
|
path: "/modules",
|
|
54
54
|
name: "miniprogram-v2-module-center",
|
|
55
55
|
meta: { title: "Module library" },
|
|
56
|
-
component: () => import("./ModuleCenterView-
|
|
56
|
+
component: () => import("./ModuleCenterView-ujyL9wW3.js")
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
59
|
// Keyed by the module's directory name, which is what the catalog, the
|
|
@@ -61,13 +61,24 @@ const o = [
|
|
|
61
61
|
path: "/modules/:name",
|
|
62
62
|
name: "miniprogram-v2-module-detail",
|
|
63
63
|
meta: { title: "Module library" },
|
|
64
|
-
component: () => import("./ModuleDetailView-
|
|
64
|
+
component: () => import("./ModuleDetailView-DFXFxSIN.js")
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
// Internal-only: linked from the main nav (App.vue), but only once
|
|
68
|
+
// `useIsPlatformAdmin()` resolves true — a non-admin who still guesses the
|
|
69
|
+
// URL is caught by the `beforeEach` guard in `./index.ts`, which checks
|
|
70
|
+
// `meta.requiresAdmin` and sends them to the same place an unmatched URL
|
|
71
|
+
// goes, below.
|
|
72
|
+
path: "/internal/template-center",
|
|
73
|
+
name: "miniprogram-v2-template-center",
|
|
74
|
+
meta: { title: "Template library", requiresAdmin: !0 },
|
|
75
|
+
component: () => import("./TemplateCenterView-BOS6FDQ0.js")
|
|
65
76
|
},
|
|
66
77
|
{
|
|
67
78
|
path: "/:pathMatch(.*)*",
|
|
68
79
|
redirect: (e) => ({ name: "miniprogram-v2-ecosystem", query: e.query, params: {} })
|
|
69
80
|
}
|
|
70
|
-
], r = {}, a = t(() => import("./App-
|
|
81
|
+
], r = {}, a = t(() => import("./App-BWnR2QQN.js")), i = t(() => import("./LegacyWorkspaceEntry-lEMtmdIe.js"));
|
|
71
82
|
export {
|
|
72
83
|
a as FmApp,
|
|
73
84
|
i as MiniprogramWorkspace,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const c = "69cde0740c0106001ca83dff", t = {
|
|
1
|
+
const c = "69cde0740c0106001ca83dff", s = "0000000074656d706c617465", t = {
|
|
2
2
|
dev: {
|
|
3
3
|
env: "dev",
|
|
4
4
|
liveDomain: "feedmedev.vip",
|
|
@@ -21,12 +21,12 @@ const c = "69cde0740c0106001ca83dff", t = {
|
|
|
21
21
|
function o(e) {
|
|
22
22
|
return e === "dev" || e === "prod";
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function v(e) {
|
|
25
25
|
if (!o(e))
|
|
26
26
|
throw new Error(`MINIPROGRAM_ENV must be 'dev' or 'prod', got ${JSON.stringify(e)}`);
|
|
27
27
|
return t[e];
|
|
28
28
|
}
|
|
29
|
-
function
|
|
29
|
+
function f(e) {
|
|
30
30
|
const r = e.toLowerCase().replace(/^fmmf:/, "");
|
|
31
31
|
return r === "prod" || r === "production" ? "prod" : "dev";
|
|
32
32
|
}
|
|
@@ -34,11 +34,11 @@ const a = /^[a-f0-9]{24}$/;
|
|
|
34
34
|
function d(e) {
|
|
35
35
|
return a.test(e);
|
|
36
36
|
}
|
|
37
|
-
function
|
|
37
|
+
function g(e = crypto.randomUUID()) {
|
|
38
38
|
const r = m("prj", e, 24);
|
|
39
39
|
return r.length === 27 ? r : r.padEnd(27, "0");
|
|
40
40
|
}
|
|
41
|
-
function
|
|
41
|
+
function u(e) {
|
|
42
42
|
if (!d(e)) throw new Error(`Invalid business id: ${e}`);
|
|
43
43
|
return `prj${e}`;
|
|
44
44
|
}
|
|
@@ -48,8 +48,9 @@ function m(e, r, n) {
|
|
|
48
48
|
}
|
|
49
49
|
export {
|
|
50
50
|
c as D,
|
|
51
|
-
s as
|
|
52
|
-
v as
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
s as T,
|
|
52
|
+
v as a,
|
|
53
|
+
f as e,
|
|
54
|
+
u as l,
|
|
55
|
+
g as m
|
|
55
56
|
};
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as b } from "./routes-
|
|
1
|
+
import { a as b } from "./routes-Cay_S88s.js";
|
|
2
2
|
import { useCoreStore as d } from "@feedmepos/mf-common";
|
|
3
|
-
import { c as g, e as h } from "./controlPlane-
|
|
3
|
+
import { c as g, e as h } from "./controlPlane-sXaC6pAh.js";
|
|
4
4
|
import { provide as y, computed as f, ref as c, watch as C, onScopeDispose as w, inject as x } from "vue";
|
|
5
5
|
function P() {
|
|
6
6
|
const e = d(), r = f(() => {
|