@mulmoclaude/collection-plugin 0.4.1 → 0.5.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/index.cjs +4 -47
- package/dist/index.js +1 -44
- package/dist/{promptSafety-BSO2gdsg.cjs → promptSafety-B0pPJkfQ.cjs} +60 -1
- package/dist/promptSafety-B0pPJkfQ.cjs.map +1 -0
- package/dist/{promptSafety-DShN_VCG.js → promptSafety-DIQ2yDca.js} +43 -2
- package/dist/promptSafety-DIQ2yDca.js.map +1 -0
- package/dist/style.css +102 -0
- package/dist/vue/chat/Preview.vue.d.ts +8 -0
- package/dist/vue/chat/Preview.vue.d.ts.map +1 -0
- package/dist/vue/chat/View.vue.d.ts +16 -0
- package/dist/vue/chat/View.vue.d.ts.map +1 -0
- package/dist/vue/components/CollectionEmbedView.vue.d.ts.map +1 -1
- package/dist/vue/components/CollectionRecordModal.vue.d.ts.map +1 -1
- 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/index.d.ts +6 -0
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/lang/de.d.ts.map +1 -1
- package/dist/vue/lang/en.d.ts +5 -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 +5 -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 +18 -0
- package/dist/vue/uiContext.d.ts.map +1 -1
- package/dist/vue.cjs +882 -710
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +881 -712
- package/dist/vue.js.map +1 -1
- package/package.json +1 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/promptSafety-BSO2gdsg.cjs.map +0 -1
- package/dist/promptSafety-DShN_VCG.js.map +0 -1
package/dist/vue.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as buildUpdatedRecord, C as dateSortValue, D as numericSortValue, E as nextSortDirection, F as rowFromItem, I as actionVisible, L as fieldVisible, M as draftToRecord, N as emptyRow, O as sortItems, P as firstMissingRequiredField, T as isSortableField, W as resolveEnumColor, _ as ymdKey, a as assignLanes, b as labelFieldFor, i as MINUTES_PER_DAY, j as coerceInlineValue, k as stringSortValue, l as dateOf, n as shortHexId, o as bucketRecords, r as errorMessage, s as buildMonthGrid, t as defangForPrompt, u as daySlice, v as itemIdOf, w as enumSortValue, x as boolSortValue, y as itemLabelOf } from "./promptSafety-
|
|
1
|
+
import { A as buildUpdatedRecord, C as dateSortValue, D as numericSortValue, E as nextSortDirection, F as rowFromItem, G as TOOL_DEFINITION, I as actionVisible, L as fieldVisible, M as draftToRecord, N as emptyRow, O as sortItems, P as firstMissingRequiredField, T as isSortableField, W as resolveEnumColor, _ as ymdKey, a as assignLanes, b as labelFieldFor, i as MINUTES_PER_DAY, j as coerceInlineValue, k as stringSortValue, l as dateOf, n as shortHexId, o as bucketRecords, q as executePresentCollection, r as errorMessage, s as buildMonthGrid, t as defangForPrompt, u as daySlice, v as itemIdOf, w as enumSortValue, x as boolSortValue, y as itemLabelOf } from "./promptSafety-DIQ2yDca.js";
|
|
2
2
|
import { t as deriveAll } from "./deriveAll-BHcs1erT.js";
|
|
3
|
-
import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, effectScope, mergeModels, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, renderSlot,
|
|
3
|
+
import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, effectScope, mergeModels, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useModel, vModelCheckbox, vModelDynamic, vModelSelect, vModelText, watch, watchEffect, withCtx, withDirectives, withKeys, withModifiers } from "vue";
|
|
4
4
|
import { createI18n } from "vue-i18n";
|
|
5
5
|
import draggable from "vuedraggable";
|
|
6
6
|
//#region src/vue/uiContext.ts
|
|
@@ -14,395 +14,6 @@ function collectionUi() {
|
|
|
14
14
|
return current;
|
|
15
15
|
}
|
|
16
16
|
//#endregion
|
|
17
|
-
//#region src/vue/useCollectionRendering.ts
|
|
18
|
-
function useCollectionRendering(collection, locale) {
|
|
19
|
-
const refCache = ref({});
|
|
20
|
-
const refRecordCache = ref({});
|
|
21
|
-
const embedCache = ref({});
|
|
22
|
-
function resetLinkedCaches() {
|
|
23
|
-
refCache.value = {};
|
|
24
|
-
refRecordCache.value = {};
|
|
25
|
-
embedCache.value = {};
|
|
26
|
-
}
|
|
27
|
-
function uniqueRefTargets(schema) {
|
|
28
|
-
const targets = /* @__PURE__ */ new Set();
|
|
29
|
-
const walk = (fields) => {
|
|
30
|
-
for (const field of Object.values(fields)) {
|
|
31
|
-
if (field.type === "ref" && typeof field.to === "string" && field.to.length > 0) targets.add(field.to);
|
|
32
|
-
if (field.type === "table" && field.of) walk(field.of);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
walk(schema.fields);
|
|
36
|
-
return [...targets];
|
|
37
|
-
}
|
|
38
|
-
function uniqueEmbedTargets(schema) {
|
|
39
|
-
const targets = /* @__PURE__ */ new Set();
|
|
40
|
-
for (const field of Object.values(schema.fields)) if (field.type === "embed" && typeof field.to === "string" && field.to.length > 0) targets.add(field.to);
|
|
41
|
-
return [...targets];
|
|
42
|
-
}
|
|
43
|
-
function buildRefDisplayMap(detail) {
|
|
44
|
-
const { fields, primaryKey } = detail.collection.schema;
|
|
45
|
-
const displayField = "name" in fields ? "name" : "title" in fields ? "title" : primaryKey;
|
|
46
|
-
const map = {};
|
|
47
|
-
for (const item of detail.items) {
|
|
48
|
-
const slugRaw = item[primaryKey];
|
|
49
|
-
if (typeof slugRaw !== "string" || slugRaw.length === 0) continue;
|
|
50
|
-
const displayRaw = item[displayField];
|
|
51
|
-
map[slugRaw] = typeof displayRaw === "string" && displayRaw.length > 0 ? displayRaw : slugRaw;
|
|
52
|
-
}
|
|
53
|
-
return map;
|
|
54
|
-
}
|
|
55
|
-
function buildRefRecordMap(detail) {
|
|
56
|
-
const { schema } = detail.collection;
|
|
57
|
-
const map = {};
|
|
58
|
-
for (const item of detail.items) {
|
|
59
|
-
const slugRaw = item[schema.primaryKey];
|
|
60
|
-
if (typeof slugRaw === "string" && slugRaw.length > 0) map[slugRaw] = deriveAll(schema, item, {});
|
|
61
|
-
}
|
|
62
|
-
return map;
|
|
63
|
-
}
|
|
64
|
-
async function loadLinkedCollections(schema, expectedSlug) {
|
|
65
|
-
const refTargets = new Set(uniqueRefTargets(schema));
|
|
66
|
-
const embedTargets = new Set(uniqueEmbedTargets(schema));
|
|
67
|
-
const allTargets = [...new Set([...refTargets, ...embedTargets])];
|
|
68
|
-
if (allTargets.length === 0) return;
|
|
69
|
-
const binding = collectionUi();
|
|
70
|
-
const results = await Promise.all(allTargets.map(async (target) => {
|
|
71
|
-
try {
|
|
72
|
-
return {
|
|
73
|
-
target,
|
|
74
|
-
result: await binding.fetchCollectionDetail(target)
|
|
75
|
-
};
|
|
76
|
-
} catch {
|
|
77
|
-
return {
|
|
78
|
-
target,
|
|
79
|
-
result: { ok: false }
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
}));
|
|
83
|
-
if (collection.value?.slug !== expectedSlug) return;
|
|
84
|
-
const nextRef = {};
|
|
85
|
-
const nextRefRecords = {};
|
|
86
|
-
const nextEmbed = {};
|
|
87
|
-
for (const { target, result } of results) {
|
|
88
|
-
if (!result.ok) continue;
|
|
89
|
-
if (refTargets.has(target)) {
|
|
90
|
-
nextRef[target] = buildRefDisplayMap(result.data);
|
|
91
|
-
nextRefRecords[target] = buildRefRecordMap(result.data);
|
|
92
|
-
}
|
|
93
|
-
if (embedTargets.has(target)) nextEmbed[target] = {
|
|
94
|
-
schema: result.data.collection.schema,
|
|
95
|
-
items: result.data.items
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
refCache.value = nextRef;
|
|
99
|
-
refRecordCache.value = nextRefRecords;
|
|
100
|
-
embedCache.value = nextEmbed;
|
|
101
|
-
}
|
|
102
|
-
function refDisplay(targetSlug, itemSlug) {
|
|
103
|
-
const map = refCache.value[targetSlug];
|
|
104
|
-
return map && map[itemSlug] || itemSlug;
|
|
105
|
-
}
|
|
106
|
-
function refOptions(targetSlug) {
|
|
107
|
-
const map = refCache.value[targetSlug];
|
|
108
|
-
if (!map) return [];
|
|
109
|
-
return Object.entries(map).map(([slug, display]) => ({
|
|
110
|
-
slug,
|
|
111
|
-
display
|
|
112
|
-
})).sort((left, right) => left.display.localeCompare(right.display));
|
|
113
|
-
}
|
|
114
|
-
function resolveEmbed(field) {
|
|
115
|
-
if (field.type !== "embed" || !field.to || !field.id) return {
|
|
116
|
-
schema: null,
|
|
117
|
-
item: null
|
|
118
|
-
};
|
|
119
|
-
const data = embedCache.value[field.to];
|
|
120
|
-
if (!data) return {
|
|
121
|
-
schema: null,
|
|
122
|
-
item: null
|
|
123
|
-
};
|
|
124
|
-
const item = data.items.find((entry) => String(entry[data.schema.primaryKey] ?? "") === field.id) ?? null;
|
|
125
|
-
return {
|
|
126
|
-
schema: data.schema,
|
|
127
|
-
item
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
function embedValue(field, value, record) {
|
|
131
|
-
if (field.type === "money") return formatMoney(value, resolveCurrency(field, record), locale.value);
|
|
132
|
-
return detailText(value);
|
|
133
|
-
}
|
|
134
|
-
const embedViews = computed(() => {
|
|
135
|
-
const out = {};
|
|
136
|
-
if (!collection.value) return out;
|
|
137
|
-
for (const [key, field] of Object.entries(collection.value.schema.fields)) {
|
|
138
|
-
if (field.type !== "embed") continue;
|
|
139
|
-
const { schema, item } = resolveEmbed(field);
|
|
140
|
-
const rows = [];
|
|
141
|
-
if (schema && item) for (const [subKey, subField] of Object.entries(schema.fields)) {
|
|
142
|
-
const value = item[subKey];
|
|
143
|
-
if (value === void 0 || value === null || value === "") continue;
|
|
144
|
-
rows.push({
|
|
145
|
-
key: subKey,
|
|
146
|
-
label: subField.label,
|
|
147
|
-
type: subField.type,
|
|
148
|
-
value,
|
|
149
|
-
display: embedValue(subField, value, item)
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
out[key] = {
|
|
153
|
-
found: Boolean(item),
|
|
154
|
-
rows,
|
|
155
|
-
targetSlug: field.to ?? "",
|
|
156
|
-
recordId: field.id ?? ""
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
return out;
|
|
160
|
-
});
|
|
161
|
-
function resolveCurrency(field, record) {
|
|
162
|
-
if (field.currencyField && record) {
|
|
163
|
-
const code = record[field.currencyField];
|
|
164
|
-
if (typeof code === "string" && code.trim().length > 0) return code;
|
|
165
|
-
}
|
|
166
|
-
return field.currency;
|
|
167
|
-
}
|
|
168
|
-
function currencySymbol(currency) {
|
|
169
|
-
const code = currency && currency.length > 0 ? currency : "USD";
|
|
170
|
-
try {
|
|
171
|
-
return new Intl.NumberFormat(locale.value, {
|
|
172
|
-
style: "currency",
|
|
173
|
-
currency: code
|
|
174
|
-
}).formatToParts(0).find((entry) => entry.type === "currency")?.value ?? code;
|
|
175
|
-
} catch {
|
|
176
|
-
return code;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
function formatMoney(value, currency, displayLocale) {
|
|
180
|
-
if (value === void 0 || value === "") return "—";
|
|
181
|
-
const amount = typeof value === "number" ? value : Number(value);
|
|
182
|
-
if (!Number.isFinite(amount)) return String(value);
|
|
183
|
-
const currencyCode = currency && currency.length > 0 ? currency : "USD";
|
|
184
|
-
try {
|
|
185
|
-
return new Intl.NumberFormat(displayLocale, {
|
|
186
|
-
style: "currency",
|
|
187
|
-
currency: currencyCode
|
|
188
|
-
}).format(amount);
|
|
189
|
-
} catch {
|
|
190
|
-
return String(amount);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
function formatCell(value, type) {
|
|
194
|
-
if (value === void 0 || value === null || value === "") return "—";
|
|
195
|
-
if (type === "markdown" && typeof value === "string") return value.length > 80 ? `${value.slice(0, 80)}…` : value;
|
|
196
|
-
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
197
|
-
return JSON.stringify(value);
|
|
198
|
-
}
|
|
199
|
-
function isExternalUrl(value) {
|
|
200
|
-
return typeof value === "string" && /^https?:\/\//i.test(value);
|
|
201
|
-
}
|
|
202
|
-
function artifactUrl(value) {
|
|
203
|
-
return collectionUi().fileAssetUrl(value);
|
|
204
|
-
}
|
|
205
|
-
function fileRoutePath(value) {
|
|
206
|
-
return collectionUi().fileRoutePath(value);
|
|
207
|
-
}
|
|
208
|
-
function detailText(value) {
|
|
209
|
-
if (value === void 0 || value === null || value === "") return "—";
|
|
210
|
-
return String(value);
|
|
211
|
-
}
|
|
212
|
-
function tableRows(value) {
|
|
213
|
-
if (!Array.isArray(value)) return [];
|
|
214
|
-
return value.filter((row) => Boolean(row) && typeof row === "object" && !Array.isArray(row));
|
|
215
|
-
}
|
|
216
|
-
function hasTableRows(value) {
|
|
217
|
-
return tableRows(value).length > 0;
|
|
218
|
-
}
|
|
219
|
-
function formatSubCell(subField, value, record) {
|
|
220
|
-
if (subField.type === "money") return formatMoney(value, resolveCurrency(subField, record), locale.value);
|
|
221
|
-
if (subField.type === "ref" && subField.to && typeof value === "string" && value.length > 0) return refDisplay(subField.to, value);
|
|
222
|
-
return formatCell(value, subField.type);
|
|
223
|
-
}
|
|
224
|
-
function inputTypeFor(type) {
|
|
225
|
-
if (type === "email") return "email";
|
|
226
|
-
if (type === "number") return "number";
|
|
227
|
-
if (type === "money") return "number";
|
|
228
|
-
if (type === "date") return "date";
|
|
229
|
-
if (type === "datetime") return "datetime-local";
|
|
230
|
-
return "text";
|
|
231
|
-
}
|
|
232
|
-
function evaluateDerivedAgainstItem(field, fieldKey, item) {
|
|
233
|
-
if (!field.formula || !collection.value) return null;
|
|
234
|
-
const result = deriveAll(collection.value.schema, item, refRecordCache.value)[fieldKey];
|
|
235
|
-
return typeof result === "number" && Number.isFinite(result) ? result : null;
|
|
236
|
-
}
|
|
237
|
-
function derivedDisplay(field, computedValue, record) {
|
|
238
|
-
if (computedValue === null || computedValue === void 0) return "—";
|
|
239
|
-
if (field.display === "money") return formatMoney(computedValue, resolveCurrency(field, record), locale.value);
|
|
240
|
-
return formatCell(computedValue, field.display ?? "number");
|
|
241
|
-
}
|
|
242
|
-
return {
|
|
243
|
-
refCache,
|
|
244
|
-
refRecordCache,
|
|
245
|
-
embedCache,
|
|
246
|
-
resetLinkedCaches,
|
|
247
|
-
loadLinkedCollections,
|
|
248
|
-
refDisplay,
|
|
249
|
-
refOptions,
|
|
250
|
-
embedViews,
|
|
251
|
-
resolveCurrency,
|
|
252
|
-
currencySymbol,
|
|
253
|
-
formatMoney,
|
|
254
|
-
formatCell,
|
|
255
|
-
detailText,
|
|
256
|
-
isExternalUrl,
|
|
257
|
-
artifactUrl,
|
|
258
|
-
fileRoutePath,
|
|
259
|
-
tableRows,
|
|
260
|
-
hasTableRows,
|
|
261
|
-
formatSubCell,
|
|
262
|
-
inputTypeFor,
|
|
263
|
-
deriveAll,
|
|
264
|
-
evaluateDerivedAgainstItem,
|
|
265
|
-
derivedDisplay
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
//#endregion
|
|
269
|
-
//#region src/vue/collectionViewMode.ts
|
|
270
|
-
var STORAGE_KEY = "collection_view_modes";
|
|
271
|
-
var SORT_STORAGE_KEY = "collection_sorts";
|
|
272
|
-
var BUILT_IN_MODES = [
|
|
273
|
-
"table",
|
|
274
|
-
"calendar",
|
|
275
|
-
"kanban"
|
|
276
|
-
];
|
|
277
|
-
/** A persisted mode is valid if it's a known built-in OR any `custom:<id>`
|
|
278
|
-
* key (the id is validated against the live schema at render time, so an
|
|
279
|
-
* unknown custom id simply collapses to the table there). Takes `unknown`
|
|
280
|
-
* and type-guards `string` first: a corrupted localStorage entry could hold a
|
|
281
|
-
* number/object, and calling `.startsWith` on that would throw. */
|
|
282
|
-
function isValidViewMode(value) {
|
|
283
|
-
return typeof value === "string" && (BUILT_IN_MODES.includes(value) || value.startsWith("custom:"));
|
|
284
|
-
}
|
|
285
|
-
function readAll() {
|
|
286
|
-
try {
|
|
287
|
-
const raw = localStorage.getItem(STORAGE_KEY);
|
|
288
|
-
if (!raw) return {};
|
|
289
|
-
const parsed = JSON.parse(raw);
|
|
290
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
291
|
-
} catch {
|
|
292
|
-
return {};
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
function readCollectionViewMode(slug) {
|
|
296
|
-
const stored = readAll()[slug];
|
|
297
|
-
return isValidViewMode(stored) ? stored : null;
|
|
298
|
-
}
|
|
299
|
-
function writeCollectionViewMode(slug, view) {
|
|
300
|
-
try {
|
|
301
|
-
const all = readAll();
|
|
302
|
-
all[slug] = view;
|
|
303
|
-
localStorage.setItem(STORAGE_KEY, JSON.stringify(all));
|
|
304
|
-
} catch {}
|
|
305
|
-
}
|
|
306
|
-
function isSortState(value) {
|
|
307
|
-
if (!value || typeof value !== "object") return false;
|
|
308
|
-
const rec = value;
|
|
309
|
-
return typeof rec.field === "string" && (rec.direction === "asc" || rec.direction === "desc");
|
|
310
|
-
}
|
|
311
|
-
function readAllSorts() {
|
|
312
|
-
try {
|
|
313
|
-
const raw = localStorage.getItem(SORT_STORAGE_KEY);
|
|
314
|
-
if (!raw) return {};
|
|
315
|
-
const parsed = JSON.parse(raw);
|
|
316
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
317
|
-
const out = {};
|
|
318
|
-
for (const [slug, value] of Object.entries(parsed)) if (isSortState(value)) out[slug] = value;
|
|
319
|
-
return out;
|
|
320
|
-
} catch {
|
|
321
|
-
return {};
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
function readCollectionSort(slug) {
|
|
325
|
-
return readAllSorts()[slug] ?? null;
|
|
326
|
-
}
|
|
327
|
-
/** Persist (or, when `sort` is null, clear) the slug's active column sort. */
|
|
328
|
-
function writeCollectionSort(slug, sort) {
|
|
329
|
-
try {
|
|
330
|
-
const all = Object.fromEntries(Object.entries(readAllSorts()).filter(([key]) => key !== slug));
|
|
331
|
-
if (sort) all[slug] = sort;
|
|
332
|
-
localStorage.setItem(SORT_STORAGE_KEY, JSON.stringify(all));
|
|
333
|
-
} catch {}
|
|
334
|
-
}
|
|
335
|
-
//#endregion
|
|
336
|
-
//#region src/vue/components/CollectionRecordModal.vue
|
|
337
|
-
var CollectionRecordModal_default = /* @__PURE__ */ defineComponent({
|
|
338
|
-
__name: "CollectionRecordModal",
|
|
339
|
-
emits: ["close"],
|
|
340
|
-
setup(__props, { emit: __emit }) {
|
|
341
|
-
const emit = __emit;
|
|
342
|
-
const dialogEl = ref(null);
|
|
343
|
-
let previouslyFocused = null;
|
|
344
|
-
const FOCUSABLE_SELECTOR = [
|
|
345
|
-
"a[href]",
|
|
346
|
-
"button:not([disabled])",
|
|
347
|
-
"input:not([disabled])",
|
|
348
|
-
"select:not([disabled])",
|
|
349
|
-
"textarea:not([disabled])",
|
|
350
|
-
"[tabindex]:not([tabindex=\"-1\"])"
|
|
351
|
-
].join(",");
|
|
352
|
-
/** Visible, focusable controls inside the dialog, in DOM order. */
|
|
353
|
-
function focusableItems() {
|
|
354
|
-
if (!dialogEl.value) return [];
|
|
355
|
-
return Array.from(dialogEl.value.querySelectorAll(FOCUSABLE_SELECTOR)).filter((node) => node.offsetParent !== null);
|
|
356
|
-
}
|
|
357
|
-
/** Trap Tab / Shift+Tab inside the dialog so focus can't escape to the
|
|
358
|
-
* page behind the overlay. Wraps at both ends; the dialog container
|
|
359
|
-
* itself (tabindex -1) counts as "before the first item". */
|
|
360
|
-
function onTab(event) {
|
|
361
|
-
const items = focusableItems();
|
|
362
|
-
if (items.length === 0) {
|
|
363
|
-
event.preventDefault();
|
|
364
|
-
dialogEl.value?.focus();
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
const [first] = items;
|
|
368
|
-
const last = items[items.length - 1];
|
|
369
|
-
const active = document.activeElement;
|
|
370
|
-
if (event.shiftKey) {
|
|
371
|
-
if (active === first || active === dialogEl.value) {
|
|
372
|
-
event.preventDefault();
|
|
373
|
-
last.focus();
|
|
374
|
-
}
|
|
375
|
-
} else if (active === last) {
|
|
376
|
-
event.preventDefault();
|
|
377
|
-
first.focus();
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
onMounted(async () => {
|
|
381
|
-
previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
382
|
-
await nextTick();
|
|
383
|
-
dialogEl.value?.focus();
|
|
384
|
-
});
|
|
385
|
-
onBeforeUnmount(() => {
|
|
386
|
-
previouslyFocused?.focus?.();
|
|
387
|
-
});
|
|
388
|
-
return (_ctx, _cache) => {
|
|
389
|
-
return openBlock(), createBlock(Teleport, { to: "body" }, [createElementVNode("div", {
|
|
390
|
-
class: "fixed inset-0 z-40 flex items-center justify-center bg-slate-900/40 p-4",
|
|
391
|
-
"data-testid": "collections-record-modal",
|
|
392
|
-
onClick: _cache[1] || (_cache[1] = withModifiers(($event) => emit("close"), ["self"]))
|
|
393
|
-
}, [createElementVNode("div", {
|
|
394
|
-
ref_key: "dialogEl",
|
|
395
|
-
ref: dialogEl,
|
|
396
|
-
class: "flex max-h-[85vh] w-full max-w-2xl flex-col overflow-hidden rounded-2xl bg-white shadow-xl focus:outline-none",
|
|
397
|
-
role: "dialog",
|
|
398
|
-
"aria-modal": "true",
|
|
399
|
-
tabindex: "-1",
|
|
400
|
-
onKeydown: [_cache[0] || (_cache[0] = withKeys(($event) => emit("close"), ["esc"])), withKeys(onTab, ["tab"])]
|
|
401
|
-
}, [renderSlot(_ctx.$slots, "default")], 544)])]);
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
});
|
|
405
|
-
//#endregion
|
|
406
17
|
//#region src/vue/lang/index.ts
|
|
407
18
|
var i18n = createI18n({
|
|
408
19
|
legacy: false,
|
|
@@ -503,6 +114,11 @@ var i18n = createI18n({
|
|
|
503
114
|
save: "Save",
|
|
504
115
|
saving: "Saving...",
|
|
505
116
|
yes: "Yes"
|
|
117
|
+
},
|
|
118
|
+
pluginPresentCollection: {
|
|
119
|
+
fallbackTitle: "Collection",
|
|
120
|
+
itemLabel: "Item: {id}",
|
|
121
|
+
listLabel: "All records"
|
|
506
122
|
}
|
|
507
123
|
},
|
|
508
124
|
ja: {
|
|
@@ -599,6 +215,11 @@ var i18n = createI18n({
|
|
|
599
215
|
save: "保存",
|
|
600
216
|
saving: "保存中...",
|
|
601
217
|
yes: "はい"
|
|
218
|
+
},
|
|
219
|
+
pluginPresentCollection: {
|
|
220
|
+
fallbackTitle: "コレクション",
|
|
221
|
+
itemLabel: "項目: {id}",
|
|
222
|
+
listLabel: "すべてのレコード"
|
|
602
223
|
}
|
|
603
224
|
},
|
|
604
225
|
zh: {
|
|
@@ -695,6 +316,11 @@ var i18n = createI18n({
|
|
|
695
316
|
save: "保存",
|
|
696
317
|
saving: "保存中...",
|
|
697
318
|
yes: "是"
|
|
319
|
+
},
|
|
320
|
+
pluginPresentCollection: {
|
|
321
|
+
fallbackTitle: "集合",
|
|
322
|
+
itemLabel: "项目:{id}",
|
|
323
|
+
listLabel: "全部记录"
|
|
698
324
|
}
|
|
699
325
|
},
|
|
700
326
|
ko: {
|
|
@@ -791,6 +417,11 @@ var i18n = createI18n({
|
|
|
791
417
|
save: "저장",
|
|
792
418
|
saving: "저장 중...",
|
|
793
419
|
yes: "예"
|
|
420
|
+
},
|
|
421
|
+
pluginPresentCollection: {
|
|
422
|
+
fallbackTitle: "컬렉션",
|
|
423
|
+
itemLabel: "항목: {id}",
|
|
424
|
+
listLabel: "모든 레코드"
|
|
794
425
|
}
|
|
795
426
|
},
|
|
796
427
|
es: {
|
|
@@ -887,6 +518,11 @@ var i18n = createI18n({
|
|
|
887
518
|
save: "Guardar",
|
|
888
519
|
saving: "Guardando...",
|
|
889
520
|
yes: "Sí"
|
|
521
|
+
},
|
|
522
|
+
pluginPresentCollection: {
|
|
523
|
+
fallbackTitle: "Colección",
|
|
524
|
+
itemLabel: "Elemento: {id}",
|
|
525
|
+
listLabel: "Todos los registros"
|
|
890
526
|
}
|
|
891
527
|
},
|
|
892
528
|
"pt-BR": {
|
|
@@ -983,6 +619,11 @@ var i18n = createI18n({
|
|
|
983
619
|
save: "Salvar",
|
|
984
620
|
saving: "Salvando...",
|
|
985
621
|
yes: "Sim"
|
|
622
|
+
},
|
|
623
|
+
pluginPresentCollection: {
|
|
624
|
+
fallbackTitle: "Coleção",
|
|
625
|
+
itemLabel: "Item: {id}",
|
|
626
|
+
listLabel: "Todos os registros"
|
|
986
627
|
}
|
|
987
628
|
},
|
|
988
629
|
fr: {
|
|
@@ -1079,6 +720,11 @@ var i18n = createI18n({
|
|
|
1079
720
|
save: "Enregistrer",
|
|
1080
721
|
saving: "Enregistrement...",
|
|
1081
722
|
yes: "Oui"
|
|
723
|
+
},
|
|
724
|
+
pluginPresentCollection: {
|
|
725
|
+
fallbackTitle: "Collection",
|
|
726
|
+
itemLabel: "Élément : {id}",
|
|
727
|
+
listLabel: "Tous les enregistrements"
|
|
1082
728
|
}
|
|
1083
729
|
},
|
|
1084
730
|
de: {
|
|
@@ -1175,6 +821,11 @@ var i18n = createI18n({
|
|
|
1175
821
|
save: "Speichern",
|
|
1176
822
|
saving: "Wird gespeichert...",
|
|
1177
823
|
yes: "Ja"
|
|
824
|
+
},
|
|
825
|
+
pluginPresentCollection: {
|
|
826
|
+
fallbackTitle: "Sammlung",
|
|
827
|
+
itemLabel: "Eintrag: {id}",
|
|
828
|
+
listLabel: "Alle Datensätze"
|
|
1178
829
|
}
|
|
1179
830
|
}
|
|
1180
831
|
}
|
|
@@ -1206,121 +857,106 @@ function useCollectionI18n() {
|
|
|
1206
857
|
};
|
|
1207
858
|
}
|
|
1208
859
|
//#endregion
|
|
1209
|
-
//#region src/vue/components/
|
|
1210
|
-
var
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
860
|
+
//#region src/vue/components/CollectionRecordModal.vue
|
|
861
|
+
var CollectionRecordModal_default = /* @__PURE__ */ defineComponent({
|
|
862
|
+
__name: "CollectionRecordModal",
|
|
863
|
+
emits: ["close"],
|
|
864
|
+
setup(__props, { emit: __emit }) {
|
|
865
|
+
const emit = __emit;
|
|
866
|
+
const teleportTarget = collectionUi().modalTeleportTarget?.() ?? "body";
|
|
867
|
+
const dialogEl = ref(null);
|
|
868
|
+
let previouslyFocused = null;
|
|
869
|
+
const FOCUSABLE_SELECTOR = [
|
|
870
|
+
"a[href]",
|
|
871
|
+
"button:not([disabled])",
|
|
872
|
+
"input:not([disabled])",
|
|
873
|
+
"select:not([disabled])",
|
|
874
|
+
"textarea:not([disabled])",
|
|
875
|
+
"[tabindex]:not([tabindex=\"-1\"])"
|
|
876
|
+
].join(",");
|
|
877
|
+
/** Visible, focusable controls inside the dialog, in DOM order. */
|
|
878
|
+
function focusableItems() {
|
|
879
|
+
if (!dialogEl.value) return [];
|
|
880
|
+
return Array.from(dialogEl.value.querySelectorAll(FOCUSABLE_SELECTOR)).filter((node) => node.offsetParent !== null);
|
|
881
|
+
}
|
|
882
|
+
/** Trap Tab / Shift+Tab inside the dialog so focus can't escape to the
|
|
883
|
+
* page behind the overlay. Wraps at both ends; the dialog container
|
|
884
|
+
* itself (tabindex -1) counts as "before the first item". */
|
|
885
|
+
function onTab(event) {
|
|
886
|
+
const items = focusableItems();
|
|
887
|
+
if (items.length === 0) {
|
|
888
|
+
event.preventDefault();
|
|
889
|
+
dialogEl.value?.focus();
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
const [first] = items;
|
|
893
|
+
const last = items[items.length - 1];
|
|
894
|
+
const active = document.activeElement;
|
|
895
|
+
if (event.shiftKey) {
|
|
896
|
+
if (active === first || active === dialogEl.value) {
|
|
897
|
+
event.preventDefault();
|
|
898
|
+
last.focus();
|
|
899
|
+
}
|
|
900
|
+
} else if (active === last) {
|
|
901
|
+
event.preventDefault();
|
|
902
|
+
first.focus();
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
onMounted(async () => {
|
|
906
|
+
previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
907
|
+
await nextTick();
|
|
908
|
+
dialogEl.value?.focus();
|
|
909
|
+
});
|
|
910
|
+
onBeforeUnmount(() => {
|
|
911
|
+
previouslyFocused?.focus?.();
|
|
912
|
+
});
|
|
1244
913
|
return (_ctx, _cache) => {
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
class: "
|
|
1253
|
-
"
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
createElementVNode("div", _hoisted_4$9, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.view.rows, (row) => {
|
|
1259
|
-
return openBlock(), createElementBlock("div", {
|
|
1260
|
-
key: row.key,
|
|
1261
|
-
class: "space-y-0.5"
|
|
1262
|
-
}, [createElementVNode("div", _hoisted_5$8, toDisplayString(row.label), 1), createElementVNode("div", {
|
|
1263
|
-
class: "text-xs text-slate-700 font-medium break-words",
|
|
1264
|
-
"data-testid": `collections-embed-${__props.fieldKey}-${row.key}`
|
|
1265
|
-
}, [row.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [row.value === true ? (openBlock(), createElementBlock("span", _hoisted_7$8, "check_circle")) : (openBlock(), createElementBlock("span", _hoisted_8$8, "—"))], 64)) : row.type === "markdown" ? (openBlock(), createElementBlock("p", _hoisted_9$8, toDisplayString(row.display), 1)) : (openBlock(), createElementBlock("span", _hoisted_10$8, toDisplayString(row.display), 1))], 8, _hoisted_6$8)]);
|
|
1266
|
-
}), 128))])
|
|
1267
|
-
]),
|
|
1268
|
-
_: 1
|
|
1269
|
-
}, 8, ["to", "data-testid"])) : (openBlock(), createElementBlock("div", {
|
|
1270
|
-
key: 1,
|
|
1271
|
-
class: "relative rounded-xl border border-red-100 bg-red-50/30 p-4 pl-5 shadow-sm",
|
|
1272
|
-
"data-testid": `collections-embed-${__props.fieldKey}`
|
|
1273
|
-
}, [_cache[4] || (_cache[4] = createElementVNode("div", { class: "absolute left-0 top-0 bottom-0 w-1 bg-red-400 rounded-l-xl" }, null, -1)), createElementVNode("div", _hoisted_12$7, [_cache[3] || (_cache[3] = createElementVNode("span", { class: "material-icons text-red-500 text-lg mt-0.5" }, "error_outline", -1)), createElementVNode("div", _hoisted_13$6, [
|
|
1274
|
-
createElementVNode("p", _hoisted_14$5, toDisplayString(unref(t)("collectionsView.embedMissingTitle")), 1),
|
|
1275
|
-
createElementVNode("p", {
|
|
1276
|
-
class: "text-xs text-red-600",
|
|
1277
|
-
"data-testid": `collections-embed-missing-${__props.fieldKey}`
|
|
1278
|
-
}, toDisplayString(unref(t)("collectionsView.embedMissing", {
|
|
1279
|
-
collection: __props.view.targetSlug,
|
|
1280
|
-
id: __props.view.recordId
|
|
1281
|
-
})), 9, _hoisted_15$5),
|
|
1282
|
-
__props.view.targetSlug ? (openBlock(), createBlock(_component_router_link, {
|
|
1283
|
-
key: 0,
|
|
1284
|
-
to: { path: `/collections/${__props.view.targetSlug}` },
|
|
1285
|
-
class: "inline-flex items-center gap-0.5 text-xs text-indigo-600 hover:text-indigo-800 font-semibold mt-2 hover:underline"
|
|
1286
|
-
}, {
|
|
1287
|
-
default: withCtx(() => [createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.embedCreate")), 1), _cache[2] || (_cache[2] = createElementVNode("span", { class: "material-icons text-xs" }, "arrow_forward", -1))]),
|
|
1288
|
-
_: 1
|
|
1289
|
-
}, 8, ["to"])) : createCommentVNode("", true)
|
|
1290
|
-
])])], 8, _hoisted_11$8));
|
|
914
|
+
return openBlock(), createBlock(Teleport, { to: unref(teleportTarget) }, [createElementVNode("div", {
|
|
915
|
+
class: "fixed inset-0 z-40 flex items-center justify-center bg-slate-900/40 p-4",
|
|
916
|
+
"data-testid": "collections-record-modal",
|
|
917
|
+
onClick: _cache[1] || (_cache[1] = withModifiers(($event) => emit("close"), ["self"]))
|
|
918
|
+
}, [createElementVNode("div", {
|
|
919
|
+
ref_key: "dialogEl",
|
|
920
|
+
ref: dialogEl,
|
|
921
|
+
class: "flex max-h-[85vh] w-full max-w-2xl flex-col overflow-hidden rounded-2xl bg-white shadow-xl focus:outline-none",
|
|
922
|
+
role: "dialog",
|
|
923
|
+
"aria-modal": "true",
|
|
924
|
+
tabindex: "-1",
|
|
925
|
+
onKeydown: [_cache[0] || (_cache[0] = withKeys(($event) => emit("close"), ["esc"])), withKeys(onTab, ["tab"])]
|
|
926
|
+
}, [renderSlot(_ctx.$slots, "default")], 544)])], 8, ["to"]);
|
|
1291
927
|
};
|
|
1292
928
|
}
|
|
1293
929
|
});
|
|
1294
930
|
//#endregion
|
|
1295
931
|
//#region src/vue/components/CollectionCalendarView.vue?vue&type=script&setup=true&lang.ts
|
|
1296
|
-
var _hoisted_1$
|
|
932
|
+
var _hoisted_1$11 = {
|
|
1297
933
|
class: "flex flex-col gap-3",
|
|
1298
934
|
"data-testid": "collection-calendar"
|
|
1299
935
|
};
|
|
1300
|
-
var _hoisted_2$
|
|
1301
|
-
var _hoisted_3$
|
|
1302
|
-
var _hoisted_4$
|
|
1303
|
-
var _hoisted_5$
|
|
936
|
+
var _hoisted_2$10 = { class: "flex items-center gap-2" };
|
|
937
|
+
var _hoisted_3$10 = ["aria-label"];
|
|
938
|
+
var _hoisted_4$10 = ["aria-label"];
|
|
939
|
+
var _hoisted_5$9 = {
|
|
1304
940
|
class: "text-sm font-bold text-slate-800 flex-1",
|
|
1305
941
|
"data-testid": "collection-calendar-month"
|
|
1306
942
|
};
|
|
1307
|
-
var _hoisted_6$
|
|
1308
|
-
var _hoisted_7$
|
|
1309
|
-
var _hoisted_8$
|
|
943
|
+
var _hoisted_6$8 = { class: "grid grid-cols-7 gap-1 text-[10px] font-bold text-slate-400 uppercase tracking-wider select-none" };
|
|
944
|
+
var _hoisted_7$8 = { class: "grid grid-cols-7 gap-1" };
|
|
945
|
+
var _hoisted_8$8 = [
|
|
1310
946
|
"aria-label",
|
|
1311
947
|
"data-testid",
|
|
1312
948
|
"onClick",
|
|
1313
949
|
"onKeydown"
|
|
1314
950
|
];
|
|
1315
|
-
var _hoisted_9$
|
|
1316
|
-
var _hoisted_10$
|
|
1317
|
-
var _hoisted_11$
|
|
951
|
+
var _hoisted_9$8 = { class: "flex items-center justify-end" };
|
|
952
|
+
var _hoisted_10$8 = ["data-testid", "onClick"];
|
|
953
|
+
var _hoisted_11$8 = {
|
|
1318
954
|
key: 0,
|
|
1319
955
|
class: "flex flex-wrap items-center gap-1.5 pt-1",
|
|
1320
956
|
"data-testid": "collection-calendar-no-date"
|
|
1321
957
|
};
|
|
1322
|
-
var _hoisted_12$
|
|
1323
|
-
var _hoisted_13$
|
|
958
|
+
var _hoisted_12$7 = { class: "text-[10px] font-bold text-slate-400 uppercase tracking-wider mr-1" };
|
|
959
|
+
var _hoisted_13$6 = ["data-testid", "onClick"];
|
|
1324
960
|
/** Sort key for ordering a day's chips by start time: earliest first, with
|
|
1325
961
|
* clock-less all-day records sinking to the bottom (matching the day view). */
|
|
1326
962
|
var DAY_CHIP_DEFAULT = "bg-indigo-50 text-indigo-700 border-indigo-100 hover:bg-indigo-100";
|
|
@@ -1434,23 +1070,23 @@ var CollectionCalendarView_default = /* @__PURE__ */ defineComponent({
|
|
|
1434
1070
|
viewMonth.value = now.getMonth() + 1;
|
|
1435
1071
|
}
|
|
1436
1072
|
return (_ctx, _cache) => {
|
|
1437
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
1438
|
-
createElementVNode("div", _hoisted_2$
|
|
1073
|
+
return openBlock(), createElementBlock("div", _hoisted_1$11, [
|
|
1074
|
+
createElementVNode("div", _hoisted_2$10, [
|
|
1439
1075
|
createElementVNode("button", {
|
|
1440
1076
|
type: "button",
|
|
1441
1077
|
class: "h-8 w-8 flex items-center justify-center rounded text-slate-500 hover:bg-slate-100 transition-colors",
|
|
1442
1078
|
"aria-label": unref(t)("collectionsView.calendarPrevMonth"),
|
|
1443
1079
|
"data-testid": "collection-calendar-prev",
|
|
1444
1080
|
onClick: _cache[0] || (_cache[0] = ($event) => stepMonth(-1))
|
|
1445
|
-
}, [..._cache[2] || (_cache[2] = [createElementVNode("span", { class: "material-icons text-lg" }, "chevron_left", -1)])], 8, _hoisted_3$
|
|
1081
|
+
}, [..._cache[2] || (_cache[2] = [createElementVNode("span", { class: "material-icons text-lg" }, "chevron_left", -1)])], 8, _hoisted_3$10),
|
|
1446
1082
|
createElementVNode("button", {
|
|
1447
1083
|
type: "button",
|
|
1448
1084
|
class: "h-8 w-8 flex items-center justify-center rounded text-slate-500 hover:bg-slate-100 transition-colors",
|
|
1449
1085
|
"aria-label": unref(t)("collectionsView.calendarNextMonth"),
|
|
1450
1086
|
"data-testid": "collection-calendar-next",
|
|
1451
1087
|
onClick: _cache[1] || (_cache[1] = ($event) => stepMonth(1))
|
|
1452
|
-
}, [..._cache[3] || (_cache[3] = [createElementVNode("span", { class: "material-icons text-lg" }, "chevron_right", -1)])], 8, _hoisted_4$
|
|
1453
|
-
createElementVNode("h3", _hoisted_5$
|
|
1088
|
+
}, [..._cache[3] || (_cache[3] = [createElementVNode("span", { class: "material-icons text-lg" }, "chevron_right", -1)])], 8, _hoisted_4$10),
|
|
1089
|
+
createElementVNode("h3", _hoisted_5$9, toDisplayString(monthLabel.value), 1),
|
|
1454
1090
|
createElementVNode("button", {
|
|
1455
1091
|
type: "button",
|
|
1456
1092
|
class: "h-8 px-2.5 flex items-center gap-1 rounded border border-slate-200 bg-white text-slate-600 hover:bg-slate-50 text-xs font-bold transition-colors",
|
|
@@ -1458,13 +1094,13 @@ var CollectionCalendarView_default = /* @__PURE__ */ defineComponent({
|
|
|
1458
1094
|
onClick: goToday
|
|
1459
1095
|
}, toDisplayString(unref(t)("collectionsView.calendarToday")), 1)
|
|
1460
1096
|
]),
|
|
1461
|
-
createElementVNode("div", _hoisted_6$
|
|
1097
|
+
createElementVNode("div", _hoisted_6$8, [(openBlock(true), createElementBlock(Fragment, null, renderList(weekdayLabels.value, (label, idx) => {
|
|
1462
1098
|
return openBlock(), createElementBlock("div", {
|
|
1463
1099
|
key: idx,
|
|
1464
1100
|
class: "px-1 py-1 text-center"
|
|
1465
1101
|
}, toDisplayString(label), 1);
|
|
1466
1102
|
}), 128))]),
|
|
1467
|
-
createElementVNode("div", _hoisted_7$
|
|
1103
|
+
createElementVNode("div", _hoisted_7$8, [(openBlock(true), createElementBlock(Fragment, null, renderList(cells.value, ({ cell, entries }) => {
|
|
1468
1104
|
return openBlock(), createElementBlock("div", {
|
|
1469
1105
|
key: cell.key,
|
|
1470
1106
|
class: normalizeClass(["min-h-[5.5rem] rounded-lg border p-1 flex flex-col gap-1 overflow-hidden transition-colors cursor-pointer hover:border-indigo-300 focus:outline-none focus:ring-2 focus:ring-indigo-500/30", cell.inMonth ? "bg-white border-slate-200" : "bg-slate-50/50 border-slate-100"]),
|
|
@@ -1474,24 +1110,24 @@ var CollectionCalendarView_default = /* @__PURE__ */ defineComponent({
|
|
|
1474
1110
|
"data-testid": `collection-calendar-day-${cell.key}`,
|
|
1475
1111
|
onClick: ($event) => emit("openDay", cell.ymd),
|
|
1476
1112
|
onKeydown: [withKeys(withModifiers(($event) => emit("openDay", cell.ymd), ["self", "prevent"]), ["enter"]), withKeys(withModifiers(($event) => emit("openDay", cell.ymd), ["self", "prevent"]), ["space"])]
|
|
1477
|
-
}, [createElementVNode("div", _hoisted_9$
|
|
1113
|
+
}, [createElementVNode("div", _hoisted_9$8, [createElementVNode("span", { class: normalizeClass(["text-[11px] font-bold h-5 min-w-5 px-1 inline-flex items-center justify-center rounded-full", cell.key === unref(todayKey) ? "bg-indigo-600 text-white" : cell.inMonth ? "text-slate-500" : "text-slate-300"]) }, toDisplayString(cell.ymd.day), 3)]), (openBlock(true), createElementBlock(Fragment, null, renderList(entries, (entry) => {
|
|
1478
1114
|
return openBlock(), createElementBlock("button", {
|
|
1479
1115
|
key: entry.id,
|
|
1480
1116
|
type: "button",
|
|
1481
1117
|
class: normalizeClass(["text-left text-[11px] leading-tight font-semibold truncate rounded px-1.5 py-0.5 border transition-colors", chipClass(entry, DAY_CHIP_DEFAULT)]),
|
|
1482
1118
|
"data-testid": `collection-calendar-chip-${entry.id}`,
|
|
1483
1119
|
onClick: withModifiers(($event) => emit("select", entry.id), ["stop"])
|
|
1484
|
-
}, toDisplayString(entry.label), 11, _hoisted_10$
|
|
1485
|
-
}), 128))], 42, _hoisted_8$
|
|
1120
|
+
}, toDisplayString(entry.label), 11, _hoisted_10$8);
|
|
1121
|
+
}), 128))], 42, _hoisted_8$8);
|
|
1486
1122
|
}), 128))]),
|
|
1487
|
-
bucketed.value.noDate.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_11$
|
|
1123
|
+
bucketed.value.noDate.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_11$8, [createElementVNode("span", _hoisted_12$7, toDisplayString(unref(t)("collectionsView.calendarNoDate")), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(undatedEntries.value, (entry) => {
|
|
1488
1124
|
return openBlock(), createElementBlock("button", {
|
|
1489
1125
|
key: entry.id,
|
|
1490
1126
|
type: "button",
|
|
1491
1127
|
class: normalizeClass(["text-[11px] font-semibold truncate rounded px-1.5 py-0.5 border transition-colors", chipClass(entry, UNDATED_CHIP_DEFAULT)]),
|
|
1492
1128
|
"data-testid": `collection-calendar-undated-${entry.id}`,
|
|
1493
1129
|
onClick: ($event) => emit("select", entry.id)
|
|
1494
|
-
}, toDisplayString(entry.label), 11, _hoisted_13$
|
|
1130
|
+
}, toDisplayString(entry.label), 11, _hoisted_13$6);
|
|
1495
1131
|
}), 128))])) : createCommentVNode("", true)
|
|
1496
1132
|
]);
|
|
1497
1133
|
};
|
|
@@ -1499,40 +1135,40 @@ var CollectionCalendarView_default = /* @__PURE__ */ defineComponent({
|
|
|
1499
1135
|
});
|
|
1500
1136
|
//#endregion
|
|
1501
1137
|
//#region src/vue/components/CollectionDayView.vue?vue&type=script&setup=true&lang.ts
|
|
1502
|
-
var _hoisted_1$
|
|
1503
|
-
var _hoisted_2$
|
|
1138
|
+
var _hoisted_1$10 = { class: "flex items-center gap-2 border-b border-slate-200 px-4 py-3" };
|
|
1139
|
+
var _hoisted_2$9 = {
|
|
1504
1140
|
class: "flex-1 text-sm font-bold text-slate-800",
|
|
1505
1141
|
"data-testid": "collection-day-view-title"
|
|
1506
1142
|
};
|
|
1507
|
-
var _hoisted_3$
|
|
1508
|
-
var _hoisted_4$
|
|
1509
|
-
var _hoisted_5$
|
|
1143
|
+
var _hoisted_3$9 = ["aria-label"];
|
|
1144
|
+
var _hoisted_4$9 = ["aria-label"];
|
|
1145
|
+
var _hoisted_5$8 = {
|
|
1510
1146
|
key: 0,
|
|
1511
1147
|
class: "px-4 py-10 text-center text-sm text-slate-400"
|
|
1512
1148
|
};
|
|
1513
|
-
var _hoisted_6$
|
|
1514
|
-
var _hoisted_7$
|
|
1149
|
+
var _hoisted_6$7 = { class: "absolute -top-2 left-0 w-10 pr-1 text-right text-[10px] tabular-nums text-slate-400" };
|
|
1150
|
+
var _hoisted_7$7 = {
|
|
1515
1151
|
class: "absolute inset-y-0 right-0",
|
|
1516
1152
|
style: { "left": "2.75rem" }
|
|
1517
1153
|
};
|
|
1518
|
-
var _hoisted_8$
|
|
1519
|
-
var _hoisted_9$
|
|
1520
|
-
var _hoisted_10$
|
|
1154
|
+
var _hoisted_8$7 = ["data-testid", "onClick"];
|
|
1155
|
+
var _hoisted_9$7 = { class: "block truncate text-[11px] font-semibold leading-tight" };
|
|
1156
|
+
var _hoisted_10$7 = {
|
|
1521
1157
|
key: 0,
|
|
1522
1158
|
"aria-hidden": "true"
|
|
1523
1159
|
};
|
|
1524
|
-
var _hoisted_11$
|
|
1160
|
+
var _hoisted_11$7 = {
|
|
1525
1161
|
key: 1,
|
|
1526
1162
|
"aria-hidden": "true"
|
|
1527
1163
|
};
|
|
1528
|
-
var _hoisted_12$
|
|
1164
|
+
var _hoisted_12$6 = {
|
|
1529
1165
|
key: 2,
|
|
1530
1166
|
class: "flex flex-wrap items-center gap-1.5 border-t border-slate-200 px-4 py-2",
|
|
1531
1167
|
"data-testid": "collection-day-view-all-day"
|
|
1532
1168
|
};
|
|
1533
|
-
var _hoisted_13$
|
|
1534
|
-
var _hoisted_14$
|
|
1535
|
-
var _hoisted_15$
|
|
1169
|
+
var _hoisted_13$5 = { class: "mr-1 text-[10px] font-bold uppercase tracking-wider text-slate-400" };
|
|
1170
|
+
var _hoisted_14$5 = ["data-testid", "onClick"];
|
|
1171
|
+
var _hoisted_15$5 = {
|
|
1536
1172
|
key: 0,
|
|
1537
1173
|
class: "min-w-0 flex-1 overflow-y-auto",
|
|
1538
1174
|
"data-testid": "collection-day-view-detail"
|
|
@@ -1691,8 +1327,8 @@ var CollectionDayView_default = /* @__PURE__ */ defineComponent({
|
|
|
1691
1327
|
role: "dialog",
|
|
1692
1328
|
"aria-modal": "true"
|
|
1693
1329
|
}, [createElementVNode("div", { class: normalizeClass(["flex min-h-0 flex-col", __props.showDetail ? "w-80 shrink-0 border-r border-slate-200" : "w-full"]) }, [
|
|
1694
|
-
createElementVNode("div", _hoisted_1$
|
|
1695
|
-
createElementVNode("h3", _hoisted_2$
|
|
1330
|
+
createElementVNode("div", _hoisted_1$10, [
|
|
1331
|
+
createElementVNode("h3", _hoisted_2$9, toDisplayString(dayLabel.value), 1),
|
|
1696
1332
|
__props.canCreate ? (openBlock(), createElementBlock("button", {
|
|
1697
1333
|
key: 0,
|
|
1698
1334
|
type: "button",
|
|
@@ -1700,16 +1336,16 @@ var CollectionDayView_default = /* @__PURE__ */ defineComponent({
|
|
|
1700
1336
|
"aria-label": unref(t)("collectionsView.calendarCreateOn", { date: dayKey.value }),
|
|
1701
1337
|
"data-testid": "collection-day-view-create",
|
|
1702
1338
|
onClick: onCreate
|
|
1703
|
-
}, [..._cache[3] || (_cache[3] = [createElementVNode("span", { class: "material-icons text-lg" }, "add", -1)])], 8, _hoisted_3$
|
|
1339
|
+
}, [..._cache[3] || (_cache[3] = [createElementVNode("span", { class: "material-icons text-lg" }, "add", -1)])], 8, _hoisted_3$9)) : createCommentVNode("", true),
|
|
1704
1340
|
createElementVNode("button", {
|
|
1705
1341
|
type: "button",
|
|
1706
1342
|
class: "h-8 w-8 flex items-center justify-center rounded text-slate-500 hover:bg-slate-100 transition-colors",
|
|
1707
1343
|
"aria-label": unref(t)("collectionsView.dayViewClose"),
|
|
1708
1344
|
"data-testid": "collection-day-view-close",
|
|
1709
1345
|
onClick: _cache[0] || (_cache[0] = ($event) => emit("close"))
|
|
1710
|
-
}, [..._cache[4] || (_cache[4] = [createElementVNode("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_4$
|
|
1346
|
+
}, [..._cache[4] || (_cache[4] = [createElementVNode("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_4$9)
|
|
1711
1347
|
]),
|
|
1712
|
-
timedEntries.value.length === 0 && allDayEntries.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_5$
|
|
1348
|
+
timedEntries.value.length === 0 && allDayEntries.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_5$8, toDisplayString(unref(t)("collectionsView.dayViewEmpty")), 1)) : (openBlock(), createElementBlock("div", {
|
|
1713
1349
|
key: 1,
|
|
1714
1350
|
ref_key: "scrollEl",
|
|
1715
1351
|
ref: scrollEl,
|
|
@@ -1723,8 +1359,8 @@ var CollectionDayView_default = /* @__PURE__ */ defineComponent({
|
|
|
1723
1359
|
key: hour,
|
|
1724
1360
|
class: "absolute left-0 right-0 border-t border-slate-100",
|
|
1725
1361
|
style: normalizeStyle({ top: `${(hour - 1) * HOUR_PX}px` })
|
|
1726
|
-
}, [createElementVNode("span", _hoisted_6$
|
|
1727
|
-
}), 64)), createElementVNode("div", _hoisted_7$
|
|
1362
|
+
}, [createElementVNode("span", _hoisted_6$7, toDisplayString(hourLabel(hour - 1)), 1)], 4);
|
|
1363
|
+
}), 64)), createElementVNode("div", _hoisted_7$7, [(openBlock(true), createElementBlock(Fragment, null, renderList(timedEntries.value, (entry) => {
|
|
1728
1364
|
return openBlock(), createElementBlock("button", {
|
|
1729
1365
|
key: entry.id,
|
|
1730
1366
|
type: "button",
|
|
@@ -1732,56 +1368,56 @@ var CollectionDayView_default = /* @__PURE__ */ defineComponent({
|
|
|
1732
1368
|
style: normalizeStyle(entry.style),
|
|
1733
1369
|
"data-testid": `collection-day-view-chip-${entry.id}`,
|
|
1734
1370
|
onClick: ($event) => onSelect(entry.id)
|
|
1735
|
-
}, [createElementVNode("span", _hoisted_9$
|
|
1736
|
-
entry.slice.bleedsBefore ? (openBlock(), createElementBlock("span", _hoisted_10$
|
|
1371
|
+
}, [createElementVNode("span", _hoisted_9$7, [
|
|
1372
|
+
entry.slice.bleedsBefore ? (openBlock(), createElementBlock("span", _hoisted_10$7, "▲ ")) : createCommentVNode("", true),
|
|
1737
1373
|
createTextVNode(toDisplayString(entry.label), 1),
|
|
1738
|
-
entry.slice.bleedsAfter ? (openBlock(), createElementBlock("span", _hoisted_11$
|
|
1374
|
+
entry.slice.bleedsAfter ? (openBlock(), createElementBlock("span", _hoisted_11$7, " ▼")) : createCommentVNode("", true)
|
|
1739
1375
|
]), (openBlock(true), createElementBlock(Fragment, null, renderList(entry.secondary, (text, i) => {
|
|
1740
1376
|
return openBlock(), createElementBlock("span", {
|
|
1741
1377
|
key: i,
|
|
1742
1378
|
class: "block truncate text-[10px] leading-tight opacity-70"
|
|
1743
1379
|
}, toDisplayString(text), 1);
|
|
1744
|
-
}), 128))], 14, _hoisted_8$
|
|
1380
|
+
}), 128))], 14, _hoisted_8$7);
|
|
1745
1381
|
}), 128))])], 4)], 512)),
|
|
1746
|
-
allDayEntries.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_12$
|
|
1382
|
+
allDayEntries.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_12$6, [createElementVNode("span", _hoisted_13$5, toDisplayString(unref(t)("collectionsView.dayViewAllDay")), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(allDayEntries.value, (entry) => {
|
|
1747
1383
|
return openBlock(), createElementBlock("button", {
|
|
1748
1384
|
key: entry.id,
|
|
1749
1385
|
type: "button",
|
|
1750
1386
|
class: normalizeClass(["truncate rounded border px-1.5 py-0.5 text-[11px] font-semibold transition-colors", allDayChipClass(entry)]),
|
|
1751
1387
|
"data-testid": `collection-day-view-allday-${entry.id}`,
|
|
1752
1388
|
onClick: ($event) => onSelect(entry.id)
|
|
1753
|
-
}, toDisplayString(entry.label), 11, _hoisted_14$
|
|
1389
|
+
}, toDisplayString(entry.label), 11, _hoisted_14$5);
|
|
1754
1390
|
}), 128))])) : createCommentVNode("", true)
|
|
1755
|
-
], 2), __props.showDetail ? (openBlock(), createElementBlock("div", _hoisted_15$
|
|
1391
|
+
], 2), __props.showDetail ? (openBlock(), createElementBlock("div", _hoisted_15$5, [renderSlot(_ctx.$slots, "detail")])) : createCommentVNode("", true)], 2)], 32);
|
|
1756
1392
|
};
|
|
1757
1393
|
}
|
|
1758
1394
|
});
|
|
1759
1395
|
//#endregion
|
|
1760
1396
|
//#region src/vue/components/CollectionKanbanView.vue?vue&type=script&setup=true&lang.ts
|
|
1761
|
-
var _hoisted_1$
|
|
1397
|
+
var _hoisted_1$9 = {
|
|
1762
1398
|
class: "h-full overflow-x-auto overflow-y-hidden",
|
|
1763
1399
|
"data-testid": "collection-kanban"
|
|
1764
1400
|
};
|
|
1765
|
-
var _hoisted_2$
|
|
1766
|
-
var _hoisted_3$
|
|
1767
|
-
var _hoisted_4$
|
|
1768
|
-
var _hoisted_5$
|
|
1769
|
-
var _hoisted_6$
|
|
1770
|
-
var _hoisted_7$
|
|
1771
|
-
var _hoisted_8$
|
|
1401
|
+
var _hoisted_2$8 = { class: "flex gap-3 h-full p-1 min-w-max" };
|
|
1402
|
+
var _hoisted_3$8 = ["data-testid"];
|
|
1403
|
+
var _hoisted_4$8 = { class: "flex items-center justify-between px-3 py-2 border-b border-slate-200" };
|
|
1404
|
+
var _hoisted_5$7 = { class: "flex items-center gap-2 min-w-0" };
|
|
1405
|
+
var _hoisted_6$6 = ["title"];
|
|
1406
|
+
var _hoisted_7$6 = { class: "text-[11px] text-slate-400 shrink-0" };
|
|
1407
|
+
var _hoisted_8$6 = [
|
|
1772
1408
|
"data-testid",
|
|
1773
1409
|
"aria-label",
|
|
1774
1410
|
"onClick",
|
|
1775
1411
|
"onKeydown"
|
|
1776
1412
|
];
|
|
1777
|
-
var _hoisted_9$
|
|
1778
|
-
var _hoisted_10$
|
|
1413
|
+
var _hoisted_9$6 = { class: "flex items-start gap-2" };
|
|
1414
|
+
var _hoisted_10$6 = [
|
|
1779
1415
|
"checked",
|
|
1780
1416
|
"aria-label",
|
|
1781
1417
|
"data-testid",
|
|
1782
1418
|
"onChange"
|
|
1783
1419
|
];
|
|
1784
|
-
var _hoisted_11$
|
|
1420
|
+
var _hoisted_11$6 = { class: "text-sm font-medium text-slate-800 truncate" };
|
|
1785
1421
|
var UNCATEGORIZED = "";
|
|
1786
1422
|
//#endregion
|
|
1787
1423
|
//#region src/vue/components/CollectionKanbanView.vue
|
|
@@ -1879,15 +1515,15 @@ var CollectionKanbanView_default = /* @__PURE__ */ defineComponent({
|
|
|
1879
1515
|
emit("move", itemId(item), next);
|
|
1880
1516
|
}
|
|
1881
1517
|
return (_ctx, _cache) => {
|
|
1882
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
1518
|
+
return openBlock(), createElementBlock("div", _hoisted_1$9, [createElementVNode("div", _hoisted_2$8, [(openBlock(true), createElementBlock(Fragment, null, renderList(columns.value, (column) => {
|
|
1883
1519
|
return openBlock(), createElementBlock("div", {
|
|
1884
1520
|
key: column.value,
|
|
1885
1521
|
"data-testid": `collection-kanban-column-${column.value || "uncategorized"}`,
|
|
1886
1522
|
class: "w-72 shrink-0 flex flex-col bg-slate-100 rounded-lg"
|
|
1887
|
-
}, [createElementVNode("div", _hoisted_4$
|
|
1523
|
+
}, [createElementVNode("div", _hoisted_4$8, [createElementVNode("div", _hoisted_5$7, [createElementVNode("span", { class: normalizeClass(["w-2 h-2 rounded-full shrink-0", unref(resolveEnumColor)(__props.schema, __props.groupField, column.value).dot]) }, null, 2), createElementVNode("span", {
|
|
1888
1524
|
class: "font-semibold text-xs text-slate-600 truncate",
|
|
1889
1525
|
title: column.label
|
|
1890
|
-
}, toDisplayString(column.label), 9, _hoisted_6$
|
|
1526
|
+
}, toDisplayString(column.label), 9, _hoisted_6$6)]), createElementVNode("span", _hoisted_7$6, toDisplayString(itemsByColumn(column.value).length), 1)]), createVNode(unref(draggable), {
|
|
1891
1527
|
"model-value": itemsByColumn(column.value),
|
|
1892
1528
|
"item-key": __props.schema.primaryKey,
|
|
1893
1529
|
group: "collection-kanban-cards",
|
|
@@ -1903,7 +1539,7 @@ var CollectionKanbanView_default = /* @__PURE__ */ defineComponent({
|
|
|
1903
1539
|
class: normalizeClass(["bg-white border border-slate-200 rounded shadow-sm p-2 cursor-grab hover:shadow active:cursor-grabbing focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-400", [itemId(element) === __props.selected ? "ring-2 ring-indigo-500 border-indigo-300" : "", notifyAccentClass(element)]]),
|
|
1904
1540
|
onClick: ($event) => emit("select", itemId(element)),
|
|
1905
1541
|
onKeydown: [withKeys(withModifiers((e) => !e.repeat && emit("select", itemId(element)), ["prevent", "self"]), ["enter"]), withKeys(withModifiers((e) => !e.repeat && emit("select", itemId(element)), ["prevent", "self"]), ["space"])]
|
|
1906
|
-
}, [createElementVNode("div", _hoisted_9$
|
|
1542
|
+
}, [createElementVNode("div", _hoisted_9$6, [cardToggle.value ? (openBlock(), createElementBlock("input", {
|
|
1907
1543
|
key: 0,
|
|
1908
1544
|
type: "checkbox",
|
|
1909
1545
|
checked: cardChecked(element),
|
|
@@ -1912,24 +1548,105 @@ var CollectionKanbanView_default = /* @__PURE__ */ defineComponent({
|
|
|
1912
1548
|
"data-testid": `collection-kanban-toggle-${itemId(element)}`,
|
|
1913
1549
|
onClick: _cache[0] || (_cache[0] = withModifiers(() => {}, ["stop"])),
|
|
1914
1550
|
onChange: ($event) => onCardToggle(element)
|
|
1915
|
-
}, null, 40, _hoisted_10$
|
|
1551
|
+
}, null, 40, _hoisted_10$6)) : createCommentVNode("", true), createElementVNode("div", _hoisted_11$6, toDisplayString(itemLabel(element)), 1)])], 42, _hoisted_8$6)]),
|
|
1916
1552
|
_: 1
|
|
1917
1553
|
}, 8, [
|
|
1918
1554
|
"model-value",
|
|
1919
1555
|
"item-key",
|
|
1920
1556
|
"onChange"
|
|
1921
|
-
])], 8, _hoisted_3$
|
|
1557
|
+
])], 8, _hoisted_3$8);
|
|
1922
1558
|
}), 128))])]);
|
|
1923
1559
|
};
|
|
1924
1560
|
}
|
|
1925
1561
|
});
|
|
1926
1562
|
//#endregion
|
|
1563
|
+
//#region src/vue/components/CollectionEmbedView.vue?vue&type=script&setup=true&lang.ts
|
|
1564
|
+
var _hoisted_1$8 = ["href", "data-testid"];
|
|
1565
|
+
var _hoisted_2$7 = { class: "flex items-center justify-between text-[10px] font-bold text-indigo-600/90 tracking-wider uppercase" };
|
|
1566
|
+
var _hoisted_3$7 = { class: "flex items-center gap-1.5" };
|
|
1567
|
+
var _hoisted_4$7 = { class: "bg-indigo-100/60 text-indigo-700 px-1.5 py-0.5 rounded font-mono font-medium lowercase" };
|
|
1568
|
+
var _hoisted_5$6 = { class: "grid gap-x-4 gap-y-3 grid-cols-2" };
|
|
1569
|
+
var _hoisted_6$5 = { class: "text-[10px] font-semibold text-slate-400 uppercase tracking-wide" };
|
|
1570
|
+
var _hoisted_7$5 = ["data-testid"];
|
|
1571
|
+
var _hoisted_8$5 = {
|
|
1572
|
+
key: 0,
|
|
1573
|
+
class: "material-icons text-emerald-600 text-sm align-middle"
|
|
1574
|
+
};
|
|
1575
|
+
var _hoisted_9$5 = {
|
|
1576
|
+
key: 1,
|
|
1577
|
+
class: "text-slate-300"
|
|
1578
|
+
};
|
|
1579
|
+
var _hoisted_10$5 = {
|
|
1580
|
+
key: 1,
|
|
1581
|
+
class: "whitespace-pre-wrap font-normal text-slate-600"
|
|
1582
|
+
};
|
|
1583
|
+
var _hoisted_11$5 = { key: 2 };
|
|
1584
|
+
var _hoisted_12$5 = ["data-testid"];
|
|
1585
|
+
var _hoisted_13$4 = { class: "flex items-start gap-3" };
|
|
1586
|
+
var _hoisted_14$4 = { class: "flex-1 min-w-0" };
|
|
1587
|
+
var _hoisted_15$4 = { class: "text-xs font-semibold text-red-800 uppercase tracking-wider mb-1" };
|
|
1588
|
+
var _hoisted_16$3 = ["data-testid"];
|
|
1589
|
+
var _hoisted_17$3 = ["href"];
|
|
1590
|
+
//#endregion
|
|
1591
|
+
//#region src/vue/components/CollectionEmbedView.vue
|
|
1592
|
+
var CollectionEmbedView_default = /* @__PURE__ */ defineComponent({
|
|
1593
|
+
__name: "CollectionEmbedView",
|
|
1594
|
+
props: {
|
|
1595
|
+
view: {},
|
|
1596
|
+
fieldKey: {}
|
|
1597
|
+
},
|
|
1598
|
+
setup(__props) {
|
|
1599
|
+
const { t } = useCollectionI18n();
|
|
1600
|
+
const cui = collectionUi();
|
|
1601
|
+
return (_ctx, _cache) => {
|
|
1602
|
+
return __props.view.found ? (openBlock(), createElementBlock("a", {
|
|
1603
|
+
key: 0,
|
|
1604
|
+
href: unref(cui).recordHref?.(__props.view.targetSlug, __props.view.recordId),
|
|
1605
|
+
class: "group block relative rounded-xl border border-slate-200 bg-slate-50/50 p-4 pl-5 space-y-3 hover:bg-indigo-50/20 hover:border-indigo-200 transition-all duration-300 shadow-sm",
|
|
1606
|
+
"data-testid": `collections-embed-${__props.fieldKey}`,
|
|
1607
|
+
onClick: _cache[0] || (_cache[0] = withModifiers(($event) => unref(cui).navigateToRecord(__props.view.targetSlug, __props.view.recordId), ["exact", "prevent"]))
|
|
1608
|
+
}, [
|
|
1609
|
+
_cache[3] || (_cache[3] = createElementVNode("div", { class: "absolute left-0 top-0 bottom-0 w-1 bg-indigo-500 rounded-l-xl transition-all duration-300 group-hover:w-1.5 group-hover:bg-indigo-600" }, null, -1)),
|
|
1610
|
+
createElementVNode("div", _hoisted_2$7, [createElementVNode("div", _hoisted_3$7, [_cache[2] || (_cache[2] = createElementVNode("span", { class: "material-icons text-sm" }, "link", -1)), createElementVNode("span", null, toDisplayString(__props.view.targetSlug), 1)]), createElementVNode("span", _hoisted_4$7, toDisplayString(__props.view.recordId), 1)]),
|
|
1611
|
+
createElementVNode("div", _hoisted_5$6, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.view.rows, (row) => {
|
|
1612
|
+
return openBlock(), createElementBlock("div", {
|
|
1613
|
+
key: row.key,
|
|
1614
|
+
class: "space-y-0.5"
|
|
1615
|
+
}, [createElementVNode("div", _hoisted_6$5, toDisplayString(row.label), 1), createElementVNode("div", {
|
|
1616
|
+
class: "text-xs text-slate-700 font-medium break-words",
|
|
1617
|
+
"data-testid": `collections-embed-${__props.fieldKey}-${row.key}`
|
|
1618
|
+
}, [row.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [row.value === true ? (openBlock(), createElementBlock("span", _hoisted_8$5, "check_circle")) : (openBlock(), createElementBlock("span", _hoisted_9$5, "—"))], 64)) : row.type === "markdown" ? (openBlock(), createElementBlock("p", _hoisted_10$5, toDisplayString(row.display), 1)) : (openBlock(), createElementBlock("span", _hoisted_11$5, toDisplayString(row.display), 1))], 8, _hoisted_7$5)]);
|
|
1619
|
+
}), 128))])
|
|
1620
|
+
], 8, _hoisted_1$8)) : (openBlock(), createElementBlock("div", {
|
|
1621
|
+
key: 1,
|
|
1622
|
+
class: "relative rounded-xl border border-red-100 bg-red-50/30 p-4 pl-5 shadow-sm",
|
|
1623
|
+
"data-testid": `collections-embed-${__props.fieldKey}`
|
|
1624
|
+
}, [_cache[6] || (_cache[6] = createElementVNode("div", { class: "absolute left-0 top-0 bottom-0 w-1 bg-red-400 rounded-l-xl" }, null, -1)), createElementVNode("div", _hoisted_13$4, [_cache[5] || (_cache[5] = createElementVNode("span", { class: "material-icons text-red-500 text-lg mt-0.5" }, "error_outline", -1)), createElementVNode("div", _hoisted_14$4, [
|
|
1625
|
+
createElementVNode("p", _hoisted_15$4, toDisplayString(unref(t)("collectionsView.embedMissingTitle")), 1),
|
|
1626
|
+
createElementVNode("p", {
|
|
1627
|
+
class: "text-xs text-red-600",
|
|
1628
|
+
"data-testid": `collections-embed-missing-${__props.fieldKey}`
|
|
1629
|
+
}, toDisplayString(unref(t)("collectionsView.embedMissing", {
|
|
1630
|
+
collection: __props.view.targetSlug,
|
|
1631
|
+
id: __props.view.recordId
|
|
1632
|
+
})), 9, _hoisted_16$3),
|
|
1633
|
+
__props.view.targetSlug ? (openBlock(), createElementBlock("a", {
|
|
1634
|
+
key: 0,
|
|
1635
|
+
href: unref(cui).recordHref?.(__props.view.targetSlug),
|
|
1636
|
+
class: "inline-flex items-center gap-0.5 text-xs text-indigo-600 hover:text-indigo-800 font-semibold mt-2 hover:underline",
|
|
1637
|
+
onClick: _cache[1] || (_cache[1] = withModifiers(($event) => unref(cui).navigateToRecord(__props.view.targetSlug), ["exact", "prevent"]))
|
|
1638
|
+
}, [createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.embedCreate")), 1), _cache[4] || (_cache[4] = createElementVNode("span", { class: "material-icons text-xs" }, "arrow_forward", -1))], 8, _hoisted_17$3)) : createCommentVNode("", true)
|
|
1639
|
+
])])], 8, _hoisted_12$5));
|
|
1640
|
+
};
|
|
1641
|
+
}
|
|
1642
|
+
});
|
|
1643
|
+
//#endregion
|
|
1927
1644
|
//#region src/vue/components/CollectionRecordPanel.vue?vue&type=script&setup=true&lang.ts
|
|
1928
|
-
var _hoisted_1$
|
|
1929
|
-
var _hoisted_2$
|
|
1930
|
-
var _hoisted_3$
|
|
1931
|
-
var _hoisted_4$
|
|
1932
|
-
var _hoisted_5$
|
|
1645
|
+
var _hoisted_1$7 = { class: "flex items-center gap-2 mb-4" };
|
|
1646
|
+
var _hoisted_2$6 = { class: "flex-1 min-w-0" };
|
|
1647
|
+
var _hoisted_3$6 = { class: "block text-[9px] font-bold text-slate-400 uppercase tracking-wider" };
|
|
1648
|
+
var _hoisted_4$6 = ["data-testid"];
|
|
1649
|
+
var _hoisted_5$5 = ["disabled"];
|
|
1933
1650
|
var _hoisted_6$4 = {
|
|
1934
1651
|
key: 1,
|
|
1935
1652
|
class: "flex items-center gap-2"
|
|
@@ -2065,49 +1782,59 @@ var _hoisted_52$1 = {
|
|
|
2065
1782
|
key: 2,
|
|
2066
1783
|
class: "text-slate-300"
|
|
2067
1784
|
};
|
|
2068
|
-
var _hoisted_53$1 =
|
|
1785
|
+
var _hoisted_53$1 = [
|
|
1786
|
+
"href",
|
|
1787
|
+
"data-testid",
|
|
1788
|
+
"onClick"
|
|
1789
|
+
];
|
|
1790
|
+
var _hoisted_54$1 = {
|
|
2069
1791
|
key: 3,
|
|
2070
1792
|
class: "font-semibold text-slate-900 tabular-nums text-sm"
|
|
2071
1793
|
};
|
|
2072
|
-
var
|
|
1794
|
+
var _hoisted_55$1 = {
|
|
2073
1795
|
key: 4,
|
|
2074
1796
|
class: "inline-block truncate tabular-nums font-bold text-indigo-900 bg-indigo-50/50 px-2 py-0.5 rounded border border-indigo-100/50"
|
|
2075
1797
|
};
|
|
2076
|
-
var
|
|
1798
|
+
var _hoisted_56$1 = {
|
|
2077
1799
|
key: 5,
|
|
2078
1800
|
class: "border border-slate-200/80 rounded-xl overflow-hidden shadow-sm mt-1"
|
|
2079
1801
|
};
|
|
2080
|
-
var
|
|
2081
|
-
var
|
|
2082
|
-
var
|
|
2083
|
-
var
|
|
1802
|
+
var _hoisted_57$1 = { class: "w-full text-[11px] text-slate-600 bg-white" };
|
|
1803
|
+
var _hoisted_58$1 = { class: "bg-slate-50 border-b border-slate-200 text-slate-500 font-bold uppercase tracking-wider" };
|
|
1804
|
+
var _hoisted_59$1 = { class: "divide-y divide-slate-100" };
|
|
1805
|
+
var _hoisted_60$1 = {
|
|
2084
1806
|
key: 0,
|
|
2085
1807
|
class: "material-icons text-emerald-600 text-base"
|
|
2086
1808
|
};
|
|
2087
|
-
var
|
|
1809
|
+
var _hoisted_61$1 = {
|
|
2088
1810
|
key: 1,
|
|
2089
1811
|
class: "text-slate-300"
|
|
2090
1812
|
};
|
|
2091
|
-
var
|
|
1813
|
+
var _hoisted_62$1 = {
|
|
2092
1814
|
key: 6,
|
|
2093
1815
|
class: "text-slate-400 italic"
|
|
2094
1816
|
};
|
|
2095
|
-
var
|
|
1817
|
+
var _hoisted_63$1 = {
|
|
2096
1818
|
key: 7,
|
|
2097
1819
|
class: "bg-slate-50 rounded-xl p-4 border border-slate-200/60 text-slate-600 text-xs whitespace-pre-wrap leading-relaxed max-h-[30vh] overflow-y-auto"
|
|
2098
1820
|
};
|
|
2099
|
-
var
|
|
1821
|
+
var _hoisted_64$1 = [
|
|
2100
1822
|
"src",
|
|
2101
1823
|
"alt",
|
|
2102
1824
|
"data-testid"
|
|
2103
1825
|
];
|
|
2104
|
-
var _hoisted_64$1 = ["href", "data-testid"];
|
|
2105
1826
|
var _hoisted_65$1 = ["href", "data-testid"];
|
|
2106
|
-
var _hoisted_66$1 =
|
|
1827
|
+
var _hoisted_66$1 = ["href", "data-testid"];
|
|
1828
|
+
var _hoisted_67$1 = [
|
|
1829
|
+
"href",
|
|
1830
|
+
"data-testid",
|
|
1831
|
+
"onClick"
|
|
1832
|
+
];
|
|
1833
|
+
var _hoisted_68$1 = {
|
|
2107
1834
|
key: 13,
|
|
2108
1835
|
class: "text-slate-800 font-semibold"
|
|
2109
1836
|
};
|
|
2110
|
-
var
|
|
1837
|
+
var _hoisted_69$1 = {
|
|
2111
1838
|
key: 0,
|
|
2112
1839
|
class: "col-span-full text-xs font-semibold text-red-600 bg-red-50 border border-red-100 p-2.5 rounded-xl"
|
|
2113
1840
|
};
|
|
@@ -2142,7 +1869,8 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2142
1869
|
"runAction"
|
|
2143
1870
|
], ["update:editing"]),
|
|
2144
1871
|
setup(__props, { emit: __emit }) {
|
|
2145
|
-
const
|
|
1872
|
+
const cui = collectionUi();
|
|
1873
|
+
const resolveImageSrc = cui.imageSrc;
|
|
2146
1874
|
const props = __props;
|
|
2147
1875
|
const editing = useModel(__props, "editing");
|
|
2148
1876
|
const emit = __emit;
|
|
@@ -2222,17 +1950,16 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2222
1950
|
if (rows) rows.splice(index, 1);
|
|
2223
1951
|
}
|
|
2224
1952
|
return (_ctx, _cache) => {
|
|
2225
|
-
const _component_router_link = resolveComponent("router-link");
|
|
2226
1953
|
return openBlock(), createBlock(resolveDynamicComponent(editing.value ? "form" : "div"), {
|
|
2227
1954
|
class: "px-6 py-5 max-h-[60vh] overflow-y-auto",
|
|
2228
1955
|
"data-testid": rootTestid.value,
|
|
2229
1956
|
onSubmit: _cache[4] || (_cache[4] = withModifiers(($event) => emit("submit"), ["prevent"]))
|
|
2230
1957
|
}, {
|
|
2231
1958
|
default: withCtx(() => [
|
|
2232
|
-
createElementVNode("div", _hoisted_1$
|
|
1959
|
+
createElementVNode("div", _hoisted_1$7, [createElementVNode("div", _hoisted_2$6, [createElementVNode("span", _hoisted_3$6, toDisplayString(__props.collection.title), 1), createElementVNode("h2", {
|
|
2233
1960
|
class: "text-base font-bold text-slate-800 truncate",
|
|
2234
1961
|
"data-testid": editing.value ? "collections-edit-title" : "collections-detail-title"
|
|
2235
|
-
}, toDisplayString(headerTitle.value), 9, _hoisted_4$
|
|
1962
|
+
}, toDisplayString(headerTitle.value), 9, _hoisted_4$6)]), editing.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createElementVNode("button", {
|
|
2236
1963
|
type: "button",
|
|
2237
1964
|
class: "h-8 px-2.5 rounded text-xs font-bold text-slate-500 hover:bg-slate-200/50 transition-colors",
|
|
2238
1965
|
"data-testid": "collections-editor-cancel",
|
|
@@ -2242,7 +1969,7 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2242
1969
|
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",
|
|
2243
1970
|
disabled: __props.saving,
|
|
2244
1971
|
"data-testid": "collections-editor-save"
|
|
2245
|
-
}, toDisplayString(__props.saving ? unref(t)("common.saving") : unref(t)("common.save")), 9, _hoisted_5$
|
|
1972
|
+
}, toDisplayString(__props.saving ? unref(t)("common.saving") : unref(t)("common.save")), 9, _hoisted_5$5)], 64)) : (openBlock(), createElementBlock("div", _hoisted_6$4, [
|
|
2246
1973
|
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.visibleActions, (action) => {
|
|
2247
1974
|
return openBlock(), createElementBlock("button", {
|
|
2248
1975
|
key: action.id,
|
|
@@ -2418,23 +2145,18 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2418
2145
|
key: 1,
|
|
2419
2146
|
class: "text-xs font-medium text-slate-700 break-words",
|
|
2420
2147
|
"data-testid": `collections-detail-value-${key}`
|
|
2421
|
-
}, [field.type === "toggle" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [field.field !== void 0 && String(detailRecord.value[field.field] ?? "") === field.onValue ? (openBlock(), createElementBlock("span", _hoisted_48$1, [_cache[11] || (_cache[11] = createElementVNode("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), createTextVNode(" " + toDisplayString(unref(t)("common.yes")), 1)])) : (openBlock(), createElementBlock("span", _hoisted_49$1, toDisplayString(unref(t)("common.no")), 1))], 64)) : field.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [detailRecord.value[key] === true ? (openBlock(), createElementBlock("span", _hoisted_50$1, [_cache[12] || (_cache[12] = createElementVNode("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), createTextVNode(" " + toDisplayString(unref(t)("common.yes")), 1)])) : detailRecord.value[key] === false ? (openBlock(), createElementBlock("span", _hoisted_51$1, toDisplayString(unref(t)("common.no")), 1)) : (openBlock(), createElementBlock("span", _hoisted_52$1, "—"))], 64)) : field.type === "ref" && field.to && typeof detailRecord.value[key] === "string" && detailRecord.value[key] ? (openBlock(),
|
|
2148
|
+
}, [field.type === "toggle" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [field.field !== void 0 && String(detailRecord.value[field.field] ?? "") === field.onValue ? (openBlock(), createElementBlock("span", _hoisted_48$1, [_cache[11] || (_cache[11] = createElementVNode("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), createTextVNode(" " + toDisplayString(unref(t)("common.yes")), 1)])) : (openBlock(), createElementBlock("span", _hoisted_49$1, toDisplayString(unref(t)("common.no")), 1))], 64)) : field.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [detailRecord.value[key] === true ? (openBlock(), createElementBlock("span", _hoisted_50$1, [_cache[12] || (_cache[12] = createElementVNode("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), createTextVNode(" " + toDisplayString(unref(t)("common.yes")), 1)])) : detailRecord.value[key] === false ? (openBlock(), createElementBlock("span", _hoisted_51$1, toDisplayString(unref(t)("common.no")), 1)) : (openBlock(), createElementBlock("span", _hoisted_52$1, "—"))], 64)) : field.type === "ref" && field.to && typeof detailRecord.value[key] === "string" && detailRecord.value[key] ? (openBlock(), createElementBlock("a", {
|
|
2422
2149
|
key: 2,
|
|
2423
|
-
|
|
2424
|
-
path: `/collections/${field.to}`,
|
|
2425
|
-
query: { selected: String(detailRecord.value[key]) }
|
|
2426
|
-
},
|
|
2150
|
+
href: unref(cui).recordHref?.(field.to, String(detailRecord.value[key])),
|
|
2427
2151
|
class: "text-indigo-600 hover:text-indigo-800 font-bold hover:underline",
|
|
2428
|
-
"data-testid": `collections-detail-ref-${key}
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
_: 2
|
|
2432
|
-
}, 1032, ["to", "data-testid"])) : field.type === "money" ? (openBlock(), createElementBlock("span", _hoisted_53$1, toDisplayString(__props.render.formatMoney(detailRecord.value[key], __props.render.resolveCurrency(field, detailRecord.value), __props.locale)), 1)) : field.type === "derived" ? (openBlock(), createElementBlock("span", _hoisted_54$1, toDisplayString(__props.render.derivedDisplay(field, __props.render.evaluateDerivedAgainstItem(field, String(key), detailRecord.value), detailRecord.value)), 1)) : field.type === "table" && field.of && __props.render.hasTableRows(detailRecord.value[key]) ? (openBlock(), createElementBlock("div", _hoisted_55$1, [createElementVNode("table", _hoisted_56$1, [createElementVNode("thead", _hoisted_57$1, [createElementVNode("tr", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(field.of, (subField, subKey) => {
|
|
2152
|
+
"data-testid": `collections-detail-ref-${key}`,
|
|
2153
|
+
onClick: withModifiers(($event) => unref(cui).navigateToRecord(field.to, String(detailRecord.value[key])), ["exact", "prevent"])
|
|
2154
|
+
}, toDisplayString(__props.render.refDisplay(field.to, String(detailRecord.value[key]))), 9, _hoisted_53$1)) : field.type === "money" ? (openBlock(), createElementBlock("span", _hoisted_54$1, toDisplayString(__props.render.formatMoney(detailRecord.value[key], __props.render.resolveCurrency(field, detailRecord.value), __props.locale)), 1)) : field.type === "derived" ? (openBlock(), createElementBlock("span", _hoisted_55$1, toDisplayString(__props.render.derivedDisplay(field, __props.render.evaluateDerivedAgainstItem(field, String(key), detailRecord.value), detailRecord.value)), 1)) : field.type === "table" && field.of && __props.render.hasTableRows(detailRecord.value[key]) ? (openBlock(), createElementBlock("div", _hoisted_56$1, [createElementVNode("table", _hoisted_57$1, [createElementVNode("thead", _hoisted_58$1, [createElementVNode("tr", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(field.of, (subField, subKey) => {
|
|
2433
2155
|
return openBlock(), createElementBlock("th", {
|
|
2434
2156
|
key: subKey,
|
|
2435
2157
|
class: "text-left px-4 py-2 font-bold"
|
|
2436
2158
|
}, toDisplayString(subField.label), 1);
|
|
2437
|
-
}), 128))])]), createElementVNode("tbody",
|
|
2159
|
+
}), 128))])]), createElementVNode("tbody", _hoisted_59$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.render.tableRows(detailRecord.value[key]), (row, rowIdx) => {
|
|
2438
2160
|
return openBlock(), createElementBlock("tr", {
|
|
2439
2161
|
key: rowIdx,
|
|
2440
2162
|
class: "hover:bg-slate-50/50"
|
|
@@ -2442,12 +2164,12 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2442
2164
|
return openBlock(), createElementBlock("td", {
|
|
2443
2165
|
key: subKey,
|
|
2444
2166
|
class: "px-4 py-2 align-middle font-medium"
|
|
2445
|
-
}, [subField.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [row[subKey] === true ? (openBlock(), createElementBlock("span",
|
|
2167
|
+
}, [subField.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [row[subKey] === true ? (openBlock(), createElementBlock("span", _hoisted_60$1, "check_circle")) : (openBlock(), createElementBlock("span", _hoisted_61$1, "—"))], 64)) : (openBlock(), createElementBlock("span", {
|
|
2446
2168
|
key: 1,
|
|
2447
2169
|
class: normalizeClass([subField.type === "money" ? "font-bold text-slate-800 tabular-nums" : ""])
|
|
2448
2170
|
}, toDisplayString(__props.render.formatSubCell(subField, row[subKey], detailRecord.value)), 3))]);
|
|
2449
2171
|
}), 128))]);
|
|
2450
|
-
}), 128))])])])) : field.type === "table" ? (openBlock(), createElementBlock("span",
|
|
2172
|
+
}), 128))])])])) : field.type === "table" ? (openBlock(), createElementBlock("span", _hoisted_62$1, toDisplayString(unref(t)("collectionsView.noRows")), 1)) : field.type === "markdown" ? (openBlock(), createElementBlock("div", _hoisted_63$1, toDisplayString(__props.render.detailText(detailRecord.value[key])), 1)) : field.type === "embed" && embedViews.value[key] ? (openBlock(), createBlock(CollectionEmbedView_default, {
|
|
2451
2173
|
key: 8,
|
|
2452
2174
|
view: embedViews.value[key],
|
|
2453
2175
|
"field-key": String(key)
|
|
@@ -2457,30 +2179,28 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2457
2179
|
alt: field.label,
|
|
2458
2180
|
class: "max-h-64 max-w-full object-contain rounded-lg border border-slate-200 bg-slate-50",
|
|
2459
2181
|
"data-testid": `collections-detail-image-${key}`
|
|
2460
|
-
}, null, 8,
|
|
2182
|
+
}, null, 8, _hoisted_64$1)) : field.type !== "file" && __props.render.isExternalUrl(detailRecord.value[key]) ? (openBlock(), createElementBlock("a", {
|
|
2461
2183
|
key: 10,
|
|
2462
2184
|
href: String(detailRecord.value[key]),
|
|
2463
2185
|
target: "_blank",
|
|
2464
2186
|
rel: "noopener noreferrer",
|
|
2465
2187
|
class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
|
|
2466
2188
|
"data-testid": `collections-detail-url-${key}`
|
|
2467
|
-
}, toDisplayString(String(detailRecord.value[key])), 9,
|
|
2189
|
+
}, toDisplayString(String(detailRecord.value[key])), 9, _hoisted_65$1)) : field.type === "file" && __props.render.artifactUrl(detailRecord.value[key]) ? (openBlock(), createElementBlock("a", {
|
|
2468
2190
|
key: 11,
|
|
2469
2191
|
href: __props.render.artifactUrl(detailRecord.value[key]) ?? void 0,
|
|
2470
2192
|
target: "_blank",
|
|
2471
2193
|
rel: "noopener noreferrer",
|
|
2472
2194
|
class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
|
|
2473
2195
|
"data-testid": `collections-detail-file-${key}`
|
|
2474
|
-
}, toDisplayString(String(detailRecord.value[key])), 9,
|
|
2196
|
+
}, toDisplayString(String(detailRecord.value[key])), 9, _hoisted_66$1)) : field.type === "file" && __props.render.fileRoutePath(detailRecord.value[key]) ? (openBlock(), createElementBlock("a", {
|
|
2475
2197
|
key: 12,
|
|
2476
|
-
|
|
2198
|
+
href: __props.render.fileRoutePath(detailRecord.value[key]) ?? void 0,
|
|
2477
2199
|
class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
|
|
2478
|
-
"data-testid": `collections-detail-file-${key}
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
}, 1032, ["to", "data-testid"])) : (openBlock(), createElementBlock("span", _hoisted_66$1, toDisplayString(__props.render.formatCell(detailRecord.value[key], field.type)), 1))], 8, _hoisted_47$1))], 2)) : createCommentVNode("", true)], 64);
|
|
2483
|
-
}), 128)), editing.value && __props.saveError ? (openBlock(), createElementBlock("p", _hoisted_67$1, toDisplayString(__props.saveError), 1)) : createCommentVNode("", true)])
|
|
2200
|
+
"data-testid": `collections-detail-file-${key}`,
|
|
2201
|
+
onClick: withModifiers(($event) => unref(cui).navigate?.(__props.render.fileRoutePath(detailRecord.value[key]) ?? ""), ["exact", "prevent"])
|
|
2202
|
+
}, toDisplayString(String(detailRecord.value[key])), 9, _hoisted_67$1)) : (openBlock(), createElementBlock("span", _hoisted_68$1, toDisplayString(__props.render.formatCell(detailRecord.value[key], field.type)), 1))], 8, _hoisted_47$1))], 2)) : createCommentVNode("", true)], 64);
|
|
2203
|
+
}), 128)), editing.value && __props.saveError ? (openBlock(), createElementBlock("p", _hoisted_69$1, toDisplayString(__props.saveError), 1)) : createCommentVNode("", true)])
|
|
2484
2204
|
]),
|
|
2485
2205
|
_: 1
|
|
2486
2206
|
}, 40, ["data-testid"]);
|
|
@@ -2489,14 +2209,14 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2489
2209
|
});
|
|
2490
2210
|
//#endregion
|
|
2491
2211
|
//#region src/vue/components/CollectionViewConfigModal.vue?vue&type=script&setup=true&lang.ts
|
|
2492
|
-
var _hoisted_1$
|
|
2212
|
+
var _hoisted_1$6 = {
|
|
2493
2213
|
"data-testid": "collection-config-modal",
|
|
2494
2214
|
class: "flex flex-col overflow-hidden"
|
|
2495
2215
|
};
|
|
2496
|
-
var _hoisted_2$
|
|
2497
|
-
var _hoisted_3$
|
|
2498
|
-
var _hoisted_4$
|
|
2499
|
-
var _hoisted_5$
|
|
2216
|
+
var _hoisted_2$5 = { class: "flex items-center justify-between gap-2 border-b border-slate-100 px-5 py-3" };
|
|
2217
|
+
var _hoisted_3$5 = { class: "text-sm font-bold text-slate-700" };
|
|
2218
|
+
var _hoisted_4$5 = ["title", "aria-label"];
|
|
2219
|
+
var _hoisted_5$4 = { class: "overflow-y-auto px-5 py-4" };
|
|
2500
2220
|
var _hoisted_6$3 = { class: "mb-2 text-[10px] font-bold uppercase tracking-wider text-slate-400" };
|
|
2501
2221
|
var _hoisted_7$3 = {
|
|
2502
2222
|
key: 0,
|
|
@@ -2561,14 +2281,14 @@ var CollectionViewConfigModal_default = /* @__PURE__ */ defineComponent({
|
|
|
2561
2281
|
}
|
|
2562
2282
|
return (_ctx, _cache) => {
|
|
2563
2283
|
return openBlock(), createBlock(CollectionRecordModal_default, { onClose: _cache[1] || (_cache[1] = ($event) => emit("close")) }, {
|
|
2564
|
-
default: withCtx(() => [createElementVNode("div", _hoisted_1$
|
|
2284
|
+
default: withCtx(() => [createElementVNode("div", _hoisted_1$6, [createElementVNode("header", _hoisted_2$5, [createElementVNode("h2", _hoisted_3$5, toDisplayString(unref(t)("collectionsView.config.title", { title: __props.title })), 1), createElementVNode("button", {
|
|
2565
2285
|
type: "button",
|
|
2566
2286
|
class: "h-8 w-8 flex items-center justify-center rounded text-slate-400 hover:bg-slate-50 hover:text-slate-600",
|
|
2567
2287
|
title: unref(t)("common.close"),
|
|
2568
2288
|
"aria-label": unref(t)("common.close"),
|
|
2569
2289
|
"data-testid": "collection-config-close",
|
|
2570
2290
|
onClick: _cache[0] || (_cache[0] = ($event) => emit("close"))
|
|
2571
|
-
}, [..._cache[2] || (_cache[2] = [createElementVNode("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_4$
|
|
2291
|
+
}, [..._cache[2] || (_cache[2] = [createElementVNode("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_4$5)]), createElementVNode("div", _hoisted_5$4, [
|
|
2572
2292
|
createElementVNode("h3", _hoisted_6$3, toDisplayString(unref(t)("collectionsView.config.viewsHeading")), 1),
|
|
2573
2293
|
error.value ? (openBlock(), createElementBlock("p", _hoisted_7$3, toDisplayString(error.value), 1)) : createCommentVNode("", true),
|
|
2574
2294
|
__props.views.length > 0 ? (openBlock(), createElementBlock("ul", _hoisted_8$3, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.views, (view) => {
|
|
@@ -2597,19 +2317,19 @@ var CollectionViewConfigModal_default = /* @__PURE__ */ defineComponent({
|
|
|
2597
2317
|
});
|
|
2598
2318
|
//#endregion
|
|
2599
2319
|
//#region src/vue/components/CollectionCustomView.vue?vue&type=script&setup=true&lang.ts
|
|
2600
|
-
var _hoisted_1$
|
|
2601
|
-
var _hoisted_2$
|
|
2320
|
+
var _hoisted_1$5 = { class: "custom-view-container" };
|
|
2321
|
+
var _hoisted_2$4 = {
|
|
2602
2322
|
key: 0,
|
|
2603
2323
|
class: "custom-view-message",
|
|
2604
2324
|
role: "alert",
|
|
2605
2325
|
"data-testid": "collection-custom-view-error"
|
|
2606
2326
|
};
|
|
2607
|
-
var _hoisted_3$
|
|
2327
|
+
var _hoisted_3$4 = {
|
|
2608
2328
|
key: 1,
|
|
2609
2329
|
class: "custom-view-message",
|
|
2610
2330
|
"data-testid": "collection-custom-view-loading"
|
|
2611
2331
|
};
|
|
2612
|
-
var _hoisted_4$
|
|
2332
|
+
var _hoisted_4$4 = ["title", "srcdoc"];
|
|
2613
2333
|
var REMINT_LEAD_MS = 6e4;
|
|
2614
2334
|
var MIN_REMINT_DELAY_MS = 1e4;
|
|
2615
2335
|
var CollectionCustomView_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
|
|
@@ -2665,46 +2385,365 @@ var CollectionCustomView_vue_vue_type_script_setup_true_lang_default = /* @__PUR
|
|
|
2665
2385
|
dataUrl: mint.data.dataUrl,
|
|
2666
2386
|
origin: window.location.origin
|
|
2667
2387
|
});
|
|
2668
|
-
} catch (err) {
|
|
2669
|
-
if (!stale()) error.value = errorMessage(err);
|
|
2670
|
-
} finally {
|
|
2671
|
-
if (!stale()) loading.value = false;
|
|
2388
|
+
} catch (err) {
|
|
2389
|
+
if (!stale()) error.value = errorMessage(err);
|
|
2390
|
+
} finally {
|
|
2391
|
+
if (!stale()) loading.value = false;
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
watch([() => props.slug, () => props.view.id], () => void load(), { immediate: true });
|
|
2395
|
+
onBeforeUnmount(clearRefresh);
|
|
2396
|
+
return (_ctx, _cache) => {
|
|
2397
|
+
return openBlock(), createElementBlock("div", _hoisted_1$5, [error.value ? (openBlock(), createElementBlock("div", _hoisted_2$4, toDisplayString(unref(t)("collectionsView.customViewError", { error: error.value })), 1)) : loading.value ? (openBlock(), createElementBlock("div", _hoisted_3$4, toDisplayString(unref(t)("collectionsView.customViewLoading")), 1)) : srcdoc.value ? (openBlock(), createElementBlock("iframe", {
|
|
2398
|
+
key: __props.view.id,
|
|
2399
|
+
"data-testid": "collection-custom-view-iframe",
|
|
2400
|
+
title: __props.view.label,
|
|
2401
|
+
srcdoc: srcdoc.value,
|
|
2402
|
+
sandbox: "allow-scripts allow-popups allow-popups-to-escape-sandbox",
|
|
2403
|
+
class: "w-full h-full border-0"
|
|
2404
|
+
}, null, 8, _hoisted_4$4)) : createCommentVNode("", true)]);
|
|
2405
|
+
};
|
|
2406
|
+
}
|
|
2407
|
+
});
|
|
2408
|
+
//#endregion
|
|
2409
|
+
//#region \0plugin-vue:export-helper
|
|
2410
|
+
var _plugin_vue_export_helper_default = (sfc, props) => {
|
|
2411
|
+
const target = sfc.__vccOpts || sfc;
|
|
2412
|
+
for (const [key, val] of props) target[key] = val;
|
|
2413
|
+
return target;
|
|
2414
|
+
};
|
|
2415
|
+
//#endregion
|
|
2416
|
+
//#region src/vue/components/CollectionCustomView.vue
|
|
2417
|
+
var CollectionCustomView_default = /* @__PURE__ */ _plugin_vue_export_helper_default(CollectionCustomView_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-3ab71997"]]);
|
|
2418
|
+
//#endregion
|
|
2419
|
+
//#region src/vue/useCollectionRendering.ts
|
|
2420
|
+
function useCollectionRendering(collection, locale) {
|
|
2421
|
+
const refCache = ref({});
|
|
2422
|
+
const refRecordCache = ref({});
|
|
2423
|
+
const embedCache = ref({});
|
|
2424
|
+
function resetLinkedCaches() {
|
|
2425
|
+
refCache.value = {};
|
|
2426
|
+
refRecordCache.value = {};
|
|
2427
|
+
embedCache.value = {};
|
|
2428
|
+
}
|
|
2429
|
+
function uniqueRefTargets(schema) {
|
|
2430
|
+
const targets = /* @__PURE__ */ new Set();
|
|
2431
|
+
const walk = (fields) => {
|
|
2432
|
+
for (const field of Object.values(fields)) {
|
|
2433
|
+
if (field.type === "ref" && typeof field.to === "string" && field.to.length > 0) targets.add(field.to);
|
|
2434
|
+
if (field.type === "table" && field.of) walk(field.of);
|
|
2435
|
+
}
|
|
2436
|
+
};
|
|
2437
|
+
walk(schema.fields);
|
|
2438
|
+
return [...targets];
|
|
2439
|
+
}
|
|
2440
|
+
function uniqueEmbedTargets(schema) {
|
|
2441
|
+
const targets = /* @__PURE__ */ new Set();
|
|
2442
|
+
for (const field of Object.values(schema.fields)) if (field.type === "embed" && typeof field.to === "string" && field.to.length > 0) targets.add(field.to);
|
|
2443
|
+
return [...targets];
|
|
2444
|
+
}
|
|
2445
|
+
function buildRefDisplayMap(detail) {
|
|
2446
|
+
const { fields, primaryKey } = detail.collection.schema;
|
|
2447
|
+
const displayField = "name" in fields ? "name" : "title" in fields ? "title" : primaryKey;
|
|
2448
|
+
const map = {};
|
|
2449
|
+
for (const item of detail.items) {
|
|
2450
|
+
const slugRaw = item[primaryKey];
|
|
2451
|
+
if (typeof slugRaw !== "string" || slugRaw.length === 0) continue;
|
|
2452
|
+
const displayRaw = item[displayField];
|
|
2453
|
+
map[slugRaw] = typeof displayRaw === "string" && displayRaw.length > 0 ? displayRaw : slugRaw;
|
|
2454
|
+
}
|
|
2455
|
+
return map;
|
|
2456
|
+
}
|
|
2457
|
+
function buildRefRecordMap(detail) {
|
|
2458
|
+
const { schema } = detail.collection;
|
|
2459
|
+
const map = {};
|
|
2460
|
+
for (const item of detail.items) {
|
|
2461
|
+
const slugRaw = item[schema.primaryKey];
|
|
2462
|
+
if (typeof slugRaw === "string" && slugRaw.length > 0) map[slugRaw] = deriveAll(schema, item, {});
|
|
2463
|
+
}
|
|
2464
|
+
return map;
|
|
2465
|
+
}
|
|
2466
|
+
async function loadLinkedCollections(schema, expectedSlug) {
|
|
2467
|
+
const refTargets = new Set(uniqueRefTargets(schema));
|
|
2468
|
+
const embedTargets = new Set(uniqueEmbedTargets(schema));
|
|
2469
|
+
const allTargets = [...new Set([...refTargets, ...embedTargets])];
|
|
2470
|
+
if (allTargets.length === 0) return;
|
|
2471
|
+
const binding = collectionUi();
|
|
2472
|
+
const results = await Promise.all(allTargets.map(async (target) => {
|
|
2473
|
+
try {
|
|
2474
|
+
return {
|
|
2475
|
+
target,
|
|
2476
|
+
result: await binding.fetchCollectionDetail(target)
|
|
2477
|
+
};
|
|
2478
|
+
} catch {
|
|
2479
|
+
return {
|
|
2480
|
+
target,
|
|
2481
|
+
result: { ok: false }
|
|
2482
|
+
};
|
|
2483
|
+
}
|
|
2484
|
+
}));
|
|
2485
|
+
if (collection.value?.slug !== expectedSlug) return;
|
|
2486
|
+
const nextRef = {};
|
|
2487
|
+
const nextRefRecords = {};
|
|
2488
|
+
const nextEmbed = {};
|
|
2489
|
+
for (const { target, result } of results) {
|
|
2490
|
+
if (!result.ok) continue;
|
|
2491
|
+
if (refTargets.has(target)) {
|
|
2492
|
+
nextRef[target] = buildRefDisplayMap(result.data);
|
|
2493
|
+
nextRefRecords[target] = buildRefRecordMap(result.data);
|
|
2494
|
+
}
|
|
2495
|
+
if (embedTargets.has(target)) nextEmbed[target] = {
|
|
2496
|
+
schema: result.data.collection.schema,
|
|
2497
|
+
items: result.data.items
|
|
2498
|
+
};
|
|
2499
|
+
}
|
|
2500
|
+
refCache.value = nextRef;
|
|
2501
|
+
refRecordCache.value = nextRefRecords;
|
|
2502
|
+
embedCache.value = nextEmbed;
|
|
2503
|
+
}
|
|
2504
|
+
function refDisplay(targetSlug, itemSlug) {
|
|
2505
|
+
const map = refCache.value[targetSlug];
|
|
2506
|
+
return map && map[itemSlug] || itemSlug;
|
|
2507
|
+
}
|
|
2508
|
+
function refOptions(targetSlug) {
|
|
2509
|
+
const map = refCache.value[targetSlug];
|
|
2510
|
+
if (!map) return [];
|
|
2511
|
+
return Object.entries(map).map(([slug, display]) => ({
|
|
2512
|
+
slug,
|
|
2513
|
+
display
|
|
2514
|
+
})).sort((left, right) => left.display.localeCompare(right.display));
|
|
2515
|
+
}
|
|
2516
|
+
function resolveEmbed(field) {
|
|
2517
|
+
if (field.type !== "embed" || !field.to || !field.id) return {
|
|
2518
|
+
schema: null,
|
|
2519
|
+
item: null
|
|
2520
|
+
};
|
|
2521
|
+
const data = embedCache.value[field.to];
|
|
2522
|
+
if (!data) return {
|
|
2523
|
+
schema: null,
|
|
2524
|
+
item: null
|
|
2525
|
+
};
|
|
2526
|
+
const item = data.items.find((entry) => String(entry[data.schema.primaryKey] ?? "") === field.id) ?? null;
|
|
2527
|
+
return {
|
|
2528
|
+
schema: data.schema,
|
|
2529
|
+
item
|
|
2530
|
+
};
|
|
2531
|
+
}
|
|
2532
|
+
function embedValue(field, value, record) {
|
|
2533
|
+
if (field.type === "money") return formatMoney(value, resolveCurrency(field, record), locale.value);
|
|
2534
|
+
return detailText(value);
|
|
2535
|
+
}
|
|
2536
|
+
const embedViews = computed(() => {
|
|
2537
|
+
const out = {};
|
|
2538
|
+
if (!collection.value) return out;
|
|
2539
|
+
for (const [key, field] of Object.entries(collection.value.schema.fields)) {
|
|
2540
|
+
if (field.type !== "embed") continue;
|
|
2541
|
+
const { schema, item } = resolveEmbed(field);
|
|
2542
|
+
const rows = [];
|
|
2543
|
+
if (schema && item) for (const [subKey, subField] of Object.entries(schema.fields)) {
|
|
2544
|
+
const value = item[subKey];
|
|
2545
|
+
if (value === void 0 || value === null || value === "") continue;
|
|
2546
|
+
rows.push({
|
|
2547
|
+
key: subKey,
|
|
2548
|
+
label: subField.label,
|
|
2549
|
+
type: subField.type,
|
|
2550
|
+
value,
|
|
2551
|
+
display: embedValue(subField, value, item)
|
|
2552
|
+
});
|
|
2672
2553
|
}
|
|
2554
|
+
out[key] = {
|
|
2555
|
+
found: Boolean(item),
|
|
2556
|
+
rows,
|
|
2557
|
+
targetSlug: field.to ?? "",
|
|
2558
|
+
recordId: field.id ?? ""
|
|
2559
|
+
};
|
|
2673
2560
|
}
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
sandbox: "allow-scripts allow-popups allow-popups-to-escape-sandbox",
|
|
2683
|
-
class: "w-full h-full border-0"
|
|
2684
|
-
}, null, 8, _hoisted_4$3)) : createCommentVNode("", true)]);
|
|
2685
|
-
};
|
|
2561
|
+
return out;
|
|
2562
|
+
});
|
|
2563
|
+
function resolveCurrency(field, record) {
|
|
2564
|
+
if (field.currencyField && record) {
|
|
2565
|
+
const code = record[field.currencyField];
|
|
2566
|
+
if (typeof code === "string" && code.trim().length > 0) return code;
|
|
2567
|
+
}
|
|
2568
|
+
return field.currency;
|
|
2686
2569
|
}
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
}
|
|
2570
|
+
function currencySymbol(currency) {
|
|
2571
|
+
const code = currency && currency.length > 0 ? currency : "USD";
|
|
2572
|
+
try {
|
|
2573
|
+
return new Intl.NumberFormat(locale.value, {
|
|
2574
|
+
style: "currency",
|
|
2575
|
+
currency: code
|
|
2576
|
+
}).formatToParts(0).find((entry) => entry.type === "currency")?.value ?? code;
|
|
2577
|
+
} catch {
|
|
2578
|
+
return code;
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
function formatMoney(value, currency, displayLocale) {
|
|
2582
|
+
if (value === void 0 || value === "") return "—";
|
|
2583
|
+
const amount = typeof value === "number" ? value : Number(value);
|
|
2584
|
+
if (!Number.isFinite(amount)) return String(value);
|
|
2585
|
+
const currencyCode = currency && currency.length > 0 ? currency : "USD";
|
|
2586
|
+
try {
|
|
2587
|
+
return new Intl.NumberFormat(displayLocale, {
|
|
2588
|
+
style: "currency",
|
|
2589
|
+
currency: currencyCode
|
|
2590
|
+
}).format(amount);
|
|
2591
|
+
} catch {
|
|
2592
|
+
return String(amount);
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
function formatCell(value, type) {
|
|
2596
|
+
if (value === void 0 || value === null || value === "") return "—";
|
|
2597
|
+
if (type === "markdown" && typeof value === "string") return value.length > 80 ? `${value.slice(0, 80)}…` : value;
|
|
2598
|
+
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
2599
|
+
return JSON.stringify(value);
|
|
2600
|
+
}
|
|
2601
|
+
function isExternalUrl(value) {
|
|
2602
|
+
return typeof value === "string" && /^https?:\/\//i.test(value);
|
|
2603
|
+
}
|
|
2604
|
+
function artifactUrl(value) {
|
|
2605
|
+
return collectionUi().fileAssetUrl(value);
|
|
2606
|
+
}
|
|
2607
|
+
function fileRoutePath(value) {
|
|
2608
|
+
return collectionUi().fileRoutePath(value);
|
|
2609
|
+
}
|
|
2610
|
+
function detailText(value) {
|
|
2611
|
+
if (value === void 0 || value === null || value === "") return "—";
|
|
2612
|
+
return String(value);
|
|
2613
|
+
}
|
|
2614
|
+
function tableRows(value) {
|
|
2615
|
+
if (!Array.isArray(value)) return [];
|
|
2616
|
+
return value.filter((row) => Boolean(row) && typeof row === "object" && !Array.isArray(row));
|
|
2617
|
+
}
|
|
2618
|
+
function hasTableRows(value) {
|
|
2619
|
+
return tableRows(value).length > 0;
|
|
2620
|
+
}
|
|
2621
|
+
function formatSubCell(subField, value, record) {
|
|
2622
|
+
if (subField.type === "money") return formatMoney(value, resolveCurrency(subField, record), locale.value);
|
|
2623
|
+
if (subField.type === "ref" && subField.to && typeof value === "string" && value.length > 0) return refDisplay(subField.to, value);
|
|
2624
|
+
return formatCell(value, subField.type);
|
|
2625
|
+
}
|
|
2626
|
+
function inputTypeFor(type) {
|
|
2627
|
+
if (type === "email") return "email";
|
|
2628
|
+
if (type === "number") return "number";
|
|
2629
|
+
if (type === "money") return "number";
|
|
2630
|
+
if (type === "date") return "date";
|
|
2631
|
+
if (type === "datetime") return "datetime-local";
|
|
2632
|
+
return "text";
|
|
2633
|
+
}
|
|
2634
|
+
function evaluateDerivedAgainstItem(field, fieldKey, item) {
|
|
2635
|
+
if (!field.formula || !collection.value) return null;
|
|
2636
|
+
const result = deriveAll(collection.value.schema, item, refRecordCache.value)[fieldKey];
|
|
2637
|
+
return typeof result === "number" && Number.isFinite(result) ? result : null;
|
|
2638
|
+
}
|
|
2639
|
+
function derivedDisplay(field, computedValue, record) {
|
|
2640
|
+
if (computedValue === null || computedValue === void 0) return "—";
|
|
2641
|
+
if (field.display === "money") return formatMoney(computedValue, resolveCurrency(field, record), locale.value);
|
|
2642
|
+
return formatCell(computedValue, field.display ?? "number");
|
|
2643
|
+
}
|
|
2644
|
+
return {
|
|
2645
|
+
refCache,
|
|
2646
|
+
refRecordCache,
|
|
2647
|
+
embedCache,
|
|
2648
|
+
resetLinkedCaches,
|
|
2649
|
+
loadLinkedCollections,
|
|
2650
|
+
refDisplay,
|
|
2651
|
+
refOptions,
|
|
2652
|
+
embedViews,
|
|
2653
|
+
resolveCurrency,
|
|
2654
|
+
currencySymbol,
|
|
2655
|
+
formatMoney,
|
|
2656
|
+
formatCell,
|
|
2657
|
+
detailText,
|
|
2658
|
+
isExternalUrl,
|
|
2659
|
+
artifactUrl,
|
|
2660
|
+
fileRoutePath,
|
|
2661
|
+
tableRows,
|
|
2662
|
+
hasTableRows,
|
|
2663
|
+
formatSubCell,
|
|
2664
|
+
inputTypeFor,
|
|
2665
|
+
deriveAll,
|
|
2666
|
+
evaluateDerivedAgainstItem,
|
|
2667
|
+
derivedDisplay
|
|
2668
|
+
};
|
|
2669
|
+
}
|
|
2695
2670
|
//#endregion
|
|
2696
|
-
//#region src/vue/
|
|
2697
|
-
var
|
|
2671
|
+
//#region src/vue/collectionViewMode.ts
|
|
2672
|
+
var STORAGE_KEY = "collection_view_modes";
|
|
2673
|
+
var SORT_STORAGE_KEY = "collection_sorts";
|
|
2674
|
+
var BUILT_IN_MODES = [
|
|
2675
|
+
"table",
|
|
2676
|
+
"calendar",
|
|
2677
|
+
"kanban"
|
|
2678
|
+
];
|
|
2679
|
+
/** A persisted mode is valid if it's a known built-in OR any `custom:<id>`
|
|
2680
|
+
* key (the id is validated against the live schema at render time, so an
|
|
2681
|
+
* unknown custom id simply collapses to the table there). Takes `unknown`
|
|
2682
|
+
* and type-guards `string` first: a corrupted localStorage entry could hold a
|
|
2683
|
+
* number/object, and calling `.startsWith` on that would throw. */
|
|
2684
|
+
function isValidViewMode(value) {
|
|
2685
|
+
return typeof value === "string" && (BUILT_IN_MODES.includes(value) || value.startsWith("custom:"));
|
|
2686
|
+
}
|
|
2687
|
+
function readAll() {
|
|
2688
|
+
try {
|
|
2689
|
+
const raw = localStorage.getItem(STORAGE_KEY);
|
|
2690
|
+
if (!raw) return {};
|
|
2691
|
+
const parsed = JSON.parse(raw);
|
|
2692
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
2693
|
+
} catch {
|
|
2694
|
+
return {};
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
function readCollectionViewMode(slug) {
|
|
2698
|
+
const stored = readAll()[slug];
|
|
2699
|
+
return isValidViewMode(stored) ? stored : null;
|
|
2700
|
+
}
|
|
2701
|
+
function writeCollectionViewMode(slug, view) {
|
|
2702
|
+
try {
|
|
2703
|
+
const all = readAll();
|
|
2704
|
+
all[slug] = view;
|
|
2705
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(all));
|
|
2706
|
+
} catch {}
|
|
2707
|
+
}
|
|
2708
|
+
function isSortState(value) {
|
|
2709
|
+
if (!value || typeof value !== "object") return false;
|
|
2710
|
+
const rec = value;
|
|
2711
|
+
return typeof rec.field === "string" && (rec.direction === "asc" || rec.direction === "desc");
|
|
2712
|
+
}
|
|
2713
|
+
function readAllSorts() {
|
|
2714
|
+
try {
|
|
2715
|
+
const raw = localStorage.getItem(SORT_STORAGE_KEY);
|
|
2716
|
+
if (!raw) return {};
|
|
2717
|
+
const parsed = JSON.parse(raw);
|
|
2718
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
2719
|
+
const out = {};
|
|
2720
|
+
for (const [slug, value] of Object.entries(parsed)) if (isSortState(value)) out[slug] = value;
|
|
2721
|
+
return out;
|
|
2722
|
+
} catch {
|
|
2723
|
+
return {};
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
function readCollectionSort(slug) {
|
|
2727
|
+
return readAllSorts()[slug] ?? null;
|
|
2728
|
+
}
|
|
2729
|
+
/** Persist (or, when `sort` is null, clear) the slug's active column sort. */
|
|
2730
|
+
function writeCollectionSort(slug, sort) {
|
|
2731
|
+
try {
|
|
2732
|
+
const all = Object.fromEntries(Object.entries(readAllSorts()).filter(([key]) => key !== slug));
|
|
2733
|
+
if (sort) all[slug] = sort;
|
|
2734
|
+
localStorage.setItem(SORT_STORAGE_KEY, JSON.stringify(all));
|
|
2735
|
+
} catch {}
|
|
2736
|
+
}
|
|
2698
2737
|
//#endregion
|
|
2699
2738
|
//#region src/vue/components/CollectionView.vue?vue&type=script&setup=true&lang.ts
|
|
2700
|
-
var _hoisted_1$
|
|
2701
|
-
var _hoisted_2$
|
|
2702
|
-
var _hoisted_3$
|
|
2703
|
-
var _hoisted_4$
|
|
2739
|
+
var _hoisted_1$4 = { class: "h-full flex flex-col bg-slate-50/30" };
|
|
2740
|
+
var _hoisted_2$3 = { class: "flex items-center gap-3 px-6 py-2 border-b border-slate-200 bg-white" };
|
|
2741
|
+
var _hoisted_3$3 = ["title", "aria-label"];
|
|
2742
|
+
var _hoisted_4$3 = {
|
|
2704
2743
|
key: 1,
|
|
2705
2744
|
class: "h-9 w-9 flex items-center justify-center rounded-xl bg-indigo-50 text-indigo-600 border border-indigo-100"
|
|
2706
2745
|
};
|
|
2707
|
-
var _hoisted_5$
|
|
2746
|
+
var _hoisted_5$3 = { class: "material-symbols-outlined text-xl" };
|
|
2708
2747
|
var _hoisted_6$2 = { class: "flex-1 min-w-0" };
|
|
2709
2748
|
var _hoisted_7$2 = { class: "text-base font-bold text-slate-800 truncate" };
|
|
2710
2749
|
var _hoisted_8$2 = {
|
|
@@ -2851,48 +2890,58 @@ var _hoisted_65 = {
|
|
|
2851
2890
|
class: "block truncate"
|
|
2852
2891
|
};
|
|
2853
2892
|
var _hoisted_66 = [
|
|
2893
|
+
"href",
|
|
2894
|
+
"data-testid",
|
|
2895
|
+
"onClick"
|
|
2896
|
+
];
|
|
2897
|
+
var _hoisted_67 = [
|
|
2854
2898
|
"value",
|
|
2855
2899
|
"disabled",
|
|
2856
2900
|
"data-testid",
|
|
2857
2901
|
"aria-label",
|
|
2858
2902
|
"onChange"
|
|
2859
2903
|
];
|
|
2860
|
-
var
|
|
2904
|
+
var _hoisted_68 = {
|
|
2861
2905
|
key: 0,
|
|
2862
2906
|
value: ""
|
|
2863
2907
|
};
|
|
2864
|
-
var
|
|
2865
|
-
var
|
|
2908
|
+
var _hoisted_69 = ["value"];
|
|
2909
|
+
var _hoisted_70 = {
|
|
2866
2910
|
key: 4,
|
|
2867
2911
|
class: "block truncate tabular-nums font-semibold text-slate-900"
|
|
2868
2912
|
};
|
|
2869
|
-
var
|
|
2913
|
+
var _hoisted_71 = {
|
|
2870
2914
|
key: 5,
|
|
2871
2915
|
class: "inline-flex items-center gap-1 px-2 py-0.5 rounded-lg text-[10px] font-bold bg-slate-100 text-slate-600 border border-slate-200/40"
|
|
2872
2916
|
};
|
|
2873
|
-
var
|
|
2917
|
+
var _hoisted_72 = {
|
|
2874
2918
|
key: 6,
|
|
2875
2919
|
class: "inline-block truncate tabular-nums font-bold text-indigo-900 bg-indigo-50/50 px-1.5 py-0.5 rounded border border-indigo-100/50"
|
|
2876
2920
|
};
|
|
2877
|
-
var _hoisted_72 = ["href", "data-testid"];
|
|
2878
2921
|
var _hoisted_73 = ["href", "data-testid"];
|
|
2879
|
-
var _hoisted_74 =
|
|
2922
|
+
var _hoisted_74 = ["href", "data-testid"];
|
|
2923
|
+
var _hoisted_75 = [
|
|
2924
|
+
"href",
|
|
2925
|
+
"data-testid",
|
|
2926
|
+
"onClick"
|
|
2927
|
+
];
|
|
2928
|
+
var _hoisted_76 = {
|
|
2880
2929
|
key: 10,
|
|
2881
2930
|
class: "block truncate text-slate-600"
|
|
2882
2931
|
};
|
|
2883
|
-
var
|
|
2884
|
-
var
|
|
2885
|
-
var
|
|
2886
|
-
var
|
|
2932
|
+
var _hoisted_77 = { class: "bg-white rounded-2xl shadow-2xl w-full max-w-xl flex flex-col border border-slate-200 overflow-hidden" };
|
|
2933
|
+
var _hoisted_78 = { class: "px-6 py-4 border-b border-slate-100 flex items-center gap-3 bg-slate-50/50" };
|
|
2934
|
+
var _hoisted_79 = { class: "flex-1" };
|
|
2935
|
+
var _hoisted_80 = {
|
|
2887
2936
|
id: "collections-chat-title",
|
|
2888
2937
|
class: "text-sm font-bold text-slate-800 uppercase tracking-wide"
|
|
2889
2938
|
};
|
|
2890
|
-
var
|
|
2891
|
-
var
|
|
2892
|
-
var
|
|
2893
|
-
var
|
|
2894
|
-
var
|
|
2895
|
-
var
|
|
2939
|
+
var _hoisted_81 = { class: "text-xs text-slate-400 font-semibold" };
|
|
2940
|
+
var _hoisted_82 = ["aria-label"];
|
|
2941
|
+
var _hoisted_83 = { class: "px-6 py-5" };
|
|
2942
|
+
var _hoisted_84 = ["placeholder", "onKeydown"];
|
|
2943
|
+
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" };
|
|
2944
|
+
var _hoisted_86 = ["disabled"];
|
|
2896
2945
|
//#endregion
|
|
2897
2946
|
//#region src/vue/components/CollectionView.vue
|
|
2898
2947
|
var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
@@ -2913,6 +2962,18 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
2913
2962
|
const cui = collectionUi();
|
|
2914
2963
|
const { confirm: openConfirm, unpin, pinToggle, startChat } = cui;
|
|
2915
2964
|
const appApi = { startNewChat: startChat };
|
|
2965
|
+
function onRefLinkClick(event, targetSlug, recordId) {
|
|
2966
|
+
event.stopPropagation();
|
|
2967
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
2968
|
+
event.preventDefault();
|
|
2969
|
+
cui.navigateToRecord(targetSlug, recordId);
|
|
2970
|
+
}
|
|
2971
|
+
function onFileLinkClick(event, path) {
|
|
2972
|
+
event.stopPropagation();
|
|
2973
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
2974
|
+
event.preventDefault();
|
|
2975
|
+
cui.navigate?.(path);
|
|
2976
|
+
}
|
|
2916
2977
|
/** Embedded when a `slug` prop is supplied; standalone (route-driven)
|
|
2917
2978
|
* otherwise. Switches the slug/selected source and the open/close
|
|
2918
2979
|
* navigation behaviour. */
|
|
@@ -3859,9 +3920,8 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
3859
3920
|
openDay.value = viewing.value ? dayOfItem(viewing.value) : null;
|
|
3860
3921
|
});
|
|
3861
3922
|
return (_ctx, _cache) => {
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
createElementVNode("header", _hoisted_2$2, [
|
|
3923
|
+
return openBlock(), createElementBlock("div", _hoisted_1$4, [
|
|
3924
|
+
createElementVNode("header", _hoisted_2$3, [
|
|
3865
3925
|
!embedded.value ? (openBlock(), createElementBlock("button", {
|
|
3866
3926
|
key: 0,
|
|
3867
3927
|
type: "button",
|
|
@@ -3870,8 +3930,8 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
3870
3930
|
"aria-label": unref(t)("collectionsView.backToIndex"),
|
|
3871
3931
|
"data-testid": "collections-back",
|
|
3872
3932
|
onClick: goBack
|
|
3873
|
-
}, [..._cache[
|
|
3874
|
-
collection.value ? (openBlock(), createElementBlock("div", _hoisted_4$
|
|
3933
|
+
}, [..._cache[23] || (_cache[23] = [createElementVNode("span", { class: "material-icons text-lg" }, "arrow_back", -1)])], 8, _hoisted_3$3)) : createCommentVNode("", true),
|
|
3934
|
+
collection.value ? (openBlock(), createElementBlock("div", _hoisted_4$3, [createElementVNode("span", _hoisted_5$3, toDisplayString(collection.value.icon), 1)])) : createCommentVNode("", true),
|
|
3875
3935
|
createElementVNode("div", _hoisted_6$2, [createElementVNode("h1", _hoisted_7$2, toDisplayString(collection.value?.title ?? unref(t)("collectionsView.title")), 1), collection.value ? (openBlock(), createElementBlock("span", _hoisted_8$2, toDisplayString(collection.value.slug), 1)) : createCommentVNode("", true)]),
|
|
3876
3936
|
collection.value && !embedded.value ? (openBlock(), createBlock(resolveDynamicComponent(unref(pinToggle)), {
|
|
3877
3937
|
key: 2,
|
|
@@ -3899,7 +3959,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
3899
3959
|
class: "h-8 px-2.5 flex items-center gap-1 rounded border border-indigo-200 bg-white hover:bg-indigo-50 text-indigo-600 font-bold text-xs transition-colors",
|
|
3900
3960
|
"data-testid": "collections-chat",
|
|
3901
3961
|
onClick: openChat
|
|
3902
|
-
}, [_cache[
|
|
3962
|
+
}, [_cache[24] || (_cache[24] = createElementVNode("span", { class: "material-icons text-sm" }, "forum", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.chat")), 1)])) : createCommentVNode("", true),
|
|
3903
3963
|
(openBlock(true), createElementBlock(Fragment, null, renderList(collectionActions.value, (action) => {
|
|
3904
3964
|
return openBlock(), createElementBlock("button", {
|
|
3905
3965
|
key: action.id,
|
|
@@ -3916,7 +3976,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
3916
3976
|
class: "h-8 px-2.5 flex items-center gap-1 rounded bg-indigo-600 hover:bg-indigo-700 text-white font-bold text-xs transition-colors shadow-sm",
|
|
3917
3977
|
"data-testid": "collections-add-item",
|
|
3918
3978
|
onClick: openCreate
|
|
3919
|
-
}, [_cache[
|
|
3979
|
+
}, [_cache[25] || (_cache[25] = createElementVNode("span", { class: "material-icons text-sm" }, "add", -1)), createElementVNode("span", null, toDisplayString(unref(t)("common.add")), 1)])) : createCommentVNode("", true),
|
|
3920
3980
|
canDeleteCollection.value && !embedded.value ? (openBlock(), createElementBlock("button", {
|
|
3921
3981
|
key: 6,
|
|
3922
3982
|
type: "button",
|
|
@@ -3925,7 +3985,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
3925
3985
|
"aria-label": unref(t)("collectionsView.deleteCollection"),
|
|
3926
3986
|
"data-testid": "collections-delete",
|
|
3927
3987
|
onClick: confirmCollectionDelete
|
|
3928
|
-
}, [..._cache[
|
|
3988
|
+
}, [..._cache[26] || (_cache[26] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_13$2)) : createCommentVNode("", true),
|
|
3929
3989
|
canDeleteFeed.value && !embedded.value ? (openBlock(), createElementBlock("button", {
|
|
3930
3990
|
key: 7,
|
|
3931
3991
|
type: "button",
|
|
@@ -3934,10 +3994,10 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
3934
3994
|
"aria-label": unref(t)("collectionsView.deleteFeed"),
|
|
3935
3995
|
"data-testid": "feeds-delete",
|
|
3936
3996
|
onClick: confirmFeedDelete
|
|
3937
|
-
}, [..._cache[
|
|
3997
|
+
}, [..._cache[27] || (_cache[27] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_14$2)) : createCommentVNode("", true)
|
|
3938
3998
|
]),
|
|
3939
3999
|
collection.value && (items.value.length > 0 || hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value) ? (openBlock(), createElementBlock("div", _hoisted_15$2, [items.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_16$1, [
|
|
3940
|
-
_cache[
|
|
4000
|
+
_cache[29] || (_cache[29] = createElementVNode("span", { class: "absolute inset-y-0 left-0 flex items-center pl-3 text-slate-400 pointer-events-none" }, [createElementVNode("span", { class: "material-icons text-lg" }, "search")], -1)),
|
|
3941
4001
|
withDirectives(createElementVNode("input", {
|
|
3942
4002
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchQuery.value = $event),
|
|
3943
4003
|
type: "text",
|
|
@@ -3951,7 +4011,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
3951
4011
|
"aria-label": unref(t)("collectionsView.clearSearch"),
|
|
3952
4012
|
class: "absolute inset-y-0 right-0 flex items-center pr-2.5 text-slate-400 hover:text-slate-600",
|
|
3953
4013
|
onClick: _cache[1] || (_cache[1] = ($event) => searchQuery.value = "")
|
|
3954
|
-
}, [..._cache[
|
|
4014
|
+
}, [..._cache[28] || (_cache[28] = [createElementVNode("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_18$1)) : createCommentVNode("", true)
|
|
3955
4015
|
])) : createCommentVNode("", true), createElementVNode("div", _hoisted_19$1, [
|
|
3956
4016
|
hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value ? (openBlock(), createElementBlock("div", {
|
|
3957
4017
|
key: 0,
|
|
@@ -3965,7 +4025,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
3965
4025
|
"aria-pressed": activeView.value === "table",
|
|
3966
4026
|
"data-testid": "collection-view-toggle-table",
|
|
3967
4027
|
onClick: _cache[2] || (_cache[2] = ($event) => setView("table"))
|
|
3968
|
-
}, [_cache[
|
|
4028
|
+
}, [_cache[30] || (_cache[30] = createElementVNode("span", { class: "material-icons text-sm" }, "table_rows", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewTable")), 1)], 10, _hoisted_21$1),
|
|
3969
4029
|
hasCalendar.value ? (openBlock(), createElementBlock("button", {
|
|
3970
4030
|
key: 0,
|
|
3971
4031
|
type: "button",
|
|
@@ -3973,7 +4033,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
3973
4033
|
"aria-pressed": activeView.value === "calendar",
|
|
3974
4034
|
"data-testid": "collection-view-toggle-calendar",
|
|
3975
4035
|
onClick: _cache[3] || (_cache[3] = ($event) => setView("calendar"))
|
|
3976
|
-
}, [_cache[
|
|
4036
|
+
}, [_cache[31] || (_cache[31] = createElementVNode("span", { class: "material-icons text-sm" }, "calendar_month", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewCalendar")), 1)], 10, _hoisted_22$1)) : createCommentVNode("", true),
|
|
3977
4037
|
hasKanban.value ? (openBlock(), createElementBlock("button", {
|
|
3978
4038
|
key: 1,
|
|
3979
4039
|
type: "button",
|
|
@@ -3981,7 +4041,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
3981
4041
|
"aria-pressed": activeView.value === "kanban",
|
|
3982
4042
|
"data-testid": "collection-view-toggle-kanban",
|
|
3983
4043
|
onClick: _cache[4] || (_cache[4] = ($event) => setView("kanban"))
|
|
3984
|
-
}, [_cache[
|
|
4044
|
+
}, [_cache[32] || (_cache[32] = createElementVNode("span", { class: "material-icons text-sm" }, "view_kanban", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewKanban")), 1)], 10, _hoisted_23$1)) : createCommentVNode("", true),
|
|
3985
4045
|
(openBlock(true), createElementBlock(Fragment, null, renderList(customViews.value, (cv) => {
|
|
3986
4046
|
return openBlock(), createElementBlock("button", {
|
|
3987
4047
|
key: cv.id,
|
|
@@ -4000,7 +4060,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
4000
4060
|
"aria-label": unref(t)("collectionsView.addView"),
|
|
4001
4061
|
"data-testid": "collection-view-add",
|
|
4002
4062
|
onClick: addCustomView
|
|
4003
|
-
}, [..._cache[
|
|
4063
|
+
}, [..._cache[33] || (_cache[33] = [createElementVNode("span", { class: "material-icons text-sm" }, "add", -1)])], 8, _hoisted_26)) : createCommentVNode("", true),
|
|
4004
4064
|
canConfigureViews.value ? (openBlock(), createElementBlock("button", {
|
|
4005
4065
|
key: 3,
|
|
4006
4066
|
type: "button",
|
|
@@ -4009,7 +4069,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
4009
4069
|
"aria-label": unref(t)("collectionsView.config.open"),
|
|
4010
4070
|
"data-testid": "collection-config-open",
|
|
4011
4071
|
onClick: _cache[5] || (_cache[5] = ($event) => configOpen.value = true)
|
|
4012
|
-
}, [..._cache[
|
|
4072
|
+
}, [..._cache[34] || (_cache[34] = [createElementVNode("span", { class: "material-icons text-sm" }, "settings", -1)])], 8, _hoisted_27)) : createCommentVNode("", true)
|
|
4013
4073
|
], 8, _hoisted_20$1)) : createCommentVNode("", true),
|
|
4014
4074
|
calendarActive.value && dateFields.value.length > 1 ? (openBlock(), createElementBlock("select", {
|
|
4015
4075
|
key: 1,
|
|
@@ -4043,16 +4103,16 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
4043
4103
|
})), 1)) : createCommentVNode("", true)
|
|
4044
4104
|
])])) : createCommentVNode("", true),
|
|
4045
4105
|
collection.value && dataIssues.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_33, [
|
|
4046
|
-
_cache[
|
|
4106
|
+
_cache[36] || (_cache[36] = createElementVNode("span", { class: "material-icons text-amber-600" }, "warning", -1)),
|
|
4047
4107
|
createElementVNode("span", _hoisted_34, toDisplayString(unref(t)("collectionsView.dataIssuesDetected", { count: dataIssues.value.length })), 1),
|
|
4048
4108
|
createElementVNode("button", {
|
|
4049
4109
|
type: "button",
|
|
4050
4110
|
class: "h-8 px-2.5 flex items-center gap-1 rounded border border-amber-300 bg-white hover:bg-amber-100 text-amber-700 font-bold text-xs transition-colors",
|
|
4051
4111
|
"data-testid": "collections-repair",
|
|
4052
4112
|
onClick: repairCollection
|
|
4053
|
-
}, [_cache[
|
|
4113
|
+
}, [_cache[35] || (_cache[35] = createElementVNode("span", { class: "material-icons text-sm" }, "build", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.repair")), 1)])
|
|
4054
4114
|
])) : createCommentVNode("", true),
|
|
4055
|
-
createElementVNode("div", _hoisted_35, [loading.value ? (openBlock(), createElementBlock("div", _hoisted_36, [_cache[
|
|
4115
|
+
createElementVNode("div", _hoisted_35, [loading.value ? (openBlock(), createElementBlock("div", _hoisted_36, [_cache[37] || (_cache[37] = createElementVNode("div", { class: "h-8 w-8 border-2 border-indigo-600/20 border-t-indigo-600 rounded-full animate-spin" }, null, -1)), createElementVNode("span", null, toDisplayString(unref(t)("common.loading")), 1)])) : loadError.value ? (openBlock(), createElementBlock("div", _hoisted_37, [_cache[38] || (_cache[38] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)), createElementVNode("span", null, toDisplayString(loadError.value === "not-found" ? unref(t)("collectionsView.notFound") : `${unref(t)("collectionsView.loadFailed")}: ${loadError.value}`), 1)])) : !collection.value ? (openBlock(), createElementBlock("div", _hoisted_38)) : calendarActive.value ? (openBlock(), createElementBlock("div", _hoisted_39, [createVNode(CollectionCalendarView_default, {
|
|
4056
4116
|
schema: collection.value.schema,
|
|
4057
4117
|
items: filteredItems.value,
|
|
4058
4118
|
"anchor-field": calendarAnchorField.value,
|
|
@@ -4137,14 +4197,14 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
4137
4197
|
"can-create",
|
|
4138
4198
|
"show-detail"
|
|
4139
4199
|
])) : createCommentVNode("", true)])) : kanbanActive.value ? (openBlock(), createElementBlock("div", _hoisted_40, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_41, [
|
|
4140
|
-
_cache[
|
|
4200
|
+
_cache[40] || (_cache[40] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
|
|
4141
4201
|
createElementVNode("span", _hoisted_42, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
|
|
4142
4202
|
createElementVNode("button", {
|
|
4143
4203
|
type: "button",
|
|
4144
4204
|
class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
|
|
4145
4205
|
"aria-label": unref(t)("common.close"),
|
|
4146
4206
|
onClick: _cache[10] || (_cache[10] = ($event) => inlineError.value = null)
|
|
4147
|
-
}, [..._cache[
|
|
4207
|
+
}, [..._cache[39] || (_cache[39] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_43)
|
|
4148
4208
|
])) : createCommentVNode("", true), createElementVNode("div", _hoisted_44, [createVNode(CollectionKanbanView_default, {
|
|
4149
4209
|
schema: collection.value.schema,
|
|
4150
4210
|
items: filteredItems.value,
|
|
@@ -4162,8 +4222,8 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
4162
4222
|
])])])) : activeCustomView.value ? (openBlock(), createElementBlock("div", _hoisted_45, [createVNode(CollectionCustomView_default, {
|
|
4163
4223
|
slug: collection.value.slug,
|
|
4164
4224
|
view: activeCustomView.value
|
|
4165
|
-
}, null, 8, ["slug", "view"])])) : items.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_46, [_cache[
|
|
4166
|
-
_cache[
|
|
4225
|
+
}, null, 8, ["slug", "view"])])) : items.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_46, [_cache[41] || (_cache[41] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "folder_open", -1)), createElementVNode("p", _hoisted_47, toDisplayString(unref(t)("collectionsView.itemsEmpty")), 1)])) : filteredItems.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_48, [
|
|
4226
|
+
_cache[42] || (_cache[42] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "search_off", -1)),
|
|
4167
4227
|
createElementVNode("p", _hoisted_49, toDisplayString(unref(t)("collectionsView.noMatchingItems")), 1),
|
|
4168
4228
|
createElementVNode("button", {
|
|
4169
4229
|
type: "button",
|
|
@@ -4171,14 +4231,14 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
4171
4231
|
onClick: _cache[11] || (_cache[11] = ($event) => searchQuery.value = "")
|
|
4172
4232
|
}, toDisplayString(unref(t)("collectionsView.clearSearch")), 1)
|
|
4173
4233
|
])) : (openBlock(), createElementBlock("div", _hoisted_50, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_51, [
|
|
4174
|
-
_cache[
|
|
4234
|
+
_cache[44] || (_cache[44] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
|
|
4175
4235
|
createElementVNode("span", _hoisted_52, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
|
|
4176
4236
|
createElementVNode("button", {
|
|
4177
4237
|
type: "button",
|
|
4178
4238
|
class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
|
|
4179
4239
|
"aria-label": unref(t)("common.close"),
|
|
4180
4240
|
onClick: _cache[12] || (_cache[12] = ($event) => inlineError.value = null)
|
|
4181
|
-
}, [..._cache[
|
|
4241
|
+
}, [..._cache[43] || (_cache[43] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_53)
|
|
4182
4242
|
])) : createCommentVNode("", true), createElementVNode("table", _hoisted_54, [createElementVNode("thead", null, [createElementVNode("tr", _hoisted_55, [(openBlock(true), createElementBlock(Fragment, null, renderList(listColumnFields.value, ([key, field]) => {
|
|
4183
4243
|
return openBlock(), createElementBlock("th", {
|
|
4184
4244
|
key,
|
|
@@ -4231,57 +4291,48 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
4231
4291
|
"aria-label": field.label,
|
|
4232
4292
|
onClick: _cache[15] || (_cache[15] = withModifiers(() => {}, ["stop"])),
|
|
4233
4293
|
onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.checked)
|
|
4234
|
-
}, null, 40, _hoisted_64)) : field.type === "ref" && field.to && typeof item[key] === "string" && item[key] ? (openBlock(), createElementBlock("span", _hoisted_65, [
|
|
4235
|
-
|
|
4236
|
-
path: `/collections/${field.to}`,
|
|
4237
|
-
query: { selected: String(item[key]) }
|
|
4238
|
-
},
|
|
4294
|
+
}, null, 40, _hoisted_64)) : field.type === "ref" && field.to && typeof item[key] === "string" && item[key] ? (openBlock(), createElementBlock("span", _hoisted_65, [createElementVNode("a", {
|
|
4295
|
+
href: unref(cui).recordHref?.(field.to, String(item[key])),
|
|
4239
4296
|
class: "text-indigo-600 hover:text-indigo-800 hover:underline font-semibold",
|
|
4240
4297
|
"data-testid": `collections-ref-link-${key}-${item[key]}`,
|
|
4241
|
-
onClick:
|
|
4242
|
-
}, {
|
|
4243
|
-
default: withCtx(() => [createTextVNode(toDisplayString(unref(refDisplay)(field.to, String(item[key]))), 1)]),
|
|
4244
|
-
_: 2
|
|
4245
|
-
}, 1032, ["to", "data-testid"])])) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? (openBlock(), createElementBlock("select", {
|
|
4298
|
+
onClick: ($event) => onRefLinkClick($event, field.to, String(item[key]))
|
|
4299
|
+
}, toDisplayString(unref(refDisplay)(field.to, String(item[key]))), 9, _hoisted_66)])) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? (openBlock(), createElementBlock("select", {
|
|
4246
4300
|
key: 3,
|
|
4247
4301
|
value: item[key] == null ? "" : String(item[key]),
|
|
4248
4302
|
disabled: isRowInlineSaving(item),
|
|
4249
4303
|
class: normalizeClass(["rounded-lg border px-2 py-0.5 text-[11px] font-semibold focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed", enumControlClass(String(key), item[key])]),
|
|
4250
4304
|
"data-testid": `collections-inline-enum-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
4251
4305
|
"aria-label": field.label,
|
|
4252
|
-
onClick: _cache[
|
|
4306
|
+
onClick: _cache[16] || (_cache[16] = withModifiers(() => {}, ["stop"])),
|
|
4253
4307
|
onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.value)
|
|
4254
|
-
}, [showEnumPlaceholder(item, String(key)) ? (openBlock(), createElementBlock("option",
|
|
4308
|
+
}, [showEnumPlaceholder(item, String(key)) ? (openBlock(), createElementBlock("option", _hoisted_68, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(field.values, (value) => {
|
|
4255
4309
|
return openBlock(), createElementBlock("option", {
|
|
4256
4310
|
key: value,
|
|
4257
4311
|
value
|
|
4258
|
-
}, toDisplayString(value), 9,
|
|
4259
|
-
}), 128))], 42,
|
|
4312
|
+
}, toDisplayString(value), 9, _hoisted_69);
|
|
4313
|
+
}), 128))], 42, _hoisted_67)) : field.type === "money" ? (openBlock(), createElementBlock("span", _hoisted_70, toDisplayString(unref(formatMoney)(item[key], unref(resolveCurrency)(field, item), unref(locale))), 1)) : field.type === "table" ? (openBlock(), createElementBlock("span", _hoisted_71, [_cache[45] || (_cache[45] = createElementVNode("span", { class: "material-icons text-[11px]" }, "list", -1)), createElementVNode("span", null, toDisplayString(tableSummary(item[key])), 1)])) : field.type === "derived" ? (openBlock(), createElementBlock("span", _hoisted_72, toDisplayString(unref(derivedDisplay)(field, unref(evaluateDerivedAgainstItem)(field, String(key), item), item)), 1)) : field.type !== "file" && unref(isExternalUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
|
|
4260
4314
|
key: 7,
|
|
4261
4315
|
href: String(item[key]),
|
|
4262
4316
|
target: "_blank",
|
|
4263
4317
|
rel: "noopener noreferrer",
|
|
4264
4318
|
class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
|
|
4265
4319
|
"data-testid": `collections-url-link-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
4266
|
-
onClick: _cache[
|
|
4267
|
-
}, toDisplayString(String(item[key])), 9,
|
|
4320
|
+
onClick: _cache[17] || (_cache[17] = withModifiers(() => {}, ["stop"]))
|
|
4321
|
+
}, toDisplayString(String(item[key])), 9, _hoisted_73)) : field.type === "file" && unref(artifactUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
|
|
4268
4322
|
key: 8,
|
|
4269
4323
|
href: unref(artifactUrl)(item[key]) ?? void 0,
|
|
4270
4324
|
target: "_blank",
|
|
4271
4325
|
rel: "noopener noreferrer",
|
|
4272
4326
|
class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
|
|
4273
4327
|
"data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
4274
|
-
onClick: _cache[
|
|
4275
|
-
}, toDisplayString(String(item[key])), 9,
|
|
4328
|
+
onClick: _cache[18] || (_cache[18] = withModifiers(() => {}, ["stop"]))
|
|
4329
|
+
}, toDisplayString(String(item[key])), 9, _hoisted_74)) : field.type === "file" && unref(fileRoutePath)(item[key]) ? (openBlock(), createElementBlock("a", {
|
|
4276
4330
|
key: 9,
|
|
4277
|
-
|
|
4331
|
+
href: unref(fileRoutePath)(item[key]) ?? void 0,
|
|
4278
4332
|
class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
|
|
4279
4333
|
"data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
4280
|
-
onClick:
|
|
4281
|
-
},
|
|
4282
|
-
default: withCtx(() => [createTextVNode(toDisplayString(String(item[key])), 1)]),
|
|
4283
|
-
_: 2
|
|
4284
|
-
}, 1032, ["to", "data-testid"])) : (openBlock(), createElementBlock("span", _hoisted_74, toDisplayString(unref(formatCell)(item[key], field.type)), 1))], 64)) : createCommentVNode("", true)]);
|
|
4334
|
+
onClick: ($event) => onFileLinkClick($event, unref(fileRoutePath)(item[key]) ?? "")
|
|
4335
|
+
}, toDisplayString(String(item[key])), 9, _hoisted_75)) : (openBlock(), createElementBlock("span", _hoisted_76, toDisplayString(unref(formatCell)(item[key], field.type)), 1))], 64)) : createCommentVNode("", true)]);
|
|
4285
4336
|
}), 128))], 42, _hoisted_62);
|
|
4286
4337
|
}), 128))])])]))]),
|
|
4287
4338
|
collection.value && (viewing.value || editing.value) && !(calendarActive.value && openDay.value) ? (openBlock(), createBlock(CollectionRecordModal_default, {
|
|
@@ -4290,7 +4341,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
4290
4341
|
}, {
|
|
4291
4342
|
default: withCtx(() => [createVNode(CollectionRecordPanel_default, {
|
|
4292
4343
|
editing: editing.value,
|
|
4293
|
-
"onUpdate:editing": _cache[
|
|
4344
|
+
"onUpdate:editing": _cache[19] || (_cache[19] = ($event) => editing.value = $event),
|
|
4294
4345
|
collection: collection.value,
|
|
4295
4346
|
viewing: viewing.value,
|
|
4296
4347
|
saving: saving.value,
|
|
@@ -4308,7 +4359,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
4308
4359
|
onCancel: cancelEditor,
|
|
4309
4360
|
onEdit: editFromView,
|
|
4310
4361
|
onClose: closeView,
|
|
4311
|
-
onDelete: _cache[
|
|
4362
|
+
onDelete: _cache[20] || (_cache[20] = ($event) => viewing.value && confirmDelete(viewing.value)),
|
|
4312
4363
|
onRunAction: runAction
|
|
4313
4364
|
}, null, 8, [
|
|
4314
4365
|
"editing",
|
|
@@ -4334,7 +4385,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
4334
4385
|
title: collection.value.title,
|
|
4335
4386
|
views: customViews.value,
|
|
4336
4387
|
onChanged: onViewsChanged,
|
|
4337
|
-
onClose: _cache[
|
|
4388
|
+
onClose: _cache[21] || (_cache[21] = ($event) => configOpen.value = false)
|
|
4338
4389
|
}, null, 8, [
|
|
4339
4390
|
"slug",
|
|
4340
4391
|
"title",
|
|
@@ -4349,29 +4400,29 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
4349
4400
|
"data-testid": "collections-chat-modal",
|
|
4350
4401
|
onClick: withModifiers(closeChat, ["self"]),
|
|
4351
4402
|
onKeydown: withKeys(closeChat, ["esc"])
|
|
4352
|
-
}, [createElementVNode("div",
|
|
4353
|
-
createElementVNode("header",
|
|
4354
|
-
_cache[
|
|
4355
|
-
createElementVNode("div",
|
|
4403
|
+
}, [createElementVNode("div", _hoisted_77, [
|
|
4404
|
+
createElementVNode("header", _hoisted_78, [
|
|
4405
|
+
_cache[47] || (_cache[47] = createElementVNode("div", { class: "h-9 w-9 flex items-center justify-center rounded-xl bg-indigo-50 text-indigo-600 border border-indigo-100/50" }, [createElementVNode("span", { class: "material-icons text-lg" }, "forum")], -1)),
|
|
4406
|
+
createElementVNode("div", _hoisted_79, [createElementVNode("h2", _hoisted_80, toDisplayString(unref(t)("collectionsView.chatTitle")), 1), createElementVNode("span", _hoisted_81, toDisplayString(collection.value.title), 1)]),
|
|
4356
4407
|
createElementVNode("button", {
|
|
4357
4408
|
type: "button",
|
|
4358
4409
|
class: "h-8 w-8 flex items-center justify-center rounded text-slate-400 hover:bg-slate-200/50 hover:text-slate-600 transition-colors",
|
|
4359
4410
|
"aria-label": unref(t)("common.close"),
|
|
4360
4411
|
"data-testid": "collections-chat-close",
|
|
4361
4412
|
onClick: closeChat
|
|
4362
|
-
}, [..._cache[
|
|
4413
|
+
}, [..._cache[46] || (_cache[46] = [createElementVNode("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_82)
|
|
4363
4414
|
]),
|
|
4364
|
-
createElementVNode("div",
|
|
4415
|
+
createElementVNode("div", _hoisted_83, [withDirectives(createElementVNode("textarea", {
|
|
4365
4416
|
ref_key: "chatInputEl",
|
|
4366
4417
|
ref: chatInputEl,
|
|
4367
|
-
"onUpdate:modelValue": _cache[
|
|
4418
|
+
"onUpdate:modelValue": _cache[22] || (_cache[22] = ($event) => chatMessage.value = $event),
|
|
4368
4419
|
rows: "4",
|
|
4369
4420
|
placeholder: unref(t)("collectionsView.chatPlaceholder"),
|
|
4370
4421
|
class: "w-full bg-slate-50 border border-slate-200/80 rounded-xl px-3 py-2.5 text-sm 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",
|
|
4371
4422
|
"data-testid": "collections-chat-input",
|
|
4372
4423
|
onKeydown: [withKeys(withModifiers(submitChat, ["meta"]), ["enter"]), withKeys(withModifiers(submitChat, ["ctrl"]), ["enter"])]
|
|
4373
|
-
}, null, 40,
|
|
4374
|
-
createElementVNode("footer",
|
|
4424
|
+
}, null, 40, _hoisted_84), [[vModelText, chatMessage.value]])]),
|
|
4425
|
+
createElementVNode("footer", _hoisted_85, [createElementVNode("button", {
|
|
4375
4426
|
type: "button",
|
|
4376
4427
|
class: "h-8 px-2.5 rounded text-xs font-bold text-slate-500 hover:bg-slate-200/50 transition-colors",
|
|
4377
4428
|
"data-testid": "collections-chat-cancel",
|
|
@@ -4382,13 +4433,121 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
|
|
|
4382
4433
|
disabled: !chatMessage.value.trim(),
|
|
4383
4434
|
"data-testid": "collections-chat-send",
|
|
4384
4435
|
onClick: submitChat
|
|
4385
|
-
}, toDisplayString(unref(t)("collectionsView.chatStart")), 9,
|
|
4436
|
+
}, toDisplayString(unref(t)("collectionsView.chatStart")), 9, _hoisted_86)])
|
|
4386
4437
|
])], 32)) : createCommentVNode("", true)
|
|
4387
4438
|
]);
|
|
4388
4439
|
};
|
|
4389
4440
|
}
|
|
4390
4441
|
});
|
|
4391
4442
|
//#endregion
|
|
4443
|
+
//#region src/vue/chat/View.vue?vue&type=script&setup=true&lang.ts
|
|
4444
|
+
var _hoisted_1$3 = {
|
|
4445
|
+
class: "w-full h-full",
|
|
4446
|
+
"data-testid": "present-collection"
|
|
4447
|
+
};
|
|
4448
|
+
//#endregion
|
|
4449
|
+
//#region src/vue/chat/View.vue
|
|
4450
|
+
var View_default = /* @__PURE__ */ defineComponent({
|
|
4451
|
+
__name: "View",
|
|
4452
|
+
props: {
|
|
4453
|
+
selectedResult: {},
|
|
4454
|
+
sendTextMessage: { type: Function }
|
|
4455
|
+
},
|
|
4456
|
+
emits: ["updateResult"],
|
|
4457
|
+
setup(__props, { emit: __emit }) {
|
|
4458
|
+
const props = __props;
|
|
4459
|
+
const emit = __emit;
|
|
4460
|
+
const data = computed(() => props.selectedResult?.data ?? props.selectedResult?.jsonData ?? null);
|
|
4461
|
+
const slug = computed(() => data.value?.collectionSlug);
|
|
4462
|
+
const viewState = computed(() => props.selectedResult?.viewState ?? null);
|
|
4463
|
+
/** Open record: the card-local `viewState.selected` once the user has
|
|
4464
|
+
* navigated within the card (including an explicit close → null), else
|
|
4465
|
+
* the tool's initial `itemId`. */
|
|
4466
|
+
const selected = computed(() => {
|
|
4467
|
+
const state = viewState.value;
|
|
4468
|
+
if (state && "selected" in state) return state.selected ?? void 0;
|
|
4469
|
+
return data.value?.itemId;
|
|
4470
|
+
});
|
|
4471
|
+
function onSelect(itemId) {
|
|
4472
|
+
if (!props.selectedResult) return;
|
|
4473
|
+
emit("updateResult", {
|
|
4474
|
+
...props.selectedResult,
|
|
4475
|
+
viewState: {
|
|
4476
|
+
...viewState.value,
|
|
4477
|
+
selected: itemId
|
|
4478
|
+
}
|
|
4479
|
+
});
|
|
4480
|
+
}
|
|
4481
|
+
function onViewStateChange(state) {
|
|
4482
|
+
if (!props.selectedResult) return;
|
|
4483
|
+
const current = viewState.value;
|
|
4484
|
+
if (current?.view === state.view && current?.anchorField === state.anchorField && current?.groupField === state.groupField) return;
|
|
4485
|
+
emit("updateResult", {
|
|
4486
|
+
...props.selectedResult,
|
|
4487
|
+
viewState: {
|
|
4488
|
+
...current,
|
|
4489
|
+
view: state.view,
|
|
4490
|
+
anchorField: state.anchorField,
|
|
4491
|
+
groupField: state.groupField
|
|
4492
|
+
}
|
|
4493
|
+
});
|
|
4494
|
+
}
|
|
4495
|
+
return (_ctx, _cache) => {
|
|
4496
|
+
return openBlock(), createElementBlock("div", _hoisted_1$3, [slug.value ? (openBlock(), createBlock(CollectionView_default, {
|
|
4497
|
+
key: 0,
|
|
4498
|
+
slug: slug.value,
|
|
4499
|
+
selected: selected.value,
|
|
4500
|
+
"initial-view": viewState.value?.view,
|
|
4501
|
+
"initial-anchor-field": viewState.value?.anchorField,
|
|
4502
|
+
"initial-group-field": viewState.value?.groupField,
|
|
4503
|
+
"send-text-message": __props.sendTextMessage,
|
|
4504
|
+
onSelect,
|
|
4505
|
+
onViewStateChange
|
|
4506
|
+
}, null, 8, [
|
|
4507
|
+
"slug",
|
|
4508
|
+
"selected",
|
|
4509
|
+
"initial-view",
|
|
4510
|
+
"initial-anchor-field",
|
|
4511
|
+
"initial-group-field",
|
|
4512
|
+
"send-text-message"
|
|
4513
|
+
])) : createCommentVNode("", true)]);
|
|
4514
|
+
};
|
|
4515
|
+
}
|
|
4516
|
+
});
|
|
4517
|
+
//#endregion
|
|
4518
|
+
//#region src/vue/chat/Preview.vue?vue&type=script&setup=true&lang.ts
|
|
4519
|
+
var _hoisted_1$2 = { class: "w-full h-full flex flex-col items-center justify-center p-4 bg-gradient-to-br from-indigo-50 to-slate-50 rounded-lg border-2 border-gray-200" };
|
|
4520
|
+
var _hoisted_2$2 = { class: "text-center" };
|
|
4521
|
+
var _hoisted_3$2 = { class: "text-gray-900 font-bold text-lg mb-1 line-clamp-2" };
|
|
4522
|
+
var _hoisted_4$2 = {
|
|
4523
|
+
key: 0,
|
|
4524
|
+
class: "text-gray-600 text-sm"
|
|
4525
|
+
};
|
|
4526
|
+
var _hoisted_5$2 = {
|
|
4527
|
+
key: 1,
|
|
4528
|
+
class: "text-gray-500 text-sm"
|
|
4529
|
+
};
|
|
4530
|
+
//#endregion
|
|
4531
|
+
//#region src/vue/chat/Preview.vue
|
|
4532
|
+
var Preview_default = /* @__PURE__ */ defineComponent({
|
|
4533
|
+
__name: "Preview",
|
|
4534
|
+
props: { result: {} },
|
|
4535
|
+
setup(__props) {
|
|
4536
|
+
const { t } = useCollectionI18n();
|
|
4537
|
+
const props = __props;
|
|
4538
|
+
const data = computed(() => props.result?.data ?? props.result?.jsonData ?? null);
|
|
4539
|
+
const collectionSlug = computed(() => data.value?.collectionSlug ?? "");
|
|
4540
|
+
const itemId = computed(() => data.value?.itemId);
|
|
4541
|
+
return (_ctx, _cache) => {
|
|
4542
|
+
return openBlock(), createElementBlock("div", _hoisted_1$2, [createElementVNode("div", _hoisted_2$2, [
|
|
4543
|
+
_cache[0] || (_cache[0] = createElementVNode("span", { class: "material-icons text-4xl text-indigo-600 mb-2" }, "collections_bookmark", -1)),
|
|
4544
|
+
createElementVNode("h3", _hoisted_3$2, toDisplayString(collectionSlug.value || unref(t)("pluginPresentCollection.fallbackTitle")), 1),
|
|
4545
|
+
itemId.value ? (openBlock(), createElementBlock("p", _hoisted_4$2, toDisplayString(unref(t)("pluginPresentCollection.itemLabel", { id: itemId.value })), 1)) : (openBlock(), createElementBlock("p", _hoisted_5$2, toDisplayString(unref(t)("pluginPresentCollection.listLabel")), 1))
|
|
4546
|
+
])]);
|
|
4547
|
+
};
|
|
4548
|
+
}
|
|
4549
|
+
});
|
|
4550
|
+
//#endregion
|
|
4392
4551
|
//#region src/vue/components/CollectionsIndexView.vue?vue&type=script&setup=true&lang.ts
|
|
4393
4552
|
var _hoisted_1$1 = {
|
|
4394
4553
|
class: "h-full overflow-y-auto bg-slate-50/50 px-6 py-6",
|
|
@@ -4696,6 +4855,16 @@ var FeedsView_default = /* @__PURE__ */ defineComponent({
|
|
|
4696
4855
|
}
|
|
4697
4856
|
});
|
|
4698
4857
|
//#endregion
|
|
4699
|
-
|
|
4858
|
+
//#region src/vue/index.ts
|
|
4859
|
+
var plugin = {
|
|
4860
|
+
toolDefinition: TOOL_DEFINITION,
|
|
4861
|
+
execute: executePresentCollection,
|
|
4862
|
+
generatingMessage: "Loading collection...",
|
|
4863
|
+
isEnabled: () => true,
|
|
4864
|
+
viewComponent: View_default,
|
|
4865
|
+
previewComponent: Preview_default
|
|
4866
|
+
};
|
|
4867
|
+
//#endregion
|
|
4868
|
+
export { CollectionCalendarView_default as CollectionCalendarView, CollectionCustomView_default as CollectionCustomView, CollectionDayView_default as CollectionDayView, CollectionEmbedView_default as CollectionEmbedView, CollectionKanbanView_default as CollectionKanbanView, CollectionRecordModal_default as CollectionRecordModal, CollectionRecordPanel_default as CollectionRecordPanel, CollectionView_default as CollectionView, CollectionViewConfigModal_default as CollectionViewConfigModal, CollectionsIndexView_default as CollectionsIndexView, FeedsView_default as FeedsView, Preview_default as PresentCollectionPreview, View_default as PresentCollectionView, collectionUi, configureCollectionUi, plugin, readCollectionSort, readCollectionViewMode, useCollectionRendering, writeCollectionSort, writeCollectionViewMode };
|
|
4700
4869
|
|
|
4701
4870
|
//# sourceMappingURL=vue.js.map
|