@fayz-ai/plugin-menu 0.10.8 → 0.10.10
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/{MenuPage-SO7EDR6R.js → MenuPage-GC6ATJTT.js} +100 -104
- package/dist/MenuPage-GC6ATJTT.js.map +1 -0
- package/dist/chunk-FVDAVCK4.js +14 -0
- package/dist/chunk-FVDAVCK4.js.map +1 -0
- package/dist/components/DraftSectionCard.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +52 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-surface.d.ts +12 -0
- package/dist/lib/agent-surface.d.ts.map +1 -1
- package/dist/locales/en.d.ts.map +1 -1
- package/dist/locales/pt-BR.d.ts.map +1 -1
- package/dist/store.d.ts +18 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/views/MenuManagerView.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/MenuPage-SO7EDR6R.js.map +0 -1
- package/dist/chunk-C6W53TML.js +0 -65
- package/dist/chunk-C6W53TML.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createPluginContext, PageActions, useAgentSurface, askAI, RightRailPage, formatCurrency, requestChatUpload } from '@fayz-ai/admin';
|
|
3
|
-
import { useState,
|
|
1
|
+
import { normalizeName } from './chunk-FVDAVCK4.js';
|
|
2
|
+
import { createPluginContext, PageActions, useAgentSurface, askAI, RightRailPage, formatCurrency, requestChatUpload, useChatStore } from '@fayz-ai/admin';
|
|
3
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
4
4
|
import { Plus, Sparkles, Search, UtensilsCrossed, MoreVertical, Pencil, Copy, Power, Eye, Trash2, GripVertical, ChevronRight, ChevronDown, Loader2, MoreHorizontal, X, ImageOff, Star, XCircle } from 'lucide-react';
|
|
5
5
|
import { useSensors, useSensor, PointerSensor, DndContext, closestCenter, DragOverlay } from '@dnd-kit/core';
|
|
6
6
|
import { SortableContext, verticalListSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
7
|
-
import { useTranslation
|
|
7
|
+
import { useTranslation } from '@fayz-ai/core';
|
|
8
8
|
import { PageHeaderActions, PageTabs, Button, toast, ConfirmDialog, Dropdown, DropdownTrigger, Hint, DropdownContent, DropdownItem, DropdownSeparator, DraftCommitBar, SheetBody, Input, Switch, SheetFooter, ImageDrop, CurrencyInput, SegmentedControl, Modal, ModalContent, ModalHeader, ModalTitle, ModalBody, TimePicker } from '@fayz-ai/ui';
|
|
9
9
|
import { CSS } from '@dnd-kit/utilities';
|
|
10
10
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
@@ -62,79 +62,20 @@ function describeAvailability(availability, locale, alwaysLabel) {
|
|
|
62
62
|
if (rule.from || rule.to) parts.push(`${rule.from ?? "\u2026"} \u2192 ${rule.to ?? "\u2026"}`);
|
|
63
63
|
return parts.length > 0 ? parts.join(" \xB7 ") : alwaysLabel;
|
|
64
64
|
}
|
|
65
|
-
function resolveMenuExtractor(options) {
|
|
66
|
-
const client = getSupabaseClientOptional();
|
|
67
|
-
if (!client?.functions?.invoke) return null;
|
|
68
|
-
const functionName = "menu-extract";
|
|
69
|
-
return async (images, hint) => {
|
|
70
|
-
const { data, error } = await client.functions.invoke(functionName, {
|
|
71
|
-
body: { images, hint }
|
|
72
|
-
});
|
|
73
|
-
if (error) {
|
|
74
|
-
const detail = await safeMessage(error) ?? error.message;
|
|
75
|
-
throw new Error(detail || "menu extraction failed");
|
|
76
|
-
}
|
|
77
|
-
return normalizeExtraction(data);
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
async function safeMessage(error) {
|
|
81
|
-
try {
|
|
82
|
-
const body = await error?.context?.json?.();
|
|
83
|
-
return typeof body?.error === "string" ? body.error : null;
|
|
84
|
-
} catch {
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// src/lib/images.ts
|
|
90
|
-
async function downscaleImage(file, options) {
|
|
91
|
-
const maxDimension = 1600;
|
|
92
|
-
const quality = 0.82;
|
|
93
|
-
const bitmap = await loadImage(file);
|
|
94
|
-
const scale = Math.min(1, maxDimension / Math.max(bitmap.width, bitmap.height));
|
|
95
|
-
const width = Math.round(bitmap.width * scale);
|
|
96
|
-
const height = Math.round(bitmap.height * scale);
|
|
97
|
-
const canvas = document.createElement("canvas");
|
|
98
|
-
canvas.width = width;
|
|
99
|
-
canvas.height = height;
|
|
100
|
-
const context = canvas.getContext("2d");
|
|
101
|
-
if (!context) return fileToDataUrl(file);
|
|
102
|
-
context.drawImage(bitmap, 0, 0, width, height);
|
|
103
|
-
return canvas.toDataURL("image/jpeg", quality);
|
|
104
|
-
}
|
|
105
|
-
async function loadImage(file) {
|
|
106
|
-
if (typeof createImageBitmap === "function") {
|
|
107
|
-
try {
|
|
108
|
-
return await createImageBitmap(file);
|
|
109
|
-
} catch {
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
const url = await fileToDataUrl(file);
|
|
113
|
-
return new Promise((resolve, reject) => {
|
|
114
|
-
const image = new Image();
|
|
115
|
-
image.onload = () => resolve(image);
|
|
116
|
-
image.onerror = () => reject(new Error("Could not read the image"));
|
|
117
|
-
image.src = url;
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
function fileToDataUrl(file) {
|
|
121
|
-
return new Promise((resolve, reject) => {
|
|
122
|
-
const reader = new FileReader();
|
|
123
|
-
reader.onload = () => resolve(String(reader.result));
|
|
124
|
-
reader.onerror = () => reject(new Error("Could not read the file"));
|
|
125
|
-
reader.readAsDataURL(file);
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
65
|
var INSTRUCTIONS = `Voc\xEA est\xE1 com a tela de Card\xE1pio aberta e \xE9 VOC\xCA quem conduz o cadastro.
|
|
129
66
|
- Trabalhe sempre no card\xE1pio ativo mostrado no estado; se o usu\xE1rio pedir outro, troque ou crie.
|
|
130
67
|
- Se\xE7\xF5es e itens s\xE3o identificados por NOME, do jeito que o usu\xE1rio fala. Pre\xE7o \xE9 n\xFAmero (29.9), sem moeda.
|
|
131
68
|
|
|
132
|
-
Cadastro
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
69
|
+
Cadastro em MASSA (foto, PDF ou texto de card\xE1pio):
|
|
70
|
+
- Se a foto/texto do card\xE1pio J\xC1 EST\xC1 nesta conversa: leia voc\xEA mesmo e chame stageMenuImport UMA vez com todas as se\xE7\xF5es e itens. NUNCA cadastre se\xE7\xE3o por se\xE7\xE3o ou item por item com createMenuSection/createMenuItem \u2014 isso estoura o limite de passos e duplica se\xE7\xF5es. A ferramenta j\xE1 reaproveita se\xE7\xF5es existentes e pula itens repetidos.
|
|
71
|
+
- Se o usu\xE1rio ainda n\xE3o mandou a foto: diga em uma linha o que vai fazer e chame requestMenuPhotos. Isso p\xF5e um bot\xE3o grande aqui na conversa ("Subir foto do card\xE1pio") que abre a c\xE2mera ou os arquivos \u2014 n\xE3o pe\xE7a para o usu\xE1rio usar o clipe, e n\xE3o mande ele fazer nada na tela. A foto enviada chega AQUI na conversa como anexo da pr\xF3xima mensagem: leia e chame stageMenuImport.
|
|
72
|
+
- Este fluxo \xE9 todo conversado: NUNCA use startFeatureSetup ou highlightFeature para o cadastro de card\xE1pio \u2014 n\xE3o existe tour para isso, o bot\xE3o de foto \xE9 a ferramenta.
|
|
73
|
+
Depois, nos dois caminhos:
|
|
74
|
+
1. Quando \`draft\` aparecer no estado, LEIA em voz alta o que veio: quantas se\xE7\xF5es, quantos itens, e quais ficaram com pre\xE7o 0.
|
|
75
|
+
2. Resolva as pend\xEAncias conversando \u2014 pergunte o pre\xE7o que faltou e chame updateMenuDraftItem. O usu\xE1rio tamb\xE9m pode editar direto na tela; o estado sempre reflete o que est\xE1 l\xE1.
|
|
76
|
+
3. S\xF3 chame commitMenuDraft depois que o usu\xE1rio confirmar. Se ele desistir, discardMenuDraft.
|
|
77
|
+
|
|
78
|
+
createMenuSection e createMenuItem s\xE3o para ajustes pontuais (uma se\xE7\xE3o nova, um prato novo) \u2014 nunca para importar um card\xE1pio inteiro.
|
|
138
79
|
|
|
139
80
|
NUNCA escreva um bot\xE3o em texto (nada de "[Subir foto do card\xE1pio]" ou "clique no bot\xE3o abaixo") \u2014 o bot\xE3o s\xF3 existe se voc\xEA chamar a ferramenta. Se ela n\xE3o estiver dispon\xEDvel, diga isso com todas as letras e ofere\xE7a cadastrar item a item.
|
|
140
81
|
|
|
@@ -188,6 +129,8 @@ function useMenuAgentSurface(deps) {
|
|
|
188
129
|
["name"]
|
|
189
130
|
),
|
|
190
131
|
execute: async ({ name }) => {
|
|
132
|
+
const existing = deps.sections.find((s) => normalizeName(s.name) === normalizeName(String(name)));
|
|
133
|
+
if (existing) return { ok: true, section: existing.name, alreadyExisted: true };
|
|
191
134
|
const created = await deps.actions.createSection(String(name));
|
|
192
135
|
return created ? { ok: true, section: created.name } : { error: "section_not_created" };
|
|
193
136
|
}
|
|
@@ -315,21 +258,67 @@ function useMenuAgentSurface(deps) {
|
|
|
315
258
|
return { ok: true, menu: created.name };
|
|
316
259
|
}
|
|
317
260
|
},
|
|
261
|
+
{
|
|
262
|
+
tool: tool(
|
|
263
|
+
"menu.surface.stage-import",
|
|
264
|
+
"stageMenuImport",
|
|
265
|
+
'IMPORTA O CARD\xC1PIO ("importa/cadastra esse card\xE1pio", foto de card\xE1pio na conversa): voc\xEA l\xEA a foto ou o texto e passa o card\xE1pio INTEIRO (todas as se\xE7\xF5es com seus itens) numa chamada s\xF3 \u2014 vira um rascunho na tela para o usu\xE1rio conferir. Se\xE7\xF5es com nome de uma se\xE7\xE3o existente recebem os itens nela (sem duplicar), e itens que j\xE1 existem s\xE3o pulados. Nada \xE9 gravado at\xE9 commitMenuDraft. Nunca use tour/setup para importar card\xE1pio.',
|
|
266
|
+
{
|
|
267
|
+
sections: {
|
|
268
|
+
type: "array",
|
|
269
|
+
description: "Todas as se\xE7\xF5es do card\xE1pio lido",
|
|
270
|
+
items: {
|
|
271
|
+
type: "object",
|
|
272
|
+
properties: {
|
|
273
|
+
name: { type: "string", description: "Nome da se\xE7\xE3o (ex.: Pizzas, Bebidas)" },
|
|
274
|
+
items: {
|
|
275
|
+
type: "array",
|
|
276
|
+
items: {
|
|
277
|
+
type: "object",
|
|
278
|
+
properties: {
|
|
279
|
+
name: { type: "string" },
|
|
280
|
+
price: { type: "number", description: "N\xFAmero, sem moeda. 0 se a foto n\xE3o mostra o pre\xE7o." },
|
|
281
|
+
description: { type: "string" }
|
|
282
|
+
},
|
|
283
|
+
required: ["name", "price"]
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
required: ["name", "items"]
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
["sections"]
|
|
292
|
+
),
|
|
293
|
+
execute: async ({ sections }) => {
|
|
294
|
+
if (!Array.isArray(sections) || sections.length === 0) return { error: "empty_import" };
|
|
295
|
+
const staged = deps.actions.stageDraft(sections);
|
|
296
|
+
if (staged.sections === 0) {
|
|
297
|
+
return {
|
|
298
|
+
ok: true,
|
|
299
|
+
staged,
|
|
300
|
+
note: "Nada novo para cadastrar \u2014 tudo que veio j\xE1 existe no card\xE1pio."
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
ok: true,
|
|
305
|
+
staged,
|
|
306
|
+
next: "O rascunho est\xE1 na tela. Leia para o usu\xE1rio o que veio (se\xE7\xF5es, itens, pre\xE7os zerados), resolva pend\xEAncias e s\xF3 chame commitMenuDraft depois que ele confirmar."
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
},
|
|
318
310
|
{
|
|
319
311
|
tool: tool(
|
|
320
312
|
"menu.surface.request-photos",
|
|
321
313
|
"requestMenuPhotos",
|
|
322
|
-
"Pede as fotos do card\xE1pio ao usu\xE1rio: aparece um bot\xE3o grande aqui na conversa para tirar a foto ou escolher o arquivo.
|
|
314
|
+
"Pede as fotos do card\xE1pio ao usu\xE1rio: aparece um bot\xE3o grande aqui na conversa para tirar a foto ou escolher o arquivo. A foto enviada chega como anexo da pr\xF3xima mensagem do usu\xE1rio \u2014 voc\xEA l\xEA e chama stageMenuImport.",
|
|
323
315
|
{},
|
|
324
316
|
[],
|
|
325
317
|
"read"
|
|
326
318
|
),
|
|
327
319
|
execute: async () => {
|
|
328
|
-
if (!deps.hasExtractor) {
|
|
329
|
-
return { error: "extractor_unavailable", message: "Este espa\xE7o ainda n\xE3o tem a leitura por foto configurada. O cadastro pode ser feito item a item." };
|
|
330
|
-
}
|
|
331
320
|
deps.actions.requestPhotos();
|
|
332
|
-
return { ok: true, asked: true, next: "O bot\xE3o j\xE1 est\xE1 na conversa.
|
|
321
|
+
return { ok: true, asked: true, next: "O bot\xE3o j\xE1 est\xE1 na conversa. A foto chega como anexo da pr\xF3xima mensagem: leia e chame stageMenuImport com o card\xE1pio inteiro." };
|
|
333
322
|
}
|
|
334
323
|
},
|
|
335
324
|
{
|
|
@@ -1235,7 +1224,6 @@ function DraftRow({ item, onChange, onRemove }) {
|
|
|
1235
1224
|
}
|
|
1236
1225
|
function DraftSectionCard({ section, sections, onPatchSection, onRemoveSection, onPatchItem, onRemoveItem }) {
|
|
1237
1226
|
const t = useTranslation();
|
|
1238
|
-
const existing = sections.find((s) => s.id === section.targetSectionId);
|
|
1239
1227
|
return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-card border-2 border-dashed border-primary/40 bg-primary/[0.03]", children: [
|
|
1240
1228
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 border-b border-dashed border-primary/30 px-3 py-2", children: [
|
|
1241
1229
|
/* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5 text-primary" }),
|
|
@@ -1247,30 +1235,38 @@ function DraftSectionCard({ section, sections, onPatchSection, onRemoveSection,
|
|
|
1247
1235
|
className: "rounded border border-transparent bg-transparent px-1 py-0.5 text-sm font-semibold hover:border-border focus:border-border focus:outline-none focus:ring-2 focus:ring-ring"
|
|
1248
1236
|
}
|
|
1249
1237
|
),
|
|
1250
|
-
/* @__PURE__ */ jsxs(
|
|
1251
|
-
"select",
|
|
1252
|
-
{
|
|
1253
|
-
value: section.targetSectionId ?? "",
|
|
1254
|
-
onChange: (e) => onPatchSection({ targetSectionId: e.target.value || void 0 }),
|
|
1255
|
-
className: "h-7 rounded-md border bg-card px-2 text-xs",
|
|
1256
|
-
children: [
|
|
1257
|
-
/* @__PURE__ */ jsx("option", { value: "", children: t("menu.import.createSection") }),
|
|
1258
|
-
sections.map((s) => /* @__PURE__ */ jsx("option", { value: s.id, children: t("menu.import.intoSection", { name: s.name }) }, s.id))
|
|
1259
|
-
]
|
|
1260
|
-
}
|
|
1261
|
-
),
|
|
1262
1238
|
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground", children: t("menu.manager.itemsCount", { count: String(section.items.length) }) }),
|
|
1263
|
-
|
|
1239
|
+
/* @__PURE__ */ jsxs("label", { className: "ml-auto flex items-center gap-1.5 text-[11px] text-muted-foreground", children: [
|
|
1240
|
+
t("menu.import.destination"),
|
|
1241
|
+
/* @__PURE__ */ jsxs(
|
|
1242
|
+
"select",
|
|
1243
|
+
{
|
|
1244
|
+
value: section.targetSectionId ?? "",
|
|
1245
|
+
onChange: (e) => onPatchSection({ targetSectionId: e.target.value || void 0 }),
|
|
1246
|
+
className: "h-7 rounded-md border bg-card px-2 text-xs text-foreground",
|
|
1247
|
+
children: [
|
|
1248
|
+
/* @__PURE__ */ jsx("option", { value: "", children: t("menu.import.createSection") }),
|
|
1249
|
+
sections.map((s) => /* @__PURE__ */ jsx("option", { value: s.id, children: s.name }, s.id))
|
|
1250
|
+
]
|
|
1251
|
+
}
|
|
1252
|
+
)
|
|
1253
|
+
] }),
|
|
1264
1254
|
/* @__PURE__ */ jsx(
|
|
1265
1255
|
"button",
|
|
1266
1256
|
{
|
|
1267
1257
|
onClick: onRemoveSection,
|
|
1268
|
-
className: "
|
|
1258
|
+
className: "rounded p-1 text-muted-foreground hover:text-destructive",
|
|
1269
1259
|
"aria-label": t("menu.import.dropSection"),
|
|
1270
1260
|
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
1271
1261
|
}
|
|
1272
1262
|
)
|
|
1273
1263
|
] }),
|
|
1264
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b border-dashed border-primary/20 px-3 py-1 text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: [
|
|
1265
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 px-1", children: t("menu.itemForm.name") }),
|
|
1266
|
+
/* @__PURE__ */ jsx("span", { className: "hidden min-w-0 flex-1 px-1 sm:block", children: t("menu.itemForm.description") }),
|
|
1267
|
+
/* @__PURE__ */ jsx("span", { className: "w-20 px-1.5 text-right", children: t("menu.itemForm.price") }),
|
|
1268
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "w-[22px]" })
|
|
1269
|
+
] }),
|
|
1274
1270
|
/* @__PURE__ */ jsx("div", { children: section.items.map((item) => /* @__PURE__ */ jsx(
|
|
1275
1271
|
DraftRow,
|
|
1276
1272
|
{
|
|
@@ -1372,13 +1368,13 @@ function MenuManagerView() {
|
|
|
1372
1368
|
const setItemStatus = useMenuStore((s) => s.setItemStatus);
|
|
1373
1369
|
const toggleAvailability = useMenuStore((s) => s.toggleAvailability);
|
|
1374
1370
|
const uploadImage = useMenuStore((s) => s.uploadImage);
|
|
1375
|
-
const runExtraction = useMenuStore((s) => s.runExtraction);
|
|
1376
1371
|
const updateDraftItem = useMenuStore((s) => s.updateDraftItem);
|
|
1377
1372
|
const removeDraftItem = useMenuStore((s) => s.removeDraftItem);
|
|
1378
1373
|
const updateDraftSection = useMenuStore((s) => s.updateDraftSection);
|
|
1379
1374
|
const removeDraftSection = useMenuStore((s) => s.removeDraftSection);
|
|
1380
1375
|
const discardDraft = useMenuStore((s) => s.discardDraft);
|
|
1381
1376
|
const commitDraft = useMenuStore((s) => s.commitDraft);
|
|
1377
|
+
const stageDraft = useMenuStore((s) => s.stageDraft);
|
|
1382
1378
|
const [search, setSearch] = useState("");
|
|
1383
1379
|
const [menuEditor, setMenuEditor] = useState({ open: false });
|
|
1384
1380
|
const [itemEditor, setItemEditor] = useState({ open: false, sectionId: "" });
|
|
@@ -1386,11 +1382,8 @@ function MenuManagerView() {
|
|
|
1386
1382
|
const [confirm, setConfirm] = useState(null);
|
|
1387
1383
|
const [dragging, setDragging] = useState(null);
|
|
1388
1384
|
const [committing, setCommitting] = useState(false);
|
|
1389
|
-
const extractor = useMemo(() => resolveMenuExtractor(), []);
|
|
1390
1385
|
const readPhotos = async (files) => {
|
|
1391
|
-
|
|
1392
|
-
const images = await Promise.all(files.map((file) => downscaleImage(file)));
|
|
1393
|
-
await runExtraction(images, extractor);
|
|
1386
|
+
useChatStore.getState().queuePrompt(t("menu.import.photoSentPrompt"), files);
|
|
1394
1387
|
};
|
|
1395
1388
|
const askForPhotos = () => requestChatUpload({
|
|
1396
1389
|
label: t("menu.import.uploadCta"),
|
|
@@ -1499,7 +1492,9 @@ function MenuManagerView() {
|
|
|
1499
1492
|
placements,
|
|
1500
1493
|
itemsById,
|
|
1501
1494
|
draft,
|
|
1502
|
-
|
|
1495
|
+
// The chat reads the photo now; the ask-for-photo card never depends on a
|
|
1496
|
+
// dedicated extraction backend.
|
|
1497
|
+
hasExtractor: true,
|
|
1503
1498
|
actions: {
|
|
1504
1499
|
createSection: (name) => createSection(name),
|
|
1505
1500
|
renameSection: (sectionId, name) => updateSection(sectionId, { name }),
|
|
@@ -1514,6 +1509,7 @@ function MenuManagerView() {
|
|
|
1514
1509
|
}),
|
|
1515
1510
|
duplicateMenu,
|
|
1516
1511
|
requestPhotos: askForPhotos,
|
|
1512
|
+
stageDraft,
|
|
1517
1513
|
updateDraftItem,
|
|
1518
1514
|
removeDraftItem,
|
|
1519
1515
|
updateDraftSection,
|
|
@@ -1608,7 +1604,7 @@ function MenuManagerView() {
|
|
|
1608
1604
|
creates: true,
|
|
1609
1605
|
onSelect: () => setMenuEditor({ open: true })
|
|
1610
1606
|
}] : [],
|
|
1611
|
-
|
|
1607
|
+
{
|
|
1612
1608
|
id: "ai-import",
|
|
1613
1609
|
label: t("menu.import.action"),
|
|
1614
1610
|
description: t("menu.import.actionDesc"),
|
|
@@ -1618,7 +1614,7 @@ function MenuManagerView() {
|
|
|
1618
1614
|
intent: multiMenu ? "secondary" : "primary",
|
|
1619
1615
|
creates: true,
|
|
1620
1616
|
onSelect: () => startAiImport()
|
|
1621
|
-
}
|
|
1617
|
+
}
|
|
1622
1618
|
]
|
|
1623
1619
|
}
|
|
1624
1620
|
) }),
|
|
@@ -1687,7 +1683,7 @@ function MenuManagerView() {
|
|
|
1687
1683
|
" ",
|
|
1688
1684
|
t("menu.manager.addSection")
|
|
1689
1685
|
] }),
|
|
1690
|
-
|
|
1686
|
+
/* @__PURE__ */ jsxs(Button, { onClick: startAiImport, children: [
|
|
1691
1687
|
/* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5" }),
|
|
1692
1688
|
" ",
|
|
1693
1689
|
t("menu.import.action")
|
|
@@ -1819,5 +1815,5 @@ function MenuPage({ config, provider, store, registries }) {
|
|
|
1819
1815
|
}
|
|
1820
1816
|
|
|
1821
1817
|
export { MenuPage };
|
|
1822
|
-
//# sourceMappingURL=MenuPage-
|
|
1823
|
-
//# sourceMappingURL=MenuPage-
|
|
1818
|
+
//# sourceMappingURL=MenuPage-GC6ATJTT.js.map
|
|
1819
|
+
//# sourceMappingURL=MenuPage-GC6ATJTT.js.map
|