@mulmoclaude/collection-plugin 0.7.4 → 0.7.5
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/style.css +78 -61
- package/dist/vue/components/CollectionView.vue.d.ts.map +1 -1
- package/dist/vue/lang/de.d.ts.map +1 -1
- package/dist/vue/lang/en.d.ts +3 -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 +3 -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/useCollectionRendering.d.ts +0 -1
- package/dist/vue/useCollectionRendering.d.ts.map +1 -1
- package/dist/vue/useCollectionRendering.helpers.d.ts +27 -0
- package/dist/vue/useCollectionRendering.helpers.d.ts.map +1 -0
- package/dist/vue.cjs +355 -255
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +355 -255
- package/dist/vue.js.map +1 -1
- package/package.json +3 -3
package/dist/vue.cjs
CHANGED
|
@@ -142,6 +142,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
142
142
|
kanbanUncategorized: "Uncategorized",
|
|
143
143
|
kanbanOpenCard: "Open {label}",
|
|
144
144
|
addView: "Add view",
|
|
145
|
+
addViewDesktop: "Custom view",
|
|
146
|
+
addViewMobile: "Phone view",
|
|
145
147
|
config: {
|
|
146
148
|
open: "Collection settings",
|
|
147
149
|
title: "{title} · settings",
|
|
@@ -153,6 +155,7 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
153
155
|
customViewLoading: "Loading view…",
|
|
154
156
|
customViewError: "Couldn't load this view: {error}",
|
|
155
157
|
addViewPrompt: "I want to add a custom view to the \"{title}\" collection. Ask me what I want to see or edit, then author the HTML view file at {base}/views/your-view.html and register it in {base}/schema.json under `views[]` (capabilities [\"read\"] for a read-only view, [\"read\",\"write\"] if it edits records). Follow the custom-view help for the data contract.",
|
|
158
|
+
addMobileViewPrompt: "I want to add a phone (remote app) custom view to the \"{title}\" collection. Ask me what I want to see or edit, then author the HTML view file at {base}/views/your-view.html and register it in {base}/schema.json under `views[]` with `target: \"mobile\"` (read-only by default; declare `editableFields` / `allowDelete` only if it edits records). Follow the custom-view-remote help for the postMessage data contract — no fetch of any kind in the view.",
|
|
156
159
|
repair: "Repair",
|
|
157
160
|
dataIssuesDetected: "{count} record file(s) have data problems and may be missing from this view.",
|
|
158
161
|
repairPrompt: "The \"{title}\" collection has {count} record file(s) with data problems that keep them from appearing. Fix each one — Read the file, correct it, then Write it back:\n{issues}\n\nWhen you're done, call presentCollection to confirm the records load.",
|
|
@@ -275,6 +278,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
275
278
|
kanbanUncategorized: "未分類",
|
|
276
279
|
kanbanOpenCard: "{label} を開く",
|
|
277
280
|
addView: "ビューを追加",
|
|
281
|
+
addViewDesktop: "カスタムビュー",
|
|
282
|
+
addViewMobile: "スマホビュー",
|
|
278
283
|
config: {
|
|
279
284
|
open: "コレクション設定",
|
|
280
285
|
title: "{title} · 設定",
|
|
@@ -286,6 +291,7 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
286
291
|
customViewLoading: "ビューを読み込み中…",
|
|
287
292
|
customViewError: "このビューを読み込めませんでした: {error}",
|
|
288
293
|
addViewPrompt: "「{title}」コレクションにカスタムビューを追加したい。何を見たい/編集したいか質問してから、HTML ビューファイルを {base}/views/your-view.html に作成し、{base}/schema.json の `views[]` に登録して(読み取り専用なら capabilities [\"read\"]、レコードを編集するなら [\"read\",\"write\"])。データ契約は custom-view ヘルプに従ってください。",
|
|
294
|
+
addMobileViewPrompt: "「{title}」コレクションにスマホ(リモートアプリ)用カスタムビューを追加したい。何を見たい/編集したいか質問してから、HTML ビューファイルを {base}/views/your-view.html に作成し、{base}/schema.json の `views[]` に `target: \"mobile\"` 付きで登録して(デフォルトは読み取り専用。レコードを編集する場合のみ `editableFields` / `allowDelete` を宣言)。データ契約は custom-view-remote ヘルプに従ってください — ビュー内での fetch は一切禁止です。",
|
|
289
295
|
repair: "修復",
|
|
290
296
|
dataIssuesDetected: "{count} 件のレコードファイルにデータの問題があり、この表示に出てこない可能性があります。",
|
|
291
297
|
repairPrompt: "コレクション「{title}」に、表示されない原因となるデータの問題を持つレコードファイルが {count} 件あります。それぞれを修正してください — ファイルを Read し、修正してから Write し直します:\n{issues}\n\n完了したら presentCollection を呼び出して、レコードが読み込めることを確認してください。",
|
|
@@ -408,6 +414,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
408
414
|
kanbanUncategorized: "未分类",
|
|
409
415
|
kanbanOpenCard: "打开 {label}",
|
|
410
416
|
addView: "添加视图",
|
|
417
|
+
addViewDesktop: "自定义视图",
|
|
418
|
+
addViewMobile: "手机视图",
|
|
411
419
|
config: {
|
|
412
420
|
open: "集合设置",
|
|
413
421
|
title: "{title} · 设置",
|
|
@@ -419,6 +427,7 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
419
427
|
customViewLoading: "正在加载视图…",
|
|
420
428
|
customViewError: "无法加载此视图:{error}",
|
|
421
429
|
addViewPrompt: "我想为“{title}”集合添加一个自定义视图。先问我想查看或编辑什么,然后在 {base}/views/your-view.html 创建 HTML 视图文件,并在 {base}/schema.json 的 `views[]` 中注册(只读视图用 capabilities [\"read\"],需要编辑记录则用 [\"read\",\"write\"])。数据契约请遵循 custom-view 帮助文档。",
|
|
430
|
+
addMobileViewPrompt: "我想为“{title}”集合添加一个手机(远程应用)自定义视图。先问我想查看或编辑什么,然后在 {base}/views/your-view.html 创建 HTML 视图文件,并在 {base}/schema.json 的 `views[]` 中以 `target: \"mobile\"` 注册(默认只读;仅在需要编辑记录时声明 `editableFields` / `allowDelete`)。数据契约请遵循 custom-view-remote 帮助文档 — 视图内禁止任何 fetch。",
|
|
422
431
|
repair: "修复",
|
|
423
432
|
dataIssuesDetected: "有 {count} 个记录文件存在数据问题,可能未显示在此视图中。",
|
|
424
433
|
repairPrompt: "集合 {title} 有 {count} 个记录文件存在导致无法显示的数据问题。请逐一修复——用 Read 读取该文件,更正后再用 Write 写回:\n{issues}\n\n完成后,调用 presentCollection 确认记录可以正常加载。",
|
|
@@ -541,6 +550,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
541
550
|
kanbanUncategorized: "미분류",
|
|
542
551
|
kanbanOpenCard: "{label} 열기",
|
|
543
552
|
addView: "보기 추가",
|
|
553
|
+
addViewDesktop: "사용자 지정 보기",
|
|
554
|
+
addViewMobile: "스마트폰 보기",
|
|
544
555
|
config: {
|
|
545
556
|
open: "컬렉션 설정",
|
|
546
557
|
title: "{title} · 설정",
|
|
@@ -552,6 +563,7 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
552
563
|
customViewLoading: "보기를 불러오는 중…",
|
|
553
564
|
customViewError: "이 보기를 불러오지 못했습니다: {error}",
|
|
554
565
|
addViewPrompt: "{title} 컬렉션에 사용자 지정 보기를 추가하고 싶어요. 무엇을 보거나 편집하고 싶은지 먼저 물어본 뒤, {base}/views/your-view.html 에 HTML 보기 파일을 만들고 {base}/schema.json의 `views[]`에 등록해 주세요(읽기 전용 보기는 capabilities [\"read\"], 레코드를 편집하면 [\"read\",\"write\"]). 데이터 계약은 custom-view 도움말을 따르세요.",
|
|
566
|
+
addMobileViewPrompt: "{title} 컬렉션에 스마트폰(리모트 앱)용 사용자 지정 보기를 추가하고 싶어요. 무엇을 보거나 편집하고 싶은지 먼저 물어본 뒤, {base}/views/your-view.html 에 HTML 보기 파일을 만들고 {base}/schema.json의 `views[]`에 `target: \"mobile\"`과 함께 등록해 주세요(기본은 읽기 전용, 레코드를 편집할 때만 `editableFields` / `allowDelete` 선언). 데이터 계약은 custom-view-remote 도움말을 따르세요 — 보기 안에서 fetch는 일절 금지입니다.",
|
|
555
567
|
repair: "복구",
|
|
556
568
|
dataIssuesDetected: "{count}개의 레코드 파일에 데이터 문제가 있어 이 보기에 표시되지 않을 수 있습니다.",
|
|
557
569
|
repairPrompt: "{title} 컬렉션에 표시되지 않는 원인이 되는 데이터 문제가 있는 레코드 파일이 {count}개 있습니다. 각 파일을 수정하세요 — Read로 파일을 읽고 수정한 뒤 Write로 다시 저장하세요:\n{issues}\n\n완료되면 presentCollection을 호출하여 레코드가 로드되는지 확인하세요.",
|
|
@@ -674,6 +686,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
674
686
|
kanbanUncategorized: "Sin categoría",
|
|
675
687
|
kanbanOpenCard: "Abrir {label}",
|
|
676
688
|
addView: "Añadir vista",
|
|
689
|
+
addViewDesktop: "Vista personalizada",
|
|
690
|
+
addViewMobile: "Vista móvil",
|
|
677
691
|
config: {
|
|
678
692
|
open: "Ajustes de la colección",
|
|
679
693
|
title: "{title} · ajustes",
|
|
@@ -685,6 +699,7 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
685
699
|
customViewLoading: "Cargando vista…",
|
|
686
700
|
customViewError: "No se pudo cargar esta vista: {error}",
|
|
687
701
|
addViewPrompt: "Quiero añadir una vista personalizada a la colección «{title}». Pregúntame qué quiero ver o editar, luego crea el archivo HTML de la vista en {base}/views/your-view.html y regístralo en {base}/schema.json dentro de `views[]` (capabilities [\"read\"] para una vista de solo lectura, [\"read\",\"write\"] si edita registros). Sigue la ayuda custom-view para el contrato de datos.",
|
|
702
|
+
addMobileViewPrompt: "Quiero añadir una vista personalizada para el móvil (aplicación remota) a la colección «{title}». Pregúntame qué quiero ver o editar, luego crea el archivo HTML de la vista en {base}/views/your-view.html y regístralo en {base}/schema.json dentro de `views[]` con `target: \"mobile\"` (de solo lectura por defecto; declara `editableFields` / `allowDelete` solo si edita registros). Sigue la ayuda custom-view-remote para el contrato de datos por postMessage — nada de fetch en la vista.",
|
|
688
703
|
repair: "Reparar",
|
|
689
704
|
dataIssuesDetected: "{count} archivo(s) de registro tienen problemas de datos y podrían no aparecer en esta vista.",
|
|
690
705
|
repairPrompt: "La colección {title} tiene {count} archivo(s) de registro con problemas de datos que impiden que aparezcan. Corrige cada uno: lee el archivo con Read, corrígelo y vuelve a escribirlo con Write:\n{issues}\n\nCuando termines, llama a presentCollection para confirmar que los registros se cargan.",
|
|
@@ -807,6 +822,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
807
822
|
kanbanUncategorized: "Sem categoria",
|
|
808
823
|
kanbanOpenCard: "Abrir {label}",
|
|
809
824
|
addView: "Adicionar visualização",
|
|
825
|
+
addViewDesktop: "Visualização personalizada",
|
|
826
|
+
addViewMobile: "Visualização para celular",
|
|
810
827
|
config: {
|
|
811
828
|
open: "Configurações da coleção",
|
|
812
829
|
title: "{title} · configurações",
|
|
@@ -818,6 +835,7 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
818
835
|
customViewLoading: "Carregando visualização…",
|
|
819
836
|
customViewError: "Não foi possível carregar esta visualização: {error}",
|
|
820
837
|
addViewPrompt: "Quero adicionar uma visualização personalizada à coleção \"{title}\". Pergunte o que eu quero ver ou editar, depois crie o arquivo HTML da visualização em {base}/views/your-view.html e registre-o em {base}/schema.json em `views[]` (capabilities [\"read\"] para uma visualização somente leitura, [\"read\",\"write\"] se editar registros). Siga a ajuda custom-view para o contrato de dados.",
|
|
838
|
+
addMobileViewPrompt: "Quero adicionar uma visualização personalizada para o celular (app remoto) à coleção \"{title}\". Pergunte o que eu quero ver ou editar, depois crie o arquivo HTML da visualização em {base}/views/your-view.html e registre-o em {base}/schema.json em `views[]` com `target: \"mobile\"` (somente leitura por padrão; declare `editableFields` / `allowDelete` apenas se editar registros). Siga a ajuda custom-view-remote para o contrato de dados via postMessage — nenhum fetch na visualização.",
|
|
821
839
|
repair: "Reparar",
|
|
822
840
|
dataIssuesDetected: "{count} arquivo(s) de registro têm problemas de dados e podem não aparecer nesta visualização.",
|
|
823
841
|
repairPrompt: "A coleção {title} tem {count} arquivo(s) de registro com problemas de dados que impedem que apareçam. Corrija cada um: leia o arquivo com Read, corrija-o e grave-o novamente com Write:\n{issues}\n\nQuando terminar, chame presentCollection para confirmar que os registros carregam.",
|
|
@@ -940,6 +958,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
940
958
|
kanbanUncategorized: "Non classé",
|
|
941
959
|
kanbanOpenCard: "Ouvrir {label}",
|
|
942
960
|
addView: "Ajouter une vue",
|
|
961
|
+
addViewDesktop: "Vue personnalisée",
|
|
962
|
+
addViewMobile: "Vue mobile",
|
|
943
963
|
config: {
|
|
944
964
|
open: "Paramètres de la collection",
|
|
945
965
|
title: "{title} · paramètres",
|
|
@@ -951,6 +971,7 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
951
971
|
customViewLoading: "Chargement de la vue…",
|
|
952
972
|
customViewError: "Impossible de charger cette vue : {error}",
|
|
953
973
|
addViewPrompt: "Je veux ajouter une vue personnalisée à la collection « {title} ». Demande-moi ce que je veux voir ou modifier, puis crée le fichier HTML de la vue dans {base}/views/your-view.html et enregistre-le dans {base}/schema.json sous `views[]` (capabilities [\"read\"] pour une vue en lecture seule, [\"read\",\"write\"] si elle modifie des enregistrements). Suis l'aide custom-view pour le contrat de données.",
|
|
974
|
+
addMobileViewPrompt: "Je veux ajouter une vue personnalisée pour le mobile (application distante) à la collection « {title} ». Demande-moi ce que je veux voir ou modifier, puis crée le fichier HTML de la vue dans {base}/views/your-view.html et enregistre-le dans {base}/schema.json sous `views[]` avec `target: \"mobile\"` (en lecture seule par défaut ; déclare `editableFields` / `allowDelete` uniquement si elle modifie des enregistrements). Suis l'aide custom-view-remote pour le contrat de données par postMessage — aucun fetch dans la vue.",
|
|
954
975
|
repair: "Réparer",
|
|
955
976
|
dataIssuesDetected: "{count} fichier(s) d'enregistrement présentent des problèmes de données et peuvent être absents de cette vue.",
|
|
956
977
|
repairPrompt: "La collection « {title} » comporte {count} fichier(s) d'enregistrement présentant des problèmes de données qui les empêchent d'apparaître. Corrigez chacun : lisez le fichier avec Read, corrigez-le, puis réécrivez-le avec Write :\n{issues}\n\nUne fois terminé, appelez presentCollection pour confirmer que les enregistrements se chargent.",
|
|
@@ -1073,6 +1094,8 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
1073
1094
|
kanbanUncategorized: "Nicht kategorisiert",
|
|
1074
1095
|
kanbanOpenCard: "{label} öffnen",
|
|
1075
1096
|
addView: "Ansicht hinzufügen",
|
|
1097
|
+
addViewDesktop: "Benutzerdefinierte Ansicht",
|
|
1098
|
+
addViewMobile: "Smartphone-Ansicht",
|
|
1076
1099
|
config: {
|
|
1077
1100
|
open: "Sammlungseinstellungen",
|
|
1078
1101
|
title: "{title} · Einstellungen",
|
|
@@ -1084,6 +1107,7 @@ var i18n = (0, vue_i18n.createI18n)({
|
|
|
1084
1107
|
customViewLoading: "Ansicht wird geladen…",
|
|
1085
1108
|
customViewError: "Diese Ansicht konnte nicht geladen werden: {error}",
|
|
1086
1109
|
addViewPrompt: "Ich möchte der Sammlung {title} eine benutzerdefinierte Ansicht hinzufügen. Frag mich, was ich sehen oder bearbeiten möchte, erstelle dann die HTML-Ansichtsdatei unter {base}/views/your-view.html und registriere sie in {base}/schema.json unter `views[]` (capabilities [\"read\"] für eine schreibgeschützte Ansicht, [\"read\",\"write\"] wenn sie Datensätze bearbeitet). Folge der custom-view-Hilfe für den Datenvertrag.",
|
|
1110
|
+
addMobileViewPrompt: "Ich möchte der Sammlung {title} eine benutzerdefinierte Ansicht für das Smartphone (Remote-App) hinzufügen. Frag mich, was ich sehen oder bearbeiten möchte, erstelle dann die HTML-Ansichtsdatei unter {base}/views/your-view.html und registriere sie in {base}/schema.json unter `views[]` mit `target: \"mobile\"` (standardmäßig schreibgeschützt; deklariere `editableFields` / `allowDelete` nur, wenn sie Datensätze bearbeitet). Folge der custom-view-remote-Hilfe für den postMessage-Datenvertrag — kein fetch jeglicher Art in der Ansicht.",
|
|
1087
1111
|
repair: "Reparieren",
|
|
1088
1112
|
dataIssuesDetected: "{count} Datensatzdatei(en) haben Datenprobleme und fehlen möglicherweise in dieser Ansicht.",
|
|
1089
1113
|
repairPrompt: "Die Sammlung {title} hat {count} Datensatzdatei(en) mit Datenproblemen, die ihr Erscheinen verhindern. Korrigiere jede — die Datei mit Read lesen, korrigieren und mit Write zurückschreiben:\n{issues}\n\nRufe anschließend presentCollection auf, um zu bestätigen, dass die Datensätze geladen werden.",
|
|
@@ -3012,11 +3036,144 @@ var CollectionRemoteViewPreview_default = /*#__PURE__*/ _plugin_vue_export_helpe
|
|
|
3012
3036
|
}
|
|
3013
3037
|
}), [["__scopeId", "data-v-965ade6c"]]);
|
|
3014
3038
|
//#endregion
|
|
3015
|
-
//#region src/vue/useCollectionRendering.ts
|
|
3039
|
+
//#region src/vue/useCollectionRendering.helpers.ts
|
|
3040
|
+
var EM_DASH = "—";
|
|
3041
|
+
var DEFAULT_CURRENCY = "USD";
|
|
3042
|
+
var MARKDOWN_CELL_PREVIEW_MAX = 80;
|
|
3016
3043
|
function stepForFieldType(type) {
|
|
3017
3044
|
if (type === "money") return "0.01";
|
|
3018
3045
|
if (type === "number") return "any";
|
|
3019
3046
|
}
|
|
3047
|
+
function inputTypeFor(type) {
|
|
3048
|
+
if (type === "email") return "email";
|
|
3049
|
+
if (type === "number") return "number";
|
|
3050
|
+
if (type === "money") return "number";
|
|
3051
|
+
if (type === "date") return "date";
|
|
3052
|
+
if (type === "datetime") return "datetime-local";
|
|
3053
|
+
return "text";
|
|
3054
|
+
}
|
|
3055
|
+
function isExternalUrl(value) {
|
|
3056
|
+
return typeof value === "string" && /^https?:\/\//i.test(value);
|
|
3057
|
+
}
|
|
3058
|
+
function detailText(value) {
|
|
3059
|
+
if (value === void 0 || value === null || value === "") return EM_DASH;
|
|
3060
|
+
return String(value);
|
|
3061
|
+
}
|
|
3062
|
+
function formatCell(value, type) {
|
|
3063
|
+
if (value === void 0 || value === null || value === "") return EM_DASH;
|
|
3064
|
+
if (type === "markdown" && typeof value === "string") return value.length > MARKDOWN_CELL_PREVIEW_MAX ? `${value.slice(0, MARKDOWN_CELL_PREVIEW_MAX)}…` : value;
|
|
3065
|
+
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
3066
|
+
return JSON.stringify(value);
|
|
3067
|
+
}
|
|
3068
|
+
/** Resolve the ISO 4217 code for a money field: a per-record
|
|
3069
|
+
* `currencyField` (when present and non-blank) wins over the field's
|
|
3070
|
+
* literal `currency`. */
|
|
3071
|
+
function resolveCurrency(field, record) {
|
|
3072
|
+
if (field.currencyField && record) {
|
|
3073
|
+
const code = record[field.currencyField];
|
|
3074
|
+
if (typeof code === "string" && code.trim().length > 0) return code;
|
|
3075
|
+
}
|
|
3076
|
+
return field.currency;
|
|
3077
|
+
}
|
|
3078
|
+
function formatMoney(value, currency, displayLocale) {
|
|
3079
|
+
if (value === void 0 || value === "") return EM_DASH;
|
|
3080
|
+
const amount = typeof value === "number" ? value : Number(value);
|
|
3081
|
+
if (!Number.isFinite(amount)) return String(value);
|
|
3082
|
+
const currencyCode = currency && currency.length > 0 ? currency : DEFAULT_CURRENCY;
|
|
3083
|
+
try {
|
|
3084
|
+
return new Intl.NumberFormat(displayLocale, {
|
|
3085
|
+
style: "currency",
|
|
3086
|
+
currency: currencyCode
|
|
3087
|
+
}).format(amount);
|
|
3088
|
+
} catch {
|
|
3089
|
+
return String(amount);
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
function currencySymbolForLocale(currency, locale) {
|
|
3093
|
+
const code = currency && currency.length > 0 ? currency : DEFAULT_CURRENCY;
|
|
3094
|
+
try {
|
|
3095
|
+
return new Intl.NumberFormat(locale, {
|
|
3096
|
+
style: "currency",
|
|
3097
|
+
currency: code
|
|
3098
|
+
}).formatToParts(0).find((entry) => entry.type === "currency")?.value ?? code;
|
|
3099
|
+
} catch {
|
|
3100
|
+
return code;
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
function tableRows(value) {
|
|
3104
|
+
if (!Array.isArray(value)) return [];
|
|
3105
|
+
return value.filter((row) => Boolean(row) && typeof row === "object" && !Array.isArray(row));
|
|
3106
|
+
}
|
|
3107
|
+
function hasTableRows(value) {
|
|
3108
|
+
return tableRows(value).length > 0;
|
|
3109
|
+
}
|
|
3110
|
+
/** Pick the field used to label a referenced/embedded record: prefer a
|
|
3111
|
+
* `name` field, then `title`, else fall back to the primary key. */
|
|
3112
|
+
function displayFieldFor(fields, primaryKey) {
|
|
3113
|
+
if ("name" in fields) return "name";
|
|
3114
|
+
if ("title" in fields) return "title";
|
|
3115
|
+
return primaryKey;
|
|
3116
|
+
}
|
|
3117
|
+
function uniqueRefTargets(schema) {
|
|
3118
|
+
const targets = /* @__PURE__ */ new Set();
|
|
3119
|
+
const walk = (fields) => {
|
|
3120
|
+
for (const field of Object.values(fields)) {
|
|
3121
|
+
if (field.type === "ref" && typeof field.to === "string" && field.to.length > 0) targets.add(field.to);
|
|
3122
|
+
if (field.type === "table" && field.of) walk(field.of);
|
|
3123
|
+
}
|
|
3124
|
+
};
|
|
3125
|
+
walk(schema.fields);
|
|
3126
|
+
return [...targets];
|
|
3127
|
+
}
|
|
3128
|
+
function uniqueEmbedTargets(schema) {
|
|
3129
|
+
const targets = /* @__PURE__ */ new Set();
|
|
3130
|
+
for (const field of Object.values(schema.fields)) if (field.type === "embed" && typeof field.to === "string" && field.to.length > 0) targets.add(field.to);
|
|
3131
|
+
return [...targets];
|
|
3132
|
+
}
|
|
3133
|
+
function buildRefDisplayMap(detail) {
|
|
3134
|
+
const { fields, primaryKey } = detail.collection.schema;
|
|
3135
|
+
const displayField = displayFieldFor(fields, primaryKey);
|
|
3136
|
+
const map = {};
|
|
3137
|
+
for (const item of detail.items) {
|
|
3138
|
+
const slugRaw = item[primaryKey];
|
|
3139
|
+
if (typeof slugRaw !== "string" || slugRaw.length === 0) continue;
|
|
3140
|
+
const displayRaw = item[displayField];
|
|
3141
|
+
map[slugRaw] = typeof displayRaw === "string" && displayRaw.length > 0 ? displayRaw : slugRaw;
|
|
3142
|
+
}
|
|
3143
|
+
return map;
|
|
3144
|
+
}
|
|
3145
|
+
function buildRefRecordMap(detail) {
|
|
3146
|
+
const { schema } = detail.collection;
|
|
3147
|
+
const map = {};
|
|
3148
|
+
for (const item of detail.items) {
|
|
3149
|
+
const slugRaw = item[schema.primaryKey];
|
|
3150
|
+
if (typeof slugRaw === "string" && slugRaw.length > 0) map[slugRaw] = (0, _mulmoclaude_core_collection.deriveAll)(schema, item, {});
|
|
3151
|
+
}
|
|
3152
|
+
return map;
|
|
3153
|
+
}
|
|
3154
|
+
function sortedRefOptions(map) {
|
|
3155
|
+
return Object.entries(map).map(([slug, display]) => ({
|
|
3156
|
+
slug,
|
|
3157
|
+
display
|
|
3158
|
+
})).sort((left, right) => left.display.localeCompare(right.display));
|
|
3159
|
+
}
|
|
3160
|
+
/** Dropdown options for an `embed` field's per-record picker: every
|
|
3161
|
+
* record in the target collection, labelled by its name/title (or
|
|
3162
|
+
* primary key), skipping records without a slug and sorted by label. */
|
|
3163
|
+
function buildEmbedOptions(schema, items) {
|
|
3164
|
+
const { fields, primaryKey } = schema;
|
|
3165
|
+
const displayField = displayFieldFor(fields, primaryKey);
|
|
3166
|
+
return items.map((item) => {
|
|
3167
|
+
const slug = String(item[primaryKey] ?? "");
|
|
3168
|
+
const labelRaw = item[displayField];
|
|
3169
|
+
return {
|
|
3170
|
+
slug,
|
|
3171
|
+
display: typeof labelRaw === "string" && labelRaw.length > 0 ? labelRaw : slug
|
|
3172
|
+
};
|
|
3173
|
+
}).filter((opt) => opt.slug.length > 0).sort((left, right) => left.display.localeCompare(right.display));
|
|
3174
|
+
}
|
|
3175
|
+
//#endregion
|
|
3176
|
+
//#region src/vue/useCollectionRendering.ts
|
|
3020
3177
|
function useCollectionRendering(collection, locale) {
|
|
3021
3178
|
const refCache = (0, vue.ref)({});
|
|
3022
3179
|
const refRecordCache = (0, vue.ref)({});
|
|
@@ -3026,43 +3183,6 @@ function useCollectionRendering(collection, locale) {
|
|
|
3026
3183
|
refRecordCache.value = {};
|
|
3027
3184
|
embedCache.value = {};
|
|
3028
3185
|
}
|
|
3029
|
-
function uniqueRefTargets(schema) {
|
|
3030
|
-
const targets = /* @__PURE__ */ new Set();
|
|
3031
|
-
const walk = (fields) => {
|
|
3032
|
-
for (const field of Object.values(fields)) {
|
|
3033
|
-
if (field.type === "ref" && typeof field.to === "string" && field.to.length > 0) targets.add(field.to);
|
|
3034
|
-
if (field.type === "table" && field.of) walk(field.of);
|
|
3035
|
-
}
|
|
3036
|
-
};
|
|
3037
|
-
walk(schema.fields);
|
|
3038
|
-
return [...targets];
|
|
3039
|
-
}
|
|
3040
|
-
function uniqueEmbedTargets(schema) {
|
|
3041
|
-
const targets = /* @__PURE__ */ new Set();
|
|
3042
|
-
for (const field of Object.values(schema.fields)) if (field.type === "embed" && typeof field.to === "string" && field.to.length > 0) targets.add(field.to);
|
|
3043
|
-
return [...targets];
|
|
3044
|
-
}
|
|
3045
|
-
function buildRefDisplayMap(detail) {
|
|
3046
|
-
const { fields, primaryKey } = detail.collection.schema;
|
|
3047
|
-
const displayField = "name" in fields ? "name" : "title" in fields ? "title" : primaryKey;
|
|
3048
|
-
const map = {};
|
|
3049
|
-
for (const item of detail.items) {
|
|
3050
|
-
const slugRaw = item[primaryKey];
|
|
3051
|
-
if (typeof slugRaw !== "string" || slugRaw.length === 0) continue;
|
|
3052
|
-
const displayRaw = item[displayField];
|
|
3053
|
-
map[slugRaw] = typeof displayRaw === "string" && displayRaw.length > 0 ? displayRaw : slugRaw;
|
|
3054
|
-
}
|
|
3055
|
-
return map;
|
|
3056
|
-
}
|
|
3057
|
-
function buildRefRecordMap(detail) {
|
|
3058
|
-
const { schema } = detail.collection;
|
|
3059
|
-
const map = {};
|
|
3060
|
-
for (const item of detail.items) {
|
|
3061
|
-
const slugRaw = item[schema.primaryKey];
|
|
3062
|
-
if (typeof slugRaw === "string" && slugRaw.length > 0) map[slugRaw] = (0, _mulmoclaude_core_collection.deriveAll)(schema, item, {});
|
|
3063
|
-
}
|
|
3064
|
-
return map;
|
|
3065
|
-
}
|
|
3066
3186
|
async function loadLinkedCollections(schema, expectedSlug) {
|
|
3067
3187
|
const refTargets = new Set(uniqueRefTargets(schema));
|
|
3068
3188
|
const embedTargets = new Set(uniqueEmbedTargets(schema));
|
|
@@ -3107,11 +3227,7 @@ function useCollectionRendering(collection, locale) {
|
|
|
3107
3227
|
}
|
|
3108
3228
|
function refOptions(targetSlug) {
|
|
3109
3229
|
const map = refCache.value[targetSlug];
|
|
3110
|
-
|
|
3111
|
-
return Object.entries(map).map(([slug, display]) => ({
|
|
3112
|
-
slug,
|
|
3113
|
-
display
|
|
3114
|
-
})).sort((left, right) => left.display.localeCompare(right.display));
|
|
3230
|
+
return map ? sortedRefOptions(map) : [];
|
|
3115
3231
|
}
|
|
3116
3232
|
/** Dropdown options for an `embed` field's per-record picker (`idField`):
|
|
3117
3233
|
* every record in the target collection, labelled by its name/title (or
|
|
@@ -3119,17 +3235,7 @@ function useCollectionRendering(collection, locale) {
|
|
|
3119
3235
|
* that aren't also `ref` targets (the profile collection, say). */
|
|
3120
3236
|
function embedOptions(targetSlug) {
|
|
3121
3237
|
const data = embedCache.value[targetSlug];
|
|
3122
|
-
|
|
3123
|
-
const { fields, primaryKey } = data.schema;
|
|
3124
|
-
const displayField = "name" in fields ? "name" : "title" in fields ? "title" : primaryKey;
|
|
3125
|
-
return data.items.map((item) => {
|
|
3126
|
-
const slug = String(item[primaryKey] ?? "");
|
|
3127
|
-
const labelRaw = item[displayField];
|
|
3128
|
-
return {
|
|
3129
|
-
slug,
|
|
3130
|
-
display: typeof labelRaw === "string" && labelRaw.length > 0 ? labelRaw : slug
|
|
3131
|
-
};
|
|
3132
|
-
}).filter((opt) => opt.slug.length > 0).sort((left, right) => left.display.localeCompare(right.display));
|
|
3238
|
+
return data ? buildEmbedOptions(data.schema, data.items) : [];
|
|
3133
3239
|
}
|
|
3134
3240
|
function resolveEmbed(field, record) {
|
|
3135
3241
|
if (field.type !== "embed" || !field.to) return {
|
|
@@ -3182,46 +3288,8 @@ function useCollectionRendering(collection, locale) {
|
|
|
3182
3288
|
}
|
|
3183
3289
|
return out;
|
|
3184
3290
|
}
|
|
3185
|
-
function resolveCurrency(field, record) {
|
|
3186
|
-
if (field.currencyField && record) {
|
|
3187
|
-
const code = record[field.currencyField];
|
|
3188
|
-
if (typeof code === "string" && code.trim().length > 0) return code;
|
|
3189
|
-
}
|
|
3190
|
-
return field.currency;
|
|
3191
|
-
}
|
|
3192
3291
|
function currencySymbol(currency) {
|
|
3193
|
-
|
|
3194
|
-
try {
|
|
3195
|
-
return new Intl.NumberFormat(locale.value, {
|
|
3196
|
-
style: "currency",
|
|
3197
|
-
currency: code
|
|
3198
|
-
}).formatToParts(0).find((entry) => entry.type === "currency")?.value ?? code;
|
|
3199
|
-
} catch {
|
|
3200
|
-
return code;
|
|
3201
|
-
}
|
|
3202
|
-
}
|
|
3203
|
-
function formatMoney(value, currency, displayLocale) {
|
|
3204
|
-
if (value === void 0 || value === "") return "—";
|
|
3205
|
-
const amount = typeof value === "number" ? value : Number(value);
|
|
3206
|
-
if (!Number.isFinite(amount)) return String(value);
|
|
3207
|
-
const currencyCode = currency && currency.length > 0 ? currency : "USD";
|
|
3208
|
-
try {
|
|
3209
|
-
return new Intl.NumberFormat(displayLocale, {
|
|
3210
|
-
style: "currency",
|
|
3211
|
-
currency: currencyCode
|
|
3212
|
-
}).format(amount);
|
|
3213
|
-
} catch {
|
|
3214
|
-
return String(amount);
|
|
3215
|
-
}
|
|
3216
|
-
}
|
|
3217
|
-
function formatCell(value, type) {
|
|
3218
|
-
if (value === void 0 || value === null || value === "") return "—";
|
|
3219
|
-
if (type === "markdown" && typeof value === "string") return value.length > 80 ? `${value.slice(0, 80)}…` : value;
|
|
3220
|
-
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
3221
|
-
return JSON.stringify(value);
|
|
3222
|
-
}
|
|
3223
|
-
function isExternalUrl(value) {
|
|
3224
|
-
return typeof value === "string" && /^https?:\/\//i.test(value);
|
|
3292
|
+
return currencySymbolForLocale(currency, locale.value);
|
|
3225
3293
|
}
|
|
3226
3294
|
function artifactUrl(value) {
|
|
3227
3295
|
return collectionUi().fileAssetUrl(value);
|
|
@@ -3229,30 +3297,11 @@ function useCollectionRendering(collection, locale) {
|
|
|
3229
3297
|
function fileRoutePath(value) {
|
|
3230
3298
|
return collectionUi().fileRoutePath(value);
|
|
3231
3299
|
}
|
|
3232
|
-
function detailText(value) {
|
|
3233
|
-
if (value === void 0 || value === null || value === "") return "—";
|
|
3234
|
-
return String(value);
|
|
3235
|
-
}
|
|
3236
|
-
function tableRows(value) {
|
|
3237
|
-
if (!Array.isArray(value)) return [];
|
|
3238
|
-
return value.filter((row) => Boolean(row) && typeof row === "object" && !Array.isArray(row));
|
|
3239
|
-
}
|
|
3240
|
-
function hasTableRows(value) {
|
|
3241
|
-
return tableRows(value).length > 0;
|
|
3242
|
-
}
|
|
3243
3300
|
function formatSubCell(subField, value, record) {
|
|
3244
3301
|
if (subField.type === "money") return formatMoney(value, resolveCurrency(subField, record), locale.value);
|
|
3245
3302
|
if (subField.type === "ref" && subField.to && typeof value === "string" && value.length > 0) return refDisplay(subField.to, value);
|
|
3246
3303
|
return formatCell(value, subField.type);
|
|
3247
3304
|
}
|
|
3248
|
-
function inputTypeFor(type) {
|
|
3249
|
-
if (type === "email") return "email";
|
|
3250
|
-
if (type === "number") return "number";
|
|
3251
|
-
if (type === "money") return "number";
|
|
3252
|
-
if (type === "date") return "date";
|
|
3253
|
-
if (type === "datetime") return "datetime-local";
|
|
3254
|
-
return "text";
|
|
3255
|
-
}
|
|
3256
3305
|
const stepFor = stepForFieldType;
|
|
3257
3306
|
function evaluateDerivedAgainstItem(field, fieldKey, item) {
|
|
3258
3307
|
if (!field.formula || !collection.value) return null;
|
|
@@ -3436,166 +3485,175 @@ var _hoisted_26$1 = [
|
|
|
3436
3485
|
"onClick"
|
|
3437
3486
|
];
|
|
3438
3487
|
var _hoisted_27$1 = { class: "material-icons text-sm" };
|
|
3439
|
-
var _hoisted_28 = [
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
var
|
|
3445
|
-
|
|
3488
|
+
var _hoisted_28 = [
|
|
3489
|
+
"title",
|
|
3490
|
+
"aria-label",
|
|
3491
|
+
"aria-expanded"
|
|
3492
|
+
];
|
|
3493
|
+
var _hoisted_29 = {
|
|
3494
|
+
key: 0,
|
|
3495
|
+
class: "absolute left-0 top-full mt-1 z-20 min-w-max rounded border border-slate-200 bg-white shadow-lg py-1",
|
|
3496
|
+
"data-testid": "collection-view-add-menu"
|
|
3497
|
+
};
|
|
3498
|
+
var _hoisted_30 = ["title", "aria-label"];
|
|
3499
|
+
var _hoisted_31 = ["value", "aria-label"];
|
|
3500
|
+
var _hoisted_32 = ["value"];
|
|
3501
|
+
var _hoisted_33 = ["value", "aria-label"];
|
|
3502
|
+
var _hoisted_34 = ["value"];
|
|
3503
|
+
var _hoisted_35 = {
|
|
3446
3504
|
key: 3,
|
|
3447
3505
|
class: "text-[10px] text-slate-400 font-bold uppercase tracking-wider select-none"
|
|
3448
3506
|
};
|
|
3449
|
-
var
|
|
3507
|
+
var _hoisted_36 = {
|
|
3450
3508
|
key: 3,
|
|
3451
3509
|
class: "mx-6 mt-4 rounded-xl border border-amber-200 bg-amber-50/60 p-4 text-sm text-amber-900 shadow-sm flex items-center gap-3",
|
|
3452
3510
|
"data-testid": "collections-data-issues"
|
|
3453
3511
|
};
|
|
3454
|
-
var
|
|
3455
|
-
var
|
|
3456
|
-
var
|
|
3512
|
+
var _hoisted_37 = { class: "flex-1" };
|
|
3513
|
+
var _hoisted_38 = { class: "flex-1 overflow-auto" };
|
|
3514
|
+
var _hoisted_39 = {
|
|
3457
3515
|
key: 0,
|
|
3458
3516
|
class: "flex flex-col items-center justify-center py-20 text-sm text-slate-500 gap-3"
|
|
3459
3517
|
};
|
|
3460
|
-
var
|
|
3518
|
+
var _hoisted_40 = {
|
|
3461
3519
|
key: 1,
|
|
3462
3520
|
class: "m-6 rounded-xl border border-red-200 bg-red-50/50 p-4 text-sm text-red-800 shadow-sm flex items-center gap-3"
|
|
3463
3521
|
};
|
|
3464
|
-
var
|
|
3465
|
-
var
|
|
3522
|
+
var _hoisted_41 = { key: 2 };
|
|
3523
|
+
var _hoisted_42 = {
|
|
3466
3524
|
key: 3,
|
|
3467
3525
|
class: "p-4"
|
|
3468
3526
|
};
|
|
3469
|
-
var
|
|
3527
|
+
var _hoisted_43 = {
|
|
3470
3528
|
key: 4,
|
|
3471
3529
|
class: "h-full flex flex-col"
|
|
3472
3530
|
};
|
|
3473
|
-
var
|
|
3531
|
+
var _hoisted_44 = {
|
|
3474
3532
|
key: 0,
|
|
3475
3533
|
class: "m-3 mb-0 rounded-xl border border-red-200 bg-red-50/50 p-4 text-sm text-red-800 shadow-sm flex items-center gap-3",
|
|
3476
3534
|
"data-testid": "collections-inline-error"
|
|
3477
3535
|
};
|
|
3478
|
-
var
|
|
3479
|
-
var
|
|
3480
|
-
var
|
|
3481
|
-
var
|
|
3536
|
+
var _hoisted_45 = { class: "flex-1" };
|
|
3537
|
+
var _hoisted_46 = ["aria-label"];
|
|
3538
|
+
var _hoisted_47 = { class: "flex-1 min-h-0 px-3 py-2" };
|
|
3539
|
+
var _hoisted_48 = {
|
|
3482
3540
|
key: 5,
|
|
3483
3541
|
class: "h-full",
|
|
3484
3542
|
"data-testid": "collection-custom-view-body"
|
|
3485
3543
|
};
|
|
3486
|
-
var
|
|
3544
|
+
var _hoisted_49 = {
|
|
3487
3545
|
key: 6,
|
|
3488
3546
|
class: "flex flex-col items-center justify-center py-20 text-sm text-slate-400 gap-2"
|
|
3489
3547
|
};
|
|
3490
|
-
var
|
|
3491
|
-
var
|
|
3548
|
+
var _hoisted_50 = { class: "font-semibold text-slate-600" };
|
|
3549
|
+
var _hoisted_51 = {
|
|
3492
3550
|
key: 7,
|
|
3493
3551
|
class: "flex flex-col items-center justify-center py-20 text-sm text-slate-400 gap-2"
|
|
3494
3552
|
};
|
|
3495
|
-
var
|
|
3496
|
-
var
|
|
3553
|
+
var _hoisted_52 = { class: "font-semibold text-slate-600" };
|
|
3554
|
+
var _hoisted_53 = {
|
|
3497
3555
|
key: 8,
|
|
3498
3556
|
class: "overflow-x-auto [container-type:inline-size]"
|
|
3499
3557
|
};
|
|
3500
|
-
var
|
|
3558
|
+
var _hoisted_54 = {
|
|
3501
3559
|
key: 0,
|
|
3502
3560
|
class: "m-4 rounded-xl border border-red-200 bg-red-50/50 p-4 text-sm text-red-800 shadow-sm flex items-center gap-3",
|
|
3503
3561
|
"data-testid": "collections-inline-error"
|
|
3504
3562
|
};
|
|
3505
|
-
var
|
|
3506
|
-
var
|
|
3507
|
-
var
|
|
3508
|
-
var
|
|
3509
|
-
var
|
|
3510
|
-
var
|
|
3511
|
-
var
|
|
3512
|
-
var
|
|
3563
|
+
var _hoisted_55 = { class: "flex-1" };
|
|
3564
|
+
var _hoisted_56 = ["aria-label"];
|
|
3565
|
+
var _hoisted_57 = { class: "min-w-full text-xs" };
|
|
3566
|
+
var _hoisted_58 = { class: "bg-slate-50 border-b border-slate-200" };
|
|
3567
|
+
var _hoisted_59 = ["aria-sort"];
|
|
3568
|
+
var _hoisted_60 = { class: "flex items-center gap-1" };
|
|
3569
|
+
var _hoisted_61 = ["title"];
|
|
3570
|
+
var _hoisted_62 = [
|
|
3513
3571
|
"data-testid",
|
|
3514
3572
|
"aria-label",
|
|
3515
3573
|
"onClick",
|
|
3516
3574
|
"onPointerenter"
|
|
3517
3575
|
];
|
|
3518
|
-
var
|
|
3519
|
-
var
|
|
3520
|
-
var
|
|
3576
|
+
var _hoisted_63 = { class: "material-icons text-base align-middle" };
|
|
3577
|
+
var _hoisted_64 = { class: "divide-y divide-slate-100 bg-white" };
|
|
3578
|
+
var _hoisted_65 = [
|
|
3521
3579
|
"aria-label",
|
|
3522
3580
|
"data-testid",
|
|
3523
3581
|
"onClick",
|
|
3524
3582
|
"onKeydown"
|
|
3525
3583
|
];
|
|
3526
|
-
var
|
|
3584
|
+
var _hoisted_66 = [
|
|
3527
3585
|
"checked",
|
|
3528
3586
|
"disabled",
|
|
3529
3587
|
"data-testid",
|
|
3530
3588
|
"aria-label",
|
|
3531
3589
|
"onChange"
|
|
3532
3590
|
];
|
|
3533
|
-
var
|
|
3591
|
+
var _hoisted_67 = [
|
|
3534
3592
|
"checked",
|
|
3535
3593
|
"disabled",
|
|
3536
3594
|
"data-testid",
|
|
3537
3595
|
"aria-label",
|
|
3538
3596
|
"onChange"
|
|
3539
3597
|
];
|
|
3540
|
-
var
|
|
3598
|
+
var _hoisted_68 = {
|
|
3541
3599
|
key: 2,
|
|
3542
3600
|
class: "block truncate"
|
|
3543
3601
|
};
|
|
3544
|
-
var
|
|
3602
|
+
var _hoisted_69 = [
|
|
3545
3603
|
"href",
|
|
3546
3604
|
"tabindex",
|
|
3547
3605
|
"data-testid",
|
|
3548
3606
|
"onClick",
|
|
3549
3607
|
"onKeydown"
|
|
3550
3608
|
];
|
|
3551
|
-
var
|
|
3609
|
+
var _hoisted_70 = [
|
|
3552
3610
|
"value",
|
|
3553
3611
|
"disabled",
|
|
3554
3612
|
"data-testid",
|
|
3555
3613
|
"aria-label",
|
|
3556
3614
|
"onChange"
|
|
3557
3615
|
];
|
|
3558
|
-
var
|
|
3616
|
+
var _hoisted_71 = {
|
|
3559
3617
|
key: 0,
|
|
3560
3618
|
value: ""
|
|
3561
3619
|
};
|
|
3562
|
-
var
|
|
3563
|
-
var
|
|
3620
|
+
var _hoisted_72 = ["value"];
|
|
3621
|
+
var _hoisted_73 = {
|
|
3564
3622
|
key: 4,
|
|
3565
3623
|
class: "block truncate tabular-nums font-semibold text-slate-900"
|
|
3566
3624
|
};
|
|
3567
|
-
var
|
|
3625
|
+
var _hoisted_74 = {
|
|
3568
3626
|
key: 5,
|
|
3569
3627
|
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"
|
|
3570
3628
|
};
|
|
3571
|
-
var
|
|
3629
|
+
var _hoisted_75 = {
|
|
3572
3630
|
key: 6,
|
|
3573
3631
|
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"
|
|
3574
3632
|
};
|
|
3575
|
-
var _hoisted_75 = ["href", "data-testid"];
|
|
3576
3633
|
var _hoisted_76 = ["href", "data-testid"];
|
|
3577
|
-
var _hoisted_77 = [
|
|
3634
|
+
var _hoisted_77 = ["href", "data-testid"];
|
|
3635
|
+
var _hoisted_78 = [
|
|
3578
3636
|
"href",
|
|
3579
3637
|
"data-testid",
|
|
3580
3638
|
"onClick"
|
|
3581
3639
|
];
|
|
3582
|
-
var
|
|
3640
|
+
var _hoisted_79 = {
|
|
3583
3641
|
key: 10,
|
|
3584
3642
|
class: "block truncate text-slate-600"
|
|
3585
3643
|
};
|
|
3586
|
-
var
|
|
3587
|
-
var
|
|
3588
|
-
var
|
|
3589
|
-
var
|
|
3644
|
+
var _hoisted_80 = { class: "bg-white rounded-2xl shadow-2xl w-full max-w-xl flex flex-col border border-slate-200 overflow-hidden" };
|
|
3645
|
+
var _hoisted_81 = { class: "px-6 py-4 border-b border-slate-100 flex items-center gap-3 bg-slate-50/50" };
|
|
3646
|
+
var _hoisted_82 = { class: "flex-1" };
|
|
3647
|
+
var _hoisted_83 = {
|
|
3590
3648
|
id: "collections-chat-title",
|
|
3591
3649
|
class: "text-sm font-bold text-slate-800 uppercase tracking-wide"
|
|
3592
3650
|
};
|
|
3593
|
-
var
|
|
3594
|
-
var
|
|
3595
|
-
var
|
|
3596
|
-
var
|
|
3597
|
-
var
|
|
3598
|
-
var
|
|
3651
|
+
var _hoisted_84 = { class: "text-xs text-slate-400 font-semibold" };
|
|
3652
|
+
var _hoisted_85 = ["aria-label"];
|
|
3653
|
+
var _hoisted_86 = { class: "px-6 py-5" };
|
|
3654
|
+
var _hoisted_87 = ["placeholder", "onKeydown"];
|
|
3655
|
+
var _hoisted_88 = { class: "px-6 py-3.5 border-t border-slate-100 flex items-center justify-end gap-2 bg-slate-50/50" };
|
|
3656
|
+
var _hoisted_89 = ["disabled"];
|
|
3599
3657
|
/** `slug` / `selected` are supplied only in EMBEDDED mode (the
|
|
3600
3658
|
* `presentCollection` chat card mounts this component and drives both
|
|
3601
3659
|
* from the tool result). In standalone route mode (the
|
|
@@ -4121,16 +4179,41 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4121
4179
|
* page only (the seed starts a chat). Feeds qualify too — their views are
|
|
4122
4180
|
* authored under feeds/<slug>/ and the seed prompt points there. */
|
|
4123
4181
|
const canAddCustomView = (0, vue.computed)(() => Boolean(collection.value) && !embedded.value);
|
|
4182
|
+
const addMenuOpen = (0, vue.ref)(false);
|
|
4183
|
+
const addMenuRef = (0, vue.ref)(null);
|
|
4184
|
+
/** Whether authoring a phone (remote app) view is worth offering — mirrors
|
|
4185
|
+
* the selector filter above: without the host's `fetchRemoteView` binding a
|
|
4186
|
+
* mobile view could be authored but never shown here. */
|
|
4187
|
+
const canAddMobileView = (0, vue.computed)(() => Boolean(cui.fetchRemoteView));
|
|
4188
|
+
/** "+" click: open the target chooser, or skip the one-item menu and seed
|
|
4189
|
+
* the desktop prompt directly when mobile views aren't available. */
|
|
4190
|
+
function onAddViewClick() {
|
|
4191
|
+
if (!canAddMobileView.value) {
|
|
4192
|
+
addCustomView("desktop");
|
|
4193
|
+
return;
|
|
4194
|
+
}
|
|
4195
|
+
addMenuOpen.value = !addMenuOpen.value;
|
|
4196
|
+
}
|
|
4197
|
+
function closeAddMenuOnOutsideClick(event) {
|
|
4198
|
+
if (!addMenuRef.value?.contains(event.target)) addMenuOpen.value = false;
|
|
4199
|
+
}
|
|
4200
|
+
(0, vue.watch)(addMenuOpen, (open) => {
|
|
4201
|
+
if (open) document.addEventListener("mousedown", closeAddMenuOnOutsideClick);
|
|
4202
|
+
else document.removeEventListener("mousedown", closeAddMenuOnOutsideClick);
|
|
4203
|
+
});
|
|
4124
4204
|
/** Seed a chat asking Claude to author a new custom view for this collection.
|
|
4125
4205
|
* Reuses the same chat-seed path as collection actions — the host injects a
|
|
4126
4206
|
* templated prompt; Claude asks, authors the HTML, and registers it. The
|
|
4127
4207
|
* authoring base is source-aware: a feed lives under `feeds/<slug>/`, every
|
|
4128
|
-
* other collection under the `data/skills/<slug>/` staging dir.
|
|
4129
|
-
|
|
4208
|
+
* other collection under the `data/skills/<slug>/` staging dir. The prompt
|
|
4209
|
+
* is target-aware: phone views follow the custom-view-remote contract and
|
|
4210
|
+
* register with `target: "mobile"`. */
|
|
4211
|
+
function addCustomView(target) {
|
|
4212
|
+
addMenuOpen.value = false;
|
|
4130
4213
|
const current = collection.value;
|
|
4131
4214
|
if (!current) return;
|
|
4132
4215
|
const base = current.source === "feed" ? `feeds/${current.slug}` : `data/skills/${current.slug}`;
|
|
4133
|
-
const prompt = t("collectionsView.addViewPrompt", {
|
|
4216
|
+
const prompt = t(target === "mobile" ? "collectionsView.addMobileViewPrompt" : "collectionsView.addViewPrompt", {
|
|
4134
4217
|
title: current.title,
|
|
4135
4218
|
base
|
|
4136
4219
|
});
|
|
@@ -4606,6 +4689,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4606
4689
|
view.value = slug && readCollectionViewMode(slug) || "table";
|
|
4607
4690
|
anchorOverride.value = null;
|
|
4608
4691
|
kanbanOverride.value = null;
|
|
4692
|
+
addMenuOpen.value = false;
|
|
4609
4693
|
sortState.value = storedSortFor(slug);
|
|
4610
4694
|
}
|
|
4611
4695
|
if (slug) loadCollection(slug);
|
|
@@ -4654,6 +4738,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4654
4738
|
changeUnsub = null;
|
|
4655
4739
|
clearLiveRefreshTimer();
|
|
4656
4740
|
if (refreshNoteTimer !== void 0) clearTimeout(refreshNoteTimer);
|
|
4741
|
+
document.removeEventListener("mousedown", closeAddMenuOnOutsideClick);
|
|
4657
4742
|
});
|
|
4658
4743
|
(0, vue.watch)([
|
|
4659
4744
|
activeView,
|
|
@@ -4688,7 +4773,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4688
4773
|
"aria-label": (0, vue.unref)(t)("collectionsView.backToIndex"),
|
|
4689
4774
|
"data-testid": "collections-back",
|
|
4690
4775
|
onClick: goBack
|
|
4691
|
-
}, [..._cache[
|
|
4776
|
+
}, [..._cache[25] || (_cache[25] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "arrow_back", -1)])], 8, _hoisted_3$5)) : (0, vue.createCommentVNode)("", true),
|
|
4692
4777
|
collection.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_4$5, [(0, vue.createElementVNode)("span", _hoisted_5$5, (0, vue.toDisplayString)(collection.value.icon), 1)])) : (0, vue.createCommentVNode)("", true),
|
|
4693
4778
|
(0, vue.createElementVNode)("div", _hoisted_6$4, [(0, vue.createElementVNode)("h1", _hoisted_7$4, (0, vue.toDisplayString)(collection.value?.title ?? (0, vue.unref)(t)("collectionsView.title")), 1), collection.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_8$4, (0, vue.toDisplayString)(collection.value.slug), 1)) : (0, vue.createCommentVNode)("", true)]),
|
|
4694
4779
|
collection.value && !embedded.value ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(pinToggle)), {
|
|
@@ -4717,7 +4802,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4717
4802
|
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",
|
|
4718
4803
|
"data-testid": "collections-chat",
|
|
4719
4804
|
onClick: openChat
|
|
4720
|
-
}, [_cache[
|
|
4805
|
+
}, [_cache[26] || (_cache[26] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "forum", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.chat")), 1)])) : (0, vue.createCommentVNode)("", true),
|
|
4721
4806
|
((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(collectionActions.value, (action) => {
|
|
4722
4807
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
4723
4808
|
key: action.id,
|
|
@@ -4734,7 +4819,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4734
4819
|
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",
|
|
4735
4820
|
"data-testid": "collections-add-item",
|
|
4736
4821
|
onClick: openCreate
|
|
4737
|
-
}, [_cache[
|
|
4822
|
+
}, [_cache[27] || (_cache[27] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "add", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("common.add")), 1)])) : (0, vue.createCommentVNode)("", true),
|
|
4738
4823
|
canDeleteCollection.value && !embedded.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
4739
4824
|
key: 6,
|
|
4740
4825
|
type: "button",
|
|
@@ -4743,7 +4828,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4743
4828
|
"aria-label": (0, vue.unref)(t)("collectionsView.deleteCollection"),
|
|
4744
4829
|
"data-testid": "collections-delete",
|
|
4745
4830
|
onClick: confirmCollectionDelete
|
|
4746
|
-
}, [..._cache[
|
|
4831
|
+
}, [..._cache[28] || (_cache[28] = [(0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_13$4)) : (0, vue.createCommentVNode)("", true),
|
|
4747
4832
|
canDeleteFeed.value && !embedded.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
4748
4833
|
key: 7,
|
|
4749
4834
|
type: "button",
|
|
@@ -4752,11 +4837,11 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4752
4837
|
"aria-label": (0, vue.unref)(t)("collectionsView.deleteFeed"),
|
|
4753
4838
|
"data-testid": "feeds-delete",
|
|
4754
4839
|
onClick: confirmFeedDelete
|
|
4755
|
-
}, [..._cache[
|
|
4840
|
+
}, [..._cache[29] || (_cache[29] = [(0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_14$4)) : (0, vue.createCommentVNode)("", true)
|
|
4756
4841
|
])) : (0, vue.createCommentVNode)("", true),
|
|
4757
|
-
refreshNote.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_15$4, [_cache[
|
|
4842
|
+
refreshNote.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_15$4, [_cache[30] || (_cache[30] = (0, vue.createElementVNode)("span", { class: "material-icons text-base text-indigo-600" }, "hourglass_top", -1)), (0, vue.createElementVNode)("span", _hoisted_16$4, (0, vue.toDisplayString)(refreshNote.value), 1)])) : (0, vue.createCommentVNode)("", true),
|
|
4758
4843
|
collection.value && (!__props.hideSearch && items.value.length > 0 || !__props.hideViewToggle && (hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value)) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_17$4, [!__props.hideSearch && items.value.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_18$4, [
|
|
4759
|
-
_cache[
|
|
4844
|
+
_cache[32] || (_cache[32] = (0, vue.createElementVNode)("span", { class: "absolute inset-y-0 left-0 flex items-center pl-3 text-slate-400 pointer-events-none" }, [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "search")], -1)),
|
|
4760
4845
|
(0, vue.withDirectives)((0, vue.createElementVNode)("input", {
|
|
4761
4846
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchQuery.value = $event),
|
|
4762
4847
|
type: "text",
|
|
@@ -4770,7 +4855,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4770
4855
|
"aria-label": (0, vue.unref)(t)("collectionsView.clearSearch"),
|
|
4771
4856
|
class: "absolute inset-y-0 right-0 flex items-center pr-2.5 text-slate-400 hover:text-slate-600",
|
|
4772
4857
|
onClick: _cache[1] || (_cache[1] = ($event) => searchQuery.value = "")
|
|
4773
|
-
}, [..._cache[
|
|
4858
|
+
}, [..._cache[31] || (_cache[31] = [(0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_20$2)) : (0, vue.createCommentVNode)("", true)
|
|
4774
4859
|
])) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("div", _hoisted_21$2, [
|
|
4775
4860
|
!__props.hideViewToggle && (hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
4776
4861
|
key: 0,
|
|
@@ -4784,7 +4869,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4784
4869
|
"aria-pressed": activeView.value === "table",
|
|
4785
4870
|
"data-testid": "collection-view-toggle-table",
|
|
4786
4871
|
onClick: _cache[2] || (_cache[2] = ($event) => setView("table"))
|
|
4787
|
-
}, [_cache[
|
|
4872
|
+
}, [_cache[33] || (_cache[33] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "table_rows", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.viewTable")), 1)], 10, _hoisted_23$2),
|
|
4788
4873
|
hasCalendar.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
4789
4874
|
key: 0,
|
|
4790
4875
|
type: "button",
|
|
@@ -4792,7 +4877,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4792
4877
|
"aria-pressed": activeView.value === "calendar",
|
|
4793
4878
|
"data-testid": "collection-view-toggle-calendar",
|
|
4794
4879
|
onClick: _cache[3] || (_cache[3] = ($event) => setView("calendar"))
|
|
4795
|
-
}, [_cache[
|
|
4880
|
+
}, [_cache[34] || (_cache[34] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "calendar_month", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.viewCalendar")), 1)], 10, _hoisted_24$1)) : (0, vue.createCommentVNode)("", true),
|
|
4796
4881
|
hasKanban.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
4797
4882
|
key: 1,
|
|
4798
4883
|
type: "button",
|
|
@@ -4800,7 +4885,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4800
4885
|
"aria-pressed": activeView.value === "kanban",
|
|
4801
4886
|
"data-testid": "collection-view-toggle-kanban",
|
|
4802
4887
|
onClick: _cache[4] || (_cache[4] = ($event) => setView("kanban"))
|
|
4803
|
-
}, [_cache[
|
|
4888
|
+
}, [_cache[35] || (_cache[35] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "view_kanban", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.viewKanban")), 1)], 10, _hoisted_25$1)) : (0, vue.createCommentVNode)("", true),
|
|
4804
4889
|
((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(customViews.value, (cv) => {
|
|
4805
4890
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
4806
4891
|
key: cv.id,
|
|
@@ -4811,15 +4896,30 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4811
4896
|
onClick: ($event) => setCustomView(cv.id)
|
|
4812
4897
|
}, [(0, vue.createElementVNode)("span", _hoisted_27$1, (0, vue.toDisplayString)(cv.icon || (cv.target === "mobile" ? "smartphone" : "dashboard_customize")), 1), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)(cv.label), 1)], 10, _hoisted_26$1);
|
|
4813
4898
|
}), 128)),
|
|
4814
|
-
canAddCustomView.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("
|
|
4899
|
+
canAddCustomView.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
4815
4900
|
key: 2,
|
|
4901
|
+
ref_key: "addMenuRef",
|
|
4902
|
+
ref: addMenuRef,
|
|
4903
|
+
class: "relative"
|
|
4904
|
+
}, [(0, vue.createElementVNode)("button", {
|
|
4816
4905
|
type: "button",
|
|
4817
4906
|
class: "h-8 w-8 flex items-center justify-center rounded bg-white text-slate-500 border border-slate-200 hover:bg-slate-50",
|
|
4818
4907
|
title: (0, vue.unref)(t)("collectionsView.addView"),
|
|
4819
4908
|
"aria-label": (0, vue.unref)(t)("collectionsView.addView"),
|
|
4909
|
+
"aria-expanded": addMenuOpen.value,
|
|
4820
4910
|
"data-testid": "collection-view-add",
|
|
4821
|
-
onClick:
|
|
4822
|
-
}, [..._cache[
|
|
4911
|
+
onClick: onAddViewClick
|
|
4912
|
+
}, [..._cache[36] || (_cache[36] = [(0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "add", -1)])], 8, _hoisted_28), addMenuOpen.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_29, [(0, vue.createElementVNode)("button", {
|
|
4913
|
+
type: "button",
|
|
4914
|
+
class: "w-full h-8 px-3 flex items-center gap-2 text-xs font-bold text-slate-600 hover:bg-slate-50",
|
|
4915
|
+
"data-testid": "collection-view-add-desktop",
|
|
4916
|
+
onClick: _cache[5] || (_cache[5] = ($event) => addCustomView("desktop"))
|
|
4917
|
+
}, [_cache[37] || (_cache[37] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "dashboard_customize", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.addViewDesktop")), 1)]), (0, vue.createElementVNode)("button", {
|
|
4918
|
+
type: "button",
|
|
4919
|
+
class: "w-full h-8 px-3 flex items-center gap-2 text-xs font-bold text-slate-600 hover:bg-slate-50",
|
|
4920
|
+
"data-testid": "collection-view-add-mobile",
|
|
4921
|
+
onClick: _cache[6] || (_cache[6] = ($event) => addCustomView("mobile"))
|
|
4922
|
+
}, [_cache[38] || (_cache[38] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "smartphone", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.addViewMobile")), 1)])])) : (0, vue.createCommentVNode)("", true)], 512)) : (0, vue.createCommentVNode)("", true),
|
|
4823
4923
|
canConfigureViews.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
4824
4924
|
key: 3,
|
|
4825
4925
|
type: "button",
|
|
@@ -4827,8 +4927,8 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4827
4927
|
title: (0, vue.unref)(t)("collectionsView.config.open"),
|
|
4828
4928
|
"aria-label": (0, vue.unref)(t)("collectionsView.config.open"),
|
|
4829
4929
|
"data-testid": "collection-config-open",
|
|
4830
|
-
onClick: _cache[
|
|
4831
|
-
}, [..._cache[
|
|
4930
|
+
onClick: _cache[7] || (_cache[7] = ($event) => configOpen.value = true)
|
|
4931
|
+
}, [..._cache[39] || (_cache[39] = [(0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "settings", -1)])], 8, _hoisted_30)) : (0, vue.createCommentVNode)("", true)
|
|
4832
4932
|
], 8, _hoisted_22$2)) : (0, vue.createCommentVNode)("", true),
|
|
4833
4933
|
calendarActive.value && dateFields.value.length > 1 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("select", {
|
|
4834
4934
|
key: 1,
|
|
@@ -4836,42 +4936,42 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4836
4936
|
class: "h-8 px-2 rounded border border-slate-200 bg-white text-xs font-semibold text-slate-600 focus:outline-none focus:border-indigo-500 cursor-pointer",
|
|
4837
4937
|
"aria-label": (0, vue.unref)(t)("collectionsView.calendarFieldLabel"),
|
|
4838
4938
|
"data-testid": "collection-calendar-field",
|
|
4839
|
-
onChange: _cache[
|
|
4939
|
+
onChange: _cache[8] || (_cache[8] = ($event) => anchorOverride.value = $event.target.value)
|
|
4840
4940
|
}, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(dateFields.value, (key) => {
|
|
4841
4941
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("option", {
|
|
4842
4942
|
key,
|
|
4843
4943
|
value: key
|
|
4844
|
-
}, (0, vue.toDisplayString)(collection.value?.schema.fields[key]?.label ?? key), 9,
|
|
4845
|
-
}), 128))], 40,
|
|
4944
|
+
}, (0, vue.toDisplayString)(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_32);
|
|
4945
|
+
}), 128))], 40, _hoisted_31)) : (0, vue.createCommentVNode)("", true),
|
|
4846
4946
|
kanbanActive.value && enumFields.value.length > 1 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("select", {
|
|
4847
4947
|
key: 2,
|
|
4848
4948
|
value: kanbanGroupField.value,
|
|
4849
4949
|
class: "h-8 px-2 rounded border border-slate-200 bg-white text-xs font-semibold text-slate-600 focus:outline-none focus:border-indigo-500 cursor-pointer",
|
|
4850
4950
|
"aria-label": (0, vue.unref)(t)("collectionsView.kanbanFieldLabel"),
|
|
4851
4951
|
"data-testid": "collection-kanban-field",
|
|
4852
|
-
onChange: _cache[
|
|
4952
|
+
onChange: _cache[9] || (_cache[9] = ($event) => kanbanOverride.value = $event.target.value)
|
|
4853
4953
|
}, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(enumFields.value, (key) => {
|
|
4854
4954
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("option", {
|
|
4855
4955
|
key,
|
|
4856
4956
|
value: key
|
|
4857
|
-
}, (0, vue.toDisplayString)(collection.value?.schema.fields[key]?.label ?? key), 9,
|
|
4858
|
-
}), 128))], 40,
|
|
4859
|
-
items.value.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div",
|
|
4957
|
+
}, (0, vue.toDisplayString)(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_34);
|
|
4958
|
+
}), 128))], 40, _hoisted_33)) : (0, vue.createCommentVNode)("", true),
|
|
4959
|
+
items.value.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_35, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.searchSummary", {
|
|
4860
4960
|
shown: filteredItems.value.length,
|
|
4861
4961
|
total: items.value.length
|
|
4862
4962
|
})), 1)) : (0, vue.createCommentVNode)("", true)
|
|
4863
4963
|
])])) : (0, vue.createCommentVNode)("", true),
|
|
4864
|
-
collection.value && dataIssues.value.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div",
|
|
4865
|
-
_cache[
|
|
4866
|
-
(0, vue.createElementVNode)("span",
|
|
4964
|
+
collection.value && dataIssues.value.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_36, [
|
|
4965
|
+
_cache[41] || (_cache[41] = (0, vue.createElementVNode)("span", { class: "material-icons text-amber-600" }, "warning", -1)),
|
|
4966
|
+
(0, vue.createElementVNode)("span", _hoisted_37, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.dataIssuesDetected", { count: dataIssues.value.length })), 1),
|
|
4867
4967
|
(0, vue.createElementVNode)("button", {
|
|
4868
4968
|
type: "button",
|
|
4869
4969
|
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",
|
|
4870
4970
|
"data-testid": "collections-repair",
|
|
4871
4971
|
onClick: repairCollection
|
|
4872
|
-
}, [_cache[
|
|
4972
|
+
}, [_cache[40] || (_cache[40] = (0, vue.createElementVNode)("span", { class: "material-icons text-sm" }, "build", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.repair")), 1)])
|
|
4873
4973
|
])) : (0, vue.createCommentVNode)("", true),
|
|
4874
|
-
(0, vue.createElementVNode)("div",
|
|
4974
|
+
(0, vue.createElementVNode)("div", _hoisted_38, [loading.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_39, [_cache[42] || (_cache[42] = (0, vue.createElementVNode)("div", { class: "h-8 w-8 border-2 border-indigo-600/20 border-t-indigo-600 rounded-full animate-spin" }, null, -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)((0, vue.unref)(t)("common.loading")), 1)])) : loadError.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_40, [_cache[43] || (_cache[43] = (0, vue.createElementVNode)("span", { class: "material-icons text-red-600" }, "error", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)(loadError.value === "not-found" ? (0, vue.unref)(t)("collectionsView.notFound") : `${(0, vue.unref)(t)("collectionsView.loadFailed")}: ${loadError.value}`), 1)])) : !collection.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_41)) : calendarActive.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_42, [(0, vue.createVNode)(CollectionCalendarView_default, {
|
|
4875
4975
|
schema: collection.value.schema,
|
|
4876
4976
|
items: filteredItems.value,
|
|
4877
4977
|
"anchor-field": calendarAnchorField.value,
|
|
@@ -4907,7 +5007,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4907
5007
|
}, {
|
|
4908
5008
|
detail: (0, vue.withCtx)(() => [(0, vue.createVNode)(CollectionRecordPanel_default, {
|
|
4909
5009
|
editing: editing.value,
|
|
4910
|
-
"onUpdate:editing": _cache[
|
|
5010
|
+
"onUpdate:editing": _cache[10] || (_cache[10] = ($event) => editing.value = $event),
|
|
4911
5011
|
collection: collection.value,
|
|
4912
5012
|
viewing: viewing.value,
|
|
4913
5013
|
saving: saving.value,
|
|
@@ -4925,7 +5025,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4925
5025
|
onCancel: cancelEditor,
|
|
4926
5026
|
onEdit: editFromView,
|
|
4927
5027
|
onClose: onDayClose,
|
|
4928
|
-
onDelete: _cache[
|
|
5028
|
+
onDelete: _cache[11] || (_cache[11] = ($event) => viewing.value && confirmDelete(viewing.value)),
|
|
4929
5029
|
onRunAction: runAction,
|
|
4930
5030
|
onItemChat
|
|
4931
5031
|
}, null, 8, [
|
|
@@ -4956,16 +5056,16 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4956
5056
|
"selected",
|
|
4957
5057
|
"can-create",
|
|
4958
5058
|
"show-detail"
|
|
4959
|
-
])) : (0, vue.createCommentVNode)("", true)])) : kanbanActive.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div",
|
|
4960
|
-
_cache[
|
|
4961
|
-
(0, vue.createElementVNode)("span",
|
|
5059
|
+
])) : (0, vue.createCommentVNode)("", true)])) : kanbanActive.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_43, [inlineError.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_44, [
|
|
5060
|
+
_cache[45] || (_cache[45] = (0, vue.createElementVNode)("span", { class: "material-icons text-red-600" }, "error", -1)),
|
|
5061
|
+
(0, vue.createElementVNode)("span", _hoisted_45, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
|
|
4962
5062
|
(0, vue.createElementVNode)("button", {
|
|
4963
5063
|
type: "button",
|
|
4964
5064
|
class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
|
|
4965
5065
|
"aria-label": (0, vue.unref)(t)("common.close"),
|
|
4966
|
-
onClick: _cache[
|
|
4967
|
-
}, [..._cache[
|
|
4968
|
-
])) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("div",
|
|
5066
|
+
onClick: _cache[12] || (_cache[12] = ($event) => inlineError.value = null)
|
|
5067
|
+
}, [..._cache[44] || (_cache[44] = [(0, vue.createElementVNode)("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_46)
|
|
5068
|
+
])) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("div", _hoisted_47, [(0, vue.createVNode)(CollectionKanbanView_default, {
|
|
4969
5069
|
schema: collection.value.schema,
|
|
4970
5070
|
items: filteredItems.value,
|
|
4971
5071
|
"group-field": kanbanGroupField.value,
|
|
@@ -4979,7 +5079,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4979
5079
|
"group-field",
|
|
4980
5080
|
"selected",
|
|
4981
5081
|
"notified"
|
|
4982
|
-
])])])) : activeCustomView.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div",
|
|
5082
|
+
])])])) : activeCustomView.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_48, [activeCustomView.value.target === "mobile" ? ((0, vue.openBlock)(), (0, vue.createBlock)(CollectionRemoteViewPreview_default, {
|
|
4983
5083
|
key: 0,
|
|
4984
5084
|
slug: collection.value.slug,
|
|
4985
5085
|
view: activeCustomView.value,
|
|
@@ -4990,32 +5090,32 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
4990
5090
|
view: activeCustomView.value,
|
|
4991
5091
|
onOpenItem: onCustomViewOpenItem,
|
|
4992
5092
|
onStartChat: onCustomViewStartChat
|
|
4993
|
-
}, null, 8, ["slug", "view"]))])) : items.value.length === 0 && editing.value?.mode !== "create" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div",
|
|
4994
|
-
_cache[
|
|
4995
|
-
(0, vue.createElementVNode)("p",
|
|
5093
|
+
}, null, 8, ["slug", "view"]))])) : items.value.length === 0 && editing.value?.mode !== "create" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_49, [_cache[46] || (_cache[46] = (0, vue.createElementVNode)("span", { class: "material-icons text-4xl text-slate-300" }, "folder_open", -1)), (0, vue.createElementVNode)("p", _hoisted_50, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.itemsEmpty")), 1)])) : filteredItems.value.length === 0 && editing.value?.mode !== "create" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_51, [
|
|
5094
|
+
_cache[47] || (_cache[47] = (0, vue.createElementVNode)("span", { class: "material-icons text-4xl text-slate-300" }, "search_off", -1)),
|
|
5095
|
+
(0, vue.createElementVNode)("p", _hoisted_52, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.noMatchingItems")), 1),
|
|
4996
5096
|
(0, vue.createElementVNode)("button", {
|
|
4997
5097
|
type: "button",
|
|
4998
5098
|
class: "text-xs text-indigo-600 font-semibold hover:underline",
|
|
4999
|
-
onClick: _cache[
|
|
5099
|
+
onClick: _cache[13] || (_cache[13] = ($event) => searchQuery.value = "")
|
|
5000
5100
|
}, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.clearSearch")), 1)
|
|
5001
|
-
])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div",
|
|
5002
|
-
_cache[
|
|
5003
|
-
(0, vue.createElementVNode)("span",
|
|
5101
|
+
])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_53, [inlineError.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_54, [
|
|
5102
|
+
_cache[49] || (_cache[49] = (0, vue.createElementVNode)("span", { class: "material-icons text-red-600" }, "error", -1)),
|
|
5103
|
+
(0, vue.createElementVNode)("span", _hoisted_55, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
|
|
5004
5104
|
(0, vue.createElementVNode)("button", {
|
|
5005
5105
|
type: "button",
|
|
5006
5106
|
class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
|
|
5007
5107
|
"aria-label": (0, vue.unref)(t)("common.close"),
|
|
5008
|
-
onClick: _cache[
|
|
5009
|
-
}, [..._cache[
|
|
5010
|
-
])) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("table",
|
|
5108
|
+
onClick: _cache[14] || (_cache[14] = ($event) => inlineError.value = null)
|
|
5109
|
+
}, [..._cache[48] || (_cache[48] = [(0, vue.createElementVNode)("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_56)
|
|
5110
|
+
])) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("table", _hoisted_57, [(0, vue.createElementVNode)("thead", null, [(0, vue.createElementVNode)("tr", _hoisted_58, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(listColumnFields.value, ([key, field]) => {
|
|
5011
5111
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("th", {
|
|
5012
5112
|
key,
|
|
5013
5113
|
"aria-sort": (0, vue.unref)(_mulmoclaude_core_collection.isSortableField)(field) ? sortAriaValue(key) : void 0,
|
|
5014
5114
|
class: "px-5 py-3 font-bold text-slate-500 text-left uppercase tracking-wider whitespace-nowrap"
|
|
5015
|
-
}, [(0, vue.createElementVNode)("div",
|
|
5115
|
+
}, [(0, vue.createElementVNode)("div", _hoisted_60, [(0, vue.createElementVNode)("span", {
|
|
5016
5116
|
class: "truncate max-w-[14rem]",
|
|
5017
5117
|
title: field.label
|
|
5018
|
-
}, (0, vue.toDisplayString)(field.label), 9,
|
|
5118
|
+
}, (0, vue.toDisplayString)(field.label), 9, _hoisted_61), (0, vue.unref)(_mulmoclaude_core_collection.isSortableField)(field) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
5019
5119
|
key: 0,
|
|
5020
5120
|
type: "button",
|
|
5021
5121
|
class: (0, vue.normalizeClass)(["inline-flex items-center justify-center rounded p-0.5 -my-1 leading-none transition-colors", sortButtonClass(key)]),
|
|
@@ -5023,9 +5123,9 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
5023
5123
|
"aria-label": (0, vue.unref)(t)("collectionsView.sortBy", { field: field.label }),
|
|
5024
5124
|
onClick: (0, vue.withModifiers)(($event) => cycleSort(key), ["stop"]),
|
|
5025
5125
|
onPointerenter: ($event) => hoveredSortKey.value = key,
|
|
5026
|
-
onPointerleave: _cache[
|
|
5027
|
-
}, [(0, vue.createElementVNode)("span",
|
|
5028
|
-
}), 128))])]), (0, vue.createElementVNode)("tbody",
|
|
5126
|
+
onPointerleave: _cache[15] || (_cache[15] = ($event) => hoveredSortKey.value = null)
|
|
5127
|
+
}, [(0, vue.createElementVNode)("span", _hoisted_63, (0, vue.toDisplayString)(sortIconName(key)), 1)], 42, _hoisted_62)) : (0, vue.createCommentVNode)("", true)])], 8, _hoisted_59);
|
|
5128
|
+
}), 128))])]), (0, vue.createElementVNode)("tbody", _hoisted_64, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(sortedItems.value, (item) => {
|
|
5029
5129
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("tr", {
|
|
5030
5130
|
key: String(item[collection.value.schema.primaryKey] ?? ""),
|
|
5031
5131
|
class: (0, vue.normalizeClass)(["hover:bg-slate-50/70 cursor-pointer transition-colors focus:outline-none focus:bg-indigo-50/30", isRowOpen(item) || isEditingRow(item) ? "bg-indigo-50/40" : ""]),
|
|
@@ -5047,9 +5147,9 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
5047
5147
|
class: "h-5 w-5 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500/20 cursor-pointer align-middle disabled:opacity-50 disabled:cursor-not-allowed",
|
|
5048
5148
|
"data-testid": `collections-inline-toggle-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
5049
5149
|
"aria-label": field.label,
|
|
5050
|
-
onClick: _cache[
|
|
5150
|
+
onClick: _cache[16] || (_cache[16] = (0, vue.withModifiers)(() => {}, ["stop"])),
|
|
5051
5151
|
onChange: ($event) => commitToggle(item, field)
|
|
5052
|
-
}, null, 40,
|
|
5152
|
+
}, null, 40, _hoisted_66)) : field.type === "boolean" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("input", {
|
|
5053
5153
|
key: 1,
|
|
5054
5154
|
type: "checkbox",
|
|
5055
5155
|
checked: item[key] === true,
|
|
@@ -5057,9 +5157,9 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
5057
5157
|
class: "h-5 w-5 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500/20 cursor-pointer align-middle disabled:opacity-50 disabled:cursor-not-allowed",
|
|
5058
5158
|
"data-testid": `collections-inline-bool-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
5059
5159
|
"aria-label": field.label,
|
|
5060
|
-
onClick: _cache[
|
|
5160
|
+
onClick: _cache[17] || (_cache[17] = (0, vue.withModifiers)(() => {}, ["stop"])),
|
|
5061
5161
|
onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.checked)
|
|
5062
|
-
}, null, 40,
|
|
5162
|
+
}, null, 40, _hoisted_67)) : field.type === "ref" && field.to && typeof item[key] === "string" && item[key] ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_68, [(0, vue.createElementVNode)("a", {
|
|
5063
5163
|
href: (0, vue.unref)(cui).recordHref?.(field.to, String(item[key])),
|
|
5064
5164
|
tabindex: (0, vue.unref)(cui).recordHref?.(field.to, String(item[key])) ? void 0 : 0,
|
|
5065
5165
|
role: "link",
|
|
@@ -5067,44 +5167,44 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
5067
5167
|
"data-testid": `collections-ref-link-${key}-${item[key]}`,
|
|
5068
5168
|
onClick: ($event) => (0, vue.unref)(activateRefLink)($event, field.to, String(item[key]), true),
|
|
5069
5169
|
onKeydown: [(0, vue.withKeys)(($event) => (0, vue.unref)(activateRefLink)($event, field.to, String(item[key]), true), ["enter"]), (0, vue.withKeys)(($event) => (0, vue.unref)(activateRefLink)($event, field.to, String(item[key]), true), ["space"])]
|
|
5070
|
-
}, (0, vue.toDisplayString)((0, vue.unref)(refDisplay)(field.to, String(item[key]))), 41,
|
|
5170
|
+
}, (0, vue.toDisplayString)((0, vue.unref)(refDisplay)(field.to, String(item[key]))), 41, _hoisted_69)])) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("select", {
|
|
5071
5171
|
key: 3,
|
|
5072
5172
|
value: item[key] == null ? "" : String(item[key]),
|
|
5073
5173
|
disabled: isRowInlineSaving(item),
|
|
5074
5174
|
class: (0, vue.normalizeClass)(["rounded-lg border px-2 py-0.5 text-[11px] font-semibold focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed", enumControlClass(String(key), item[key])]),
|
|
5075
5175
|
"data-testid": `collections-inline-enum-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
5076
5176
|
"aria-label": field.label,
|
|
5077
|
-
onClick: _cache[
|
|
5177
|
+
onClick: _cache[18] || (_cache[18] = (0, vue.withModifiers)(() => {}, ["stop"])),
|
|
5078
5178
|
onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.value)
|
|
5079
|
-
}, [showEnumPlaceholder(item, String(key)) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("option",
|
|
5179
|
+
}, [showEnumPlaceholder(item, String(key)) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("option", _hoisted_71, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.selectPlaceholder")), 1)) : (0, vue.createCommentVNode)("", true), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(field.values, (value) => {
|
|
5080
5180
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("option", {
|
|
5081
5181
|
key: value,
|
|
5082
5182
|
value
|
|
5083
|
-
}, (0, vue.toDisplayString)(value), 9,
|
|
5084
|
-
}), 128))], 42,
|
|
5183
|
+
}, (0, vue.toDisplayString)(value), 9, _hoisted_72);
|
|
5184
|
+
}), 128))], 42, _hoisted_70)) : field.type === "money" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_73, (0, vue.toDisplayString)((0, vue.unref)(formatMoney)(item[key], (0, vue.unref)(resolveCurrency)(field, item), (0, vue.unref)(locale))), 1)) : field.type === "table" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_74, [_cache[50] || (_cache[50] = (0, vue.createElementVNode)("span", { class: "material-icons text-[11px]" }, "list", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)(tableSummary(item[key])), 1)])) : field.type === "derived" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_75, (0, vue.toDisplayString)((0, vue.unref)(derivedDisplay)(field, (0, vue.unref)(evaluateDerivedAgainstItem)(field, String(key), item), item)), 1)) : field.type !== "file" && (0, vue.unref)(isExternalUrl)(item[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
5085
5185
|
key: 7,
|
|
5086
5186
|
href: String(item[key]),
|
|
5087
5187
|
target: "_blank",
|
|
5088
5188
|
rel: "noopener noreferrer",
|
|
5089
5189
|
class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
|
|
5090
5190
|
"data-testid": `collections-url-link-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
5091
|
-
onClick: _cache[
|
|
5092
|
-
}, (0, vue.toDisplayString)(String(item[key])), 9,
|
|
5191
|
+
onClick: _cache[19] || (_cache[19] = (0, vue.withModifiers)(() => {}, ["stop"]))
|
|
5192
|
+
}, (0, vue.toDisplayString)(String(item[key])), 9, _hoisted_76)) : field.type === "file" && (0, vue.unref)(artifactUrl)(item[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
5093
5193
|
key: 8,
|
|
5094
5194
|
href: (0, vue.unref)(artifactUrl)(item[key]) ?? void 0,
|
|
5095
5195
|
target: "_blank",
|
|
5096
5196
|
rel: "noopener noreferrer",
|
|
5097
5197
|
class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
|
|
5098
5198
|
"data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
5099
|
-
onClick: _cache[
|
|
5100
|
-
}, (0, vue.toDisplayString)(String(item[key])), 9,
|
|
5199
|
+
onClick: _cache[20] || (_cache[20] = (0, vue.withModifiers)(() => {}, ["stop"]))
|
|
5200
|
+
}, (0, vue.toDisplayString)(String(item[key])), 9, _hoisted_77)) : field.type === "file" && (0, vue.unref)(fileRoutePath)(item[key]) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("a", {
|
|
5101
5201
|
key: 9,
|
|
5102
5202
|
href: (0, vue.unref)(fileRoutePath)(item[key]) ?? void 0,
|
|
5103
5203
|
class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
|
|
5104
5204
|
"data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
|
|
5105
5205
|
onClick: ($event) => (0, vue.unref)(activatePathLink)($event, (0, vue.unref)(fileRoutePath)(item[key]) ?? "", true)
|
|
5106
|
-
}, (0, vue.toDisplayString)(String(item[key])), 9,
|
|
5107
|
-
}), 128))], 42,
|
|
5206
|
+
}, (0, vue.toDisplayString)(String(item[key])), 9, _hoisted_78)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_79, (0, vue.toDisplayString)((0, vue.unref)(formatCell)(item[key], field.type)), 1))], 64)) : (0, vue.createCommentVNode)("", true)]);
|
|
5207
|
+
}), 128))], 42, _hoisted_65);
|
|
5108
5208
|
}), 128))])])]))]),
|
|
5109
5209
|
collection.value && (viewing.value || editing.value) && !(calendarActive.value && openDay.value) ? ((0, vue.openBlock)(), (0, vue.createBlock)(CollectionRecordModal_default, {
|
|
5110
5210
|
key: 4,
|
|
@@ -5112,7 +5212,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
5112
5212
|
}, {
|
|
5113
5213
|
default: (0, vue.withCtx)(() => [(0, vue.createVNode)(CollectionRecordPanel_default, {
|
|
5114
5214
|
editing: editing.value,
|
|
5115
|
-
"onUpdate:editing": _cache[
|
|
5215
|
+
"onUpdate:editing": _cache[21] || (_cache[21] = ($event) => editing.value = $event),
|
|
5116
5216
|
collection: collection.value,
|
|
5117
5217
|
viewing: viewing.value,
|
|
5118
5218
|
saving: saving.value,
|
|
@@ -5130,7 +5230,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
5130
5230
|
onCancel: cancelEditor,
|
|
5131
5231
|
onEdit: editFromView,
|
|
5132
5232
|
onClose: closeView,
|
|
5133
|
-
onDelete: _cache[
|
|
5233
|
+
onDelete: _cache[22] || (_cache[22] = ($event) => viewing.value && confirmDelete(viewing.value)),
|
|
5134
5234
|
onRunAction: runAction,
|
|
5135
5235
|
onItemChat
|
|
5136
5236
|
}, null, 8, [
|
|
@@ -5157,7 +5257,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
5157
5257
|
title: collection.value.title,
|
|
5158
5258
|
views: customViews.value,
|
|
5159
5259
|
onChanged: onViewsChanged,
|
|
5160
|
-
onClose: _cache[
|
|
5260
|
+
onClose: _cache[23] || (_cache[23] = ($event) => configOpen.value = false)
|
|
5161
5261
|
}, null, 8, [
|
|
5162
5262
|
"slug",
|
|
5163
5263
|
"title",
|
|
@@ -5172,29 +5272,29 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
5172
5272
|
"data-testid": "collections-chat-modal",
|
|
5173
5273
|
onClick: (0, vue.withModifiers)(closeChat, ["self"]),
|
|
5174
5274
|
onKeydown: (0, vue.withKeys)(closeChat, ["esc"])
|
|
5175
|
-
}, [(0, vue.createElementVNode)("div",
|
|
5176
|
-
(0, vue.createElementVNode)("header",
|
|
5177
|
-
_cache[
|
|
5178
|
-
(0, vue.createElementVNode)("div",
|
|
5275
|
+
}, [(0, vue.createElementVNode)("div", _hoisted_80, [
|
|
5276
|
+
(0, vue.createElementVNode)("header", _hoisted_81, [
|
|
5277
|
+
_cache[52] || (_cache[52] = (0, vue.createElementVNode)("div", { class: "h-9 w-9 flex items-center justify-center rounded-xl bg-indigo-50 text-indigo-600 border border-indigo-100/50" }, [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "forum")], -1)),
|
|
5278
|
+
(0, vue.createElementVNode)("div", _hoisted_82, [(0, vue.createElementVNode)("h2", _hoisted_83, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.chatTitle")), 1), (0, vue.createElementVNode)("span", _hoisted_84, (0, vue.toDisplayString)(collection.value.title), 1)]),
|
|
5179
5279
|
(0, vue.createElementVNode)("button", {
|
|
5180
5280
|
type: "button",
|
|
5181
5281
|
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",
|
|
5182
5282
|
"aria-label": (0, vue.unref)(t)("common.close"),
|
|
5183
5283
|
"data-testid": "collections-chat-close",
|
|
5184
5284
|
onClick: closeChat
|
|
5185
|
-
}, [..._cache[
|
|
5285
|
+
}, [..._cache[51] || (_cache[51] = [(0, vue.createElementVNode)("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_85)
|
|
5186
5286
|
]),
|
|
5187
|
-
(0, vue.createElementVNode)("div",
|
|
5287
|
+
(0, vue.createElementVNode)("div", _hoisted_86, [(0, vue.withDirectives)((0, vue.createElementVNode)("textarea", {
|
|
5188
5288
|
ref_key: "chatInputEl",
|
|
5189
5289
|
ref: chatInputEl,
|
|
5190
|
-
"onUpdate:modelValue": _cache[
|
|
5290
|
+
"onUpdate:modelValue": _cache[24] || (_cache[24] = ($event) => chatMessage.value = $event),
|
|
5191
5291
|
rows: "4",
|
|
5192
5292
|
placeholder: (0, vue.unref)(t)("collectionsView.chatPlaceholder"),
|
|
5193
5293
|
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",
|
|
5194
5294
|
"data-testid": "collections-chat-input",
|
|
5195
5295
|
onKeydown: [(0, vue.withKeys)((0, vue.withModifiers)(submitChat, ["meta"]), ["enter"]), (0, vue.withKeys)((0, vue.withModifiers)(submitChat, ["ctrl"]), ["enter"])]
|
|
5196
|
-
}, null, 40,
|
|
5197
|
-
(0, vue.createElementVNode)("footer",
|
|
5296
|
+
}, null, 40, _hoisted_87), [[vue.vModelText, chatMessage.value]])]),
|
|
5297
|
+
(0, vue.createElementVNode)("footer", _hoisted_88, [(0, vue.createElementVNode)("button", {
|
|
5198
5298
|
type: "button",
|
|
5199
5299
|
class: "h-8 px-2.5 rounded text-xs font-bold text-slate-500 hover:bg-slate-200/50 transition-colors",
|
|
5200
5300
|
"data-testid": "collections-chat-cancel",
|
|
@@ -5205,7 +5305,7 @@ var CollectionView_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
5205
5305
|
disabled: !chatMessage.value.trim(),
|
|
5206
5306
|
"data-testid": "collections-chat-send",
|
|
5207
5307
|
onClick: submitChat
|
|
5208
|
-
}, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.chatStart")), 9,
|
|
5308
|
+
}, (0, vue.toDisplayString)((0, vue.unref)(t)("collectionsView.chatStart")), 9, _hoisted_89)])
|
|
5209
5309
|
])], 32)) : (0, vue.createCommentVNode)("", true)
|
|
5210
5310
|
]);
|
|
5211
5311
|
};
|