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