@mulmoclaude/collection-plugin 0.4.1 → 0.5.1
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/refLink.d.ts +7 -0
- package/dist/vue/refLink.d.ts.map +1 -0
- package/dist/vue/uiContext.d.ts +18 -0
- package/dist/vue/uiContext.d.ts.map +1 -1
- package/dist/vue.cjs +914 -711
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +913 -713
- 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.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("./chunk-CKQMccvm.cjs");
|
|
3
|
-
const require_promptSafety = require("./promptSafety-
|
|
3
|
+
const require_promptSafety = require("./promptSafety-B0pPJkfQ.cjs");
|
|
4
4
|
const require_deriveAll = require("./deriveAll-BJ0Lvm1Q.cjs");
|
|
5
5
|
let vue = require("vue");
|
|
6
6
|
let vue_i18n = require("vue-i18n");
|
|
@@ -17,395 +17,6 @@ function collectionUi() {
|
|
|
17
17
|
return current;
|
|
18
18
|
}
|
|
19
19
|
//#endregion
|
|
20
|
-
//#region src/vue/useCollectionRendering.ts
|
|
21
|
-
function useCollectionRendering(collection, locale) {
|
|
22
|
-
const refCache = (0, vue.ref)({});
|
|
23
|
-
const refRecordCache = (0, vue.ref)({});
|
|
24
|
-
const embedCache = (0, vue.ref)({});
|
|
25
|
-
function resetLinkedCaches() {
|
|
26
|
-
refCache.value = {};
|
|
27
|
-
refRecordCache.value = {};
|
|
28
|
-
embedCache.value = {};
|
|
29
|
-
}
|
|
30
|
-
function uniqueRefTargets(schema) {
|
|
31
|
-
const targets = /* @__PURE__ */ new Set();
|
|
32
|
-
const walk = (fields) => {
|
|
33
|
-
for (const field of Object.values(fields)) {
|
|
34
|
-
if (field.type === "ref" && typeof field.to === "string" && field.to.length > 0) targets.add(field.to);
|
|
35
|
-
if (field.type === "table" && field.of) walk(field.of);
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
walk(schema.fields);
|
|
39
|
-
return [...targets];
|
|
40
|
-
}
|
|
41
|
-
function uniqueEmbedTargets(schema) {
|
|
42
|
-
const targets = /* @__PURE__ */ new Set();
|
|
43
|
-
for (const field of Object.values(schema.fields)) if (field.type === "embed" && typeof field.to === "string" && field.to.length > 0) targets.add(field.to);
|
|
44
|
-
return [...targets];
|
|
45
|
-
}
|
|
46
|
-
function buildRefDisplayMap(detail) {
|
|
47
|
-
const { fields, primaryKey } = detail.collection.schema;
|
|
48
|
-
const displayField = "name" in fields ? "name" : "title" in fields ? "title" : primaryKey;
|
|
49
|
-
const map = {};
|
|
50
|
-
for (const item of detail.items) {
|
|
51
|
-
const slugRaw = item[primaryKey];
|
|
52
|
-
if (typeof slugRaw !== "string" || slugRaw.length === 0) continue;
|
|
53
|
-
const displayRaw = item[displayField];
|
|
54
|
-
map[slugRaw] = typeof displayRaw === "string" && displayRaw.length > 0 ? displayRaw : slugRaw;
|
|
55
|
-
}
|
|
56
|
-
return map;
|
|
57
|
-
}
|
|
58
|
-
function buildRefRecordMap(detail) {
|
|
59
|
-
const { schema } = detail.collection;
|
|
60
|
-
const map = {};
|
|
61
|
-
for (const item of detail.items) {
|
|
62
|
-
const slugRaw = item[schema.primaryKey];
|
|
63
|
-
if (typeof slugRaw === "string" && slugRaw.length > 0) map[slugRaw] = require_deriveAll.deriveAll(schema, item, {});
|
|
64
|
-
}
|
|
65
|
-
return map;
|
|
66
|
-
}
|
|
67
|
-
async function loadLinkedCollections(schema, expectedSlug) {
|
|
68
|
-
const refTargets = new Set(uniqueRefTargets(schema));
|
|
69
|
-
const embedTargets = new Set(uniqueEmbedTargets(schema));
|
|
70
|
-
const allTargets = [...new Set([...refTargets, ...embedTargets])];
|
|
71
|
-
if (allTargets.length === 0) return;
|
|
72
|
-
const binding = collectionUi();
|
|
73
|
-
const results = await Promise.all(allTargets.map(async (target) => {
|
|
74
|
-
try {
|
|
75
|
-
return {
|
|
76
|
-
target,
|
|
77
|
-
result: await binding.fetchCollectionDetail(target)
|
|
78
|
-
};
|
|
79
|
-
} catch {
|
|
80
|
-
return {
|
|
81
|
-
target,
|
|
82
|
-
result: { ok: false }
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
}));
|
|
86
|
-
if (collection.value?.slug !== expectedSlug) return;
|
|
87
|
-
const nextRef = {};
|
|
88
|
-
const nextRefRecords = {};
|
|
89
|
-
const nextEmbed = {};
|
|
90
|
-
for (const { target, result } of results) {
|
|
91
|
-
if (!result.ok) continue;
|
|
92
|
-
if (refTargets.has(target)) {
|
|
93
|
-
nextRef[target] = buildRefDisplayMap(result.data);
|
|
94
|
-
nextRefRecords[target] = buildRefRecordMap(result.data);
|
|
95
|
-
}
|
|
96
|
-
if (embedTargets.has(target)) nextEmbed[target] = {
|
|
97
|
-
schema: result.data.collection.schema,
|
|
98
|
-
items: result.data.items
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
refCache.value = nextRef;
|
|
102
|
-
refRecordCache.value = nextRefRecords;
|
|
103
|
-
embedCache.value = nextEmbed;
|
|
104
|
-
}
|
|
105
|
-
function refDisplay(targetSlug, itemSlug) {
|
|
106
|
-
const map = refCache.value[targetSlug];
|
|
107
|
-
return map && map[itemSlug] || itemSlug;
|
|
108
|
-
}
|
|
109
|
-
function refOptions(targetSlug) {
|
|
110
|
-
const map = refCache.value[targetSlug];
|
|
111
|
-
if (!map) return [];
|
|
112
|
-
return Object.entries(map).map(([slug, display]) => ({
|
|
113
|
-
slug,
|
|
114
|
-
display
|
|
115
|
-
})).sort((left, right) => left.display.localeCompare(right.display));
|
|
116
|
-
}
|
|
117
|
-
function resolveEmbed(field) {
|
|
118
|
-
if (field.type !== "embed" || !field.to || !field.id) return {
|
|
119
|
-
schema: null,
|
|
120
|
-
item: null
|
|
121
|
-
};
|
|
122
|
-
const data = embedCache.value[field.to];
|
|
123
|
-
if (!data) return {
|
|
124
|
-
schema: null,
|
|
125
|
-
item: null
|
|
126
|
-
};
|
|
127
|
-
const item = data.items.find((entry) => String(entry[data.schema.primaryKey] ?? "") === field.id) ?? null;
|
|
128
|
-
return {
|
|
129
|
-
schema: data.schema,
|
|
130
|
-
item
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
function embedValue(field, value, record) {
|
|
134
|
-
if (field.type === "money") return formatMoney(value, resolveCurrency(field, record), locale.value);
|
|
135
|
-
return detailText(value);
|
|
136
|
-
}
|
|
137
|
-
const embedViews = (0, vue.computed)(() => {
|
|
138
|
-
const out = {};
|
|
139
|
-
if (!collection.value) return out;
|
|
140
|
-
for (const [key, field] of Object.entries(collection.value.schema.fields)) {
|
|
141
|
-
if (field.type !== "embed") continue;
|
|
142
|
-
const { schema, item } = resolveEmbed(field);
|
|
143
|
-
const rows = [];
|
|
144
|
-
if (schema && item) for (const [subKey, subField] of Object.entries(schema.fields)) {
|
|
145
|
-
const value = item[subKey];
|
|
146
|
-
if (value === void 0 || value === null || value === "") continue;
|
|
147
|
-
rows.push({
|
|
148
|
-
key: subKey,
|
|
149
|
-
label: subField.label,
|
|
150
|
-
type: subField.type,
|
|
151
|
-
value,
|
|
152
|
-
display: embedValue(subField, value, item)
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
out[key] = {
|
|
156
|
-
found: Boolean(item),
|
|
157
|
-
rows,
|
|
158
|
-
targetSlug: field.to ?? "",
|
|
159
|
-
recordId: field.id ?? ""
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
return out;
|
|
163
|
-
});
|
|
164
|
-
function resolveCurrency(field, record) {
|
|
165
|
-
if (field.currencyField && record) {
|
|
166
|
-
const code = record[field.currencyField];
|
|
167
|
-
if (typeof code === "string" && code.trim().length > 0) return code;
|
|
168
|
-
}
|
|
169
|
-
return field.currency;
|
|
170
|
-
}
|
|
171
|
-
function currencySymbol(currency) {
|
|
172
|
-
const code = currency && currency.length > 0 ? currency : "USD";
|
|
173
|
-
try {
|
|
174
|
-
return new Intl.NumberFormat(locale.value, {
|
|
175
|
-
style: "currency",
|
|
176
|
-
currency: code
|
|
177
|
-
}).formatToParts(0).find((entry) => entry.type === "currency")?.value ?? code;
|
|
178
|
-
} catch {
|
|
179
|
-
return code;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
function formatMoney(value, currency, displayLocale) {
|
|
183
|
-
if (value === void 0 || value === "") return "—";
|
|
184
|
-
const amount = typeof value === "number" ? value : Number(value);
|
|
185
|
-
if (!Number.isFinite(amount)) return String(value);
|
|
186
|
-
const currencyCode = currency && currency.length > 0 ? currency : "USD";
|
|
187
|
-
try {
|
|
188
|
-
return new Intl.NumberFormat(displayLocale, {
|
|
189
|
-
style: "currency",
|
|
190
|
-
currency: currencyCode
|
|
191
|
-
}).format(amount);
|
|
192
|
-
} catch {
|
|
193
|
-
return String(amount);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
function formatCell(value, type) {
|
|
197
|
-
if (value === void 0 || value === null || value === "") return "—";
|
|
198
|
-
if (type === "markdown" && typeof value === "string") return value.length > 80 ? `${value.slice(0, 80)}…` : value;
|
|
199
|
-
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
200
|
-
return JSON.stringify(value);
|
|
201
|
-
}
|
|
202
|
-
function isExternalUrl(value) {
|
|
203
|
-
return typeof value === "string" && /^https?:\/\//i.test(value);
|
|
204
|
-
}
|
|
205
|
-
function artifactUrl(value) {
|
|
206
|
-
return collectionUi().fileAssetUrl(value);
|
|
207
|
-
}
|
|
208
|
-
function fileRoutePath(value) {
|
|
209
|
-
return collectionUi().fileRoutePath(value);
|
|
210
|
-
}
|
|
211
|
-
function detailText(value) {
|
|
212
|
-
if (value === void 0 || value === null || value === "") return "—";
|
|
213
|
-
return String(value);
|
|
214
|
-
}
|
|
215
|
-
function tableRows(value) {
|
|
216
|
-
if (!Array.isArray(value)) return [];
|
|
217
|
-
return value.filter((row) => Boolean(row) && typeof row === "object" && !Array.isArray(row));
|
|
218
|
-
}
|
|
219
|
-
function hasTableRows(value) {
|
|
220
|
-
return tableRows(value).length > 0;
|
|
221
|
-
}
|
|
222
|
-
function formatSubCell(subField, value, record) {
|
|
223
|
-
if (subField.type === "money") return formatMoney(value, resolveCurrency(subField, record), locale.value);
|
|
224
|
-
if (subField.type === "ref" && subField.to && typeof value === "string" && value.length > 0) return refDisplay(subField.to, value);
|
|
225
|
-
return formatCell(value, subField.type);
|
|
226
|
-
}
|
|
227
|
-
function inputTypeFor(type) {
|
|
228
|
-
if (type === "email") return "email";
|
|
229
|
-
if (type === "number") return "number";
|
|
230
|
-
if (type === "money") return "number";
|
|
231
|
-
if (type === "date") return "date";
|
|
232
|
-
if (type === "datetime") return "datetime-local";
|
|
233
|
-
return "text";
|
|
234
|
-
}
|
|
235
|
-
function evaluateDerivedAgainstItem(field, fieldKey, item) {
|
|
236
|
-
if (!field.formula || !collection.value) return null;
|
|
237
|
-
const result = require_deriveAll.deriveAll(collection.value.schema, item, refRecordCache.value)[fieldKey];
|
|
238
|
-
return typeof result === "number" && Number.isFinite(result) ? result : null;
|
|
239
|
-
}
|
|
240
|
-
function derivedDisplay(field, computedValue, record) {
|
|
241
|
-
if (computedValue === null || computedValue === void 0) return "—";
|
|
242
|
-
if (field.display === "money") return formatMoney(computedValue, resolveCurrency(field, record), locale.value);
|
|
243
|
-
return formatCell(computedValue, field.display ?? "number");
|
|
244
|
-
}
|
|
245
|
-
return {
|
|
246
|
-
refCache,
|
|
247
|
-
refRecordCache,
|
|
248
|
-
embedCache,
|
|
249
|
-
resetLinkedCaches,
|
|
250
|
-
loadLinkedCollections,
|
|
251
|
-
refDisplay,
|
|
252
|
-
refOptions,
|
|
253
|
-
embedViews,
|
|
254
|
-
resolveCurrency,
|
|
255
|
-
currencySymbol,
|
|
256
|
-
formatMoney,
|
|
257
|
-
formatCell,
|
|
258
|
-
detailText,
|
|
259
|
-
isExternalUrl,
|
|
260
|
-
artifactUrl,
|
|
261
|
-
fileRoutePath,
|
|
262
|
-
tableRows,
|
|
263
|
-
hasTableRows,
|
|
264
|
-
formatSubCell,
|
|
265
|
-
inputTypeFor,
|
|
266
|
-
deriveAll: require_deriveAll.deriveAll,
|
|
267
|
-
evaluateDerivedAgainstItem,
|
|
268
|
-
derivedDisplay
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
//#endregion
|
|
272
|
-
//#region src/vue/collectionViewMode.ts
|
|
273
|
-
var STORAGE_KEY = "collection_view_modes";
|
|
274
|
-
var SORT_STORAGE_KEY = "collection_sorts";
|
|
275
|
-
var BUILT_IN_MODES = [
|
|
276
|
-
"table",
|
|
277
|
-
"calendar",
|
|
278
|
-
"kanban"
|
|
279
|
-
];
|
|
280
|
-
/** A persisted mode is valid if it's a known built-in OR any `custom:<id>`
|
|
281
|
-
* key (the id is validated against the live schema at render time, so an
|
|
282
|
-
* unknown custom id simply collapses to the table there). Takes `unknown`
|
|
283
|
-
* and type-guards `string` first: a corrupted localStorage entry could hold a
|
|
284
|
-
* number/object, and calling `.startsWith` on that would throw. */
|
|
285
|
-
function isValidViewMode(value) {
|
|
286
|
-
return typeof value === "string" && (BUILT_IN_MODES.includes(value) || value.startsWith("custom:"));
|
|
287
|
-
}
|
|
288
|
-
function readAll() {
|
|
289
|
-
try {
|
|
290
|
-
const raw = localStorage.getItem(STORAGE_KEY);
|
|
291
|
-
if (!raw) return {};
|
|
292
|
-
const parsed = JSON.parse(raw);
|
|
293
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
294
|
-
} catch {
|
|
295
|
-
return {};
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
function readCollectionViewMode(slug) {
|
|
299
|
-
const stored = readAll()[slug];
|
|
300
|
-
return isValidViewMode(stored) ? stored : null;
|
|
301
|
-
}
|
|
302
|
-
function writeCollectionViewMode(slug, view) {
|
|
303
|
-
try {
|
|
304
|
-
const all = readAll();
|
|
305
|
-
all[slug] = view;
|
|
306
|
-
localStorage.setItem(STORAGE_KEY, JSON.stringify(all));
|
|
307
|
-
} catch {}
|
|
308
|
-
}
|
|
309
|
-
function isSortState(value) {
|
|
310
|
-
if (!value || typeof value !== "object") return false;
|
|
311
|
-
const rec = value;
|
|
312
|
-
return typeof rec.field === "string" && (rec.direction === "asc" || rec.direction === "desc");
|
|
313
|
-
}
|
|
314
|
-
function readAllSorts() {
|
|
315
|
-
try {
|
|
316
|
-
const raw = localStorage.getItem(SORT_STORAGE_KEY);
|
|
317
|
-
if (!raw) return {};
|
|
318
|
-
const parsed = JSON.parse(raw);
|
|
319
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
320
|
-
const out = {};
|
|
321
|
-
for (const [slug, value] of Object.entries(parsed)) if (isSortState(value)) out[slug] = value;
|
|
322
|
-
return out;
|
|
323
|
-
} catch {
|
|
324
|
-
return {};
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
function readCollectionSort(slug) {
|
|
328
|
-
return readAllSorts()[slug] ?? null;
|
|
329
|
-
}
|
|
330
|
-
/** Persist (or, when `sort` is null, clear) the slug's active column sort. */
|
|
331
|
-
function writeCollectionSort(slug, sort) {
|
|
332
|
-
try {
|
|
333
|
-
const all = Object.fromEntries(Object.entries(readAllSorts()).filter(([key]) => key !== slug));
|
|
334
|
-
if (sort) all[slug] = sort;
|
|
335
|
-
localStorage.setItem(SORT_STORAGE_KEY, JSON.stringify(all));
|
|
336
|
-
} catch {}
|
|
337
|
-
}
|
|
338
|
-
//#endregion
|
|
339
|
-
//#region src/vue/components/CollectionRecordModal.vue
|
|
340
|
-
var CollectionRecordModal_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
341
|
-
__name: "CollectionRecordModal",
|
|
342
|
-
emits: ["close"],
|
|
343
|
-
setup(__props, { emit: __emit }) {
|
|
344
|
-
const emit = __emit;
|
|
345
|
-
const dialogEl = (0, vue.ref)(null);
|
|
346
|
-
let previouslyFocused = null;
|
|
347
|
-
const FOCUSABLE_SELECTOR = [
|
|
348
|
-
"a[href]",
|
|
349
|
-
"button:not([disabled])",
|
|
350
|
-
"input:not([disabled])",
|
|
351
|
-
"select:not([disabled])",
|
|
352
|
-
"textarea:not([disabled])",
|
|
353
|
-
"[tabindex]:not([tabindex=\"-1\"])"
|
|
354
|
-
].join(",");
|
|
355
|
-
/** Visible, focusable controls inside the dialog, in DOM order. */
|
|
356
|
-
function focusableItems() {
|
|
357
|
-
if (!dialogEl.value) return [];
|
|
358
|
-
return Array.from(dialogEl.value.querySelectorAll(FOCUSABLE_SELECTOR)).filter((node) => node.offsetParent !== null);
|
|
359
|
-
}
|
|
360
|
-
/** Trap Tab / Shift+Tab inside the dialog so focus can't escape to the
|
|
361
|
-
* page behind the overlay. Wraps at both ends; the dialog container
|
|
362
|
-
* itself (tabindex -1) counts as "before the first item". */
|
|
363
|
-
function onTab(event) {
|
|
364
|
-
const items = focusableItems();
|
|
365
|
-
if (items.length === 0) {
|
|
366
|
-
event.preventDefault();
|
|
367
|
-
dialogEl.value?.focus();
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
const [first] = items;
|
|
371
|
-
const last = items[items.length - 1];
|
|
372
|
-
const active = document.activeElement;
|
|
373
|
-
if (event.shiftKey) {
|
|
374
|
-
if (active === first || active === dialogEl.value) {
|
|
375
|
-
event.preventDefault();
|
|
376
|
-
last.focus();
|
|
377
|
-
}
|
|
378
|
-
} else if (active === last) {
|
|
379
|
-
event.preventDefault();
|
|
380
|
-
first.focus();
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
(0, vue.onMounted)(async () => {
|
|
384
|
-
previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
385
|
-
await (0, vue.nextTick)();
|
|
386
|
-
dialogEl.value?.focus();
|
|
387
|
-
});
|
|
388
|
-
(0, vue.onBeforeUnmount)(() => {
|
|
389
|
-
previouslyFocused?.focus?.();
|
|
390
|
-
});
|
|
391
|
-
return (_ctx, _cache) => {
|
|
392
|
-
return (0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, { to: "body" }, [(0, vue.createElementVNode)("div", {
|
|
393
|
-
class: "fixed inset-0 z-40 flex items-center justify-center bg-slate-900/40 p-4",
|
|
394
|
-
"data-testid": "collections-record-modal",
|
|
395
|
-
onClick: _cache[1] || (_cache[1] = (0, vue.withModifiers)(($event) => emit("close"), ["self"]))
|
|
396
|
-
}, [(0, vue.createElementVNode)("div", {
|
|
397
|
-
ref_key: "dialogEl",
|
|
398
|
-
ref: dialogEl,
|
|
399
|
-
class: "flex max-h-[85vh] w-full max-w-2xl flex-col overflow-hidden rounded-2xl bg-white shadow-xl focus:outline-none",
|
|
400
|
-
role: "dialog",
|
|
401
|
-
"aria-modal": "true",
|
|
402
|
-
tabindex: "-1",
|
|
403
|
-
onKeydown: [_cache[0] || (_cache[0] = (0, vue.withKeys)(($event) => emit("close"), ["esc"])), (0, vue.withKeys)(onTab, ["tab"])]
|
|
404
|
-
}, [(0, vue.renderSlot)(_ctx.$slots, "default")], 544)])]);
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
});
|
|
408
|
-
//#endregion
|
|
409
20
|
//#region src/vue/lang/index.ts
|
|
410
21
|
var i18n = (0, vue_i18n.createI18n)({
|
|
411
22
|
legacy: false,
|
|
@@ -506,6 +117,11 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
506
117
|
save: "Save",
|
|
507
118
|
saving: "Saving...",
|
|
508
119
|
yes: "Yes"
|
|
120
|
+
},
|
|
121
|
+
pluginPresentCollection: {
|
|
122
|
+
fallbackTitle: "Collection",
|
|
123
|
+
itemLabel: "Item: {id}",
|
|
124
|
+
listLabel: "All records"
|
|
509
125
|
}
|
|
510
126
|
},
|
|
511
127
|
ja: {
|
|
@@ -602,6 +218,11 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
602
218
|
save: "保存",
|
|
603
219
|
saving: "保存中...",
|
|
604
220
|
yes: "はい"
|
|
221
|
+
},
|
|
222
|
+
pluginPresentCollection: {
|
|
223
|
+
fallbackTitle: "コレクション",
|
|
224
|
+
itemLabel: "項目: {id}",
|
|
225
|
+
listLabel: "すべてのレコード"
|
|
605
226
|
}
|
|
606
227
|
},
|
|
607
228
|
zh: {
|
|
@@ -698,6 +319,11 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
698
319
|
save: "保存",
|
|
699
320
|
saving: "保存中...",
|
|
700
321
|
yes: "是"
|
|
322
|
+
},
|
|
323
|
+
pluginPresentCollection: {
|
|
324
|
+
fallbackTitle: "集合",
|
|
325
|
+
itemLabel: "项目:{id}",
|
|
326
|
+
listLabel: "全部记录"
|
|
701
327
|
}
|
|
702
328
|
},
|
|
703
329
|
ko: {
|
|
@@ -794,6 +420,11 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
794
420
|
save: "저장",
|
|
795
421
|
saving: "저장 중...",
|
|
796
422
|
yes: "예"
|
|
423
|
+
},
|
|
424
|
+
pluginPresentCollection: {
|
|
425
|
+
fallbackTitle: "컬렉션",
|
|
426
|
+
itemLabel: "항목: {id}",
|
|
427
|
+
listLabel: "모든 레코드"
|
|
797
428
|
}
|
|
798
429
|
},
|
|
799
430
|
es: {
|
|
@@ -890,6 +521,11 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
890
521
|
save: "Guardar",
|
|
891
522
|
saving: "Guardando...",
|
|
892
523
|
yes: "Sí"
|
|
524
|
+
},
|
|
525
|
+
pluginPresentCollection: {
|
|
526
|
+
fallbackTitle: "Colección",
|
|
527
|
+
itemLabel: "Elemento: {id}",
|
|
528
|
+
listLabel: "Todos los registros"
|
|
893
529
|
}
|
|
894
530
|
},
|
|
895
531
|
"pt-BR": {
|
|
@@ -986,6 +622,11 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
986
622
|
save: "Salvar",
|
|
987
623
|
saving: "Salvando...",
|
|
988
624
|
yes: "Sim"
|
|
625
|
+
},
|
|
626
|
+
pluginPresentCollection: {
|
|
627
|
+
fallbackTitle: "Coleção",
|
|
628
|
+
itemLabel: "Item: {id}",
|
|
629
|
+
listLabel: "Todos os registros"
|
|
989
630
|
}
|
|
990
631
|
},
|
|
991
632
|
fr: {
|
|
@@ -1082,6 +723,11 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
1082
723
|
save: "Enregistrer",
|
|
1083
724
|
saving: "Enregistrement...",
|
|
1084
725
|
yes: "Oui"
|
|
726
|
+
},
|
|
727
|
+
pluginPresentCollection: {
|
|
728
|
+
fallbackTitle: "Collection",
|
|
729
|
+
itemLabel: "Élément : {id}",
|
|
730
|
+
listLabel: "Tous les enregistrements"
|
|
1085
731
|
}
|
|
1086
732
|
},
|
|
1087
733
|
de: {
|
|
@@ -1178,6 +824,11 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
1178
824
|
save: "Speichern",
|
|
1179
825
|
saving: "Wird gespeichert...",
|
|
1180
826
|
yes: "Ja"
|
|
827
|
+
},
|
|
828
|
+
pluginPresentCollection: {
|
|
829
|
+
fallbackTitle: "Sammlung",
|
|
830
|
+
itemLabel: "Eintrag: {id}",
|
|
831
|
+
listLabel: "Alle Datensätze"
|
|
1181
832
|
}
|
|
1182
833
|
}
|
|
1183
834
|
}
|
|
@@ -1209,121 +860,106 @@ function useCollectionI18n() {
|
|
|
1209
860
|
};
|
|
1210
861
|
}
|
|
1211
862
|
//#endregion
|
|
1212
|
-
//#region src/vue/components/
|
|
1213
|
-
var
|
|
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
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
"
|
|
1276
|
-
|
|
1277
|
-
(0, vue.
|
|
1278
|
-
|
|
1279
|
-
class: "text-xs text-red-600",
|
|
1280
|
-
"data-testid": `collections-embed-missing-${__props.fieldKey}`
|
|
1281
|
-
}, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.embedMissing", {
|
|
1282
|
-
collection: __props.view.targetSlug,
|
|
1283
|
-
id: __props.view.recordId
|
|
1284
|
-
})), 9, _hoisted_15$5),
|
|
1285
|
-
__props.view.targetSlug ? ((0, vue.openBlock)(), (0, vue.createBlock)(_component_router_link, {
|
|
1286
|
-
key: 0,
|
|
1287
|
-
to: { path: `/collections/${__props.view.targetSlug}` },
|
|
1288
|
-
class: "inline-flex items-center gap-0.5 text-xs text-indigo-600 hover:text-indigo-800 font-semibold mt-2 hover:underline"
|
|
1289
|
-
}, {
|
|
1290
|
-
default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.embedCreate")), 1), _cache[2] || (_cache[2] = (0, vue.createElementVNode)("span", { class: "material-icons text-xs" }, "arrow_forward", -1))]),
|
|
1291
|
-
_: 1
|
|
1292
|
-
}, 8, ["to"])) : (0, vue.createCommentVNode)("", true)
|
|
1293
|
-
])])], 8, _hoisted_11$8));
|
|
863
|
+
//#region src/vue/components/CollectionRecordModal.vue
|
|
864
|
+
var CollectionRecordModal_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
865
|
+
__name: "CollectionRecordModal",
|
|
866
|
+
emits: ["close"],
|
|
867
|
+
setup(__props, { emit: __emit }) {
|
|
868
|
+
const emit = __emit;
|
|
869
|
+
const teleportTarget = collectionUi().modalTeleportTarget?.() ?? "body";
|
|
870
|
+
const dialogEl = (0, vue.ref)(null);
|
|
871
|
+
let previouslyFocused = null;
|
|
872
|
+
const FOCUSABLE_SELECTOR = [
|
|
873
|
+
"a[href]",
|
|
874
|
+
"button:not([disabled])",
|
|
875
|
+
"input:not([disabled])",
|
|
876
|
+
"select:not([disabled])",
|
|
877
|
+
"textarea:not([disabled])",
|
|
878
|
+
"[tabindex]:not([tabindex=\"-1\"])"
|
|
879
|
+
].join(",");
|
|
880
|
+
/** Visible, focusable controls inside the dialog, in DOM order. */
|
|
881
|
+
function focusableItems() {
|
|
882
|
+
if (!dialogEl.value) return [];
|
|
883
|
+
return Array.from(dialogEl.value.querySelectorAll(FOCUSABLE_SELECTOR)).filter((node) => node.offsetParent !== null);
|
|
884
|
+
}
|
|
885
|
+
/** Trap Tab / Shift+Tab inside the dialog so focus can't escape to the
|
|
886
|
+
* page behind the overlay. Wraps at both ends; the dialog container
|
|
887
|
+
* itself (tabindex -1) counts as "before the first item". */
|
|
888
|
+
function onTab(event) {
|
|
889
|
+
const items = focusableItems();
|
|
890
|
+
if (items.length === 0) {
|
|
891
|
+
event.preventDefault();
|
|
892
|
+
dialogEl.value?.focus();
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
const [first] = items;
|
|
896
|
+
const last = items[items.length - 1];
|
|
897
|
+
const active = document.activeElement;
|
|
898
|
+
if (event.shiftKey) {
|
|
899
|
+
if (active === first || active === dialogEl.value) {
|
|
900
|
+
event.preventDefault();
|
|
901
|
+
last.focus();
|
|
902
|
+
}
|
|
903
|
+
} else if (active === last) {
|
|
904
|
+
event.preventDefault();
|
|
905
|
+
first.focus();
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
(0, vue.onMounted)(async () => {
|
|
909
|
+
previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
910
|
+
await (0, vue.nextTick)();
|
|
911
|
+
dialogEl.value?.focus();
|
|
912
|
+
});
|
|
913
|
+
(0, vue.onBeforeUnmount)(() => {
|
|
914
|
+
previouslyFocused?.focus?.();
|
|
915
|
+
});
|
|
916
|
+
return (_ctx, _cache) => {
|
|
917
|
+
return (0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, { to: (0, vue.unref)(teleportTarget) }, [(0, vue.createElementVNode)("div", {
|
|
918
|
+
class: "fixed inset-0 z-40 flex items-center justify-center bg-slate-900/40 p-4",
|
|
919
|
+
"data-testid": "collections-record-modal",
|
|
920
|
+
onClick: _cache[1] || (_cache[1] = (0, vue.withModifiers)(($event) => emit("close"), ["self"]))
|
|
921
|
+
}, [(0, vue.createElementVNode)("div", {
|
|
922
|
+
ref_key: "dialogEl",
|
|
923
|
+
ref: dialogEl,
|
|
924
|
+
class: "flex max-h-[85vh] w-full max-w-2xl flex-col overflow-hidden rounded-2xl bg-white shadow-xl focus:outline-none",
|
|
925
|
+
role: "dialog",
|
|
926
|
+
"aria-modal": "true",
|
|
927
|
+
tabindex: "-1",
|
|
928
|
+
onKeydown: [_cache[0] || (_cache[0] = (0, vue.withKeys)(($event) => emit("close"), ["esc"])), (0, vue.withKeys)(onTab, ["tab"])]
|
|
929
|
+
}, [(0, vue.renderSlot)(_ctx.$slots, "default")], 544)])], 8, ["to"]);
|
|
1294
930
|
};
|
|
1295
931
|
}
|
|
1296
932
|
});
|
|
1297
933
|
//#endregion
|
|
1298
934
|
//#region src/vue/components/CollectionCalendarView.vue?vue&type=script&setup=true&lang.ts
|
|
1299
|
-
var _hoisted_1$
|
|
935
|
+
var _hoisted_1$11 = {
|
|
1300
936
|
class: "flex flex-col gap-3",
|
|
1301
937
|
"data-testid": "collection-calendar"
|
|
1302
938
|
};
|
|
1303
|
-
var _hoisted_2$
|
|
1304
|
-
var _hoisted_3$
|
|
1305
|
-
var _hoisted_4$
|
|
1306
|
-
var _hoisted_5$
|
|
939
|
+
var _hoisted_2$10 = { class: "flex items-center gap-2" };
|
|
940
|
+
var _hoisted_3$10 = ["aria-label"];
|
|
941
|
+
var _hoisted_4$10 = ["aria-label"];
|
|
942
|
+
var _hoisted_5$9 = {
|
|
1307
943
|
class: "text-sm font-bold text-slate-800 flex-1",
|
|
1308
944
|
"data-testid": "collection-calendar-month"
|
|
1309
945
|
};
|
|
1310
|
-
var _hoisted_6$
|
|
1311
|
-
var _hoisted_7$
|
|
1312
|
-
var _hoisted_8$
|
|
946
|
+
var _hoisted_6$8 = { class: "grid grid-cols-7 gap-1 text-[10px] font-bold text-slate-400 uppercase tracking-wider select-none" };
|
|
947
|
+
var _hoisted_7$8 = { class: "grid grid-cols-7 gap-1" };
|
|
948
|
+
var _hoisted_8$8 = [
|
|
1313
949
|
"aria-label",
|
|
1314
950
|
"data-testid",
|
|
1315
951
|
"onClick",
|
|
1316
952
|
"onKeydown"
|
|
1317
953
|
];
|
|
1318
|
-
var _hoisted_9$
|
|
1319
|
-
var _hoisted_10$
|
|
1320
|
-
var _hoisted_11$
|
|
954
|
+
var _hoisted_9$8 = { class: "flex items-center justify-end" };
|
|
955
|
+
var _hoisted_10$8 = ["data-testid", "onClick"];
|
|
956
|
+
var _hoisted_11$8 = {
|
|
1321
957
|
key: 0,
|
|
1322
958
|
class: "flex flex-wrap items-center gap-1.5 pt-1",
|
|
1323
959
|
"data-testid": "collection-calendar-no-date"
|
|
1324
960
|
};
|
|
1325
|
-
var _hoisted_12$
|
|
1326
|
-
var _hoisted_13$
|
|
961
|
+
var _hoisted_12$7 = { class: "text-[10px] font-bold text-slate-400 uppercase tracking-wider mr-1" };
|
|
962
|
+
var _hoisted_13$6 = ["data-testid", "onClick"];
|
|
1327
963
|
/** Sort key for ordering a day's chips by start time: earliest first, with
|
|
1328
964
|
* clock-less all-day records sinking to the bottom (matching the day view). */
|
|
1329
965
|
var DAY_CHIP_DEFAULT = "bg-indigo-50 text-indigo-700 border-indigo-100 hover:bg-indigo-100";
|
|
@@ -1437,23 +1073,23 @@ var CollectionCalendarView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1437
1073
|
viewMonth.value = now.getMonth() + 1;
|
|
1438
1074
|
}
|
|
1439
1075
|
return (_ctx, _cache) => {
|
|
1440
|
-
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$
|
|
1441
|
-
(0, vue.createElementVNode)("div", _hoisted_2$
|
|
1076
|
+
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$11, [
|
|
1077
|
+
(0, vue.createElementVNode)("div", _hoisted_2$10, [
|
|
1442
1078
|
(0, vue.createElementVNode)("button", {
|
|
1443
1079
|
type: "button",
|
|
1444
1080
|
class: "h-8 w-8 flex items-center justify-center rounded text-slate-500 hover:bg-slate-100 transition-colors",
|
|
1445
1081
|
"aria-label": (0, vue.unref)(t)("collectionsView.calendarPrevMonth"),
|
|
1446
1082
|
"data-testid": "collection-calendar-prev",
|
|
1447
1083
|
onClick: _cache[0] || (_cache[0] = ($event) => stepMonth(-1))
|
|
1448
|
-
}, [..._cache[2] || (_cache[2] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "chevron_left", -1)])], 8, _hoisted_3$
|
|
1084
|
+
}, [..._cache[2] || (_cache[2] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "chevron_left", -1)])], 8, _hoisted_3$10),
|
|
1449
1085
|
(0, vue.createElementVNode)("button", {
|
|
1450
1086
|
type: "button",
|
|
1451
1087
|
class: "h-8 w-8 flex items-center justify-center rounded text-slate-500 hover:bg-slate-100 transition-colors",
|
|
1452
1088
|
"aria-label": (0, vue.unref)(t)("collectionsView.calendarNextMonth"),
|
|
1453
1089
|
"data-testid": "collection-calendar-next",
|
|
1454
1090
|
onClick: _cache[1] || (_cache[1] = ($event) => stepMonth(1))
|
|
1455
|
-
}, [..._cache[3] || (_cache[3] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "chevron_right", -1)])], 8, _hoisted_4$
|
|
1456
|
-
(0, vue.createElementVNode)("h3", _hoisted_5$
|
|
1091
|
+
}, [..._cache[3] || (_cache[3] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "chevron_right", -1)])], 8, _hoisted_4$10),
|
|
1092
|
+
(0, vue.createElementVNode)("h3", _hoisted_5$9, (0, vue.toDisplayString)(monthLabel.value), 1),
|
|
1457
1093
|
(0, vue.createElementVNode)("button", {
|
|
1458
1094
|
type: "button",
|
|
1459
1095
|
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",
|
|
@@ -1461,13 +1097,13 @@ var CollectionCalendarView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1461
1097
|
onClick: goToday
|
|
1462
1098
|
}, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.calendarToday")), 1)
|
|
1463
1099
|
]),
|
|
1464
|
-
(0, vue.createElementVNode)("div", _hoisted_6$
|
|
1100
|
+
(0, vue.createElementVNode)("div", _hoisted_6$8, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(weekdayLabels.value, (label, idx) => {
|
|
1465
1101
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
1466
1102
|
key: idx,
|
|
1467
1103
|
class: "px-1 py-1 text-center"
|
|
1468
1104
|
}, (0, vue.toDisplayString)(label), 1);
|
|
1469
1105
|
}), 128))]),
|
|
1470
|
-
(0, vue.createElementVNode)("div", _hoisted_7$
|
|
1106
|
+
(0, vue.createElementVNode)("div", _hoisted_7$8, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(cells.value, ({ cell, entries }) => {
|
|
1471
1107
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
1472
1108
|
key: cell.key,
|
|
1473
1109
|
class: (0, vue.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"]),
|
|
@@ -1477,24 +1113,24 @@ var CollectionCalendarView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1477
1113
|
"data-testid": `collection-calendar-day-${cell.key}`,
|
|
1478
1114
|
onClick: ($event) => emit("openDay", cell.ymd),
|
|
1479
1115
|
onKeydown: [(0, vue.withKeys)((0, vue.withModifiers)(($event) => emit("openDay", cell.ymd), ["self", "prevent"]), ["enter"]), (0, vue.withKeys)((0, vue.withModifiers)(($event) => emit("openDay", cell.ymd), ["self", "prevent"]), ["space"])]
|
|
1480
|
-
}, [(0, vue.createElementVNode)("div", _hoisted_9$
|
|
1116
|
+
}, [(0, vue.createElementVNode)("div", _hoisted_9$8, [(0, vue.createElementVNode)("span", { class: (0, vue.normalizeClass)(["text-[11px] font-bold h-5 min-w-5 px-1 inline-flex items-center justify-center rounded-full", cell.key === (0, vue.unref)(todayKey) ? "bg-indigo-600 text-white" : cell.inMonth ? "text-slate-500" : "text-slate-300"]) }, (0, vue.toDisplayString)(cell.ymd.day), 3)]), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(entries, (entry) => {
|
|
1481
1117
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
1482
1118
|
key: entry.id,
|
|
1483
1119
|
type: "button",
|
|
1484
1120
|
class: (0, vue.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)]),
|
|
1485
1121
|
"data-testid": `collection-calendar-chip-${entry.id}`,
|
|
1486
1122
|
onClick: (0, vue.withModifiers)(($event) => emit("select", entry.id), ["stop"])
|
|
1487
|
-
}, (0, vue.toDisplayString)(entry.label), 11, _hoisted_10$
|
|
1488
|
-
}), 128))], 42, _hoisted_8$
|
|
1123
|
+
}, (0, vue.toDisplayString)(entry.label), 11, _hoisted_10$8);
|
|
1124
|
+
}), 128))], 42, _hoisted_8$8);
|
|
1489
1125
|
}), 128))]),
|
|
1490
|
-
bucketed.value.noDate.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_11$
|
|
1126
|
+
bucketed.value.noDate.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_11$8, [(0, vue.createElementVNode)("span", _hoisted_12$7, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.calendarNoDate")), 1), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(undatedEntries.value, (entry) => {
|
|
1491
1127
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
1492
1128
|
key: entry.id,
|
|
1493
1129
|
type: "button",
|
|
1494
1130
|
class: (0, vue.normalizeClass)(["text-[11px] font-semibold truncate rounded px-1.5 py-0.5 border transition-colors", chipClass(entry, UNDATED_CHIP_DEFAULT)]),
|
|
1495
1131
|
"data-testid": `collection-calendar-undated-${entry.id}`,
|
|
1496
1132
|
onClick: ($event) => emit("select", entry.id)
|
|
1497
|
-
}, (0, vue.toDisplayString)(entry.label), 11, _hoisted_13$
|
|
1133
|
+
}, (0, vue.toDisplayString)(entry.label), 11, _hoisted_13$6);
|
|
1498
1134
|
}), 128))])) : (0, vue.createCommentVNode)("", true)
|
|
1499
1135
|
]);
|
|
1500
1136
|
};
|
|
@@ -1502,40 +1138,40 @@ var CollectionCalendarView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1502
1138
|
});
|
|
1503
1139
|
//#endregion
|
|
1504
1140
|
//#region src/vue/components/CollectionDayView.vue?vue&type=script&setup=true&lang.ts
|
|
1505
|
-
var _hoisted_1$
|
|
1506
|
-
var _hoisted_2$
|
|
1141
|
+
var _hoisted_1$10 = { class: "flex items-center gap-2 border-b border-slate-200 px-4 py-3" };
|
|
1142
|
+
var _hoisted_2$9 = {
|
|
1507
1143
|
class: "flex-1 text-sm font-bold text-slate-800",
|
|
1508
1144
|
"data-testid": "collection-day-view-title"
|
|
1509
1145
|
};
|
|
1510
|
-
var _hoisted_3$
|
|
1511
|
-
var _hoisted_4$
|
|
1512
|
-
var _hoisted_5$
|
|
1146
|
+
var _hoisted_3$9 = ["aria-label"];
|
|
1147
|
+
var _hoisted_4$9 = ["aria-label"];
|
|
1148
|
+
var _hoisted_5$8 = {
|
|
1513
1149
|
key: 0,
|
|
1514
1150
|
class: "px-4 py-10 text-center text-sm text-slate-400"
|
|
1515
1151
|
};
|
|
1516
|
-
var _hoisted_6$
|
|
1517
|
-
var _hoisted_7$
|
|
1152
|
+
var _hoisted_6$7 = { class: "absolute -top-2 left-0 w-10 pr-1 text-right text-[10px] tabular-nums text-slate-400" };
|
|
1153
|
+
var _hoisted_7$7 = {
|
|
1518
1154
|
class: "absolute inset-y-0 right-0",
|
|
1519
1155
|
style: { "left": "2.75rem" }
|
|
1520
1156
|
};
|
|
1521
|
-
var _hoisted_8$
|
|
1522
|
-
var _hoisted_9$
|
|
1523
|
-
var _hoisted_10$
|
|
1157
|
+
var _hoisted_8$7 = ["data-testid", "onClick"];
|
|
1158
|
+
var _hoisted_9$7 = { class: "block truncate text-[11px] font-semibold leading-tight" };
|
|
1159
|
+
var _hoisted_10$7 = {
|
|
1524
1160
|
key: 0,
|
|
1525
1161
|
"aria-hidden": "true"
|
|
1526
1162
|
};
|
|
1527
|
-
var _hoisted_11$
|
|
1163
|
+
var _hoisted_11$7 = {
|
|
1528
1164
|
key: 1,
|
|
1529
1165
|
"aria-hidden": "true"
|
|
1530
1166
|
};
|
|
1531
|
-
var _hoisted_12$
|
|
1167
|
+
var _hoisted_12$6 = {
|
|
1532
1168
|
key: 2,
|
|
1533
1169
|
class: "flex flex-wrap items-center gap-1.5 border-t border-slate-200 px-4 py-2",
|
|
1534
1170
|
"data-testid": "collection-day-view-all-day"
|
|
1535
1171
|
};
|
|
1536
|
-
var _hoisted_13$
|
|
1537
|
-
var _hoisted_14$
|
|
1538
|
-
var _hoisted_15$
|
|
1172
|
+
var _hoisted_13$5 = { class: "mr-1 text-[10px] font-bold uppercase tracking-wider text-slate-400" };
|
|
1173
|
+
var _hoisted_14$5 = ["data-testid", "onClick"];
|
|
1174
|
+
var _hoisted_15$5 = {
|
|
1539
1175
|
key: 0,
|
|
1540
1176
|
class: "min-w-0 flex-1 overflow-y-auto",
|
|
1541
1177
|
"data-testid": "collection-day-view-detail"
|
|
@@ -1694,8 +1330,8 @@ var CollectionDayView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1694
1330
|
role: "dialog",
|
|
1695
1331
|
"aria-modal": "true"
|
|
1696
1332
|
}, [(0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["flex min-h-0 flex-col", __props.showDetail ? "w-80 shrink-0 border-r border-slate-200" : "w-full"]) }, [
|
|
1697
|
-
(0, vue.createElementVNode)("div", _hoisted_1$
|
|
1698
|
-
(0, vue.createElementVNode)("h3", _hoisted_2$
|
|
1333
|
+
(0, vue.createElementVNode)("div", _hoisted_1$10, [
|
|
1334
|
+
(0, vue.createElementVNode)("h3", _hoisted_2$9, (0, vue.toDisplayString)(dayLabel.value), 1),
|
|
1699
1335
|
__props.canCreate ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
1700
1336
|
key: 0,
|
|
1701
1337
|
type: "button",
|
|
@@ -1703,16 +1339,16 @@ var CollectionDayView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1703
1339
|
"aria-label": (0, vue.unref)(t)("collectionsView.calendarCreateOn", { date: dayKey.value }),
|
|
1704
1340
|
"data-testid": "collection-day-view-create",
|
|
1705
1341
|
onClick: onCreate
|
|
1706
|
-
}, [..._cache[3] || (_cache[3] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "add", -1)])], 8, _hoisted_3$
|
|
1342
|
+
}, [..._cache[3] || (_cache[3] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "add", -1)])], 8, _hoisted_3$9)) : (0, vue.createCommentVNode)("", true),
|
|
1707
1343
|
(0, vue.createElementVNode)("button", {
|
|
1708
1344
|
type: "button",
|
|
1709
1345
|
class: "h-8 w-8 flex items-center justify-center rounded text-slate-500 hover:bg-slate-100 transition-colors",
|
|
1710
1346
|
"aria-label": (0, vue.unref)(t)("collectionsView.dayViewClose"),
|
|
1711
1347
|
"data-testid": "collection-day-view-close",
|
|
1712
1348
|
onClick: _cache[0] || (_cache[0] = ($event) => emit("close"))
|
|
1713
|
-
}, [..._cache[4] || (_cache[4] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_4$
|
|
1349
|
+
}, [..._cache[4] || (_cache[4] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_4$9)
|
|
1714
1350
|
]),
|
|
1715
|
-
timedEntries.value.length === 0 && allDayEntries.value.length === 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_5$
|
|
1351
|
+
timedEntries.value.length === 0 && allDayEntries.value.length === 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_5$8, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.dayViewEmpty")), 1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
1716
1352
|
key: 1,
|
|
1717
1353
|
ref_key: "scrollEl",
|
|
1718
1354
|
ref: scrollEl,
|
|
@@ -1726,8 +1362,8 @@ var CollectionDayView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1726
1362
|
key: hour,
|
|
1727
1363
|
class: "absolute left-0 right-0 border-t border-slate-100",
|
|
1728
1364
|
style: (0, vue.normalizeStyle)({ top: `${(hour - 1) * HOUR_PX}px` })
|
|
1729
|
-
}, [(0, vue.createElementVNode)("span", _hoisted_6$
|
|
1730
|
-
}), 64)), (0, vue.createElementVNode)("div", _hoisted_7$
|
|
1365
|
+
}, [(0, vue.createElementVNode)("span", _hoisted_6$7, (0, vue.toDisplayString)(hourLabel(hour - 1)), 1)], 4);
|
|
1366
|
+
}), 64)), (0, vue.createElementVNode)("div", _hoisted_7$7, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(timedEntries.value, (entry) => {
|
|
1731
1367
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
1732
1368
|
key: entry.id,
|
|
1733
1369
|
type: "button",
|
|
@@ -1735,56 +1371,56 @@ var CollectionDayView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1735
1371
|
style: (0, vue.normalizeStyle)(entry.style),
|
|
1736
1372
|
"data-testid": `collection-day-view-chip-${entry.id}`,
|
|
1737
1373
|
onClick: ($event) => onSelect(entry.id)
|
|
1738
|
-
}, [(0, vue.createElementVNode)("span", _hoisted_9$
|
|
1739
|
-
entry.slice.bleedsBefore ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_10$
|
|
1374
|
+
}, [(0, vue.createElementVNode)("span", _hoisted_9$7, [
|
|
1375
|
+
entry.slice.bleedsBefore ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_10$7, "▲ ")) : (0, vue.createCommentVNode)("", true),
|
|
1740
1376
|
(0, vue.createTextVNode)((0, vue.toDisplayString)(entry.label), 1),
|
|
1741
|
-
entry.slice.bleedsAfter ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_11$
|
|
1377
|
+
entry.slice.bleedsAfter ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_11$7, " ▼")) : (0, vue.createCommentVNode)("", true)
|
|
1742
1378
|
]), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(entry.secondary, (text, i) => {
|
|
1743
1379
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
|
|
1744
1380
|
key: i,
|
|
1745
1381
|
class: "block truncate text-[10px] leading-tight opacity-70"
|
|
1746
1382
|
}, (0, vue.toDisplayString)(text), 1);
|
|
1747
|
-
}), 128))], 14, _hoisted_8$
|
|
1383
|
+
}), 128))], 14, _hoisted_8$7);
|
|
1748
1384
|
}), 128))])], 4)], 512)),
|
|
1749
|
-
allDayEntries.value.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_12$
|
|
1385
|
+
allDayEntries.value.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_12$6, [(0, vue.createElementVNode)("span", _hoisted_13$5, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.dayViewAllDay")), 1), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(allDayEntries.value, (entry) => {
|
|
1750
1386
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
1751
1387
|
key: entry.id,
|
|
1752
1388
|
type: "button",
|
|
1753
1389
|
class: (0, vue.normalizeClass)(["truncate rounded border px-1.5 py-0.5 text-[11px] font-semibold transition-colors", allDayChipClass(entry)]),
|
|
1754
1390
|
"data-testid": `collection-day-view-allday-${entry.id}`,
|
|
1755
1391
|
onClick: ($event) => onSelect(entry.id)
|
|
1756
|
-
}, (0, vue.toDisplayString)(entry.label), 11, _hoisted_14$
|
|
1392
|
+
}, (0, vue.toDisplayString)(entry.label), 11, _hoisted_14$5);
|
|
1757
1393
|
}), 128))])) : (0, vue.createCommentVNode)("", true)
|
|
1758
|
-
], 2), __props.showDetail ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_15$
|
|
1394
|
+
], 2), __props.showDetail ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_15$5, [(0, vue.renderSlot)(_ctx.$slots, "detail")])) : (0, vue.createCommentVNode)("", true)], 2)], 32);
|
|
1759
1395
|
};
|
|
1760
1396
|
}
|
|
1761
1397
|
});
|
|
1762
1398
|
//#endregion
|
|
1763
1399
|
//#region src/vue/components/CollectionKanbanView.vue?vue&type=script&setup=true&lang.ts
|
|
1764
|
-
var _hoisted_1$
|
|
1400
|
+
var _hoisted_1$9 = {
|
|
1765
1401
|
class: "h-full overflow-x-auto overflow-y-hidden",
|
|
1766
1402
|
"data-testid": "collection-kanban"
|
|
1767
1403
|
};
|
|
1768
|
-
var _hoisted_2$
|
|
1769
|
-
var _hoisted_3$
|
|
1770
|
-
var _hoisted_4$
|
|
1771
|
-
var _hoisted_5$
|
|
1772
|
-
var _hoisted_6$
|
|
1773
|
-
var _hoisted_7$
|
|
1774
|
-
var _hoisted_8$
|
|
1404
|
+
var _hoisted_2$8 = { class: "flex gap-3 h-full p-1 min-w-max" };
|
|
1405
|
+
var _hoisted_3$8 = ["data-testid"];
|
|
1406
|
+
var _hoisted_4$8 = { class: "flex items-center justify-between px-3 py-2 border-b border-slate-200" };
|
|
1407
|
+
var _hoisted_5$7 = { class: "flex items-center gap-2 min-w-0" };
|
|
1408
|
+
var _hoisted_6$6 = ["title"];
|
|
1409
|
+
var _hoisted_7$6 = { class: "text-[11px] text-slate-400 shrink-0" };
|
|
1410
|
+
var _hoisted_8$6 = [
|
|
1775
1411
|
"data-testid",
|
|
1776
1412
|
"aria-label",
|
|
1777
1413
|
"onClick",
|
|
1778
1414
|
"onKeydown"
|
|
1779
1415
|
];
|
|
1780
|
-
var _hoisted_9$
|
|
1781
|
-
var _hoisted_10$
|
|
1416
|
+
var _hoisted_9$6 = { class: "flex items-start gap-2" };
|
|
1417
|
+
var _hoisted_10$6 = [
|
|
1782
1418
|
"checked",
|
|
1783
1419
|
"aria-label",
|
|
1784
1420
|
"data-testid",
|
|
1785
1421
|
"onChange"
|
|
1786
1422
|
];
|
|
1787
|
-
var _hoisted_11$
|
|
1423
|
+
var _hoisted_11$6 = { class: "text-sm font-medium text-slate-800 truncate" };
|
|
1788
1424
|
var UNCATEGORIZED = "";
|
|
1789
1425
|
//#endregion
|
|
1790
1426
|
//#region src/vue/components/CollectionKanbanView.vue
|
|
@@ -1882,15 +1518,15 @@ var CollectionKanbanView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1882
1518
|
emit("move", itemId(item), next);
|
|
1883
1519
|
}
|
|
1884
1520
|
return (_ctx, _cache) => {
|
|
1885
|
-
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$
|
|
1521
|
+
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$9, [(0, vue.createElementVNode)("div", _hoisted_2$8, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(columns.value, (column) => {
|
|
1886
1522
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
1887
1523
|
key: column.value,
|
|
1888
1524
|
"data-testid": `collection-kanban-column-${column.value || "uncategorized"}`,
|
|
1889
1525
|
class: "w-72 shrink-0 flex flex-col bg-slate-100 rounded-lg"
|
|
1890
|
-
}, [(0, vue.createElementVNode)("div", _hoisted_4$
|
|
1526
|
+
}, [(0, vue.createElementVNode)("div", _hoisted_4$8, [(0, vue.createElementVNode)("div", _hoisted_5$7, [(0, vue.createElementVNode)("span", { class: (0, vue.normalizeClass)(["w-2 h-2 rounded-full shrink-0", (0, vue.unref)(require_promptSafety.resolveEnumColor)(__props.schema, __props.groupField, column.value).dot]) }, null, 2), (0, vue.createElementVNode)("span", {
|
|
1891
1527
|
class: "font-semibold text-xs text-slate-600 truncate",
|
|
1892
1528
|
title: column.label
|
|
1893
|
-
}, (0, vue.toDisplayString)(column.label), 9, _hoisted_6$
|
|
1529
|
+
}, (0, vue.toDisplayString)(column.label), 9, _hoisted_6$6)]), (0, vue.createElementVNode)("span", _hoisted_7$6, (0, vue.toDisplayString)(itemsByColumn(column.value).length), 1)]), (0, vue.createVNode)((0, vue.unref)(vuedraggable.default), {
|
|
1894
1530
|
"model-value": itemsByColumn(column.value),
|
|
1895
1531
|
"item-key": __props.schema.primaryKey,
|
|
1896
1532
|
group: "collection-kanban-cards",
|
|
@@ -1906,7 +1542,7 @@ var CollectionKanbanView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1906
1542
|
class: (0, vue.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)]]),
|
|
1907
1543
|
onClick: ($event) => emit("select", itemId(element)),
|
|
1908
1544
|
onKeydown: [(0, vue.withKeys)((0, vue.withModifiers)((e) => !e.repeat && emit("select", itemId(element)), ["prevent", "self"]), ["enter"]), (0, vue.withKeys)((0, vue.withModifiers)((e) => !e.repeat && emit("select", itemId(element)), ["prevent", "self"]), ["space"])]
|
|
1909
|
-
}, [(0, vue.createElementVNode)("div", _hoisted_9$
|
|
1545
|
+
}, [(0, vue.createElementVNode)("div", _hoisted_9$6, [cardToggle.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("input", {
|
|
1910
1546
|
key: 0,
|
|
1911
1547
|
type: "checkbox",
|
|
1912
1548
|
checked: cardChecked(element),
|
|
@@ -1915,24 +1551,138 @@ var CollectionKanbanView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
1915
1551
|
"data-testid": `collection-kanban-toggle-${itemId(element)}`,
|
|
1916
1552
|
onClick: _cache[0] || (_cache[0] = (0, vue.withModifiers)(() => {}, ["stop"])),
|
|
1917
1553
|
onChange: ($event) => onCardToggle(element)
|
|
1918
|
-
}, null, 40, _hoisted_10$
|
|
1554
|
+
}, null, 40, _hoisted_10$6)) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("div", _hoisted_11$6, (0, vue.toDisplayString)(itemLabel(element)), 1)])], 42, _hoisted_8$6)]),
|
|
1919
1555
|
_: 1
|
|
1920
1556
|
}, 8, [
|
|
1921
1557
|
"model-value",
|
|
1922
1558
|
"item-key",
|
|
1923
1559
|
"onChange"
|
|
1924
|
-
])], 8, _hoisted_3$
|
|
1560
|
+
])], 8, _hoisted_3$8);
|
|
1925
1561
|
}), 128))])]);
|
|
1926
1562
|
};
|
|
1927
1563
|
}
|
|
1928
1564
|
});
|
|
1929
1565
|
//#endregion
|
|
1566
|
+
//#region src/vue/refLink.ts
|
|
1567
|
+
function isModifiedClick(event) {
|
|
1568
|
+
return event instanceof MouseEvent && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey);
|
|
1569
|
+
}
|
|
1570
|
+
/** Activate a ref/embed link → navigate to `targetSlug` (optionally a record). */
|
|
1571
|
+
function activateRefLink(event, targetSlug, recordId, stop = false) {
|
|
1572
|
+
if (stop) event.stopPropagation();
|
|
1573
|
+
if (isModifiedClick(event)) return;
|
|
1574
|
+
event.preventDefault();
|
|
1575
|
+
collectionUi().navigateToRecord(targetSlug, recordId);
|
|
1576
|
+
}
|
|
1577
|
+
/** Activate a `file` cell link → navigate to a host path. When the host has no
|
|
1578
|
+
* `navigate` capability, do NOT preventDefault so the `href` still works (or, in
|
|
1579
|
+
* a router-less host that also has no path, the link simply isn't rendered). */
|
|
1580
|
+
function activatePathLink(event, path, stop = false) {
|
|
1581
|
+
if (stop) event.stopPropagation();
|
|
1582
|
+
if (isModifiedClick(event)) return;
|
|
1583
|
+
const nav = collectionUi().navigate;
|
|
1584
|
+
if (!nav) return;
|
|
1585
|
+
event.preventDefault();
|
|
1586
|
+
nav(path);
|
|
1587
|
+
}
|
|
1588
|
+
//#endregion
|
|
1589
|
+
//#region src/vue/components/CollectionEmbedView.vue?vue&type=script&setup=true&lang.ts
|
|
1590
|
+
var _hoisted_1$8 = [
|
|
1591
|
+
"href",
|
|
1592
|
+
"tabindex",
|
|
1593
|
+
"data-testid"
|
|
1594
|
+
];
|
|
1595
|
+
var _hoisted_2$7 = { class: "flex items-center justify-between text-[10px] font-bold text-indigo-600/90 tracking-wider uppercase" };
|
|
1596
|
+
var _hoisted_3$7 = { class: "flex items-center gap-1.5" };
|
|
1597
|
+
var _hoisted_4$7 = { class: "bg-indigo-100/60 text-indigo-700 px-1.5 py-0.5 rounded font-mono font-medium lowercase" };
|
|
1598
|
+
var _hoisted_5$6 = { class: "grid gap-x-4 gap-y-3 grid-cols-2" };
|
|
1599
|
+
var _hoisted_6$5 = { class: "text-[10px] font-semibold text-slate-400 uppercase tracking-wide" };
|
|
1600
|
+
var _hoisted_7$5 = ["data-testid"];
|
|
1601
|
+
var _hoisted_8$5 = {
|
|
1602
|
+
key: 0,
|
|
1603
|
+
class: "material-icons text-emerald-600 text-sm align-middle"
|
|
1604
|
+
};
|
|
1605
|
+
var _hoisted_9$5 = {
|
|
1606
|
+
key: 1,
|
|
1607
|
+
class: "text-slate-300"
|
|
1608
|
+
};
|
|
1609
|
+
var _hoisted_10$5 = {
|
|
1610
|
+
key: 1,
|
|
1611
|
+
class: "whitespace-pre-wrap font-normal text-slate-600"
|
|
1612
|
+
};
|
|
1613
|
+
var _hoisted_11$5 = { key: 2 };
|
|
1614
|
+
var _hoisted_12$5 = ["data-testid"];
|
|
1615
|
+
var _hoisted_13$4 = { class: "flex items-start gap-3" };
|
|
1616
|
+
var _hoisted_14$4 = { class: "flex-1 min-w-0" };
|
|
1617
|
+
var _hoisted_15$4 = { class: "text-xs font-semibold text-red-800 uppercase tracking-wider mb-1" };
|
|
1618
|
+
var _hoisted_16$3 = ["data-testid"];
|
|
1619
|
+
var _hoisted_17$3 = ["href", "tabindex"];
|
|
1620
|
+
//#endregion
|
|
1621
|
+
//#region src/vue/components/CollectionEmbedView.vue
|
|
1622
|
+
var CollectionEmbedView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
1623
|
+
__name: "CollectionEmbedView",
|
|
1624
|
+
props: {
|
|
1625
|
+
view: {},
|
|
1626
|
+
fieldKey: {}
|
|
1627
|
+
},
|
|
1628
|
+
setup(__props) {
|
|
1629
|
+
const { t } = useCollectionI18n();
|
|
1630
|
+
const cui = collectionUi();
|
|
1631
|
+
return (_ctx, _cache) => {
|
|
1632
|
+
return __props.view.found ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
1633
|
+
key: 0,
|
|
1634
|
+
href: (0, vue.unref)(cui).recordHref?.(__props.view.targetSlug, __props.view.recordId),
|
|
1635
|
+
tabindex: (0, vue.unref)(cui).recordHref?.(__props.view.targetSlug, __props.view.recordId) ? void 0 : 0,
|
|
1636
|
+
role: "link",
|
|
1637
|
+
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",
|
|
1638
|
+
"data-testid": `collections-embed-${__props.fieldKey}`,
|
|
1639
|
+
onClick: _cache[0] || (_cache[0] = ($event) => (0, vue.unref)(activateRefLink)($event, __props.view.targetSlug, __props.view.recordId)),
|
|
1640
|
+
onKeydown: [_cache[1] || (_cache[1] = (0, vue.withKeys)(($event) => (0, vue.unref)(activateRefLink)($event, __props.view.targetSlug, __props.view.recordId), ["enter"])), _cache[2] || (_cache[2] = (0, vue.withKeys)(($event) => (0, vue.unref)(activateRefLink)($event, __props.view.targetSlug, __props.view.recordId), ["space"]))]
|
|
1641
|
+
}, [
|
|
1642
|
+
_cache[7] || (_cache[7] = (0, vue.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)),
|
|
1643
|
+
(0, vue.createElementVNode)("div", _hoisted_2$7, [(0, vue.createElementVNode)("div", _hoisted_3$7, [_cache[6] || (_cache[6] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "link", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)(__props.view.targetSlug), 1)]), (0, vue.createElementVNode)("span", _hoisted_4$7, (0, vue.toDisplayString)(__props.view.recordId), 1)]),
|
|
1644
|
+
(0, vue.createElementVNode)("div", _hoisted_5$6, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.view.rows, (row) => {
|
|
1645
|
+
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
1646
|
+
key: row.key,
|
|
1647
|
+
class: "space-y-0.5"
|
|
1648
|
+
}, [(0, vue.createElementVNode)("div", _hoisted_6$5, (0, vue.toDisplayString)(row.label), 1), (0, vue.createElementVNode)("div", {
|
|
1649
|
+
class: "text-xs text-slate-700 font-medium break-words",
|
|
1650
|
+
"data-testid": `collections-embed-${__props.fieldKey}-${row.key}`
|
|
1651
|
+
}, [row.type === "boolean" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [row.value === true ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_8$5, "check_circle")) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_9$5, "—"))], 64)) : row.type === "markdown" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_10$5, (0, vue.toDisplayString)(row.display), 1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_11$5, (0, vue.toDisplayString)(row.display), 1))], 8, _hoisted_7$5)]);
|
|
1652
|
+
}), 128))])
|
|
1653
|
+
], 40, _hoisted_1$8)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
1654
|
+
key: 1,
|
|
1655
|
+
class: "relative rounded-xl border border-red-100 bg-red-50/30 p-4 pl-5 shadow-sm",
|
|
1656
|
+
"data-testid": `collections-embed-${__props.fieldKey}`
|
|
1657
|
+
}, [_cache[10] || (_cache[10] = (0, vue.createElementVNode)("div", { class: "absolute left-0 top-0 bottom-0 w-1 bg-red-400 rounded-l-xl" }, null, -1)), (0, vue.createElementVNode)("div", _hoisted_13$4, [_cache[9] || (_cache[9] = (0, vue.createElementVNode)("span", { class: "material-icons text-red-500 text-lg mt-0.5" }, "error_outline", -1)), (0, vue.createElementVNode)("div", _hoisted_14$4, [
|
|
1658
|
+
(0, vue.createElementVNode)("p", _hoisted_15$4, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.embedMissingTitle")), 1),
|
|
1659
|
+
(0, vue.createElementVNode)("p", {
|
|
1660
|
+
class: "text-xs text-red-600",
|
|
1661
|
+
"data-testid": `collections-embed-missing-${__props.fieldKey}`
|
|
1662
|
+
}, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.embedMissing", {
|
|
1663
|
+
collection: __props.view.targetSlug,
|
|
1664
|
+
id: __props.view.recordId
|
|
1665
|
+
})), 9, _hoisted_16$3),
|
|
1666
|
+
__props.view.targetSlug ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
1667
|
+
key: 0,
|
|
1668
|
+
href: (0, vue.unref)(cui).recordHref?.(__props.view.targetSlug),
|
|
1669
|
+
tabindex: (0, vue.unref)(cui).recordHref?.(__props.view.targetSlug) ? void 0 : 0,
|
|
1670
|
+
role: "link",
|
|
1671
|
+
class: "inline-flex items-center gap-0.5 text-xs text-indigo-600 hover:text-indigo-800 font-semibold mt-2 hover:underline",
|
|
1672
|
+
onClick: _cache[3] || (_cache[3] = ($event) => (0, vue.unref)(activateRefLink)($event, __props.view.targetSlug)),
|
|
1673
|
+
onKeydown: [_cache[4] || (_cache[4] = (0, vue.withKeys)(($event) => (0, vue.unref)(activateRefLink)($event, __props.view.targetSlug), ["enter"])), _cache[5] || (_cache[5] = (0, vue.withKeys)(($event) => (0, vue.unref)(activateRefLink)($event, __props.view.targetSlug), ["space"]))]
|
|
1674
|
+
}, [(0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.embedCreate")), 1), _cache[8] || (_cache[8] = (0, vue.createElementVNode)("span", { class: "material-icons text-xs" }, "arrow_forward", -1))], 40, _hoisted_17$3)) : (0, vue.createCommentVNode)("", true)
|
|
1675
|
+
])])], 8, _hoisted_12$5));
|
|
1676
|
+
};
|
|
1677
|
+
}
|
|
1678
|
+
});
|
|
1679
|
+
//#endregion
|
|
1930
1680
|
//#region src/vue/components/CollectionRecordPanel.vue?vue&type=script&setup=true&lang.ts
|
|
1931
|
-
var _hoisted_1$
|
|
1932
|
-
var _hoisted_2$
|
|
1933
|
-
var _hoisted_3$
|
|
1934
|
-
var _hoisted_4$
|
|
1935
|
-
var _hoisted_5$
|
|
1681
|
+
var _hoisted_1$7 = { class: "flex items-center gap-2 mb-4" };
|
|
1682
|
+
var _hoisted_2$6 = { class: "flex-1 min-w-0" };
|
|
1683
|
+
var _hoisted_3$6 = { class: "block text-[9px] font-bold text-slate-400 uppercase tracking-wider" };
|
|
1684
|
+
var _hoisted_4$6 = ["data-testid"];
|
|
1685
|
+
var _hoisted_5$5 = ["disabled"];
|
|
1936
1686
|
var _hoisted_6$4 = {
|
|
1937
1687
|
key: 1,
|
|
1938
1688
|
class: "flex items-center gap-2"
|
|
@@ -2068,49 +1818,61 @@ var _hoisted_52$1 = {
|
|
|
2068
1818
|
key: 2,
|
|
2069
1819
|
class: "text-slate-300"
|
|
2070
1820
|
};
|
|
2071
|
-
var _hoisted_53$1 =
|
|
1821
|
+
var _hoisted_53$1 = [
|
|
1822
|
+
"href",
|
|
1823
|
+
"tabindex",
|
|
1824
|
+
"data-testid",
|
|
1825
|
+
"onClick",
|
|
1826
|
+
"onKeydown"
|
|
1827
|
+
];
|
|
1828
|
+
var _hoisted_54$1 = {
|
|
2072
1829
|
key: 3,
|
|
2073
1830
|
class: "font-semibold text-slate-900 tabular-nums text-sm"
|
|
2074
1831
|
};
|
|
2075
|
-
var
|
|
1832
|
+
var _hoisted_55$1 = {
|
|
2076
1833
|
key: 4,
|
|
2077
1834
|
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"
|
|
2078
1835
|
};
|
|
2079
|
-
var
|
|
1836
|
+
var _hoisted_56$1 = {
|
|
2080
1837
|
key: 5,
|
|
2081
1838
|
class: "border border-slate-200/80 rounded-xl overflow-hidden shadow-sm mt-1"
|
|
2082
1839
|
};
|
|
2083
|
-
var
|
|
2084
|
-
var
|
|
2085
|
-
var
|
|
2086
|
-
var
|
|
1840
|
+
var _hoisted_57$1 = { class: "w-full text-[11px] text-slate-600 bg-white" };
|
|
1841
|
+
var _hoisted_58$1 = { class: "bg-slate-50 border-b border-slate-200 text-slate-500 font-bold uppercase tracking-wider" };
|
|
1842
|
+
var _hoisted_59$1 = { class: "divide-y divide-slate-100" };
|
|
1843
|
+
var _hoisted_60$1 = {
|
|
2087
1844
|
key: 0,
|
|
2088
1845
|
class: "material-icons text-emerald-600 text-base"
|
|
2089
1846
|
};
|
|
2090
|
-
var
|
|
1847
|
+
var _hoisted_61$1 = {
|
|
2091
1848
|
key: 1,
|
|
2092
1849
|
class: "text-slate-300"
|
|
2093
1850
|
};
|
|
2094
|
-
var
|
|
1851
|
+
var _hoisted_62$1 = {
|
|
2095
1852
|
key: 6,
|
|
2096
1853
|
class: "text-slate-400 italic"
|
|
2097
1854
|
};
|
|
2098
|
-
var
|
|
1855
|
+
var _hoisted_63$1 = {
|
|
2099
1856
|
key: 7,
|
|
2100
1857
|
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"
|
|
2101
1858
|
};
|
|
2102
|
-
var
|
|
1859
|
+
var _hoisted_64$1 = [
|
|
2103
1860
|
"src",
|
|
2104
1861
|
"alt",
|
|
2105
1862
|
"data-testid"
|
|
2106
1863
|
];
|
|
2107
|
-
var _hoisted_64$1 = ["href", "data-testid"];
|
|
2108
1864
|
var _hoisted_65$1 = ["href", "data-testid"];
|
|
2109
|
-
var _hoisted_66$1 =
|
|
1865
|
+
var _hoisted_66$1 = ["href", "data-testid"];
|
|
1866
|
+
var _hoisted_67$1 = [
|
|
1867
|
+
"href",
|
|
1868
|
+
"data-testid",
|
|
1869
|
+
"onClick"
|
|
1870
|
+
];
|
|
1871
|
+
var _hoisted_68$1 = {
|
|
2110
1872
|
key: 13,
|
|
2111
1873
|
class: "text-slate-800 font-semibold"
|
|
2112
1874
|
};
|
|
2113
|
-
var
|
|
1875
|
+
var _hoisted_69$1 = {
|
|
2114
1876
|
key: 0,
|
|
2115
1877
|
class: "col-span-full text-xs font-semibold text-red-600 bg-red-50 border border-red-100 p-2.5 rounded-xl"
|
|
2116
1878
|
};
|
|
@@ -2145,7 +1907,8 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2145
1907
|
"runAction"
|
|
2146
1908
|
], ["update:editing"]),
|
|
2147
1909
|
setup(__props, { emit: __emit }) {
|
|
2148
|
-
const
|
|
1910
|
+
const cui = collectionUi();
|
|
1911
|
+
const resolveImageSrc = cui.imageSrc;
|
|
2149
1912
|
const props = __props;
|
|
2150
1913
|
const editing = (0, vue.useModel)(__props, "editing");
|
|
2151
1914
|
const emit = __emit;
|
|
@@ -2225,17 +1988,16 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2225
1988
|
if (rows) rows.splice(index, 1);
|
|
2226
1989
|
}
|
|
2227
1990
|
return (_ctx, _cache) => {
|
|
2228
|
-
const _component_router_link = (0, vue.resolveComponent)("router-link");
|
|
2229
1991
|
return (0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)(editing.value ? "form" : "div"), {
|
|
2230
1992
|
class: "px-6 py-5 max-h-[60vh] overflow-y-auto",
|
|
2231
1993
|
"data-testid": rootTestid.value,
|
|
2232
1994
|
onSubmit: _cache[4] || (_cache[4] = (0, vue.withModifiers)(($event) => emit("submit"), ["prevent"]))
|
|
2233
1995
|
}, {
|
|
2234
1996
|
default: (0, vue.withCtx)(() => [
|
|
2235
|
-
(0, vue.createElementVNode)("div", _hoisted_1$
|
|
1997
|
+
(0, vue.createElementVNode)("div", _hoisted_1$7, [(0, vue.createElementVNode)("div", _hoisted_2$6, [(0, vue.createElementVNode)("span", _hoisted_3$6, (0, vue.toDisplayString)(__props.collection.title), 1), (0, vue.createElementVNode)("h2", {
|
|
2236
1998
|
class: "text-base font-bold text-slate-800 truncate",
|
|
2237
1999
|
"data-testid": editing.value ? "collections-edit-title" : "collections-detail-title"
|
|
2238
|
-
}, (0, vue.toDisplayString)(headerTitle.value), 9, _hoisted_4$
|
|
2000
|
+
}, (0, vue.toDisplayString)(headerTitle.value), 9, _hoisted_4$6)]), editing.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [(0, vue.createElementVNode)("button", {
|
|
2239
2001
|
type: "button",
|
|
2240
2002
|
class: "h-8 px-2.5 rounded text-xs font-bold text-slate-500 hover:bg-slate-200/50 transition-colors",
|
|
2241
2003
|
"data-testid": "collections-editor-cancel",
|
|
@@ -2245,7 +2007,7 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2245
2007
|
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",
|
|
2246
2008
|
disabled: __props.saving,
|
|
2247
2009
|
"data-testid": "collections-editor-save"
|
|
2248
|
-
}, (0, vue.toDisplayString)(__props.saving ? (0, vue.unref)(t)("common.saving") : (0, vue.unref)(t)("common.save")), 9, _hoisted_5$
|
|
2010
|
+
}, (0, vue.toDisplayString)(__props.saving ? (0, vue.unref)(t)("common.saving") : (0, vue.unref)(t)("common.save")), 9, _hoisted_5$5)], 64)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_6$4, [
|
|
2249
2011
|
((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.visibleActions, (action) => {
|
|
2250
2012
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
2251
2013
|
key: action.id,
|
|
@@ -2421,23 +2183,21 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2421
2183
|
key: 1,
|
|
2422
2184
|
class: "text-xs font-medium text-slate-700 break-words",
|
|
2423
2185
|
"data-testid": `collections-detail-value-${key}`
|
|
2424
|
-
}, [field.type === "toggle" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [field.field !== void 0 && String(detailRecord.value[field.field] ?? "") === field.onValue ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_48$1, [_cache[11] || (_cache[11] = (0, vue.createElementVNode)("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), (0, vue.createTextVNode)(" " + (0, vue.toDisplayString)((0, vue.unref)(t)("common.yes")), 1)])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_49$1, (0, vue.toDisplayString)((0, vue.unref)(t)("common.no")), 1))], 64)) : field.type === "boolean" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 1 }, [detailRecord.value[key] === true ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_50$1, [_cache[12] || (_cache[12] = (0, vue.createElementVNode)("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), (0, vue.createTextVNode)(" " + (0, vue.toDisplayString)((0, vue.unref)(t)("common.yes")), 1)])) : detailRecord.value[key] === false ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_51$1, (0, vue.toDisplayString)((0, vue.unref)(t)("common.no")), 1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_52$1, "—"))], 64)) : field.type === "ref" && field.to && typeof detailRecord.value[key] === "string" && detailRecord.value[key] ? ((0, vue.openBlock)(), (0, vue.
|
|
2186
|
+
}, [field.type === "toggle" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [field.field !== void 0 && String(detailRecord.value[field.field] ?? "") === field.onValue ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_48$1, [_cache[11] || (_cache[11] = (0, vue.createElementVNode)("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), (0, vue.createTextVNode)(" " + (0, vue.toDisplayString)((0, vue.unref)(t)("common.yes")), 1)])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_49$1, (0, vue.toDisplayString)((0, vue.unref)(t)("common.no")), 1))], 64)) : field.type === "boolean" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 1 }, [detailRecord.value[key] === true ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_50$1, [_cache[12] || (_cache[12] = (0, vue.createElementVNode)("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), (0, vue.createTextVNode)(" " + (0, vue.toDisplayString)((0, vue.unref)(t)("common.yes")), 1)])) : detailRecord.value[key] === false ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_51$1, (0, vue.toDisplayString)((0, vue.unref)(t)("common.no")), 1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_52$1, "—"))], 64)) : field.type === "ref" && field.to && typeof detailRecord.value[key] === "string" && detailRecord.value[key] ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
2425
2187
|
key: 2,
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
},
|
|
2188
|
+
href: (0, vue.unref)(cui).recordHref?.(field.to, String(detailRecord.value[key])),
|
|
2189
|
+
tabindex: (0, vue.unref)(cui).recordHref?.(field.to, String(detailRecord.value[key])) ? void 0 : 0,
|
|
2190
|
+
role: "link",
|
|
2430
2191
|
class: "text-indigo-600 hover:text-indigo-800 font-bold hover:underline",
|
|
2431
|
-
"data-testid": `collections-detail-ref-${key}
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
}, 1032, ["to", "data-testid"])) : field.type === "money" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_53$1, (0, vue.toDisplayString)(__props.render.formatMoney(detailRecord.value[key], __props.render.resolveCurrency(field, detailRecord.value), __props.locale)), 1)) : field.type === "derived" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_54$1, (0, vue.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]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_55$1, [(0, vue.createElementVNode)("table", _hoisted_56$1, [(0, vue.createElementVNode)("thead", _hoisted_57$1, [(0, vue.createElementVNode)("tr", null, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(field.of, (subField, subKey) => {
|
|
2192
|
+
"data-testid": `collections-detail-ref-${key}`,
|
|
2193
|
+
onClick: ($event) => (0, vue.unref)(activateRefLink)($event, field.to, String(detailRecord.value[key])),
|
|
2194
|
+
onKeydown: [(0, vue.withKeys)(($event) => (0, vue.unref)(activateRefLink)($event, field.to, String(detailRecord.value[key])), ["enter"]), (0, vue.withKeys)(($event) => (0, vue.unref)(activateRefLink)($event, field.to, String(detailRecord.value[key])), ["space"])]
|
|
2195
|
+
}, (0, vue.toDisplayString)(__props.render.refDisplay(field.to, String(detailRecord.value[key]))), 41, _hoisted_53$1)) : field.type === "money" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_54$1, (0, vue.toDisplayString)(__props.render.formatMoney(detailRecord.value[key], __props.render.resolveCurrency(field, detailRecord.value), __props.locale)), 1)) : field.type === "derived" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_55$1, (0, vue.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]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_56$1, [(0, vue.createElementVNode)("table", _hoisted_57$1, [(0, vue.createElementVNode)("thead", _hoisted_58$1, [(0, vue.createElementVNode)("tr", null, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(field.of, (subField, subKey) => {
|
|
2436
2196
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("th", {
|
|
2437
2197
|
key: subKey,
|
|
2438
2198
|
class: "text-left px-4 py-2 font-bold"
|
|
2439
2199
|
}, (0, vue.toDisplayString)(subField.label), 1);
|
|
2440
|
-
}), 128))])]), (0, vue.createElementVNode)("tbody",
|
|
2200
|
+
}), 128))])]), (0, vue.createElementVNode)("tbody", _hoisted_59$1, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.render.tableRows(detailRecord.value[key]), (row, rowIdx) => {
|
|
2441
2201
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("tr", {
|
|
2442
2202
|
key: rowIdx,
|
|
2443
2203
|
class: "hover:bg-slate-50/50"
|
|
@@ -2445,12 +2205,12 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2445
2205
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("td", {
|
|
2446
2206
|
key: subKey,
|
|
2447
2207
|
class: "px-4 py-2 align-middle font-medium"
|
|
2448
|
-
}, [subField.type === "boolean" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [row[subKey] === true ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span",
|
|
2208
|
+
}, [subField.type === "boolean" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [row[subKey] === true ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_60$1, "check_circle")) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_61$1, "—"))], 64)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
|
|
2449
2209
|
key: 1,
|
|
2450
2210
|
class: (0, vue.normalizeClass)([subField.type === "money" ? "font-bold text-slate-800 tabular-nums" : ""])
|
|
2451
2211
|
}, (0, vue.toDisplayString)(__props.render.formatSubCell(subField, row[subKey], detailRecord.value)), 3))]);
|
|
2452
2212
|
}), 128))]);
|
|
2453
|
-
}), 128))])])])) : field.type === "table" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span",
|
|
2213
|
+
}), 128))])])])) : field.type === "table" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_62$1, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.noRows")), 1)) : field.type === "markdown" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_63$1, (0, vue.toDisplayString)(__props.render.detailText(detailRecord.value[key])), 1)) : field.type === "embed" && embedViews.value[key] ? ((0, vue.openBlock)(), (0, vue.createBlock)(CollectionEmbedView_default, {
|
|
2454
2214
|
key: 8,
|
|
2455
2215
|
view: embedViews.value[key],
|
|
2456
2216
|
"field-key": String(key)
|
|
@@ -2460,30 +2220,28 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2460
2220
|
alt: field.label,
|
|
2461
2221
|
class: "max-h-64 max-w-full object-contain rounded-lg border border-slate-200 bg-slate-50",
|
|
2462
2222
|
"data-testid": `collections-detail-image-${key}`
|
|
2463
|
-
}, null, 8,
|
|
2223
|
+
}, null, 8, _hoisted_64$1)) : field.type !== "file" && __props.render.isExternalUrl(detailRecord.value[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
2464
2224
|
key: 10,
|
|
2465
2225
|
href: String(detailRecord.value[key]),
|
|
2466
2226
|
target: "_blank",
|
|
2467
2227
|
rel: "noopener noreferrer",
|
|
2468
2228
|
class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
|
|
2469
2229
|
"data-testid": `collections-detail-url-${key}`
|
|
2470
|
-
}, (0, vue.toDisplayString)(String(detailRecord.value[key])), 9,
|
|
2230
|
+
}, (0, vue.toDisplayString)(String(detailRecord.value[key])), 9, _hoisted_65$1)) : field.type === "file" && __props.render.artifactUrl(detailRecord.value[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
2471
2231
|
key: 11,
|
|
2472
2232
|
href: __props.render.artifactUrl(detailRecord.value[key]) ?? void 0,
|
|
2473
2233
|
target: "_blank",
|
|
2474
2234
|
rel: "noopener noreferrer",
|
|
2475
2235
|
class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
|
|
2476
2236
|
"data-testid": `collections-detail-file-${key}`
|
|
2477
|
-
}, (0, vue.toDisplayString)(String(detailRecord.value[key])), 9,
|
|
2237
|
+
}, (0, vue.toDisplayString)(String(detailRecord.value[key])), 9, _hoisted_66$1)) : field.type === "file" && __props.render.fileRoutePath(detailRecord.value[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
2478
2238
|
key: 12,
|
|
2479
|
-
|
|
2239
|
+
href: __props.render.fileRoutePath(detailRecord.value[key]) ?? void 0,
|
|
2480
2240
|
class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
|
|
2481
|
-
"data-testid": `collections-detail-file-${key}
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
}, 1032, ["to", "data-testid"])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_66$1, (0, vue.toDisplayString)(__props.render.formatCell(detailRecord.value[key], field.type)), 1))], 8, _hoisted_47$1))], 2)) : (0, vue.createCommentVNode)("", true)], 64);
|
|
2486
|
-
}), 128)), editing.value && __props.saveError ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_67$1, (0, vue.toDisplayString)(__props.saveError), 1)) : (0, vue.createCommentVNode)("", true)])
|
|
2241
|
+
"data-testid": `collections-detail-file-${key}`,
|
|
2242
|
+
onClick: ($event) => (0, vue.unref)(activatePathLink)($event, __props.render.fileRoutePath(detailRecord.value[key]) ?? "")
|
|
2243
|
+
}, (0, vue.toDisplayString)(String(detailRecord.value[key])), 9, _hoisted_67$1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_68$1, (0, vue.toDisplayString)(__props.render.formatCell(detailRecord.value[key], field.type)), 1))], 8, _hoisted_47$1))], 2)) : (0, vue.createCommentVNode)("", true)], 64);
|
|
2244
|
+
}), 128)), editing.value && __props.saveError ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_69$1, (0, vue.toDisplayString)(__props.saveError), 1)) : (0, vue.createCommentVNode)("", true)])
|
|
2487
2245
|
]),
|
|
2488
2246
|
_: 1
|
|
2489
2247
|
}, 40, ["data-testid"]);
|
|
@@ -2492,14 +2250,14 @@ var CollectionRecordPanel_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
2492
2250
|
});
|
|
2493
2251
|
//#endregion
|
|
2494
2252
|
//#region src/vue/components/CollectionViewConfigModal.vue?vue&type=script&setup=true&lang.ts
|
|
2495
|
-
var _hoisted_1$
|
|
2253
|
+
var _hoisted_1$6 = {
|
|
2496
2254
|
"data-testid": "collection-config-modal",
|
|
2497
2255
|
class: "flex flex-col overflow-hidden"
|
|
2498
2256
|
};
|
|
2499
|
-
var _hoisted_2$
|
|
2500
|
-
var _hoisted_3$
|
|
2501
|
-
var _hoisted_4$
|
|
2502
|
-
var _hoisted_5$
|
|
2257
|
+
var _hoisted_2$5 = { class: "flex items-center justify-between gap-2 border-b border-slate-100 px-5 py-3" };
|
|
2258
|
+
var _hoisted_3$5 = { class: "text-sm font-bold text-slate-700" };
|
|
2259
|
+
var _hoisted_4$5 = ["title", "aria-label"];
|
|
2260
|
+
var _hoisted_5$4 = { class: "overflow-y-auto px-5 py-4" };
|
|
2503
2261
|
var _hoisted_6$3 = { class: "mb-2 text-[10px] font-bold uppercase tracking-wider text-slate-400" };
|
|
2504
2262
|
var _hoisted_7$3 = {
|
|
2505
2263
|
key: 0,
|
|
@@ -2564,14 +2322,14 @@ var CollectionViewConfigModal_default = /* @__PURE__ */ (0, vue.defineComponent)
|
|
|
2564
2322
|
}
|
|
2565
2323
|
return (_ctx, _cache) => {
|
|
2566
2324
|
return (0, vue.openBlock)(), (0, vue.createBlock)(CollectionRecordModal_default, { onClose: _cache[1] || (_cache[1] = ($event) => emit("close")) }, {
|
|
2567
|
-
default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("div", _hoisted_1$
|
|
2325
|
+
default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("div", _hoisted_1$6, [(0, vue.createElementVNode)("header", _hoisted_2$5, [(0, vue.createElementVNode)("h2", _hoisted_3$5, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.config.title", { title: __props.title })), 1), (0, vue.createElementVNode)("button", {
|
|
2568
2326
|
type: "button",
|
|
2569
2327
|
class: "h-8 w-8 flex items-center justify-center rounded text-slate-400 hover:bg-slate-50 hover:text-slate-600",
|
|
2570
2328
|
title: (0, vue.unref)(t)("common.close"),
|
|
2571
2329
|
"aria-label": (0, vue.unref)(t)("common.close"),
|
|
2572
2330
|
"data-testid": "collection-config-close",
|
|
2573
2331
|
onClick: _cache[0] || (_cache[0] = ($event) => emit("close"))
|
|
2574
|
-
}, [..._cache[2] || (_cache[2] = [(0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_4$
|
|
2332
|
+
}, [..._cache[2] || (_cache[2] = [(0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_4$5)]), (0, vue.createElementVNode)("div", _hoisted_5$4, [
|
|
2575
2333
|
(0, vue.createElementVNode)("h3", _hoisted_6$3, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.config.viewsHeading")), 1),
|
|
2576
2334
|
error.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_7$3, (0, vue.toDisplayString)(error.value), 1)) : (0, vue.createCommentVNode)("", true),
|
|
2577
2335
|
__props.views.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("ul", _hoisted_8$3, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.views, (view) => {
|
|
@@ -2600,19 +2358,19 @@ var CollectionViewConfigModal_default = /* @__PURE__ */ (0, vue.defineComponent)
|
|
|
2600
2358
|
});
|
|
2601
2359
|
//#endregion
|
|
2602
2360
|
//#region src/vue/components/CollectionCustomView.vue?vue&type=script&setup=true&lang.ts
|
|
2603
|
-
var _hoisted_1$
|
|
2604
|
-
var _hoisted_2$
|
|
2361
|
+
var _hoisted_1$5 = { class: "custom-view-container" };
|
|
2362
|
+
var _hoisted_2$4 = {
|
|
2605
2363
|
key: 0,
|
|
2606
2364
|
class: "custom-view-message",
|
|
2607
2365
|
role: "alert",
|
|
2608
2366
|
"data-testid": "collection-custom-view-error"
|
|
2609
2367
|
};
|
|
2610
|
-
var _hoisted_3$
|
|
2368
|
+
var _hoisted_3$4 = {
|
|
2611
2369
|
key: 1,
|
|
2612
2370
|
class: "custom-view-message",
|
|
2613
2371
|
"data-testid": "collection-custom-view-loading"
|
|
2614
2372
|
};
|
|
2615
|
-
var _hoisted_4$
|
|
2373
|
+
var _hoisted_4$4 = ["title", "srcdoc"];
|
|
2616
2374
|
var REMINT_LEAD_MS = 6e4;
|
|
2617
2375
|
var MIN_REMINT_DELAY_MS = 1e4;
|
|
2618
2376
|
var CollectionCustomView_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
@@ -2668,46 +2426,365 @@ var CollectionCustomView_vue_vue_type_script_setup_true_lang_default = /* @__PUR
|
|
|
2668
2426
|
dataUrl: mint.data.dataUrl,
|
|
2669
2427
|
origin: window.location.origin
|
|
2670
2428
|
});
|
|
2671
|
-
} catch (err) {
|
|
2672
|
-
if (!stale()) error.value = require_promptSafety.errorMessage(err);
|
|
2673
|
-
} finally {
|
|
2674
|
-
if (!stale()) loading.value = false;
|
|
2429
|
+
} catch (err) {
|
|
2430
|
+
if (!stale()) error.value = require_promptSafety.errorMessage(err);
|
|
2431
|
+
} finally {
|
|
2432
|
+
if (!stale()) loading.value = false;
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
(0, vue.watch)([() => props.slug, () => props.view.id], () => void load(), { immediate: true });
|
|
2436
|
+
(0, vue.onBeforeUnmount)(clearRefresh);
|
|
2437
|
+
return (_ctx, _cache) => {
|
|
2438
|
+
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$5, [error.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2$4, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.customViewError", { error: error.value })), 1)) : loading.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_3$4, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.customViewLoading")), 1)) : srcdoc.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("iframe", {
|
|
2439
|
+
key: __props.view.id,
|
|
2440
|
+
"data-testid": "collection-custom-view-iframe",
|
|
2441
|
+
title: __props.view.label,
|
|
2442
|
+
srcdoc: srcdoc.value,
|
|
2443
|
+
sandbox: "allow-scripts allow-popups allow-popups-to-escape-sandbox",
|
|
2444
|
+
class: "w-full h-full border-0"
|
|
2445
|
+
}, null, 8, _hoisted_4$4)) : (0, vue.createCommentVNode)("", true)]);
|
|
2446
|
+
};
|
|
2447
|
+
}
|
|
2448
|
+
});
|
|
2449
|
+
//#endregion
|
|
2450
|
+
//#region \0plugin-vue:export-helper
|
|
2451
|
+
var _plugin_vue_export_helper_default = (sfc, props) => {
|
|
2452
|
+
const target = sfc.__vccOpts || sfc;
|
|
2453
|
+
for (const [key, val] of props) target[key] = val;
|
|
2454
|
+
return target;
|
|
2455
|
+
};
|
|
2456
|
+
//#endregion
|
|
2457
|
+
//#region src/vue/components/CollectionCustomView.vue
|
|
2458
|
+
var CollectionCustomView_default = /* @__PURE__ */ _plugin_vue_export_helper_default(CollectionCustomView_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-3ab71997"]]);
|
|
2459
|
+
//#endregion
|
|
2460
|
+
//#region src/vue/useCollectionRendering.ts
|
|
2461
|
+
function useCollectionRendering(collection, locale) {
|
|
2462
|
+
const refCache = (0, vue.ref)({});
|
|
2463
|
+
const refRecordCache = (0, vue.ref)({});
|
|
2464
|
+
const embedCache = (0, vue.ref)({});
|
|
2465
|
+
function resetLinkedCaches() {
|
|
2466
|
+
refCache.value = {};
|
|
2467
|
+
refRecordCache.value = {};
|
|
2468
|
+
embedCache.value = {};
|
|
2469
|
+
}
|
|
2470
|
+
function uniqueRefTargets(schema) {
|
|
2471
|
+
const targets = /* @__PURE__ */ new Set();
|
|
2472
|
+
const walk = (fields) => {
|
|
2473
|
+
for (const field of Object.values(fields)) {
|
|
2474
|
+
if (field.type === "ref" && typeof field.to === "string" && field.to.length > 0) targets.add(field.to);
|
|
2475
|
+
if (field.type === "table" && field.of) walk(field.of);
|
|
2476
|
+
}
|
|
2477
|
+
};
|
|
2478
|
+
walk(schema.fields);
|
|
2479
|
+
return [...targets];
|
|
2480
|
+
}
|
|
2481
|
+
function uniqueEmbedTargets(schema) {
|
|
2482
|
+
const targets = /* @__PURE__ */ new Set();
|
|
2483
|
+
for (const field of Object.values(schema.fields)) if (field.type === "embed" && typeof field.to === "string" && field.to.length > 0) targets.add(field.to);
|
|
2484
|
+
return [...targets];
|
|
2485
|
+
}
|
|
2486
|
+
function buildRefDisplayMap(detail) {
|
|
2487
|
+
const { fields, primaryKey } = detail.collection.schema;
|
|
2488
|
+
const displayField = "name" in fields ? "name" : "title" in fields ? "title" : primaryKey;
|
|
2489
|
+
const map = {};
|
|
2490
|
+
for (const item of detail.items) {
|
|
2491
|
+
const slugRaw = item[primaryKey];
|
|
2492
|
+
if (typeof slugRaw !== "string" || slugRaw.length === 0) continue;
|
|
2493
|
+
const displayRaw = item[displayField];
|
|
2494
|
+
map[slugRaw] = typeof displayRaw === "string" && displayRaw.length > 0 ? displayRaw : slugRaw;
|
|
2495
|
+
}
|
|
2496
|
+
return map;
|
|
2497
|
+
}
|
|
2498
|
+
function buildRefRecordMap(detail) {
|
|
2499
|
+
const { schema } = detail.collection;
|
|
2500
|
+
const map = {};
|
|
2501
|
+
for (const item of detail.items) {
|
|
2502
|
+
const slugRaw = item[schema.primaryKey];
|
|
2503
|
+
if (typeof slugRaw === "string" && slugRaw.length > 0) map[slugRaw] = require_deriveAll.deriveAll(schema, item, {});
|
|
2504
|
+
}
|
|
2505
|
+
return map;
|
|
2506
|
+
}
|
|
2507
|
+
async function loadLinkedCollections(schema, expectedSlug) {
|
|
2508
|
+
const refTargets = new Set(uniqueRefTargets(schema));
|
|
2509
|
+
const embedTargets = new Set(uniqueEmbedTargets(schema));
|
|
2510
|
+
const allTargets = [...new Set([...refTargets, ...embedTargets])];
|
|
2511
|
+
if (allTargets.length === 0) return;
|
|
2512
|
+
const binding = collectionUi();
|
|
2513
|
+
const results = await Promise.all(allTargets.map(async (target) => {
|
|
2514
|
+
try {
|
|
2515
|
+
return {
|
|
2516
|
+
target,
|
|
2517
|
+
result: await binding.fetchCollectionDetail(target)
|
|
2518
|
+
};
|
|
2519
|
+
} catch {
|
|
2520
|
+
return {
|
|
2521
|
+
target,
|
|
2522
|
+
result: { ok: false }
|
|
2523
|
+
};
|
|
2524
|
+
}
|
|
2525
|
+
}));
|
|
2526
|
+
if (collection.value?.slug !== expectedSlug) return;
|
|
2527
|
+
const nextRef = {};
|
|
2528
|
+
const nextRefRecords = {};
|
|
2529
|
+
const nextEmbed = {};
|
|
2530
|
+
for (const { target, result } of results) {
|
|
2531
|
+
if (!result.ok) continue;
|
|
2532
|
+
if (refTargets.has(target)) {
|
|
2533
|
+
nextRef[target] = buildRefDisplayMap(result.data);
|
|
2534
|
+
nextRefRecords[target] = buildRefRecordMap(result.data);
|
|
2535
|
+
}
|
|
2536
|
+
if (embedTargets.has(target)) nextEmbed[target] = {
|
|
2537
|
+
schema: result.data.collection.schema,
|
|
2538
|
+
items: result.data.items
|
|
2539
|
+
};
|
|
2540
|
+
}
|
|
2541
|
+
refCache.value = nextRef;
|
|
2542
|
+
refRecordCache.value = nextRefRecords;
|
|
2543
|
+
embedCache.value = nextEmbed;
|
|
2544
|
+
}
|
|
2545
|
+
function refDisplay(targetSlug, itemSlug) {
|
|
2546
|
+
const map = refCache.value[targetSlug];
|
|
2547
|
+
return map && map[itemSlug] || itemSlug;
|
|
2548
|
+
}
|
|
2549
|
+
function refOptions(targetSlug) {
|
|
2550
|
+
const map = refCache.value[targetSlug];
|
|
2551
|
+
if (!map) return [];
|
|
2552
|
+
return Object.entries(map).map(([slug, display]) => ({
|
|
2553
|
+
slug,
|
|
2554
|
+
display
|
|
2555
|
+
})).sort((left, right) => left.display.localeCompare(right.display));
|
|
2556
|
+
}
|
|
2557
|
+
function resolveEmbed(field) {
|
|
2558
|
+
if (field.type !== "embed" || !field.to || !field.id) return {
|
|
2559
|
+
schema: null,
|
|
2560
|
+
item: null
|
|
2561
|
+
};
|
|
2562
|
+
const data = embedCache.value[field.to];
|
|
2563
|
+
if (!data) return {
|
|
2564
|
+
schema: null,
|
|
2565
|
+
item: null
|
|
2566
|
+
};
|
|
2567
|
+
const item = data.items.find((entry) => String(entry[data.schema.primaryKey] ?? "") === field.id) ?? null;
|
|
2568
|
+
return {
|
|
2569
|
+
schema: data.schema,
|
|
2570
|
+
item
|
|
2571
|
+
};
|
|
2572
|
+
}
|
|
2573
|
+
function embedValue(field, value, record) {
|
|
2574
|
+
if (field.type === "money") return formatMoney(value, resolveCurrency(field, record), locale.value);
|
|
2575
|
+
return detailText(value);
|
|
2576
|
+
}
|
|
2577
|
+
const embedViews = (0, vue.computed)(() => {
|
|
2578
|
+
const out = {};
|
|
2579
|
+
if (!collection.value) return out;
|
|
2580
|
+
for (const [key, field] of Object.entries(collection.value.schema.fields)) {
|
|
2581
|
+
if (field.type !== "embed") continue;
|
|
2582
|
+
const { schema, item } = resolveEmbed(field);
|
|
2583
|
+
const rows = [];
|
|
2584
|
+
if (schema && item) for (const [subKey, subField] of Object.entries(schema.fields)) {
|
|
2585
|
+
const value = item[subKey];
|
|
2586
|
+
if (value === void 0 || value === null || value === "") continue;
|
|
2587
|
+
rows.push({
|
|
2588
|
+
key: subKey,
|
|
2589
|
+
label: subField.label,
|
|
2590
|
+
type: subField.type,
|
|
2591
|
+
value,
|
|
2592
|
+
display: embedValue(subField, value, item)
|
|
2593
|
+
});
|
|
2675
2594
|
}
|
|
2595
|
+
out[key] = {
|
|
2596
|
+
found: Boolean(item),
|
|
2597
|
+
rows,
|
|
2598
|
+
targetSlug: field.to ?? "",
|
|
2599
|
+
recordId: field.id ?? ""
|
|
2600
|
+
};
|
|
2676
2601
|
}
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
sandbox: "allow-scripts allow-popups allow-popups-to-escape-sandbox",
|
|
2686
|
-
class: "w-full h-full border-0"
|
|
2687
|
-
}, null, 8, _hoisted_4$3)) : (0, vue.createCommentVNode)("", true)]);
|
|
2688
|
-
};
|
|
2602
|
+
return out;
|
|
2603
|
+
});
|
|
2604
|
+
function resolveCurrency(field, record) {
|
|
2605
|
+
if (field.currencyField && record) {
|
|
2606
|
+
const code = record[field.currencyField];
|
|
2607
|
+
if (typeof code === "string" && code.trim().length > 0) return code;
|
|
2608
|
+
}
|
|
2609
|
+
return field.currency;
|
|
2689
2610
|
}
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
}
|
|
2611
|
+
function currencySymbol(currency) {
|
|
2612
|
+
const code = currency && currency.length > 0 ? currency : "USD";
|
|
2613
|
+
try {
|
|
2614
|
+
return new Intl.NumberFormat(locale.value, {
|
|
2615
|
+
style: "currency",
|
|
2616
|
+
currency: code
|
|
2617
|
+
}).formatToParts(0).find((entry) => entry.type === "currency")?.value ?? code;
|
|
2618
|
+
} catch {
|
|
2619
|
+
return code;
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
function formatMoney(value, currency, displayLocale) {
|
|
2623
|
+
if (value === void 0 || value === "") return "—";
|
|
2624
|
+
const amount = typeof value === "number" ? value : Number(value);
|
|
2625
|
+
if (!Number.isFinite(amount)) return String(value);
|
|
2626
|
+
const currencyCode = currency && currency.length > 0 ? currency : "USD";
|
|
2627
|
+
try {
|
|
2628
|
+
return new Intl.NumberFormat(displayLocale, {
|
|
2629
|
+
style: "currency",
|
|
2630
|
+
currency: currencyCode
|
|
2631
|
+
}).format(amount);
|
|
2632
|
+
} catch {
|
|
2633
|
+
return String(amount);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
function formatCell(value, type) {
|
|
2637
|
+
if (value === void 0 || value === null || value === "") return "—";
|
|
2638
|
+
if (type === "markdown" && typeof value === "string") return value.length > 80 ? `${value.slice(0, 80)}…` : value;
|
|
2639
|
+
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
2640
|
+
return JSON.stringify(value);
|
|
2641
|
+
}
|
|
2642
|
+
function isExternalUrl(value) {
|
|
2643
|
+
return typeof value === "string" && /^https?:\/\//i.test(value);
|
|
2644
|
+
}
|
|
2645
|
+
function artifactUrl(value) {
|
|
2646
|
+
return collectionUi().fileAssetUrl(value);
|
|
2647
|
+
}
|
|
2648
|
+
function fileRoutePath(value) {
|
|
2649
|
+
return collectionUi().fileRoutePath(value);
|
|
2650
|
+
}
|
|
2651
|
+
function detailText(value) {
|
|
2652
|
+
if (value === void 0 || value === null || value === "") return "—";
|
|
2653
|
+
return String(value);
|
|
2654
|
+
}
|
|
2655
|
+
function tableRows(value) {
|
|
2656
|
+
if (!Array.isArray(value)) return [];
|
|
2657
|
+
return value.filter((row) => Boolean(row) && typeof row === "object" && !Array.isArray(row));
|
|
2658
|
+
}
|
|
2659
|
+
function hasTableRows(value) {
|
|
2660
|
+
return tableRows(value).length > 0;
|
|
2661
|
+
}
|
|
2662
|
+
function formatSubCell(subField, value, record) {
|
|
2663
|
+
if (subField.type === "money") return formatMoney(value, resolveCurrency(subField, record), locale.value);
|
|
2664
|
+
if (subField.type === "ref" && subField.to && typeof value === "string" && value.length > 0) return refDisplay(subField.to, value);
|
|
2665
|
+
return formatCell(value, subField.type);
|
|
2666
|
+
}
|
|
2667
|
+
function inputTypeFor(type) {
|
|
2668
|
+
if (type === "email") return "email";
|
|
2669
|
+
if (type === "number") return "number";
|
|
2670
|
+
if (type === "money") return "number";
|
|
2671
|
+
if (type === "date") return "date";
|
|
2672
|
+
if (type === "datetime") return "datetime-local";
|
|
2673
|
+
return "text";
|
|
2674
|
+
}
|
|
2675
|
+
function evaluateDerivedAgainstItem(field, fieldKey, item) {
|
|
2676
|
+
if (!field.formula || !collection.value) return null;
|
|
2677
|
+
const result = require_deriveAll.deriveAll(collection.value.schema, item, refRecordCache.value)[fieldKey];
|
|
2678
|
+
return typeof result === "number" && Number.isFinite(result) ? result : null;
|
|
2679
|
+
}
|
|
2680
|
+
function derivedDisplay(field, computedValue, record) {
|
|
2681
|
+
if (computedValue === null || computedValue === void 0) return "—";
|
|
2682
|
+
if (field.display === "money") return formatMoney(computedValue, resolveCurrency(field, record), locale.value);
|
|
2683
|
+
return formatCell(computedValue, field.display ?? "number");
|
|
2684
|
+
}
|
|
2685
|
+
return {
|
|
2686
|
+
refCache,
|
|
2687
|
+
refRecordCache,
|
|
2688
|
+
embedCache,
|
|
2689
|
+
resetLinkedCaches,
|
|
2690
|
+
loadLinkedCollections,
|
|
2691
|
+
refDisplay,
|
|
2692
|
+
refOptions,
|
|
2693
|
+
embedViews,
|
|
2694
|
+
resolveCurrency,
|
|
2695
|
+
currencySymbol,
|
|
2696
|
+
formatMoney,
|
|
2697
|
+
formatCell,
|
|
2698
|
+
detailText,
|
|
2699
|
+
isExternalUrl,
|
|
2700
|
+
artifactUrl,
|
|
2701
|
+
fileRoutePath,
|
|
2702
|
+
tableRows,
|
|
2703
|
+
hasTableRows,
|
|
2704
|
+
formatSubCell,
|
|
2705
|
+
inputTypeFor,
|
|
2706
|
+
deriveAll: require_deriveAll.deriveAll,
|
|
2707
|
+
evaluateDerivedAgainstItem,
|
|
2708
|
+
derivedDisplay
|
|
2709
|
+
};
|
|
2710
|
+
}
|
|
2698
2711
|
//#endregion
|
|
2699
|
-
//#region src/vue/
|
|
2700
|
-
var
|
|
2712
|
+
//#region src/vue/collectionViewMode.ts
|
|
2713
|
+
var STORAGE_KEY = "collection_view_modes";
|
|
2714
|
+
var SORT_STORAGE_KEY = "collection_sorts";
|
|
2715
|
+
var BUILT_IN_MODES = [
|
|
2716
|
+
"table",
|
|
2717
|
+
"calendar",
|
|
2718
|
+
"kanban"
|
|
2719
|
+
];
|
|
2720
|
+
/** A persisted mode is valid if it's a known built-in OR any `custom:<id>`
|
|
2721
|
+
* key (the id is validated against the live schema at render time, so an
|
|
2722
|
+
* unknown custom id simply collapses to the table there). Takes `unknown`
|
|
2723
|
+
* and type-guards `string` first: a corrupted localStorage entry could hold a
|
|
2724
|
+
* number/object, and calling `.startsWith` on that would throw. */
|
|
2725
|
+
function isValidViewMode(value) {
|
|
2726
|
+
return typeof value === "string" && (BUILT_IN_MODES.includes(value) || value.startsWith("custom:"));
|
|
2727
|
+
}
|
|
2728
|
+
function readAll() {
|
|
2729
|
+
try {
|
|
2730
|
+
const raw = localStorage.getItem(STORAGE_KEY);
|
|
2731
|
+
if (!raw) return {};
|
|
2732
|
+
const parsed = JSON.parse(raw);
|
|
2733
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
2734
|
+
} catch {
|
|
2735
|
+
return {};
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
function readCollectionViewMode(slug) {
|
|
2739
|
+
const stored = readAll()[slug];
|
|
2740
|
+
return isValidViewMode(stored) ? stored : null;
|
|
2741
|
+
}
|
|
2742
|
+
function writeCollectionViewMode(slug, view) {
|
|
2743
|
+
try {
|
|
2744
|
+
const all = readAll();
|
|
2745
|
+
all[slug] = view;
|
|
2746
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(all));
|
|
2747
|
+
} catch {}
|
|
2748
|
+
}
|
|
2749
|
+
function isSortState(value) {
|
|
2750
|
+
if (!value || typeof value !== "object") return false;
|
|
2751
|
+
const rec = value;
|
|
2752
|
+
return typeof rec.field === "string" && (rec.direction === "asc" || rec.direction === "desc");
|
|
2753
|
+
}
|
|
2754
|
+
function readAllSorts() {
|
|
2755
|
+
try {
|
|
2756
|
+
const raw = localStorage.getItem(SORT_STORAGE_KEY);
|
|
2757
|
+
if (!raw) return {};
|
|
2758
|
+
const parsed = JSON.parse(raw);
|
|
2759
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
2760
|
+
const out = {};
|
|
2761
|
+
for (const [slug, value] of Object.entries(parsed)) if (isSortState(value)) out[slug] = value;
|
|
2762
|
+
return out;
|
|
2763
|
+
} catch {
|
|
2764
|
+
return {};
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
function readCollectionSort(slug) {
|
|
2768
|
+
return readAllSorts()[slug] ?? null;
|
|
2769
|
+
}
|
|
2770
|
+
/** Persist (or, when `sort` is null, clear) the slug's active column sort. */
|
|
2771
|
+
function writeCollectionSort(slug, sort) {
|
|
2772
|
+
try {
|
|
2773
|
+
const all = Object.fromEntries(Object.entries(readAllSorts()).filter(([key]) => key !== slug));
|
|
2774
|
+
if (sort) all[slug] = sort;
|
|
2775
|
+
localStorage.setItem(SORT_STORAGE_KEY, JSON.stringify(all));
|
|
2776
|
+
} catch {}
|
|
2777
|
+
}
|
|
2701
2778
|
//#endregion
|
|
2702
2779
|
//#region src/vue/components/CollectionView.vue?vue&type=script&setup=true&lang.ts
|
|
2703
|
-
var _hoisted_1$
|
|
2704
|
-
var _hoisted_2$
|
|
2705
|
-
var _hoisted_3$
|
|
2706
|
-
var _hoisted_4$
|
|
2780
|
+
var _hoisted_1$4 = { class: "h-full flex flex-col bg-slate-50/30" };
|
|
2781
|
+
var _hoisted_2$3 = { class: "flex items-center gap-3 px-6 py-2 border-b border-slate-200 bg-white" };
|
|
2782
|
+
var _hoisted_3$3 = ["title", "aria-label"];
|
|
2783
|
+
var _hoisted_4$3 = {
|
|
2707
2784
|
key: 1,
|
|
2708
2785
|
class: "h-9 w-9 flex items-center justify-center rounded-xl bg-indigo-50 text-indigo-600 border border-indigo-100"
|
|
2709
2786
|
};
|
|
2710
|
-
var _hoisted_5$
|
|
2787
|
+
var _hoisted_5$3 = { class: "material-symbols-outlined text-xl" };
|
|
2711
2788
|
var _hoisted_6$2 = { class: "flex-1 min-w-0" };
|
|
2712
2789
|
var _hoisted_7$2 = { class: "text-base font-bold text-slate-800 truncate" };
|
|
2713
2790
|
var _hoisted_8$2 = {
|
|
@@ -2854,48 +2931,60 @@ var _hoisted_65 = {
|
|
|
2854
2931
|
class: "block truncate"
|
|
2855
2932
|
};
|
|
2856
2933
|
var _hoisted_66 = [
|
|
2934
|
+
"href",
|
|
2935
|
+
"tabindex",
|
|
2936
|
+
"data-testid",
|
|
2937
|
+
"onClick",
|
|
2938
|
+
"onKeydown"
|
|
2939
|
+
];
|
|
2940
|
+
var _hoisted_67 = [
|
|
2857
2941
|
"value",
|
|
2858
2942
|
"disabled",
|
|
2859
2943
|
"data-testid",
|
|
2860
2944
|
"aria-label",
|
|
2861
2945
|
"onChange"
|
|
2862
2946
|
];
|
|
2863
|
-
var
|
|
2947
|
+
var _hoisted_68 = {
|
|
2864
2948
|
key: 0,
|
|
2865
2949
|
value: ""
|
|
2866
2950
|
};
|
|
2867
|
-
var
|
|
2868
|
-
var
|
|
2951
|
+
var _hoisted_69 = ["value"];
|
|
2952
|
+
var _hoisted_70 = {
|
|
2869
2953
|
key: 4,
|
|
2870
2954
|
class: "block truncate tabular-nums font-semibold text-slate-900"
|
|
2871
2955
|
};
|
|
2872
|
-
var
|
|
2956
|
+
var _hoisted_71 = {
|
|
2873
2957
|
key: 5,
|
|
2874
2958
|
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"
|
|
2875
2959
|
};
|
|
2876
|
-
var
|
|
2960
|
+
var _hoisted_72 = {
|
|
2877
2961
|
key: 6,
|
|
2878
2962
|
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"
|
|
2879
2963
|
};
|
|
2880
|
-
var _hoisted_72 = ["href", "data-testid"];
|
|
2881
2964
|
var _hoisted_73 = ["href", "data-testid"];
|
|
2882
|
-
var _hoisted_74 =
|
|
2965
|
+
var _hoisted_74 = ["href", "data-testid"];
|
|
2966
|
+
var _hoisted_75 = [
|
|
2967
|
+
"href",
|
|
2968
|
+
"data-testid",
|
|
2969
|
+
"onClick"
|
|
2970
|
+
];
|
|
2971
|
+
var _hoisted_76 = {
|
|
2883
2972
|
key: 10,
|
|
2884
2973
|
class: "block truncate text-slate-600"
|
|
2885
2974
|
};
|
|
2886
|
-
var
|
|
2887
|
-
var
|
|
2888
|
-
var
|
|
2889
|
-
var
|
|
2975
|
+
var _hoisted_77 = { class: "bg-white rounded-2xl shadow-2xl w-full max-w-xl flex flex-col border border-slate-200 overflow-hidden" };
|
|
2976
|
+
var _hoisted_78 = { class: "px-6 py-4 border-b border-slate-100 flex items-center gap-3 bg-slate-50/50" };
|
|
2977
|
+
var _hoisted_79 = { class: "flex-1" };
|
|
2978
|
+
var _hoisted_80 = {
|
|
2890
2979
|
id: "collections-chat-title",
|
|
2891
2980
|
class: "text-sm font-bold text-slate-800 uppercase tracking-wide"
|
|
2892
2981
|
};
|
|
2893
|
-
var
|
|
2894
|
-
var
|
|
2895
|
-
var
|
|
2896
|
-
var
|
|
2897
|
-
var
|
|
2898
|
-
var
|
|
2982
|
+
var _hoisted_81 = { class: "text-xs text-slate-400 font-semibold" };
|
|
2983
|
+
var _hoisted_82 = ["aria-label"];
|
|
2984
|
+
var _hoisted_83 = { class: "px-6 py-5" };
|
|
2985
|
+
var _hoisted_84 = ["placeholder", "onKeydown"];
|
|
2986
|
+
var _hoisted_85 = { class: "px-6 py-3.5 border-t border-slate-100 flex items-center justify-end gap-2 bg-slate-50/50" };
|
|
2987
|
+
var _hoisted_86 = ["disabled"];
|
|
2899
2988
|
//#endregion
|
|
2900
2989
|
//#region src/vue/components/CollectionView.vue
|
|
2901
2990
|
var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
@@ -3862,9 +3951,8 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3862
3951
|
openDay.value = viewing.value ? dayOfItem(viewing.value) : null;
|
|
3863
3952
|
});
|
|
3864
3953
|
return (_ctx, _cache) => {
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
(0, vue.createElementVNode)("header", _hoisted_2$2, [
|
|
3954
|
+
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$4, [
|
|
3955
|
+
(0, vue.createElementVNode)("header", _hoisted_2$3, [
|
|
3868
3956
|
!embedded.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
3869
3957
|
key: 0,
|
|
3870
3958
|
type: "button",
|
|
@@ -3873,8 +3961,8 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3873
3961
|
"aria-label": (0, vue.unref)(t)("collectionsView.backToIndex"),
|
|
3874
3962
|
"data-testid": "collections-back",
|
|
3875
3963
|
onClick: goBack
|
|
3876
|
-
}, [..._cache[
|
|
3877
|
-
collection.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_4$
|
|
3964
|
+
}, [..._cache[23] || (_cache[23] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "arrow_back", -1)])], 8, _hoisted_3$3)) : (0, vue.createCommentVNode)("", true),
|
|
3965
|
+
collection.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_4$3, [(0, vue.createElementVNode)("span", _hoisted_5$3, (0, vue.toDisplayString)(collection.value.icon), 1)])) : (0, vue.createCommentVNode)("", true),
|
|
3878
3966
|
(0, vue.createElementVNode)("div", _hoisted_6$2, [(0, vue.createElementVNode)("h1", _hoisted_7$2, (0, vue.toDisplayString)(collection.value?.title ?? (0, vue.unref)(t)("collectionsView.title")), 1), collection.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_8$2, (0, vue.toDisplayString)(collection.value.slug), 1)) : (0, vue.createCommentVNode)("", true)]),
|
|
3879
3967
|
collection.value && !embedded.value ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(pinToggle)), {
|
|
3880
3968
|
key: 2,
|
|
@@ -3902,7 +3990,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3902
3990
|
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",
|
|
3903
3991
|
"data-testid": "collections-chat",
|
|
3904
3992
|
onClick: openChat
|
|
3905
|
-
}, [_cache[
|
|
3993
|
+
}, [_cache[24] || (_cache[24] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "forum", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.chat")), 1)])) : (0, vue.createCommentVNode)("", true),
|
|
3906
3994
|
((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(collectionActions.value, (action) => {
|
|
3907
3995
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
3908
3996
|
key: action.id,
|
|
@@ -3919,7 +4007,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3919
4007
|
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",
|
|
3920
4008
|
"data-testid": "collections-add-item",
|
|
3921
4009
|
onClick: openCreate
|
|
3922
|
-
}, [_cache[
|
|
4010
|
+
}, [_cache[25] || (_cache[25] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "add", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("common.add")), 1)])) : (0, vue.createCommentVNode)("", true),
|
|
3923
4011
|
canDeleteCollection.value && !embedded.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
3924
4012
|
key: 6,
|
|
3925
4013
|
type: "button",
|
|
@@ -3928,7 +4016,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3928
4016
|
"aria-label": (0, vue.unref)(t)("collectionsView.deleteCollection"),
|
|
3929
4017
|
"data-testid": "collections-delete",
|
|
3930
4018
|
onClick: confirmCollectionDelete
|
|
3931
|
-
}, [..._cache[
|
|
4019
|
+
}, [..._cache[26] || (_cache[26] = [(0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_13$2)) : (0, vue.createCommentVNode)("", true),
|
|
3932
4020
|
canDeleteFeed.value && !embedded.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
3933
4021
|
key: 7,
|
|
3934
4022
|
type: "button",
|
|
@@ -3937,10 +4025,10 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3937
4025
|
"aria-label": (0, vue.unref)(t)("collectionsView.deleteFeed"),
|
|
3938
4026
|
"data-testid": "feeds-delete",
|
|
3939
4027
|
onClick: confirmFeedDelete
|
|
3940
|
-
}, [..._cache[
|
|
4028
|
+
}, [..._cache[27] || (_cache[27] = [(0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_14$2)) : (0, vue.createCommentVNode)("", true)
|
|
3941
4029
|
]),
|
|
3942
4030
|
collection.value && (items.value.length > 0 || hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_15$2, [items.value.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_16$1, [
|
|
3943
|
-
_cache[
|
|
4031
|
+
_cache[29] || (_cache[29] = (0, vue.createElementVNode)("span", { class: "absolute inset-y-0 left-0 flex items-center pl-3 text-slate-400 pointer-events-none" }, [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "search")], -1)),
|
|
3944
4032
|
(0, vue.withDirectives)((0, vue.createElementVNode)("input", {
|
|
3945
4033
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchQuery.value = $event),
|
|
3946
4034
|
type: "text",
|
|
@@ -3954,7 +4042,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3954
4042
|
"aria-label": (0, vue.unref)(t)("collectionsView.clearSearch"),
|
|
3955
4043
|
class: "absolute inset-y-0 right-0 flex items-center pr-2.5 text-slate-400 hover:text-slate-600",
|
|
3956
4044
|
onClick: _cache[1] || (_cache[1] = ($event) => searchQuery.value = "")
|
|
3957
|
-
}, [..._cache[
|
|
4045
|
+
}, [..._cache[28] || (_cache[28] = [(0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_18$1)) : (0, vue.createCommentVNode)("", true)
|
|
3958
4046
|
])) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("div", _hoisted_19$1, [
|
|
3959
4047
|
hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
3960
4048
|
key: 0,
|
|
@@ -3968,7 +4056,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3968
4056
|
"aria-pressed": activeView.value === "table",
|
|
3969
4057
|
"data-testid": "collection-view-toggle-table",
|
|
3970
4058
|
onClick: _cache[2] || (_cache[2] = ($event) => setView("table"))
|
|
3971
|
-
}, [_cache[
|
|
4059
|
+
}, [_cache[30] || (_cache[30] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "table_rows", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.viewTable")), 1)], 10, _hoisted_21$1),
|
|
3972
4060
|
hasCalendar.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
3973
4061
|
key: 0,
|
|
3974
4062
|
type: "button",
|
|
@@ -3976,7 +4064,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3976
4064
|
"aria-pressed": activeView.value === "calendar",
|
|
3977
4065
|
"data-testid": "collection-view-toggle-calendar",
|
|
3978
4066
|
onClick: _cache[3] || (_cache[3] = ($event) => setView("calendar"))
|
|
3979
|
-
}, [_cache[
|
|
4067
|
+
}, [_cache[31] || (_cache[31] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "calendar_month", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.viewCalendar")), 1)], 10, _hoisted_22$1)) : (0, vue.createCommentVNode)("", true),
|
|
3980
4068
|
hasKanban.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
3981
4069
|
key: 1,
|
|
3982
4070
|
type: "button",
|
|
@@ -3984,7 +4072,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
3984
4072
|
"aria-pressed": activeView.value === "kanban",
|
|
3985
4073
|
"data-testid": "collection-view-toggle-kanban",
|
|
3986
4074
|
onClick: _cache[4] || (_cache[4] = ($event) => setView("kanban"))
|
|
3987
|
-
}, [_cache[
|
|
4075
|
+
}, [_cache[32] || (_cache[32] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "view_kanban", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.viewKanban")), 1)], 10, _hoisted_23$1)) : (0, vue.createCommentVNode)("", true),
|
|
3988
4076
|
((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(customViews.value, (cv) => {
|
|
3989
4077
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
3990
4078
|
key: cv.id,
|
|
@@ -4003,7 +4091,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4003
4091
|
"aria-label": (0, vue.unref)(t)("collectionsView.addView"),
|
|
4004
4092
|
"data-testid": "collection-view-add",
|
|
4005
4093
|
onClick: addCustomView
|
|
4006
|
-
}, [..._cache[
|
|
4094
|
+
}, [..._cache[33] || (_cache[33] = [(0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "add", -1)])], 8, _hoisted_26)) : (0, vue.createCommentVNode)("", true),
|
|
4007
4095
|
canConfigureViews.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
4008
4096
|
key: 3,
|
|
4009
4097
|
type: "button",
|
|
@@ -4012,7 +4100,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4012
4100
|
"aria-label": (0, vue.unref)(t)("collectionsView.config.open"),
|
|
4013
4101
|
"data-testid": "collection-config-open",
|
|
4014
4102
|
onClick: _cache[5] || (_cache[5] = ($event) => configOpen.value = true)
|
|
4015
|
-
}, [..._cache[
|
|
4103
|
+
}, [..._cache[34] || (_cache[34] = [(0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "settings", -1)])], 8, _hoisted_27)) : (0, vue.createCommentVNode)("", true)
|
|
4016
4104
|
], 8, _hoisted_20$1)) : (0, vue.createCommentVNode)("", true),
|
|
4017
4105
|
calendarActive.value && dateFields.value.length > 1 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("select", {
|
|
4018
4106
|
key: 1,
|
|
@@ -4046,16 +4134,16 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4046
4134
|
})), 1)) : (0, vue.createCommentVNode)("", true)
|
|
4047
4135
|
])])) : (0, vue.createCommentVNode)("", true),
|
|
4048
4136
|
collection.value && dataIssues.value.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_33, [
|
|
4049
|
-
_cache[
|
|
4137
|
+
_cache[36] || (_cache[36] = (0, vue.createElementVNode)("span", { class: "material-icons text-amber-600" }, "warning", -1)),
|
|
4050
4138
|
(0, vue.createElementVNode)("span", _hoisted_34, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.dataIssuesDetected", { count: dataIssues.value.length })), 1),
|
|
4051
4139
|
(0, vue.createElementVNode)("button", {
|
|
4052
4140
|
type: "button",
|
|
4053
4141
|
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",
|
|
4054
4142
|
"data-testid": "collections-repair",
|
|
4055
4143
|
onClick: repairCollection
|
|
4056
|
-
}, [_cache[
|
|
4144
|
+
}, [_cache[35] || (_cache[35] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "build", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.repair")), 1)])
|
|
4057
4145
|
])) : (0, vue.createCommentVNode)("", true),
|
|
4058
|
-
(0, vue.createElementVNode)("div", _hoisted_35, [loading.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_36, [_cache[
|
|
4146
|
+
(0, vue.createElementVNode)("div", _hoisted_35, [loading.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_36, [_cache[37] || (_cache[37] = (0, vue.createElementVNode)("div", { class: "h-8 w-8 border-2 border-indigo-600/20 border-t-indigo-600 rounded-full animate-spin" }, null, -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("common.loading")), 1)])) : loadError.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_37, [_cache[38] || (_cache[38] = (0, vue.createElementVNode)("span", { class: "material-icons text-red-600" }, "error", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)(loadError.value === "not-found" ? (0, vue.unref)(t)("collectionsView.notFound") : `${(0, vue.unref)(t)("collectionsView.loadFailed")}: ${loadError.value}`), 1)])) : !collection.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_38)) : calendarActive.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_39, [(0, vue.createVNode)(CollectionCalendarView_default, {
|
|
4059
4147
|
schema: collection.value.schema,
|
|
4060
4148
|
items: filteredItems.value,
|
|
4061
4149
|
"anchor-field": calendarAnchorField.value,
|
|
@@ -4140,14 +4228,14 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4140
4228
|
"can-create",
|
|
4141
4229
|
"show-detail"
|
|
4142
4230
|
])) : (0, vue.createCommentVNode)("", true)])) : kanbanActive.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_40, [inlineError.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_41, [
|
|
4143
|
-
_cache[
|
|
4231
|
+
_cache[40] || (_cache[40] = (0, vue.createElementVNode)("span", { class: "material-icons text-red-600" }, "error", -1)),
|
|
4144
4232
|
(0, vue.createElementVNode)("span", _hoisted_42, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
|
|
4145
4233
|
(0, vue.createElementVNode)("button", {
|
|
4146
4234
|
type: "button",
|
|
4147
4235
|
class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
|
|
4148
4236
|
"aria-label": (0, vue.unref)(t)("common.close"),
|
|
4149
4237
|
onClick: _cache[10] || (_cache[10] = ($event) => inlineError.value = null)
|
|
4150
|
-
}, [..._cache[
|
|
4238
|
+
}, [..._cache[39] || (_cache[39] = [(0, vue.createElementVNode)("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_43)
|
|
4151
4239
|
])) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("div", _hoisted_44, [(0, vue.createVNode)(CollectionKanbanView_default, {
|
|
4152
4240
|
schema: collection.value.schema,
|
|
4153
4241
|
items: filteredItems.value,
|
|
@@ -4165,8 +4253,8 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4165
4253
|
])])])) : activeCustomView.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_45, [(0, vue.createVNode)(CollectionCustomView_default, {
|
|
4166
4254
|
slug: collection.value.slug,
|
|
4167
4255
|
view: activeCustomView.value
|
|
4168
|
-
}, null, 8, ["slug", "view"])])) : items.value.length === 0 && editing.value?.mode !== "create" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_46, [_cache[
|
|
4169
|
-
_cache[
|
|
4256
|
+
}, null, 8, ["slug", "view"])])) : items.value.length === 0 && editing.value?.mode !== "create" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_46, [_cache[41] || (_cache[41] = (0, vue.createElementVNode)("span", { class: "material-icons text-4xl text-slate-300" }, "folder_open", -1)), (0, vue.createElementVNode)("p", _hoisted_47, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.itemsEmpty")), 1)])) : filteredItems.value.length === 0 && editing.value?.mode !== "create" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_48, [
|
|
4257
|
+
_cache[42] || (_cache[42] = (0, vue.createElementVNode)("span", { class: "material-icons text-4xl text-slate-300" }, "search_off", -1)),
|
|
4170
4258
|
(0, vue.createElementVNode)("p", _hoisted_49, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.noMatchingItems")), 1),
|
|
4171
4259
|
(0, vue.createElementVNode)("button", {
|
|
4172
4260
|
type: "button",
|
|
@@ -4174,14 +4262,14 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4174
4262
|
onClick: _cache[11] || (_cache[11] = ($event) => searchQuery.value = "")
|
|
4175
4263
|
}, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.clearSearch")), 1)
|
|
4176
4264
|
])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_50, [inlineError.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_51, [
|
|
4177
|
-
_cache[
|
|
4265
|
+
_cache[44] || (_cache[44] = (0, vue.createElementVNode)("span", { class: "material-icons text-red-600" }, "error", -1)),
|
|
4178
4266
|
(0, vue.createElementVNode)("span", _hoisted_52, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
|
|
4179
4267
|
(0, vue.createElementVNode)("button", {
|
|
4180
4268
|
type: "button",
|
|
4181
4269
|
class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
|
|
4182
4270
|
"aria-label": (0, vue.unref)(t)("common.close"),
|
|
4183
4271
|
onClick: _cache[12] || (_cache[12] = ($event) => inlineError.value = null)
|
|
4184
|
-
}, [..._cache[
|
|
4272
|
+
}, [..._cache[43] || (_cache[43] = [(0, vue.createElementVNode)("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_53)
|
|
4185
4273
|
])) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("table", _hoisted_54, [(0, vue.createElementVNode)("thead", null, [(0, vue.createElementVNode)("tr", _hoisted_55, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(listColumnFields.value, ([key, field]) => {
|
|
4186
4274
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("th", {
|
|
4187
4275
|
key,
|
|
@@ -4234,57 +4322,51 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4234
4322
|
"aria-label": field.label,
|
|
4235
4323
|
onClick: _cache[15] || (_cache[15] = (0, vue.withModifiers)(() => {}, ["stop"])),
|
|
4236
4324
|
onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.checked)
|
|
4237
|
-
}, null, 40, _hoisted_64)) : field.type === "ref" && field.to && typeof item[key] === "string" && item[key] ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_65, [(0, vue.
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
},
|
|
4325
|
+
}, null, 40, _hoisted_64)) : field.type === "ref" && field.to && typeof item[key] === "string" && item[key] ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_65, [(0, vue.createElementVNode)("a", {
|
|
4326
|
+
href: (0, vue.unref)(cui).recordHref?.(field.to, String(item[key])),
|
|
4327
|
+
tabindex: (0, vue.unref)(cui).recordHref?.(field.to, String(item[key])) ? void 0 : 0,
|
|
4328
|
+
role: "link",
|
|
4242
4329
|
class: "text-indigo-600 hover:text-indigo-800 hover:underline font-semibold",
|
|
4243
4330
|
"data-testid": `collections-ref-link-${key}-${item[key]}`,
|
|
4244
|
-
onClick:
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
_: 2
|
|
4248
|
-
}, 1032, ["to", "data-testid"])])) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("select", {
|
|
4331
|
+
onClick: ($event) => (0, vue.unref)(activateRefLink)($event, field.to, String(item[key]), true),
|
|
4332
|
+
onKeydown: [(0, vue.withKeys)(($event) => (0, vue.unref)(activateRefLink)($event, field.to, String(item[key]), true), ["enter"]), (0, vue.withKeys)(($event) => (0, vue.unref)(activateRefLink)($event, field.to, String(item[key]), true), ["space"])]
|
|
4333
|
+
}, (0, vue.toDisplayString)((0, vue.unref)(refDisplay)(field.to, String(item[key]))), 41, _hoisted_66)])) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("select", {
|
|
4249
4334
|
key: 3,
|
|
4250
4335
|
value: item[key] == null ? "" : String(item[key]),
|
|
4251
4336
|
disabled: isRowInlineSaving(item),
|
|
4252
4337
|
class: (0, vue.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])]),
|
|
4253
4338
|
"data-testid": `collections-inline-enum-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
4254
4339
|
"aria-label": field.label,
|
|
4255
|
-
onClick: _cache[
|
|
4340
|
+
onClick: _cache[16] || (_cache[16] = (0, vue.withModifiers)(() => {}, ["stop"])),
|
|
4256
4341
|
onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.value)
|
|
4257
|
-
}, [showEnumPlaceholder(item, String(key)) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("option",
|
|
4342
|
+
}, [showEnumPlaceholder(item, String(key)) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("option", _hoisted_68, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.selectPlaceholder")), 1)) : (0, vue.createCommentVNode)("", true), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(field.values, (value) => {
|
|
4258
4343
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("option", {
|
|
4259
4344
|
key: value,
|
|
4260
4345
|
value
|
|
4261
|
-
}, (0, vue.toDisplayString)(value), 9,
|
|
4262
|
-
}), 128))], 42,
|
|
4346
|
+
}, (0, vue.toDisplayString)(value), 9, _hoisted_69);
|
|
4347
|
+
}), 128))], 42, _hoisted_67)) : field.type === "money" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_70, (0, vue.toDisplayString)((0, vue.unref)(formatMoney)(item[key], (0, vue.unref)(resolveCurrency)(field, item), (0, vue.unref)(locale))), 1)) : field.type === "table" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_71, [_cache[45] || (_cache[45] = (0, vue.createElementVNode)("span", { class: "material-icons text-[11px]" }, "list", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)(tableSummary(item[key])), 1)])) : field.type === "derived" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_72, (0, vue.toDisplayString)((0, vue.unref)(derivedDisplay)(field, (0, vue.unref)(evaluateDerivedAgainstItem)(field, String(key), item), item)), 1)) : field.type !== "file" && (0, vue.unref)(isExternalUrl)(item[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
4263
4348
|
key: 7,
|
|
4264
4349
|
href: String(item[key]),
|
|
4265
4350
|
target: "_blank",
|
|
4266
4351
|
rel: "noopener noreferrer",
|
|
4267
4352
|
class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
|
|
4268
4353
|
"data-testid": `collections-url-link-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
4269
|
-
onClick: _cache[
|
|
4270
|
-
}, (0, vue.toDisplayString)(String(item[key])), 9,
|
|
4354
|
+
onClick: _cache[17] || (_cache[17] = (0, vue.withModifiers)(() => {}, ["stop"]))
|
|
4355
|
+
}, (0, vue.toDisplayString)(String(item[key])), 9, _hoisted_73)) : field.type === "file" && (0, vue.unref)(artifactUrl)(item[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
4271
4356
|
key: 8,
|
|
4272
4357
|
href: (0, vue.unref)(artifactUrl)(item[key]) ?? void 0,
|
|
4273
4358
|
target: "_blank",
|
|
4274
4359
|
rel: "noopener noreferrer",
|
|
4275
4360
|
class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
|
|
4276
4361
|
"data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
4277
|
-
onClick: _cache[
|
|
4278
|
-
}, (0, vue.toDisplayString)(String(item[key])), 9,
|
|
4362
|
+
onClick: _cache[18] || (_cache[18] = (0, vue.withModifiers)(() => {}, ["stop"]))
|
|
4363
|
+
}, (0, vue.toDisplayString)(String(item[key])), 9, _hoisted_74)) : field.type === "file" && (0, vue.unref)(fileRoutePath)(item[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
4279
4364
|
key: 9,
|
|
4280
|
-
|
|
4365
|
+
href: (0, vue.unref)(fileRoutePath)(item[key]) ?? void 0,
|
|
4281
4366
|
class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
|
|
4282
4367
|
"data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
4283
|
-
onClick:
|
|
4284
|
-
},
|
|
4285
|
-
default: (0, vue.withCtx)(() => [(0, vue.createTextVNode)((0, vue.toDisplayString)(String(item[key])), 1)]),
|
|
4286
|
-
_: 2
|
|
4287
|
-
}, 1032, ["to", "data-testid"])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_74, (0, vue.toDisplayString)((0, vue.unref)(formatCell)(item[key], field.type)), 1))], 64)) : (0, vue.createCommentVNode)("", true)]);
|
|
4368
|
+
onClick: ($event) => (0, vue.unref)(activatePathLink)($event, (0, vue.unref)(fileRoutePath)(item[key]) ?? "", true)
|
|
4369
|
+
}, (0, vue.toDisplayString)(String(item[key])), 9, _hoisted_75)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_76, (0, vue.toDisplayString)((0, vue.unref)(formatCell)(item[key], field.type)), 1))], 64)) : (0, vue.createCommentVNode)("", true)]);
|
|
4288
4370
|
}), 128))], 42, _hoisted_62);
|
|
4289
4371
|
}), 128))])])]))]),
|
|
4290
4372
|
collection.value && (viewing.value || editing.value) && !(calendarActive.value && openDay.value) ? ((0, vue.openBlock)(), (0, vue.createBlock)(CollectionRecordModal_default, {
|
|
@@ -4293,7 +4375,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4293
4375
|
}, {
|
|
4294
4376
|
default: (0, vue.withCtx)(() => [(0, vue.createVNode)(CollectionRecordPanel_default, {
|
|
4295
4377
|
editing: editing.value,
|
|
4296
|
-
"onUpdate:editing": _cache[
|
|
4378
|
+
"onUpdate:editing": _cache[19] || (_cache[19] = ($event) => editing.value = $event),
|
|
4297
4379
|
collection: collection.value,
|
|
4298
4380
|
viewing: viewing.value,
|
|
4299
4381
|
saving: saving.value,
|
|
@@ -4311,7 +4393,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4311
4393
|
onCancel: cancelEditor,
|
|
4312
4394
|
onEdit: editFromView,
|
|
4313
4395
|
onClose: closeView,
|
|
4314
|
-
onDelete: _cache[
|
|
4396
|
+
onDelete: _cache[20] || (_cache[20] = ($event) => viewing.value && confirmDelete(viewing.value)),
|
|
4315
4397
|
onRunAction: runAction
|
|
4316
4398
|
}, null, 8, [
|
|
4317
4399
|
"editing",
|
|
@@ -4337,7 +4419,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4337
4419
|
title: collection.value.title,
|
|
4338
4420
|
views: customViews.value,
|
|
4339
4421
|
onChanged: onViewsChanged,
|
|
4340
|
-
onClose: _cache[
|
|
4422
|
+
onClose: _cache[21] || (_cache[21] = ($event) => configOpen.value = false)
|
|
4341
4423
|
}, null, 8, [
|
|
4342
4424
|
"slug",
|
|
4343
4425
|
"title",
|
|
@@ -4352,29 +4434,29 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4352
4434
|
"data-testid": "collections-chat-modal",
|
|
4353
4435
|
onClick: (0, vue.withModifiers)(closeChat, ["self"]),
|
|
4354
4436
|
onKeydown: (0, vue.withKeys)(closeChat, ["esc"])
|
|
4355
|
-
}, [(0, vue.createElementVNode)("div",
|
|
4356
|
-
(0, vue.createElementVNode)("header",
|
|
4357
|
-
_cache[
|
|
4358
|
-
(0, vue.createElementVNode)("div",
|
|
4437
|
+
}, [(0, vue.createElementVNode)("div", _hoisted_77, [
|
|
4438
|
+
(0, vue.createElementVNode)("header", _hoisted_78, [
|
|
4439
|
+
_cache[47] || (_cache[47] = (0, vue.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" }, [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "forum")], -1)),
|
|
4440
|
+
(0, vue.createElementVNode)("div", _hoisted_79, [(0, vue.createElementVNode)("h2", _hoisted_80, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.chatTitle")), 1), (0, vue.createElementVNode)("span", _hoisted_81, (0, vue.toDisplayString)(collection.value.title), 1)]),
|
|
4359
4441
|
(0, vue.createElementVNode)("button", {
|
|
4360
4442
|
type: "button",
|
|
4361
4443
|
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",
|
|
4362
4444
|
"aria-label": (0, vue.unref)(t)("common.close"),
|
|
4363
4445
|
"data-testid": "collections-chat-close",
|
|
4364
4446
|
onClick: closeChat
|
|
4365
|
-
}, [..._cache[
|
|
4447
|
+
}, [..._cache[46] || (_cache[46] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_82)
|
|
4366
4448
|
]),
|
|
4367
|
-
(0, vue.createElementVNode)("div",
|
|
4449
|
+
(0, vue.createElementVNode)("div", _hoisted_83, [(0, vue.withDirectives)((0, vue.createElementVNode)("textarea", {
|
|
4368
4450
|
ref_key: "chatInputEl",
|
|
4369
4451
|
ref: chatInputEl,
|
|
4370
|
-
"onUpdate:modelValue": _cache[
|
|
4452
|
+
"onUpdate:modelValue": _cache[22] || (_cache[22] = ($event) => chatMessage.value = $event),
|
|
4371
4453
|
rows: "4",
|
|
4372
4454
|
placeholder: (0, vue.unref)(t)("collectionsView.chatPlaceholder"),
|
|
4373
4455
|
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",
|
|
4374
4456
|
"data-testid": "collections-chat-input",
|
|
4375
4457
|
onKeydown: [(0, vue.withKeys)((0, vue.withModifiers)(submitChat, ["meta"]), ["enter"]), (0, vue.withKeys)((0, vue.withModifiers)(submitChat, ["ctrl"]), ["enter"])]
|
|
4376
|
-
}, null, 40,
|
|
4377
|
-
(0, vue.createElementVNode)("footer",
|
|
4458
|
+
}, null, 40, _hoisted_84), [[vue.vModelText, chatMessage.value]])]),
|
|
4459
|
+
(0, vue.createElementVNode)("footer", _hoisted_85, [(0, vue.createElementVNode)("button", {
|
|
4378
4460
|
type: "button",
|
|
4379
4461
|
class: "h-8 px-2.5 rounded text-xs font-bold text-slate-500 hover:bg-slate-200/50 transition-colors",
|
|
4380
4462
|
"data-testid": "collections-chat-cancel",
|
|
@@ -4385,13 +4467,121 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4385
4467
|
disabled: !chatMessage.value.trim(),
|
|
4386
4468
|
"data-testid": "collections-chat-send",
|
|
4387
4469
|
onClick: submitChat
|
|
4388
|
-
}, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.chatStart")), 9,
|
|
4470
|
+
}, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.chatStart")), 9, _hoisted_86)])
|
|
4389
4471
|
])], 32)) : (0, vue.createCommentVNode)("", true)
|
|
4390
4472
|
]);
|
|
4391
4473
|
};
|
|
4392
4474
|
}
|
|
4393
4475
|
});
|
|
4394
4476
|
//#endregion
|
|
4477
|
+
//#region src/vue/chat/View.vue?vue&type=script&setup=true&lang.ts
|
|
4478
|
+
var _hoisted_1$3 = {
|
|
4479
|
+
class: "w-full h-full",
|
|
4480
|
+
"data-testid": "present-collection"
|
|
4481
|
+
};
|
|
4482
|
+
//#endregion
|
|
4483
|
+
//#region src/vue/chat/View.vue
|
|
4484
|
+
var View_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
4485
|
+
__name: "View",
|
|
4486
|
+
props: {
|
|
4487
|
+
selectedResult: {},
|
|
4488
|
+
sendTextMessage: { type: Function }
|
|
4489
|
+
},
|
|
4490
|
+
emits: ["updateResult"],
|
|
4491
|
+
setup(__props, { emit: __emit }) {
|
|
4492
|
+
const props = __props;
|
|
4493
|
+
const emit = __emit;
|
|
4494
|
+
const data = (0, vue.computed)(() => props.selectedResult?.data ?? props.selectedResult?.jsonData ?? null);
|
|
4495
|
+
const slug = (0, vue.computed)(() => data.value?.collectionSlug);
|
|
4496
|
+
const viewState = (0, vue.computed)(() => props.selectedResult?.viewState ?? null);
|
|
4497
|
+
/** Open record: the card-local `viewState.selected` once the user has
|
|
4498
|
+
* navigated within the card (including an explicit close → null), else
|
|
4499
|
+
* the tool's initial `itemId`. */
|
|
4500
|
+
const selected = (0, vue.computed)(() => {
|
|
4501
|
+
const state = viewState.value;
|
|
4502
|
+
if (state && "selected" in state) return state.selected ?? void 0;
|
|
4503
|
+
return data.value?.itemId;
|
|
4504
|
+
});
|
|
4505
|
+
function onSelect(itemId) {
|
|
4506
|
+
if (!props.selectedResult) return;
|
|
4507
|
+
emit("updateResult", {
|
|
4508
|
+
...props.selectedResult,
|
|
4509
|
+
viewState: {
|
|
4510
|
+
...viewState.value,
|
|
4511
|
+
selected: itemId
|
|
4512
|
+
}
|
|
4513
|
+
});
|
|
4514
|
+
}
|
|
4515
|
+
function onViewStateChange(state) {
|
|
4516
|
+
if (!props.selectedResult) return;
|
|
4517
|
+
const current = viewState.value;
|
|
4518
|
+
if (current?.view === state.view && current?.anchorField === state.anchorField && current?.groupField === state.groupField) return;
|
|
4519
|
+
emit("updateResult", {
|
|
4520
|
+
...props.selectedResult,
|
|
4521
|
+
viewState: {
|
|
4522
|
+
...current,
|
|
4523
|
+
view: state.view,
|
|
4524
|
+
anchorField: state.anchorField,
|
|
4525
|
+
groupField: state.groupField
|
|
4526
|
+
}
|
|
4527
|
+
});
|
|
4528
|
+
}
|
|
4529
|
+
return (_ctx, _cache) => {
|
|
4530
|
+
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$3, [slug.value ? ((0, vue.openBlock)(), (0, vue.createBlock)(CollectionView_default, {
|
|
4531
|
+
key: 0,
|
|
4532
|
+
slug: slug.value,
|
|
4533
|
+
selected: selected.value,
|
|
4534
|
+
"initial-view": viewState.value?.view,
|
|
4535
|
+
"initial-anchor-field": viewState.value?.anchorField,
|
|
4536
|
+
"initial-group-field": viewState.value?.groupField,
|
|
4537
|
+
"send-text-message": __props.sendTextMessage,
|
|
4538
|
+
onSelect,
|
|
4539
|
+
onViewStateChange
|
|
4540
|
+
}, null, 8, [
|
|
4541
|
+
"slug",
|
|
4542
|
+
"selected",
|
|
4543
|
+
"initial-view",
|
|
4544
|
+
"initial-anchor-field",
|
|
4545
|
+
"initial-group-field",
|
|
4546
|
+
"send-text-message"
|
|
4547
|
+
])) : (0, vue.createCommentVNode)("", true)]);
|
|
4548
|
+
};
|
|
4549
|
+
}
|
|
4550
|
+
});
|
|
4551
|
+
//#endregion
|
|
4552
|
+
//#region src/vue/chat/Preview.vue?vue&type=script&setup=true&lang.ts
|
|
4553
|
+
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" };
|
|
4554
|
+
var _hoisted_2$2 = { class: "text-center" };
|
|
4555
|
+
var _hoisted_3$2 = { class: "text-gray-900 font-bold text-lg mb-1 line-clamp-2" };
|
|
4556
|
+
var _hoisted_4$2 = {
|
|
4557
|
+
key: 0,
|
|
4558
|
+
class: "text-gray-600 text-sm"
|
|
4559
|
+
};
|
|
4560
|
+
var _hoisted_5$2 = {
|
|
4561
|
+
key: 1,
|
|
4562
|
+
class: "text-gray-500 text-sm"
|
|
4563
|
+
};
|
|
4564
|
+
//#endregion
|
|
4565
|
+
//#region src/vue/chat/Preview.vue
|
|
4566
|
+
var Preview_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
4567
|
+
__name: "Preview",
|
|
4568
|
+
props: { result: {} },
|
|
4569
|
+
setup(__props) {
|
|
4570
|
+
const { t } = useCollectionI18n();
|
|
4571
|
+
const props = __props;
|
|
4572
|
+
const data = (0, vue.computed)(() => props.result?.data ?? props.result?.jsonData ?? null);
|
|
4573
|
+
const collectionSlug = (0, vue.computed)(() => data.value?.collectionSlug ?? "");
|
|
4574
|
+
const itemId = (0, vue.computed)(() => data.value?.itemId);
|
|
4575
|
+
return (_ctx, _cache) => {
|
|
4576
|
+
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$2, [(0, vue.createElementVNode)("div", _hoisted_2$2, [
|
|
4577
|
+
_cache[0] || (_cache[0] = (0, vue.createElementVNode)("span", { class: "material-icons text-4xl text-indigo-600 mb-2" }, "collections_bookmark", -1)),
|
|
4578
|
+
(0, vue.createElementVNode)("h3", _hoisted_3$2, (0, vue.toDisplayString)(collectionSlug.value || (0, vue.unref)(t)("pluginPresentCollection.fallbackTitle")), 1),
|
|
4579
|
+
itemId.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_4$2, (0, vue.toDisplayString)((0, vue.unref)(t)("pluginPresentCollection.itemLabel", { id: itemId.value })), 1)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_5$2, (0, vue.toDisplayString)((0, vue.unref)(t)("pluginPresentCollection.listLabel")), 1))
|
|
4580
|
+
])]);
|
|
4581
|
+
};
|
|
4582
|
+
}
|
|
4583
|
+
});
|
|
4584
|
+
//#endregion
|
|
4395
4585
|
//#region src/vue/components/CollectionsIndexView.vue?vue&type=script&setup=true&lang.ts
|
|
4396
4586
|
var _hoisted_1$1 = {
|
|
4397
4587
|
class: "h-full overflow-y-auto bg-slate-50/50 px-6 py-6",
|
|
@@ -4699,6 +4889,16 @@ var FeedsView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4699
4889
|
}
|
|
4700
4890
|
});
|
|
4701
4891
|
//#endregion
|
|
4892
|
+
//#region src/vue/index.ts
|
|
4893
|
+
var plugin = {
|
|
4894
|
+
toolDefinition: require_promptSafety.TOOL_DEFINITION,
|
|
4895
|
+
execute: require_promptSafety.executePresentCollection,
|
|
4896
|
+
generatingMessage: "Loading collection...",
|
|
4897
|
+
isEnabled: () => true,
|
|
4898
|
+
viewComponent: View_default,
|
|
4899
|
+
previewComponent: Preview_default
|
|
4900
|
+
};
|
|
4901
|
+
//#endregion
|
|
4702
4902
|
exports.CollectionCalendarView = CollectionCalendarView_default;
|
|
4703
4903
|
exports.CollectionCustomView = CollectionCustomView_default;
|
|
4704
4904
|
exports.CollectionDayView = CollectionDayView_default;
|
|
@@ -4710,8 +4910,11 @@ exports.CollectionView = CollectionView_default;
|
|
|
4710
4910
|
exports.CollectionViewConfigModal = CollectionViewConfigModal_default;
|
|
4711
4911
|
exports.CollectionsIndexView = CollectionsIndexView_default;
|
|
4712
4912
|
exports.FeedsView = FeedsView_default;
|
|
4913
|
+
exports.PresentCollectionPreview = Preview_default;
|
|
4914
|
+
exports.PresentCollectionView = View_default;
|
|
4713
4915
|
exports.collectionUi = collectionUi;
|
|
4714
4916
|
exports.configureCollectionUi = configureCollectionUi;
|
|
4917
|
+
exports.plugin = plugin;
|
|
4715
4918
|
exports.readCollectionSort = readCollectionSort;
|
|
4716
4919
|
exports.readCollectionViewMode = readCollectionViewMode;
|
|
4717
4920
|
exports.useCollectionRendering = useCollectionRendering;
|