@mulmoclaude/collection-plugin 0.5.3 → 0.5.7
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/server/host.d.ts +25 -0
- package/dist/server/host.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/io.d.ts +6 -0
- package/dist/server/io.d.ts.map +1 -1
- package/dist/server.cjs +32 -8
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +31 -9
- package/dist/server.js.map +1 -1
- package/dist/style.css +19 -3
- package/dist/vue/components/CollectionCustomView.vue.d.ts +19 -1
- package/dist/vue/components/CollectionCustomView.vue.d.ts.map +1 -1
- package/dist/vue/components/CollectionRecordPanel.vue.d.ts +4 -2
- package/dist/vue/components/CollectionRecordPanel.vue.d.ts.map +1 -1
- package/dist/vue/components/CollectionView.vue.d.ts.map +1 -1
- package/dist/vue/lang/de.d.ts.map +1 -1
- package/dist/vue/lang/en.d.ts +2 -0
- package/dist/vue/lang/en.d.ts.map +1 -1
- package/dist/vue/lang/es.d.ts.map +1 -1
- package/dist/vue/lang/fr.d.ts.map +1 -1
- package/dist/vue/lang/index.d.ts +2 -0
- package/dist/vue/lang/index.d.ts.map +1 -1
- package/dist/vue/lang/ja.d.ts.map +1 -1
- package/dist/vue/lang/ko.d.ts.map +1 -1
- package/dist/vue/lang/ptBR.d.ts.map +1 -1
- package/dist/vue/lang/zh.d.ts.map +1 -1
- package/dist/vue/uiContext.d.ts +12 -0
- package/dist/vue/uiContext.d.ts.map +1 -1
- package/dist/vue/useCollectionRendering.d.ts +2 -0
- package/dist/vue/useCollectionRendering.d.ts.map +1 -1
- package/dist/vue.cjs +240 -19
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +241 -20
- package/dist/vue.js.map +1 -1
- package/package.json +2 -2
package/dist/vue.cjs
CHANGED
|
@@ -70,6 +70,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
70
70
|
chatTitle: "Start a chat",
|
|
71
71
|
chatPlaceholder: "Describe what you want to do with this collection…",
|
|
72
72
|
chatStart: "Start chat",
|
|
73
|
+
itemChatLabel: "Chat about this record",
|
|
74
|
+
itemChatPlaceholder: "Ask or instruct about this record…",
|
|
73
75
|
viewToggle: "View",
|
|
74
76
|
viewTable: "Table",
|
|
75
77
|
viewCalendar: "Calendar",
|
|
@@ -171,6 +173,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
171
173
|
chatTitle: "チャットを開始",
|
|
172
174
|
chatPlaceholder: "このコレクションで行いたいことを入力してください…",
|
|
173
175
|
chatStart: "チャットを開始",
|
|
176
|
+
itemChatLabel: "このレコードについてチャット",
|
|
177
|
+
itemChatPlaceholder: "このレコードについて質問・指示する…",
|
|
174
178
|
viewToggle: "表示",
|
|
175
179
|
viewTable: "テーブル",
|
|
176
180
|
viewCalendar: "カレンダー",
|
|
@@ -272,6 +276,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
272
276
|
chatTitle: "开始对话",
|
|
273
277
|
chatPlaceholder: "描述你想对这个集合做什么…",
|
|
274
278
|
chatStart: "开始对话",
|
|
279
|
+
itemChatLabel: "就此记录对话",
|
|
280
|
+
itemChatPlaceholder: "询问或指示有关此记录的操作…",
|
|
275
281
|
viewToggle: "视图",
|
|
276
282
|
viewTable: "表格",
|
|
277
283
|
viewCalendar: "日历",
|
|
@@ -373,6 +379,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
373
379
|
chatTitle: "채팅 시작",
|
|
374
380
|
chatPlaceholder: "이 컬렉션으로 하고 싶은 작업을 설명하세요…",
|
|
375
381
|
chatStart: "채팅 시작",
|
|
382
|
+
itemChatLabel: "이 레코드에 대해 채팅",
|
|
383
|
+
itemChatPlaceholder: "이 레코드에 대해 질문하거나 지시하세요…",
|
|
376
384
|
viewToggle: "보기",
|
|
377
385
|
viewTable: "표",
|
|
378
386
|
viewCalendar: "캘린더",
|
|
@@ -474,6 +482,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
474
482
|
chatTitle: "Iniciar un chat",
|
|
475
483
|
chatPlaceholder: "Describe qué quieres hacer con esta colección…",
|
|
476
484
|
chatStart: "Iniciar chat",
|
|
485
|
+
itemChatLabel: "Chatear sobre este registro",
|
|
486
|
+
itemChatPlaceholder: "Pregunta o indica algo sobre este registro…",
|
|
477
487
|
viewToggle: "Vista",
|
|
478
488
|
viewTable: "Tabla",
|
|
479
489
|
viewCalendar: "Calendario",
|
|
@@ -575,6 +585,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
575
585
|
chatTitle: "Iniciar um chat",
|
|
576
586
|
chatPlaceholder: "Descreva o que você quer fazer com esta coleção…",
|
|
577
587
|
chatStart: "Iniciar chat",
|
|
588
|
+
itemChatLabel: "Conversar sobre este registro",
|
|
589
|
+
itemChatPlaceholder: "Pergunte ou instrua sobre este registro…",
|
|
578
590
|
viewToggle: "Visualização",
|
|
579
591
|
viewTable: "Tabela",
|
|
580
592
|
viewCalendar: "Calendário",
|
|
@@ -676,6 +688,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
676
688
|
chatTitle: "Démarrer une discussion",
|
|
677
689
|
chatPlaceholder: "Décrivez ce que vous voulez faire avec cette collection…",
|
|
678
690
|
chatStart: "Démarrer la discussion",
|
|
691
|
+
itemChatLabel: "Discuter de cet enregistrement",
|
|
692
|
+
itemChatPlaceholder: "Posez une question ou donnez une instruction sur cet enregistrement…",
|
|
679
693
|
viewToggle: "Affichage",
|
|
680
694
|
viewTable: "Tableau",
|
|
681
695
|
viewCalendar: "Calendrier",
|
|
@@ -777,6 +791,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
777
791
|
chatTitle: "Chat starten",
|
|
778
792
|
chatPlaceholder: "Beschreibe, was du mit dieser Sammlung tun möchtest…",
|
|
779
793
|
chatStart: "Chat starten",
|
|
794
|
+
itemChatLabel: "Über diesen Eintrag chatten",
|
|
795
|
+
itemChatPlaceholder: "Stelle eine Frage oder gib eine Anweisung zu diesem Eintrag…",
|
|
780
796
|
viewToggle: "Ansicht",
|
|
781
797
|
viewTable: "Tabelle",
|
|
782
798
|
viewCalendar: "Kalender",
|
|
@@ -1758,6 +1774,7 @@ var _hoisted_36$1 = ["onUpdate:modelValue", "required"];
|
|
|
1758
1774
|
var _hoisted_37$1 = [
|
|
1759
1775
|
"onUpdate:modelValue",
|
|
1760
1776
|
"type",
|
|
1777
|
+
"step",
|
|
1761
1778
|
"required"
|
|
1762
1779
|
];
|
|
1763
1780
|
var _hoisted_38$1 = { class: "text-center px-1" };
|
|
@@ -1786,6 +1803,7 @@ var _hoisted_45$1 = [
|
|
|
1786
1803
|
"id",
|
|
1787
1804
|
"onUpdate:modelValue",
|
|
1788
1805
|
"type",
|
|
1806
|
+
"step",
|
|
1789
1807
|
"required",
|
|
1790
1808
|
"disabled",
|
|
1791
1809
|
"data-testid"
|
|
@@ -1876,6 +1894,18 @@ var _hoisted_69$1 = {
|
|
|
1876
1894
|
key: 0,
|
|
1877
1895
|
class: "col-span-full text-xs font-semibold text-red-600 bg-red-50 border border-red-100 p-2.5 rounded-xl"
|
|
1878
1896
|
};
|
|
1897
|
+
var _hoisted_70$1 = {
|
|
1898
|
+
key: 1,
|
|
1899
|
+
class: "mt-5 pt-4 border-t border-slate-200/60",
|
|
1900
|
+
"data-testid": "collections-detail-chat"
|
|
1901
|
+
};
|
|
1902
|
+
var _hoisted_71$1 = {
|
|
1903
|
+
class: "block text-[10px] font-bold text-slate-400 uppercase tracking-wider mb-1.5",
|
|
1904
|
+
for: "collections-detail-chat-input"
|
|
1905
|
+
};
|
|
1906
|
+
var _hoisted_72$1 = { class: "flex items-end gap-2" };
|
|
1907
|
+
var _hoisted_73$1 = ["placeholder", "onKeydown"];
|
|
1908
|
+
var _hoisted_74$1 = ["disabled"];
|
|
1879
1909
|
//#endregion
|
|
1880
1910
|
//#region src/vue/components/CollectionRecordPanel.vue
|
|
1881
1911
|
var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
@@ -1904,7 +1934,8 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1904
1934
|
"edit",
|
|
1905
1935
|
"close",
|
|
1906
1936
|
"delete",
|
|
1907
|
-
"runAction"
|
|
1937
|
+
"runAction",
|
|
1938
|
+
"itemChat"
|
|
1908
1939
|
], ["update:editing"]),
|
|
1909
1940
|
setup(__props, { emit: __emit }) {
|
|
1910
1941
|
const cui = collectionUi();
|
|
@@ -1913,6 +1944,16 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1913
1944
|
const editing = (0, vue.useModel)(__props, "editing");
|
|
1914
1945
|
const emit = __emit;
|
|
1915
1946
|
const { t } = useCollectionI18n();
|
|
1947
|
+
const chatMessage = (0, vue.ref)("");
|
|
1948
|
+
(0, vue.watch)(() => props.viewing, () => {
|
|
1949
|
+
chatMessage.value = "";
|
|
1950
|
+
});
|
|
1951
|
+
function submitItemChat() {
|
|
1952
|
+
const message = chatMessage.value.trim();
|
|
1953
|
+
if (!message) return;
|
|
1954
|
+
emit("itemChat", message);
|
|
1955
|
+
chatMessage.value = "";
|
|
1956
|
+
}
|
|
1916
1957
|
const embedViews = (0, vue.computed)(() => props.render.embedViews.value);
|
|
1917
1958
|
/** The record the read-only displays render from: the live draft while
|
|
1918
1959
|
* editing (so non-editable cells like derived/embed preview the in-flight
|
|
@@ -1991,7 +2032,7 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1991
2032
|
return (0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)(editing.value ? "form" : "div"), {
|
|
1992
2033
|
class: "px-6 py-5 max-h-[60vh] overflow-y-auto",
|
|
1993
2034
|
"data-testid": rootTestid.value,
|
|
1994
|
-
onSubmit: _cache[
|
|
2035
|
+
onSubmit: _cache[5] || (_cache[5] = (0, vue.withModifiers)(($event) => emit("submit"), ["prevent"]))
|
|
1995
2036
|
}, {
|
|
1996
2037
|
default: (0, vue.withCtx)(() => [
|
|
1997
2038
|
(0, vue.createElementVNode)("div", _hoisted_1$7, [(0, vue.createElementVNode)("div", _hoisted_2$6, [(0, vue.createElementVNode)("span", _hoisted_3$6, (0, vue.toDisplayString)(__props.collection.title), 1), (0, vue.createElementVNode)("h2", {
|
|
@@ -2023,20 +2064,20 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2023
2064
|
class: "h-8 px-2.5 rounded border border-slate-200 bg-white text-slate-700 hover:bg-slate-50 font-bold text-xs transition-all flex items-center gap-1",
|
|
2024
2065
|
"data-testid": "collections-detail-edit",
|
|
2025
2066
|
onClick: _cache[1] || (_cache[1] = ($event) => emit("edit"))
|
|
2026
|
-
}, [_cache[
|
|
2067
|
+
}, [_cache[6] || (_cache[6] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "edit", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.editItem")), 1)]),
|
|
2027
2068
|
(0, vue.createElementVNode)("button", {
|
|
2028
2069
|
type: "button",
|
|
2029
2070
|
class: "h-8 px-2.5 rounded border border-rose-200 bg-white text-rose-600 hover:bg-rose-50 font-bold text-xs transition-all flex items-center gap-1",
|
|
2030
2071
|
"data-testid": "collections-detail-remove",
|
|
2031
2072
|
onClick: _cache[2] || (_cache[2] = ($event) => emit("delete"))
|
|
2032
|
-
}, [_cache[
|
|
2073
|
+
}, [_cache[7] || (_cache[7] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "delete", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("common.remove")), 1)]),
|
|
2033
2074
|
(0, vue.createElementVNode)("button", {
|
|
2034
2075
|
type: "button",
|
|
2035
2076
|
class: "h-8 w-8 flex items-center justify-center rounded text-slate-400 hover:bg-slate-100 hover:text-slate-600 transition-colors",
|
|
2036
2077
|
"aria-label": (0, vue.unref)(t)("common.close"),
|
|
2037
2078
|
"data-testid": "collections-detail-close",
|
|
2038
2079
|
onClick: _cache[3] || (_cache[3] = ($event) => emit("close"))
|
|
2039
|
-
}, [..._cache[
|
|
2080
|
+
}, [..._cache[8] || (_cache[8] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_9$4)
|
|
2040
2081
|
]))]),
|
|
2041
2082
|
!editing.value && __props.actionError ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_10$4, (0, vue.toDisplayString)(__props.actionError), 1)) : (0, vue.createCommentVNode)("", true),
|
|
2042
2083
|
(0, vue.createElementVNode)("div", _hoisted_11$4, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.collection.schema.fields, (field, key) => {
|
|
@@ -2086,7 +2127,7 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2086
2127
|
key: subKey,
|
|
2087
2128
|
class: "text-left px-3 py-2 font-bold"
|
|
2088
2129
|
}, (0, vue.toDisplayString)(subField.label), 1);
|
|
2089
|
-
}), 128)), _cache[
|
|
2130
|
+
}), 128)), _cache[9] || (_cache[9] = (0, vue.createElementVNode)("th", { class: "w-9" }, null, -1))])]), (0, vue.createElementVNode)("tbody", _hoisted_26$1, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(editing.value.table[key], (row, rowIdx) => {
|
|
2090
2131
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("tr", {
|
|
2091
2132
|
key: rowIdx,
|
|
2092
2133
|
class: "hover:bg-slate-50/50"
|
|
@@ -2130,6 +2171,7 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2130
2171
|
key: 4,
|
|
2131
2172
|
"onUpdate:modelValue": ($event) => row.text[subKey] = $event,
|
|
2132
2173
|
type: __props.render.inputTypeFor(subField.type),
|
|
2174
|
+
step: __props.render.stepFor(subField.type),
|
|
2133
2175
|
required: subField.required,
|
|
2134
2176
|
class: "w-full rounded-lg border border-slate-200 px-2 py-1 text-xs focus:border-indigo-500 focus:outline-none font-medium text-slate-700"
|
|
2135
2177
|
}, null, 8, _hoisted_37$1)), [[vue.vModelDynamic, row.text[subKey]]])]);
|
|
@@ -2139,13 +2181,13 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2139
2181
|
"aria-label": (0, vue.unref)(t)("collectionsView.removeRow"),
|
|
2140
2182
|
"data-testid": `collections-table-${key}-remove-${rowIdx}`,
|
|
2141
2183
|
onClick: ($event) => removeTableRow(String(key), rowIdx)
|
|
2142
|
-
}, [..._cache[
|
|
2184
|
+
}, [..._cache[10] || (_cache[10] = [(0, vue.createElementVNode)("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_39$1)])]);
|
|
2143
2185
|
}), 128))])])])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_40$1, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.noRows")), 1)), (0, vue.createElementVNode)("button", {
|
|
2144
2186
|
type: "button",
|
|
2145
2187
|
class: "inline-flex items-center gap-1 text-xs text-indigo-600 hover:text-indigo-800 font-bold hover:underline",
|
|
2146
2188
|
"data-testid": `collections-table-${key}-add`,
|
|
2147
2189
|
onClick: ($event) => addTableRow(String(key), field.of)
|
|
2148
|
-
}, [_cache[
|
|
2190
|
+
}, [_cache[11] || (_cache[11] = (0, vue.createElementVNode)("span", { class: "material-icons text-xs" }, "add", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.addRow")), 1)], 8, _hoisted_41$1)], 8, _hoisted_22$2)) : field.type === "money" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_42$1, [(0, vue.createElementVNode)("div", _hoisted_43$1, (0, vue.toDisplayString)(__props.render.currencySymbol(__props.render.resolveCurrency(field, __props.liveRecord))), 1), (0, vue.withDirectives)((0, vue.createElementVNode)("input", {
|
|
2149
2191
|
id: `collections-field-${key}`,
|
|
2150
2192
|
"onUpdate:modelValue": ($event) => editing.value.text[key] = $event,
|
|
2151
2193
|
type: "number",
|
|
@@ -2167,6 +2209,7 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2167
2209
|
id: `collections-field-${key}`,
|
|
2168
2210
|
"onUpdate:modelValue": ($event) => editing.value.text[key] = $event,
|
|
2169
2211
|
type: __props.render.inputTypeFor(field.type),
|
|
2212
|
+
step: __props.render.stepFor(field.type),
|
|
2170
2213
|
required: isFieldRequiredInUi(field),
|
|
2171
2214
|
disabled: field.primary === true && (editing.value.mode === "edit" || __props.isSingleton),
|
|
2172
2215
|
class: "w-full rounded-xl border border-slate-200 px-3 py-2 text-xs focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none disabled:bg-slate-100 disabled:text-slate-400 font-medium text-slate-700 transition-all",
|
|
@@ -2183,7 +2226,7 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2183
2226
|
key: 1,
|
|
2184
2227
|
class: "text-xs font-medium text-slate-700 break-words",
|
|
2185
2228
|
"data-testid": `collections-detail-value-${key}`
|
|
2186
|
-
}, [field.type === "toggle" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [field.field !== void 0 && String(detailRecord.value[field.field] ?? "") === field.onValue ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_48$1, [_cache[
|
|
2229
|
+
}, [field.type === "toggle" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [field.field !== void 0 && String(detailRecord.value[field.field] ?? "") === field.onValue ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_48$1, [_cache[12] || (_cache[12] = (0, vue.createElementVNode)("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), (0, vue.createTextVNode)(" " + (0, vue.toDisplayString)((0, vue.unref)(t)("common.yes")), 1)])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_49$1, (0, vue.toDisplayString)((0, vue.unref)(t)("common.no")), 1))], 64)) : field.type === "boolean" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 1 }, [detailRecord.value[key] === true ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_50$1, [_cache[13] || (_cache[13] = (0, vue.createElementVNode)("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), (0, vue.createTextVNode)(" " + (0, vue.toDisplayString)((0, vue.unref)(t)("common.yes")), 1)])) : detailRecord.value[key] === false ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_51$1, (0, vue.toDisplayString)((0, vue.unref)(t)("common.no")), 1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_52$1, "—"))], 64)) : field.type === "ref" && field.to && typeof detailRecord.value[key] === "string" && detailRecord.value[key] ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
2187
2230
|
key: 2,
|
|
2188
2231
|
href: (0, vue.unref)(cui).recordHref?.(field.to, String(detailRecord.value[key])),
|
|
2189
2232
|
tabindex: (0, vue.unref)(cui).recordHref?.(field.to, String(detailRecord.value[key])) ? void 0 : 0,
|
|
@@ -2241,7 +2284,22 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2241
2284
|
"data-testid": `collections-detail-file-${key}`,
|
|
2242
2285
|
onClick: ($event) => (0, vue.unref)(activatePathLink)($event, __props.render.fileRoutePath(detailRecord.value[key]) ?? "")
|
|
2243
2286
|
}, (0, vue.toDisplayString)(String(detailRecord.value[key])), 9, _hoisted_67$1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_68$1, (0, vue.toDisplayString)(__props.render.formatCell(detailRecord.value[key], field.type)), 1))], 8, _hoisted_47$1))], 2)) : (0, vue.createCommentVNode)("", true)], 64);
|
|
2244
|
-
}), 128)), editing.value && __props.saveError ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_69$1, (0, vue.toDisplayString)(__props.saveError), 1)) : (0, vue.createCommentVNode)("", true)])
|
|
2287
|
+
}), 128)), editing.value && __props.saveError ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_69$1, (0, vue.toDisplayString)(__props.saveError), 1)) : (0, vue.createCommentVNode)("", true)]),
|
|
2288
|
+
!editing.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_70$1, [(0, vue.createElementVNode)("label", _hoisted_71$1, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.itemChatLabel")), 1), (0, vue.createElementVNode)("div", _hoisted_72$1, [(0, vue.withDirectives)((0, vue.createElementVNode)("textarea", {
|
|
2289
|
+
id: "collections-detail-chat-input",
|
|
2290
|
+
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => chatMessage.value = $event),
|
|
2291
|
+
rows: "2",
|
|
2292
|
+
placeholder: (0, vue.unref)(t)("collectionsView.itemChatPlaceholder"),
|
|
2293
|
+
class: "flex-1 bg-slate-50 border border-slate-200/80 rounded-xl px-3 py-2 text-xs placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 focus:border-indigo-500 focus:bg-white transition-all resize-none",
|
|
2294
|
+
"data-testid": "collections-detail-chat-input",
|
|
2295
|
+
onKeydown: [(0, vue.withKeys)((0, vue.withModifiers)(submitItemChat, ["meta"]), ["enter"]), (0, vue.withKeys)((0, vue.withModifiers)(submitItemChat, ["ctrl"]), ["enter"])]
|
|
2296
|
+
}, null, 40, _hoisted_73$1), [[vue.vModelText, chatMessage.value]]), (0, vue.createElementVNode)("button", {
|
|
2297
|
+
type: "button",
|
|
2298
|
+
class: "h-8 px-2.5 rounded bg-indigo-600 text-white font-bold text-xs hover:bg-indigo-700 disabled:opacity-50 transition-all shadow-sm shadow-indigo-600/10 flex items-center gap-1 shrink-0",
|
|
2299
|
+
disabled: !chatMessage.value.trim(),
|
|
2300
|
+
"data-testid": "collections-detail-chat-send",
|
|
2301
|
+
onClick: submitItemChat
|
|
2302
|
+
}, [_cache[14] || (_cache[14] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "forum", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.chat")), 1)], 8, _hoisted_74$1)])])) : (0, vue.createCommentVNode)("", true)
|
|
2245
2303
|
]),
|
|
2246
2304
|
_: 1
|
|
2247
2305
|
}, 40, ["data-testid"]);
|
|
@@ -2379,12 +2437,15 @@ var CollectionCustomView_vue_vue_type_script_setup_true_lang_default = /* @__PUR
|
|
|
2379
2437
|
slug: {},
|
|
2380
2438
|
view: {}
|
|
2381
2439
|
},
|
|
2382
|
-
|
|
2440
|
+
emits: ["openItem", "startChat"],
|
|
2441
|
+
setup(__props, { emit: __emit }) {
|
|
2383
2442
|
const { t } = useCollectionI18n();
|
|
2384
2443
|
const props = __props;
|
|
2444
|
+
const emit = __emit;
|
|
2385
2445
|
const loading = (0, vue.ref)(true);
|
|
2386
2446
|
const error = (0, vue.ref)(null);
|
|
2387
2447
|
const srcdoc = (0, vue.ref)(null);
|
|
2448
|
+
const iframeEl = (0, vue.ref)(null);
|
|
2388
2449
|
let refreshTimer;
|
|
2389
2450
|
function clearRefresh() {
|
|
2390
2451
|
if (refreshTimer !== void 0) {
|
|
@@ -2433,9 +2494,53 @@ var CollectionCustomView_vue_vue_type_script_setup_true_lang_default = /* @__PUR
|
|
|
2433
2494
|
}
|
|
2434
2495
|
}
|
|
2435
2496
|
(0, vue.watch)([() => props.slug, () => props.view.id], () => void load(), { immediate: true });
|
|
2436
|
-
|
|
2497
|
+
let changeUnsub = null;
|
|
2498
|
+
function relayChange() {
|
|
2499
|
+
iframeEl.value?.contentWindow?.postMessage({
|
|
2500
|
+
type: "mc-collection-changed",
|
|
2501
|
+
slug: props.slug
|
|
2502
|
+
}, "*");
|
|
2503
|
+
}
|
|
2504
|
+
(0, vue.watch)(() => props.slug, (slug) => {
|
|
2505
|
+
changeUnsub?.();
|
|
2506
|
+
changeUnsub = null;
|
|
2507
|
+
const subscribe = collectionUi().subscribeChanges;
|
|
2508
|
+
if (slug && subscribe) changeUnsub = subscribe(slug, relayChange);
|
|
2509
|
+
}, { immediate: true });
|
|
2510
|
+
function handleOpenItem(body) {
|
|
2511
|
+
const itemId = typeof body.id === "string" ? body.id : String(body.id ?? "");
|
|
2512
|
+
if (!itemId) return;
|
|
2513
|
+
emit("openItem", {
|
|
2514
|
+
id: itemId,
|
|
2515
|
+
mode: body.mode === "edit" ? "edit" : "view"
|
|
2516
|
+
});
|
|
2517
|
+
}
|
|
2518
|
+
function handleStartChat(body) {
|
|
2519
|
+
const prompt = typeof body.prompt === "string" ? body.prompt.trim() : "";
|
|
2520
|
+
if (!prompt) return;
|
|
2521
|
+
emit("startChat", {
|
|
2522
|
+
prompt,
|
|
2523
|
+
role: typeof body.role === "string" ? body.role : void 0
|
|
2524
|
+
});
|
|
2525
|
+
}
|
|
2526
|
+
function onWindowMessage(event) {
|
|
2527
|
+
if (event.source !== iframeEl.value?.contentWindow) return;
|
|
2528
|
+
const msg = event.data;
|
|
2529
|
+
if (!msg || msg.slug !== props.slug) return;
|
|
2530
|
+
if (msg.type === "mc-open-item") handleOpenItem(msg);
|
|
2531
|
+
else if (msg.type === "mc-start-chat") handleStartChat(msg);
|
|
2532
|
+
}
|
|
2533
|
+
(0, vue.onMounted)(() => window.addEventListener("message", onWindowMessage));
|
|
2534
|
+
(0, vue.onBeforeUnmount)(() => {
|
|
2535
|
+
clearRefresh();
|
|
2536
|
+
changeUnsub?.();
|
|
2537
|
+
changeUnsub = null;
|
|
2538
|
+
window.removeEventListener("message", onWindowMessage);
|
|
2539
|
+
});
|
|
2437
2540
|
return (_ctx, _cache) => {
|
|
2438
2541
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$5, [error.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2$4, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.customViewError", { error: error.value })), 1)) : loading.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_3$4, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.customViewLoading")), 1)) : srcdoc.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("iframe", {
|
|
2542
|
+
ref_key: "iframeEl",
|
|
2543
|
+
ref: iframeEl,
|
|
2439
2544
|
key: __props.view.id,
|
|
2440
2545
|
"data-testid": "collection-custom-view-iframe",
|
|
2441
2546
|
title: __props.view.label,
|
|
@@ -2455,9 +2560,13 @@ var _plugin_vue_export_helper_default = (sfc, props) => {
|
|
|
2455
2560
|
};
|
|
2456
2561
|
//#endregion
|
|
2457
2562
|
//#region src/vue/components/CollectionCustomView.vue
|
|
2458
|
-
var CollectionCustomView_default = /* @__PURE__ */ _plugin_vue_export_helper_default(CollectionCustomView_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-
|
|
2563
|
+
var CollectionCustomView_default = /* @__PURE__ */ _plugin_vue_export_helper_default(CollectionCustomView_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-d5fb7ca6"]]);
|
|
2459
2564
|
//#endregion
|
|
2460
2565
|
//#region src/vue/useCollectionRendering.ts
|
|
2566
|
+
function stepForFieldType(type) {
|
|
2567
|
+
if (type === "money") return "0.01";
|
|
2568
|
+
if (type === "number") return "any";
|
|
2569
|
+
}
|
|
2461
2570
|
function useCollectionRendering(collection, locale) {
|
|
2462
2571
|
const refCache = (0, vue.ref)({});
|
|
2463
2572
|
const refRecordCache = (0, vue.ref)({});
|
|
@@ -2672,6 +2781,7 @@ function useCollectionRendering(collection, locale) {
|
|
|
2672
2781
|
if (type === "datetime") return "datetime-local";
|
|
2673
2782
|
return "text";
|
|
2674
2783
|
}
|
|
2784
|
+
const stepFor = stepForFieldType;
|
|
2675
2785
|
function evaluateDerivedAgainstItem(field, fieldKey, item) {
|
|
2676
2786
|
if (!field.formula || !collection.value) return null;
|
|
2677
2787
|
const result = require_deriveAll.deriveAll(collection.value.schema, item, refRecordCache.value)[fieldKey];
|
|
@@ -2703,6 +2813,7 @@ function useCollectionRendering(collection, locale) {
|
|
|
2703
2813
|
hasTableRows,
|
|
2704
2814
|
formatSubCell,
|
|
2705
2815
|
inputTypeFor,
|
|
2816
|
+
stepFor,
|
|
2706
2817
|
deriveAll: require_deriveAll.deriveAll,
|
|
2707
2818
|
evaluateDerivedAgainstItem,
|
|
2708
2819
|
derivedDisplay
|
|
@@ -2985,6 +3096,17 @@ var _hoisted_83 = { class: "px-6 py-5" };
|
|
|
2985
3096
|
var _hoisted_84 = ["placeholder", "onKeydown"];
|
|
2986
3097
|
var _hoisted_85 = { class: "px-6 py-3.5 border-t border-slate-100 flex items-center justify-end gap-2 bg-slate-50/50" };
|
|
2987
3098
|
var _hoisted_86 = ["disabled"];
|
|
3099
|
+
/** `slug` / `selected` are supplied only in EMBEDDED mode (the
|
|
3100
|
+
* `presentCollection` chat card mounts this component and drives both
|
|
3101
|
+
* from the tool result). In standalone route mode (the
|
|
3102
|
+
* `/collections/:slug` page) both are undefined and the component reads
|
|
3103
|
+
* `route.params.slug` / `route.query.selected` as before.
|
|
3104
|
+
*
|
|
3105
|
+
* `sendTextMessage` is forwarded ONLY by the chat card — its presence
|
|
3106
|
+
* is our "rendered inside a chat" signal. When set, chat-triggering
|
|
3107
|
+
* actions send into the current session instead of spawning a new
|
|
3108
|
+
* chat (see `runAction` / `submitChat`). */
|
|
3109
|
+
var LIVE_REFRESH_DEBOUNCE_MS = 150;
|
|
2988
3110
|
//#endregion
|
|
2989
3111
|
//#region src/vue/components/CollectionView.vue
|
|
2990
3112
|
var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
@@ -3307,13 +3429,13 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3307
3429
|
* nothing. Instead, point the agent at the feed's schema + records
|
|
3308
3430
|
* (`feeds/<slug>/schema.json` and `<dataPath>/`) and let it act on the
|
|
3309
3431
|
* request directly. */
|
|
3310
|
-
function buildChatSeed(slug, message) {
|
|
3432
|
+
function buildChatSeed(slug, message, itemId) {
|
|
3311
3433
|
const schema = collection.value?.schema;
|
|
3312
|
-
if (!schema?.ingest) return `/${slug} ${message}`;
|
|
3434
|
+
if (!schema?.ingest) return itemId ? `/${slug} id=${itemId} ${message}` : `/${slug} ${message}`;
|
|
3313
3435
|
return t("collectionsView.feedChatSeed", {
|
|
3314
3436
|
slug,
|
|
3315
3437
|
dataPath: schema.dataPath ?? `data/feeds/${slug}`,
|
|
3316
|
-
message
|
|
3438
|
+
message: itemId ? `(for record \`${itemId}\`) ${message}` : message
|
|
3317
3439
|
});
|
|
3318
3440
|
}
|
|
3319
3441
|
/** Start a new general-role chat seeded from the current view. */
|
|
@@ -3329,6 +3451,21 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3329
3451
|
}
|
|
3330
3452
|
appApi.startNewChat(text, cui.generalRoleId);
|
|
3331
3453
|
}
|
|
3454
|
+
/** The open record's chat box: start a chat scoped to that one record. Seeds
|
|
3455
|
+
* the collection's skill command with an `id=<itemId>` selector
|
|
3456
|
+
* (`/<slug> id=<itemId> <message>`) so the agent acts on this record. */
|
|
3457
|
+
function onItemChat(message) {
|
|
3458
|
+
if (!collection.value || !viewing.value) return;
|
|
3459
|
+
const text = message.trim();
|
|
3460
|
+
if (!text) return;
|
|
3461
|
+
const itemId = String(viewing.value[collection.value.schema.primaryKey] ?? "");
|
|
3462
|
+
const seed = buildChatSeed(collection.value.slug, text, itemId || void 0);
|
|
3463
|
+
if (props.sendTextMessage) {
|
|
3464
|
+
props.sendTextMessage(seed);
|
|
3465
|
+
return;
|
|
3466
|
+
}
|
|
3467
|
+
appApi.startNewChat(seed, cui.generalRoleId);
|
|
3468
|
+
}
|
|
3332
3469
|
async function loadCollection(slug) {
|
|
3333
3470
|
const requestedKind = !embedded.value && cui.isFeedRoute() ? "feed" : "collection";
|
|
3334
3471
|
loading.value = true;
|
|
@@ -3358,6 +3495,26 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3358
3495
|
}
|
|
3359
3496
|
maybeAutoRefreshFeed(slug);
|
|
3360
3497
|
}
|
|
3498
|
+
/** Refresh records + schema IN PLACE for a live (pub/sub-driven) update,
|
|
3499
|
+
* preserving the user's browsing state — unlike `loadCollection`, which is the
|
|
3500
|
+
* route-change path and resets it. Specifically: does NOT null `collection`
|
|
3501
|
+
* (so the layout and an active custom-view iframe don't remount), keeps
|
|
3502
|
+
* `searchQuery` / `openDay` / `sortState`, and shows no loading spinner; the
|
|
3503
|
+
* open detail (`viewing`) is re-resolved against the fresh records by id, so it
|
|
3504
|
+
* follows an edited record and closes only if the record was deleted. A failed
|
|
3505
|
+
* fetch is a no-op (keep the current data) — a transient blip shouldn't blank a
|
|
3506
|
+
* view the user is reading. */
|
|
3507
|
+
async function refreshItemsInPlace(slug) {
|
|
3508
|
+
const result = await cui.fetchCollectionDetail(slug);
|
|
3509
|
+
if (!result.ok || activeSlug.value !== slug) return;
|
|
3510
|
+
collection.value = result.data.collection;
|
|
3511
|
+
items.value = result.data.items;
|
|
3512
|
+
dataIssues.value = result.data.issues ?? [];
|
|
3513
|
+
enumOriginallyEmpty.value = snapshotEmptyEnums(result.data.collection.schema, result.data.items);
|
|
3514
|
+
await render.loadLinkedCollections(result.data.collection.schema, slug);
|
|
3515
|
+
if (activeSlug.value !== slug) return;
|
|
3516
|
+
if (viewing.value) viewing.value = findItemById(String(viewing.value[result.data.collection.schema.primaryKey] ?? "")) ?? null;
|
|
3517
|
+
}
|
|
3361
3518
|
function maybeAutoRefreshFeed(slug) {
|
|
3362
3519
|
if (embedded.value) return;
|
|
3363
3520
|
const current = collection.value;
|
|
@@ -3873,6 +4030,30 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3873
4030
|
showDetail(item);
|
|
3874
4031
|
writeSelectedToUrl(itemId);
|
|
3875
4032
|
}
|
|
4033
|
+
/** A custom (sandboxed) view asked to open a record in the shared modal.
|
|
4034
|
+
* `view` → read-only detail, `edit` → straight into the editor. Ungated: the
|
|
4035
|
+
* capability token governs the view's *code*, not user actions through the
|
|
4036
|
+
* host's own trusted modal (no write happens without an explicit Save). */
|
|
4037
|
+
function onCustomViewOpenItem(payload) {
|
|
4038
|
+
const item = findItemById(payload.id);
|
|
4039
|
+
if (!item) return;
|
|
4040
|
+
if (editing.value) closeEditor();
|
|
4041
|
+
if (payload.mode === "edit") {
|
|
4042
|
+
openEdit(item);
|
|
4043
|
+
return;
|
|
4044
|
+
}
|
|
4045
|
+
showDetail(item);
|
|
4046
|
+
writeSelectedToUrl(payload.id);
|
|
4047
|
+
}
|
|
4048
|
+
/** The custom view called `__MC_VIEW.startChat(prompt, role)` — open a new chat
|
|
4049
|
+
* with the prompt prefilled as an editable draft. The host validates `role`
|
|
4050
|
+
* (falls back to General). The view's code only proposes text; the user
|
|
4051
|
+
* approves / edits / sends, so no capability is required. */
|
|
4052
|
+
function onCustomViewStartChat(payload) {
|
|
4053
|
+
const prompt = payload.prompt.trim();
|
|
4054
|
+
if (!prompt) return;
|
|
4055
|
+
cui.startNewChatDraft(prompt, payload.role);
|
|
4056
|
+
}
|
|
3876
4057
|
/** A calendar day cell was activated → open its popup on a clean slate
|
|
3877
4058
|
* (clear any prior selection so the popup opens timeline-only). */
|
|
3878
4059
|
function onOpenDay(day) {
|
|
@@ -3928,6 +4109,42 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3928
4109
|
loading.value = false;
|
|
3929
4110
|
}
|
|
3930
4111
|
}, { immediate: true });
|
|
4112
|
+
let changeUnsub = null;
|
|
4113
|
+
let liveRefreshTimer;
|
|
4114
|
+
let pendingRemoteRefresh = false;
|
|
4115
|
+
function clearLiveRefreshTimer() {
|
|
4116
|
+
if (liveRefreshTimer !== void 0) {
|
|
4117
|
+
clearTimeout(liveRefreshTimer);
|
|
4118
|
+
liveRefreshTimer = void 0;
|
|
4119
|
+
}
|
|
4120
|
+
}
|
|
4121
|
+
function onRemoteChange(slug) {
|
|
4122
|
+
clearLiveRefreshTimer();
|
|
4123
|
+
liveRefreshTimer = setTimeout(() => {
|
|
4124
|
+
liveRefreshTimer = void 0;
|
|
4125
|
+
if (editing.value) {
|
|
4126
|
+
pendingRemoteRefresh = true;
|
|
4127
|
+
return;
|
|
4128
|
+
}
|
|
4129
|
+
if (activeSlug.value === slug) refreshItemsInPlace(slug);
|
|
4130
|
+
}, LIVE_REFRESH_DEBOUNCE_MS);
|
|
4131
|
+
}
|
|
4132
|
+
(0, vue.watch)(editing, (current) => {
|
|
4133
|
+
if (current || !pendingRemoteRefresh) return;
|
|
4134
|
+
pendingRemoteRefresh = false;
|
|
4135
|
+
if (activeSlug.value) refreshItemsInPlace(activeSlug.value);
|
|
4136
|
+
});
|
|
4137
|
+
(0, vue.watch)(activeSlug, (slug) => {
|
|
4138
|
+
changeUnsub?.();
|
|
4139
|
+
changeUnsub = null;
|
|
4140
|
+
clearLiveRefreshTimer();
|
|
4141
|
+
if (slug && cui.subscribeChanges) changeUnsub = cui.subscribeChanges(slug, () => onRemoteChange(slug));
|
|
4142
|
+
}, { immediate: true });
|
|
4143
|
+
(0, vue.onUnmounted)(() => {
|
|
4144
|
+
changeUnsub?.();
|
|
4145
|
+
changeUnsub = null;
|
|
4146
|
+
clearLiveRefreshTimer();
|
|
4147
|
+
});
|
|
3931
4148
|
(0, vue.watch)([
|
|
3932
4149
|
activeView,
|
|
3933
4150
|
calendarAnchorField,
|
|
@@ -4198,7 +4415,8 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4198
4415
|
onEdit: editFromView,
|
|
4199
4416
|
onClose: onDayClose,
|
|
4200
4417
|
onDelete: _cache[9] || (_cache[9] = ($event) => viewing.value && confirmDelete(viewing.value)),
|
|
4201
|
-
onRunAction: runAction
|
|
4418
|
+
onRunAction: runAction,
|
|
4419
|
+
onItemChat
|
|
4202
4420
|
}, null, 8, [
|
|
4203
4421
|
"editing",
|
|
4204
4422
|
"collection",
|
|
@@ -4252,7 +4470,9 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4252
4470
|
"notified"
|
|
4253
4471
|
])])])) : activeCustomView.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_45, [(0, vue.createVNode)(CollectionCustomView_default, {
|
|
4254
4472
|
slug: collection.value.slug,
|
|
4255
|
-
view: activeCustomView.value
|
|
4473
|
+
view: activeCustomView.value,
|
|
4474
|
+
onOpenItem: onCustomViewOpenItem,
|
|
4475
|
+
onStartChat: onCustomViewStartChat
|
|
4256
4476
|
}, null, 8, ["slug", "view"])])) : items.value.length === 0 && editing.value?.mode !== "create" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_46, [_cache[41] || (_cache[41] = (0, vue.createElementVNode)("span", { class: "material-icons text-4xl text-slate-300" }, "folder_open", -1)), (0, vue.createElementVNode)("p", _hoisted_47, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.itemsEmpty")), 1)])) : filteredItems.value.length === 0 && editing.value?.mode !== "create" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_48, [
|
|
4257
4477
|
_cache[42] || (_cache[42] = (0, vue.createElementVNode)("span", { class: "material-icons text-4xl text-slate-300" }, "search_off", -1)),
|
|
4258
4478
|
(0, vue.createElementVNode)("p", _hoisted_49, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.noMatchingItems")), 1),
|
|
@@ -4394,7 +4614,8 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4394
4614
|
onEdit: editFromView,
|
|
4395
4615
|
onClose: closeView,
|
|
4396
4616
|
onDelete: _cache[20] || (_cache[20] = ($event) => viewing.value && confirmDelete(viewing.value)),
|
|
4397
|
-
onRunAction: runAction
|
|
4617
|
+
onRunAction: runAction,
|
|
4618
|
+
onItemChat
|
|
4398
4619
|
}, null, 8, [
|
|
4399
4620
|
"editing",
|
|
4400
4621
|
"collection",
|