@mulmoclaude/collection-plugin 0.11.3 → 0.12.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/vue.js CHANGED
@@ -68,6 +68,13 @@ var i18n = createI18n({
68
68
  deleteCollection: "Delete collection",
69
69
  confirmDeleteCollection: "Delete the entire \"{title}\" collection, including all its records? A restorable backup is archived first.",
70
70
  itemsEmpty: "No items yet. Click + to add one.",
71
+ readonlyChip: "Read-only",
72
+ itemsEmptyReadonly: "No rows in the data file yet. Add rows to the file and they appear here.",
73
+ filter: {
74
+ all: "All",
75
+ editable: "Editable",
76
+ data: "Data"
77
+ },
71
78
  notFound: "Collection not found",
72
79
  loadFailed: "Failed to load",
73
80
  requiredField: "This field is required",
@@ -204,6 +211,13 @@ var i18n = createI18n({
204
211
  deleteCollection: "コレクションを削除",
205
212
  confirmDeleteCollection: "コレクション「{title}」とそのすべてのレコードを削除しますか?削除前に復元可能なバックアップが保存されます。",
206
213
  itemsEmpty: "まだ項目がありません。+ を押して追加してください。",
214
+ readonlyChip: "読み取り専用",
215
+ itemsEmptyReadonly: "データファイルにまだ行がありません。ファイルに行を追加するとここに表示されます。",
216
+ filter: {
217
+ all: "すべて",
218
+ editable: "編集可能",
219
+ data: "データ"
220
+ },
207
221
  notFound: "コレクションが見つかりません",
208
222
  loadFailed: "読み込みに失敗しました",
209
223
  requiredField: "この項目は必須です",
@@ -340,6 +354,13 @@ var i18n = createI18n({
340
354
  deleteCollection: "删除集合",
341
355
  confirmDeleteCollection: "删除整个“{title}”集合及其所有记录?删除前会先归档一份可恢复的备份。",
342
356
  itemsEmpty: "暂无项目。点击 + 添加一个。",
357
+ readonlyChip: "只读",
358
+ itemsEmptyReadonly: "数据文件中还没有行。在文件中添加行后会显示在这里。",
359
+ filter: {
360
+ all: "全部",
361
+ editable: "可编辑",
362
+ data: "数据"
363
+ },
343
364
  notFound: "未找到集合",
344
365
  loadFailed: "加载失败",
345
366
  requiredField: "此字段为必填项",
@@ -476,6 +497,13 @@ var i18n = createI18n({
476
497
  deleteCollection: "컬렉션 삭제",
477
498
  confirmDeleteCollection: "\"{title}\" 컬렉션과 모든 레코드를 삭제하시겠습니까? 삭제 전에 복원 가능한 백업이 보관됩니다.",
478
499
  itemsEmpty: "아직 항목이 없습니다. + 를 눌러 추가하세요.",
500
+ readonlyChip: "읽기 전용",
501
+ itemsEmptyReadonly: "데이터 파일에 아직 행이 없습니다. 파일에 행을 추가하면 여기에 표시됩니다.",
502
+ filter: {
503
+ all: "전체",
504
+ editable: "편집 가능",
505
+ data: "데이터"
506
+ },
479
507
  notFound: "컬렉션을 찾을 수 없습니다",
480
508
  loadFailed: "불러오기에 실패했습니다",
481
509
  requiredField: "이 필드는 필수입니다",
@@ -612,6 +640,13 @@ var i18n = createI18n({
612
640
  deleteCollection: "Eliminar colección",
613
641
  confirmDeleteCollection: "¿Eliminar toda la colección \"{title}\", incluidos todos sus registros? Antes se archiva una copia de seguridad restaurable.",
614
642
  itemsEmpty: "Aún no hay elementos. Pulsa + para añadir uno.",
643
+ readonlyChip: "Solo lectura",
644
+ itemsEmptyReadonly: "El archivo de datos aún no tiene filas. Añádelas al archivo y aparecerán aquí.",
645
+ filter: {
646
+ all: "Todas",
647
+ editable: "Editables",
648
+ data: "Datos"
649
+ },
615
650
  notFound: "Colección no encontrada",
616
651
  loadFailed: "Error al cargar",
617
652
  requiredField: "Este campo es obligatorio",
@@ -748,6 +783,13 @@ var i18n = createI18n({
748
783
  deleteCollection: "Excluir coleção",
749
784
  confirmDeleteCollection: "Excluir toda a coleção \"{title}\", incluindo todos os seus registros? Um backup restaurável é arquivado antes.",
750
785
  itemsEmpty: "Ainda não há itens. Clique em + para adicionar um.",
786
+ readonlyChip: "Somente leitura",
787
+ itemsEmptyReadonly: "O arquivo de dados ainda não tem linhas. Adicione linhas ao arquivo e elas aparecerão aqui.",
788
+ filter: {
789
+ all: "Todas",
790
+ editable: "Editáveis",
791
+ data: "Dados"
792
+ },
751
793
  notFound: "Coleção não encontrada",
752
794
  loadFailed: "Falha ao carregar",
753
795
  requiredField: "Este campo é obrigatório",
@@ -884,6 +926,13 @@ var i18n = createI18n({
884
926
  deleteCollection: "Supprimer la collection",
885
927
  confirmDeleteCollection: "Supprimer toute la collection « {title} », y compris tous ses enregistrements ? Une sauvegarde restaurable est archivée au préalable.",
886
928
  itemsEmpty: "Aucun élément pour l'instant. Cliquez sur + pour en ajouter un.",
929
+ readonlyChip: "Lecture seule",
930
+ itemsEmptyReadonly: "Le fichier de données ne contient pas encore de lignes. Ajoutez-en au fichier et elles apparaîtront ici.",
931
+ filter: {
932
+ all: "Toutes",
933
+ editable: "Modifiables",
934
+ data: "Données"
935
+ },
887
936
  notFound: "Collection introuvable",
888
937
  loadFailed: "Échec du chargement",
889
938
  requiredField: "Ce champ est obligatoire",
@@ -1020,6 +1069,13 @@ var i18n = createI18n({
1020
1069
  deleteCollection: "Sammlung löschen",
1021
1070
  confirmDeleteCollection: "Die gesamte Sammlung „{title}“ einschließlich aller Datensätze löschen? Zuvor wird eine wiederherstellbare Sicherung archiviert.",
1022
1071
  itemsEmpty: "Noch keine Einträge. Klicke auf +, um einen hinzuzufügen.",
1072
+ readonlyChip: "Schreibgeschützt",
1073
+ itemsEmptyReadonly: "Noch keine Zeilen in der Datendatei. Füge der Datei Zeilen hinzu, dann erscheinen sie hier.",
1074
+ filter: {
1075
+ all: "Alle",
1076
+ editable: "Bearbeitbar",
1077
+ data: "Daten"
1078
+ },
1023
1079
  notFound: "Sammlung nicht gefunden",
1024
1080
  loadFailed: "Laden fehlgeschlagen",
1025
1081
  requiredField: "Dieses Feld ist erforderlich",
@@ -2043,7 +2099,8 @@ var CollectionKanbanView_default = /* @__PURE__ */ defineComponent({
2043
2099
  groupField: {},
2044
2100
  items: {},
2045
2101
  selected: {},
2046
- notified: {}
2102
+ notified: {},
2103
+ readonly: { type: Boolean }
2047
2104
  },
2048
2105
  emits: ["select", "move"],
2049
2106
  setup(__props, { emit: __emit }) {
@@ -2150,6 +2207,7 @@ var CollectionKanbanView_default = /* @__PURE__ */ defineComponent({
2150
2207
  group: "collection-kanban-cards",
2151
2208
  class: "flex-1 overflow-y-auto p-2 space-y-2 min-h-[2rem]",
2152
2209
  animation: 150,
2210
+ disabled: __props.readonly,
2153
2211
  onChange: (e) => onDragChange(column.value, e)
2154
2212
  }, {
2155
2213
  item: withCtx(({ element }) => [createElementVNode("div", {
@@ -2160,7 +2218,7 @@ var CollectionKanbanView_default = /* @__PURE__ */ defineComponent({
2160
2218
  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)]]),
2161
2219
  onClick: ($event) => emit("select", itemId(element)),
2162
2220
  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"])]
2163
- }, [createElementVNode("div", _hoisted_9$8, [cardToggle.value ? (openBlock(), createElementBlock("input", {
2221
+ }, [createElementVNode("div", _hoisted_9$8, [cardToggle.value && !__props.readonly ? (openBlock(), createElementBlock("input", {
2164
2222
  key: 0,
2165
2223
  type: "checkbox",
2166
2224
  checked: cardChecked(element),
@@ -2174,6 +2232,7 @@ var CollectionKanbanView_default = /* @__PURE__ */ defineComponent({
2174
2232
  }, 8, [
2175
2233
  "model-value",
2176
2234
  "item-key",
2235
+ "disabled",
2177
2236
  "onChange"
2178
2237
  ])], 8, _hoisted_3$12);
2179
2238
  }), 128))])]);
@@ -2400,23 +2459,23 @@ var _hoisted_18$5 = [
2400
2459
  "placeholder",
2401
2460
  "data-testid"
2402
2461
  ];
2403
- var _hoisted_19$3 = {
2462
+ var _hoisted_19$4 = {
2404
2463
  key: 0,
2405
2464
  class: "inline-flex items-center gap-2.5 text-sm text-slate-700 cursor-pointer select-none"
2406
2465
  };
2407
- var _hoisted_20$3 = [
2466
+ var _hoisted_20$4 = [
2408
2467
  "id",
2409
2468
  "onUpdate:modelValue",
2410
2469
  "data-testid",
2411
2470
  "onChange"
2412
2471
  ];
2413
- var _hoisted_21$3 = [
2472
+ var _hoisted_21$4 = [
2414
2473
  "id",
2415
2474
  "onUpdate:modelValue",
2416
2475
  "required",
2417
2476
  "data-testid"
2418
2477
  ];
2419
- var _hoisted_22$3 = { value: "" };
2478
+ var _hoisted_22$4 = { value: "" };
2420
2479
  var _hoisted_23$3 = ["value"];
2421
2480
  var _hoisted_24$2 = [
2422
2481
  "id",
@@ -2600,6 +2659,7 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
2600
2659
  liveDerived: {},
2601
2660
  viewTitle: {},
2602
2661
  isSingleton: { type: Boolean },
2662
+ readonly: { type: Boolean },
2603
2663
  render: {},
2604
2664
  locale: {}
2605
2665
  }, {
@@ -2753,18 +2813,20 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
2753
2813
  onClick: ($event) => emit("runAction", action)
2754
2814
  }, [__props.runningActionIds.includes(action.id) ? (openBlock(), createElementBlock("span", _hoisted_8$6, "progress_activity")) : action.icon ? (openBlock(), createElementBlock("span", _hoisted_9$6, toDisplayString(action.icon), 1)) : createCommentVNode("", true), createElementVNode("span", null, toDisplayString(action.label), 1)], 8, _hoisted_7$6);
2755
2815
  }), 128)),
2756
- createElementVNode("button", {
2816
+ !__props.readonly ? (openBlock(), createElementBlock("button", {
2817
+ key: 0,
2757
2818
  type: "button",
2758
2819
  class: "h-8 px-2.5 rounded border border-slate-200 bg-white text-slate-700 hover:bg-slate-50 font-bold text-xs transition-all flex items-center gap-1",
2759
2820
  "data-testid": "collections-detail-edit",
2760
2821
  onClick: _cache[1] || (_cache[1] = ($event) => emit("edit"))
2761
- }, [_cache[6] || (_cache[6] = createElementVNode("span", { class: "material-icons text-sm" }, "edit", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.editItem")), 1)]),
2762
- createElementVNode("button", {
2822
+ }, [_cache[6] || (_cache[6] = createElementVNode("span", { class: "material-icons text-sm" }, "edit", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.editItem")), 1)])) : createCommentVNode("", true),
2823
+ !__props.readonly ? (openBlock(), createElementBlock("button", {
2824
+ key: 1,
2763
2825
  type: "button",
2764
2826
  class: "h-8 px-2.5 rounded border border-rose-200 bg-white text-rose-600 hover:bg-rose-50 font-bold text-xs transition-all flex items-center gap-1",
2765
2827
  "data-testid": "collections-detail-remove",
2766
2828
  onClick: _cache[2] || (_cache[2] = ($event) => emit("delete"))
2767
- }, [_cache[7] || (_cache[7] = createElementVNode("span", { class: "material-icons text-sm" }, "delete", -1)), createElementVNode("span", null, toDisplayString(unref(t)("common.remove")), 1)]),
2829
+ }, [_cache[7] || (_cache[7] = createElementVNode("span", { class: "material-icons text-sm" }, "delete", -1)), createElementVNode("span", null, toDisplayString(unref(t)("common.remove")), 1)])) : createCommentVNode("", true),
2768
2830
  createElementVNode("button", {
2769
2831
  type: "button",
2770
2832
  class: "h-8 w-8 flex items-center justify-center rounded text-slate-400 hover:bg-slate-100 hover:text-slate-600 transition-colors",
@@ -2802,26 +2864,26 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
2802
2864
  placeholder: unref(t)("collectionsView.selectPlaceholder"),
2803
2865
  class: "w-full rounded-xl border border-slate-200 px-3 py-2 text-xs focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none font-medium text-slate-700 transition-all",
2804
2866
  "data-testid": `collections-input-${key}`
2805
- }, null, 8, _hoisted_18$5)), [[vModelText, editing.value.text[field.idField]]]) : editing.value && isEditableType(field.type) ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [field.type === "boolean" ? (openBlock(), createElementBlock("label", _hoisted_19$3, [withDirectives(createElementVNode("input", {
2867
+ }, null, 8, _hoisted_18$5)), [[vModelText, editing.value.text[field.idField]]]) : editing.value && isEditableType(field.type) ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [field.type === "boolean" ? (openBlock(), createElementBlock("label", _hoisted_19$4, [withDirectives(createElementVNode("input", {
2806
2868
  id: `collections-field-${key}`,
2807
2869
  "onUpdate:modelValue": ($event) => editing.value.bool[key] = $event,
2808
2870
  type: "checkbox",
2809
2871
  class: "h-5 w-5 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500/20 cursor-pointer",
2810
2872
  "data-testid": `collections-input-${key}`,
2811
2873
  onChange: ($event) => markBoolTouched(String(key))
2812
- }, null, 40, _hoisted_20$3), [[vModelCheckbox, editing.value.bool[key]]]), createElementVNode("span", { class: normalizeClass(["text-xs font-semibold", editing.value.bool[key] ? "text-indigo-600" : "text-slate-500"]) }, toDisplayString(editing.value.bool[key] ? unref(t)("common.yes") : unref(t)("common.no")), 3)])) : field.type === "ref" && field.to && __props.render.refOptions(field.to).length > 0 ? withDirectives((openBlock(), createElementBlock("select", {
2874
+ }, null, 40, _hoisted_20$4), [[vModelCheckbox, editing.value.bool[key]]]), createElementVNode("span", { class: normalizeClass(["text-xs font-semibold", editing.value.bool[key] ? "text-indigo-600" : "text-slate-500"]) }, toDisplayString(editing.value.bool[key] ? unref(t)("common.yes") : unref(t)("common.no")), 3)])) : field.type === "ref" && field.to && __props.render.refOptions(field.to).length > 0 ? withDirectives((openBlock(), createElementBlock("select", {
2813
2875
  key: 1,
2814
2876
  id: `collections-field-${key}`,
2815
2877
  "onUpdate:modelValue": ($event) => editing.value.text[key] = $event,
2816
2878
  required: isFieldRequiredInUi(field),
2817
2879
  class: "w-full rounded-xl border border-slate-200 px-3 py-2 text-xs bg-slate-50 hover:bg-slate-50/50 focus:bg-white focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none transition-all cursor-pointer font-medium text-slate-700",
2818
2880
  "data-testid": `collections-input-${key}`
2819
- }, [createElementVNode("option", _hoisted_22$3, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.render.refOptions(field.to), (opt) => {
2881
+ }, [createElementVNode("option", _hoisted_22$4, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.render.refOptions(field.to), (opt) => {
2820
2882
  return openBlock(), createElementBlock("option", {
2821
2883
  key: opt.slug,
2822
2884
  value: opt.slug
2823
2885
  }, toDisplayString(opt.display), 9, _hoisted_23$3);
2824
- }), 128))], 8, _hoisted_21$3)), [[vModelSelect, editing.value.text[key]]]) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? withDirectives((openBlock(), createElementBlock("select", {
2886
+ }), 128))], 8, _hoisted_21$4)), [[vModelSelect, editing.value.text[key]]]) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? withDirectives((openBlock(), createElementBlock("select", {
2825
2887
  key: 2,
2826
2888
  id: `collections-field-${key}`,
2827
2889
  "onUpdate:modelValue": ($event) => editing.value.text[key] = $event,
@@ -3834,222 +3896,227 @@ var _hoisted_6$4 = { class: "flex-1 min-w-0" };
3834
3896
  var _hoisted_7$4 = { class: "text-base font-bold text-slate-800 truncate" };
3835
3897
  var _hoisted_8$4 = {
3836
3898
  key: 0,
3837
- class: "block text-[10px] text-slate-400 font-bold uppercase tracking-wider"
3899
+ class: "block text-[10px] text-slate-400 font-bold uppercase tracking-wider truncate"
3838
3900
  };
3839
- var _hoisted_9$4 = ["disabled"];
3840
- var _hoisted_10$4 = { class: "material-icons text-sm" };
3841
- var _hoisted_11$4 = [
3901
+ var _hoisted_9$4 = {
3902
+ class: "inline-flex items-center gap-0.5 ml-1.5 px-1.5 py-px rounded bg-amber-50 text-amber-700 border border-amber-200 normal-case tracking-normal",
3903
+ "data-testid": "collections-readonly-chip"
3904
+ };
3905
+ var _hoisted_10$4 = ["href"];
3906
+ var _hoisted_11$4 = ["disabled"];
3907
+ var _hoisted_12$4 = { class: "material-icons text-sm" };
3908
+ var _hoisted_13$4 = [
3842
3909
  "disabled",
3843
3910
  "data-testid",
3844
3911
  "onClick"
3845
3912
  ];
3846
- var _hoisted_12$4 = {
3913
+ var _hoisted_14$4 = {
3847
3914
  key: 0,
3848
3915
  class: "material-icons text-sm animate-spin"
3849
3916
  };
3850
- var _hoisted_13$4 = {
3917
+ var _hoisted_15$4 = {
3851
3918
  key: 1,
3852
3919
  class: "material-icons text-sm"
3853
3920
  };
3854
- var _hoisted_14$4 = ["title", "aria-label"];
3855
- var _hoisted_15$4 = ["title", "aria-label"];
3856
- var _hoisted_16$4 = {
3921
+ var _hoisted_16$4 = ["title", "aria-label"];
3922
+ var _hoisted_17$4 = ["title", "aria-label"];
3923
+ var _hoisted_18$4 = {
3857
3924
  key: 1,
3858
3925
  class: "mx-6 mt-2 rounded-lg border border-indigo-200 bg-indigo-50/60 px-4 py-2 text-sm text-indigo-800 flex items-center gap-2",
3859
3926
  "data-testid": "collections-refresh-note"
3860
3927
  };
3861
- var _hoisted_17$4 = { class: "flex-1" };
3862
- var _hoisted_18$4 = {
3928
+ var _hoisted_19$3 = { class: "flex-1" };
3929
+ var _hoisted_20$3 = {
3863
3930
  key: 2,
3864
3931
  class: "px-6 py-3 bg-white border-b border-slate-100 flex items-center justify-between gap-4"
3865
3932
  };
3866
- var _hoisted_19$2 = {
3933
+ var _hoisted_21$3 = {
3867
3934
  key: 0,
3868
3935
  class: "relative flex-1 max-w-md"
3869
3936
  };
3870
- var _hoisted_20$2 = ["placeholder", "aria-label"];
3871
- var _hoisted_21$2 = ["aria-label"];
3872
- var _hoisted_22$2 = { class: "flex items-center gap-2" };
3937
+ var _hoisted_22$3 = ["placeholder", "aria-label"];
3873
3938
  var _hoisted_23$2 = ["aria-label"];
3874
- var _hoisted_24$1 = ["aria-pressed"];
3875
- var _hoisted_25$1 = ["aria-pressed"];
3939
+ var _hoisted_24$1 = { class: "flex items-center gap-2" };
3940
+ var _hoisted_25$1 = ["aria-label"];
3876
3941
  var _hoisted_26$1 = ["aria-pressed"];
3877
- var _hoisted_27$1 = [
3942
+ var _hoisted_27$1 = ["aria-pressed"];
3943
+ var _hoisted_28 = ["aria-pressed"];
3944
+ var _hoisted_29 = [
3878
3945
  "aria-pressed",
3879
3946
  "data-testid",
3880
3947
  "onClick"
3881
3948
  ];
3882
- var _hoisted_28 = { class: "material-icons text-sm" };
3883
- var _hoisted_29 = [
3949
+ var _hoisted_30 = { class: "material-icons text-sm" };
3950
+ var _hoisted_31 = [
3884
3951
  "title",
3885
3952
  "aria-label",
3886
3953
  "aria-expanded"
3887
3954
  ];
3888
- var _hoisted_30 = {
3955
+ var _hoisted_32 = {
3889
3956
  key: 0,
3890
3957
  class: "absolute left-0 top-full mt-1 z-20 min-w-max rounded border border-slate-200 bg-white shadow-lg py-1",
3891
3958
  "data-testid": "collection-view-add-menu"
3892
3959
  };
3893
- var _hoisted_31 = ["title", "aria-label"];
3894
- var _hoisted_32 = ["value", "aria-label"];
3895
- var _hoisted_33 = ["value"];
3960
+ var _hoisted_33 = ["title", "aria-label"];
3896
3961
  var _hoisted_34 = ["value", "aria-label"];
3897
3962
  var _hoisted_35 = ["value"];
3898
- var _hoisted_36 = {
3963
+ var _hoisted_36 = ["value", "aria-label"];
3964
+ var _hoisted_37 = ["value"];
3965
+ var _hoisted_38 = {
3899
3966
  key: 3,
3900
3967
  class: "text-[10px] text-slate-400 font-bold uppercase tracking-wider select-none"
3901
3968
  };
3902
- var _hoisted_37 = {
3969
+ var _hoisted_39 = {
3903
3970
  key: 3,
3904
3971
  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",
3905
3972
  "data-testid": "collections-data-issues"
3906
3973
  };
3907
- var _hoisted_38 = { class: "flex-1" };
3908
- var _hoisted_39 = { class: "flex-1 overflow-auto" };
3909
- var _hoisted_40 = {
3974
+ var _hoisted_40 = { class: "flex-1" };
3975
+ var _hoisted_41 = { class: "flex-1 overflow-auto" };
3976
+ var _hoisted_42 = {
3910
3977
  key: 0,
3911
3978
  class: "flex flex-col items-center justify-center py-20 text-sm text-slate-500 gap-3"
3912
3979
  };
3913
- var _hoisted_41 = {
3980
+ var _hoisted_43 = {
3914
3981
  key: 1,
3915
3982
  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"
3916
3983
  };
3917
- var _hoisted_42 = { key: 2 };
3918
- var _hoisted_43 = {
3984
+ var _hoisted_44 = { key: 2 };
3985
+ var _hoisted_45 = {
3919
3986
  key: 3,
3920
3987
  class: "p-4"
3921
3988
  };
3922
- var _hoisted_44 = {
3989
+ var _hoisted_46 = {
3923
3990
  key: 4,
3924
3991
  class: "h-full flex flex-col"
3925
3992
  };
3926
- var _hoisted_45 = {
3993
+ var _hoisted_47 = {
3927
3994
  key: 0,
3928
3995
  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",
3929
3996
  "data-testid": "collections-inline-error"
3930
3997
  };
3931
- var _hoisted_46 = { class: "flex-1" };
3932
- var _hoisted_47 = ["aria-label"];
3933
- var _hoisted_48 = { class: "flex-1 min-h-0 px-3 py-2" };
3934
- var _hoisted_49 = {
3998
+ var _hoisted_48 = { class: "flex-1" };
3999
+ var _hoisted_49 = ["aria-label"];
4000
+ var _hoisted_50 = { class: "flex-1 min-h-0 px-3 py-2" };
4001
+ var _hoisted_51 = {
3935
4002
  key: 5,
3936
4003
  class: "h-full",
3937
4004
  "data-testid": "collection-custom-view-body"
3938
4005
  };
3939
- var _hoisted_50 = {
4006
+ var _hoisted_52 = {
3940
4007
  key: 6,
3941
4008
  class: "flex flex-col items-center justify-center py-20 text-sm text-slate-400 gap-2"
3942
4009
  };
3943
- var _hoisted_51 = { class: "font-semibold text-slate-600" };
3944
- var _hoisted_52 = {
4010
+ var _hoisted_53 = { class: "font-semibold text-slate-600" };
4011
+ var _hoisted_54 = {
3945
4012
  key: 7,
3946
4013
  class: "flex flex-col items-center justify-center py-20 text-sm text-slate-400 gap-2"
3947
4014
  };
3948
- var _hoisted_53 = { class: "font-semibold text-slate-600" };
3949
- var _hoisted_54 = {
4015
+ var _hoisted_55 = { class: "font-semibold text-slate-600" };
4016
+ var _hoisted_56 = {
3950
4017
  key: 8,
3951
4018
  class: "overflow-x-auto [container-type:inline-size]"
3952
4019
  };
3953
- var _hoisted_55 = {
4020
+ var _hoisted_57 = {
3954
4021
  key: 0,
3955
4022
  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",
3956
4023
  "data-testid": "collections-inline-error"
3957
4024
  };
3958
- var _hoisted_56 = { class: "flex-1" };
3959
- var _hoisted_57 = ["aria-label"];
3960
- var _hoisted_58 = { class: "min-w-full text-xs" };
3961
- var _hoisted_59 = { class: "bg-slate-50 border-b border-slate-200" };
3962
- var _hoisted_60 = ["aria-sort"];
3963
- var _hoisted_61 = { class: "flex items-center gap-1" };
3964
- var _hoisted_62 = ["title"];
3965
- var _hoisted_63 = [
4025
+ var _hoisted_58 = { class: "flex-1" };
4026
+ var _hoisted_59 = ["aria-label"];
4027
+ var _hoisted_60 = { class: "min-w-full text-xs" };
4028
+ var _hoisted_61 = { class: "bg-slate-50 border-b border-slate-200" };
4029
+ var _hoisted_62 = ["aria-sort"];
4030
+ var _hoisted_63 = { class: "flex items-center gap-1" };
4031
+ var _hoisted_64 = ["title"];
4032
+ var _hoisted_65 = [
3966
4033
  "data-testid",
3967
4034
  "aria-label",
3968
4035
  "onClick",
3969
4036
  "onPointerenter"
3970
4037
  ];
3971
- var _hoisted_64 = { class: "material-icons text-base align-middle" };
3972
- var _hoisted_65 = { class: "divide-y divide-slate-100 bg-white" };
3973
- var _hoisted_66 = [
4038
+ var _hoisted_66 = { class: "material-icons text-base align-middle" };
4039
+ var _hoisted_67 = { class: "divide-y divide-slate-100 bg-white" };
4040
+ var _hoisted_68 = [
3974
4041
  "aria-label",
3975
4042
  "data-testid",
3976
4043
  "onClick",
3977
4044
  "onKeydown"
3978
4045
  ];
3979
- var _hoisted_67 = [
4046
+ var _hoisted_69 = [
3980
4047
  "checked",
3981
4048
  "disabled",
3982
4049
  "data-testid",
3983
4050
  "aria-label",
3984
4051
  "onChange"
3985
4052
  ];
3986
- var _hoisted_68 = [
4053
+ var _hoisted_70 = [
3987
4054
  "checked",
3988
4055
  "disabled",
3989
4056
  "data-testid",
3990
4057
  "aria-label",
3991
4058
  "onChange"
3992
4059
  ];
3993
- var _hoisted_69 = {
4060
+ var _hoisted_71 = {
3994
4061
  key: 2,
3995
4062
  class: "block truncate"
3996
4063
  };
3997
- var _hoisted_70 = [
4064
+ var _hoisted_72 = [
3998
4065
  "href",
3999
4066
  "tabindex",
4000
4067
  "data-testid",
4001
4068
  "onClick",
4002
4069
  "onKeydown"
4003
4070
  ];
4004
- var _hoisted_71 = [
4071
+ var _hoisted_73 = [
4005
4072
  "value",
4006
4073
  "disabled",
4007
4074
  "data-testid",
4008
4075
  "aria-label",
4009
4076
  "onChange"
4010
4077
  ];
4011
- var _hoisted_72 = {
4078
+ var _hoisted_74 = {
4012
4079
  key: 0,
4013
4080
  value: ""
4014
4081
  };
4015
- var _hoisted_73 = ["value"];
4016
- var _hoisted_74 = {
4082
+ var _hoisted_75 = ["value"];
4083
+ var _hoisted_76 = {
4017
4084
  key: 4,
4018
4085
  class: "block truncate tabular-nums font-semibold text-slate-900"
4019
4086
  };
4020
- var _hoisted_75 = {
4087
+ var _hoisted_77 = {
4021
4088
  key: 5,
4022
4089
  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"
4023
4090
  };
4024
- var _hoisted_76 = {
4091
+ var _hoisted_78 = {
4025
4092
  key: 6,
4026
4093
  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"
4027
4094
  };
4028
- var _hoisted_77 = ["data-testid"];
4029
- var _hoisted_78 = ["href", "data-testid"];
4030
- var _hoisted_79 = ["href", "data-testid"];
4031
- var _hoisted_80 = [
4095
+ var _hoisted_79 = ["data-testid"];
4096
+ var _hoisted_80 = ["href", "data-testid"];
4097
+ var _hoisted_81 = ["href", "data-testid"];
4098
+ var _hoisted_82 = [
4032
4099
  "href",
4033
4100
  "data-testid",
4034
4101
  "onClick"
4035
4102
  ];
4036
- var _hoisted_81 = {
4103
+ var _hoisted_83 = {
4037
4104
  key: 11,
4038
4105
  class: "block truncate text-slate-600"
4039
4106
  };
4040
- var _hoisted_82 = { class: "bg-white rounded-2xl shadow-2xl w-full max-w-xl flex flex-col border border-slate-200 overflow-hidden" };
4041
- var _hoisted_83 = { class: "px-6 py-4 border-b border-slate-100 flex items-center gap-3 bg-slate-50/50" };
4042
- var _hoisted_84 = { class: "flex-1" };
4043
- var _hoisted_85 = {
4107
+ var _hoisted_84 = { class: "bg-white rounded-2xl shadow-2xl w-full max-w-xl flex flex-col border border-slate-200 overflow-hidden" };
4108
+ var _hoisted_85 = { class: "px-6 py-4 border-b border-slate-100 flex items-center gap-3 bg-slate-50/50" };
4109
+ var _hoisted_86 = { class: "flex-1" };
4110
+ var _hoisted_87 = {
4044
4111
  id: "collections-chat-title",
4045
4112
  class: "text-sm font-bold text-slate-800 uppercase tracking-wide"
4046
4113
  };
4047
- var _hoisted_86 = { class: "text-xs text-slate-400 font-semibold" };
4048
- var _hoisted_87 = ["aria-label"];
4049
- var _hoisted_88 = { class: "px-6 py-5" };
4050
- var _hoisted_89 = ["placeholder", "onKeydown"];
4051
- var _hoisted_90 = { class: "px-6 py-3.5 border-t border-slate-100 flex items-center justify-end gap-2 bg-slate-50/50" };
4052
- var _hoisted_91 = ["disabled"];
4114
+ var _hoisted_88 = { class: "text-xs text-slate-400 font-semibold" };
4115
+ var _hoisted_89 = ["aria-label"];
4116
+ var _hoisted_90 = { class: "px-6 py-5" };
4117
+ var _hoisted_91 = ["placeholder", "onKeydown"];
4118
+ var _hoisted_92 = { class: "px-6 py-3.5 border-t border-slate-100 flex items-center justify-end gap-2 bg-slate-50/50" };
4119
+ var _hoisted_93 = ["disabled"];
4053
4120
  /** `slug` / `selected` are supplied only in EMBEDDED mode (the
4054
4121
  * `presentCollection` chat card mounts this component and drives both
4055
4122
  * from the tool result). In standalone route mode (the
@@ -4603,10 +4670,22 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
4603
4670
  /** True when the current collection declares `schema.singleton` —
4604
4671
  * exactly one record, its primary key fixed to the declared value. */
4605
4672
  const isSingleton = computed(() => Boolean(collection.value?.schema.singleton));
4673
+ /** True when the collection is backed by an external `dataSource` (CSV) —
4674
+ * read-only in every write surface here; the server enforces the same
4675
+ * rule with 405s, this just keeps dead controls off the screen. */
4676
+ const isReadOnly = computed(() => collection.value?.schema.dataSource !== void 0);
4677
+ /** File-explorer route for the dataSource file (the one editable thing
4678
+ * about a read-only collection), or null on a router-less host. */
4679
+ const dataSourceRoute = computed(() => {
4680
+ const sourcePath = collection.value?.schema.dataSource?.path;
4681
+ return sourcePath ? fileRoutePath(sourcePath) : null;
4682
+ });
4606
4683
  /** Whether the Add button should show. Always for a normal collection;
4607
- * for a singleton only until its one record exists. */
4684
+ * for a singleton only until its one record exists; never for a
4685
+ * read-only (dataSource) collection. */
4608
4686
  const canCreate = computed(() => {
4609
4687
  if (!collection.value) return false;
4688
+ if (isReadOnly.value) return false;
4610
4689
  return !(isSingleton.value && items.value.length > 0);
4611
4690
  });
4612
4691
  const canDeleteCollection = computed(() => {
@@ -4998,7 +5077,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
4998
5077
  * race the in-flight one. On failure, roll the cell back and surface the
4999
5078
  * error. Bypasses the detail/edit panel entirely. */
5000
5079
  async function commitInlineEdit(item, key, field, raw) {
5001
- if (!collection.value) return;
5080
+ if (!collection.value || isReadOnly.value) return;
5002
5081
  const { slug } = collection.value;
5003
5082
  const itemId = rowId(item);
5004
5083
  if (!itemId || inlineSavingRows.value.has(itemId)) return;
@@ -5268,9 +5347,15 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5268
5347
  "aria-label": unref(t)("collectionsView.backToIndex"),
5269
5348
  "data-testid": "collections-back",
5270
5349
  onClick: goBack
5271
- }, [..._cache[26] || (_cache[26] = [createElementVNode("span", { class: "material-icons text-lg" }, "arrow_back", -1)])], 8, _hoisted_3$5)) : createCommentVNode("", true),
5350
+ }, [..._cache[27] || (_cache[27] = [createElementVNode("span", { class: "material-icons text-lg" }, "arrow_back", -1)])], 8, _hoisted_3$5)) : createCommentVNode("", true),
5272
5351
  collection.value ? (openBlock(), createElementBlock("div", _hoisted_4$5, [createElementVNode("span", _hoisted_5$5, toDisplayString(collection.value.icon), 1)])) : createCommentVNode("", true),
5273
- createElementVNode("div", _hoisted_6$4, [createElementVNode("h1", _hoisted_7$4, toDisplayString(collection.value?.title ?? unref(t)("collectionsView.title")), 1), collection.value ? (openBlock(), createElementBlock("span", _hoisted_8$4, toDisplayString(collection.value.slug), 1)) : createCommentVNode("", true)]),
5352
+ createElementVNode("div", _hoisted_6$4, [createElementVNode("h1", _hoisted_7$4, toDisplayString(collection.value?.title ?? unref(t)("collectionsView.title")), 1), collection.value ? (openBlock(), createElementBlock("span", _hoisted_8$4, [createTextVNode(toDisplayString(collection.value.slug) + " ", 1), isReadOnly.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createElementVNode("span", _hoisted_9$4, [_cache[28] || (_cache[28] = createElementVNode("span", { class: "material-icons text-[11px]" }, "lock", -1)), createTextVNode(" " + toDisplayString(unref(t)("collectionsView.readonlyChip")), 1)]), dataSourceRoute.value ? (openBlock(), createElementBlock("a", {
5353
+ key: 0,
5354
+ href: dataSourceRoute.value ?? void 0,
5355
+ class: "ml-1 normal-case tracking-normal font-mono font-normal text-slate-500 hover:text-indigo-700 hover:underline",
5356
+ "data-testid": "collections-readonly-source",
5357
+ onClick: _cache[0] || (_cache[0] = ($event) => unref(activatePathLink)($event, dataSourceRoute.value ?? "", true))
5358
+ }, toDisplayString(collection.value.schema.dataSource?.path), 9, _hoisted_10$4)) : createCommentVNode("", true)], 64)) : createCommentVNode("", true)])) : createCommentVNode("", true)]),
5274
5359
  collection.value && !embedded.value ? (openBlock(), createBlock(resolveDynamicComponent(unref(pinToggle)), {
5275
5360
  key: 2,
5276
5361
  kind: isFeedRoute.value ? "feed" : "collection",
@@ -5290,14 +5375,14 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5290
5375
  disabled: refreshing.value,
5291
5376
  "data-testid": "collections-refresh-feed",
5292
5377
  onClick: refreshFeed
5293
- }, [createElementVNode("span", _hoisted_10$4, toDisplayString(refreshing.value ? "hourglass_empty" : "refresh"), 1), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.refreshFeed")), 1)], 8, _hoisted_9$4)) : createCommentVNode("", true),
5378
+ }, [createElementVNode("span", _hoisted_12$4, toDisplayString(refreshing.value ? "hourglass_empty" : "refresh"), 1), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.refreshFeed")), 1)], 8, _hoisted_11$4)) : createCommentVNode("", true),
5294
5379
  collection.value ? (openBlock(), createElementBlock("button", {
5295
5380
  key: 4,
5296
5381
  type: "button",
5297
5382
  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",
5298
5383
  "data-testid": "collections-chat",
5299
5384
  onClick: openChat
5300
- }, [_cache[27] || (_cache[27] = createElementVNode("span", { class: "material-icons text-sm" }, "forum", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.chat")), 1)])) : createCommentVNode("", true),
5385
+ }, [_cache[29] || (_cache[29] = createElementVNode("span", { class: "material-icons text-sm" }, "forum", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.chat")), 1)])) : createCommentVNode("", true),
5301
5386
  (openBlock(true), createElementBlock(Fragment, null, renderList(collectionActions.value, (action) => {
5302
5387
  return openBlock(), createElementBlock("button", {
5303
5388
  key: action.id,
@@ -5306,7 +5391,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5306
5391
  disabled: collectionActionPending.value || isActionRunning(action.id),
5307
5392
  "data-testid": `collections-action-${action.id}`,
5308
5393
  onClick: ($event) => runCollectionAction(action)
5309
- }, [isActionRunning(action.id) ? (openBlock(), createElementBlock("span", _hoisted_12$4, "progress_activity")) : action.icon ? (openBlock(), createElementBlock("span", _hoisted_13$4, toDisplayString(action.icon), 1)) : createCommentVNode("", true), createElementVNode("span", null, toDisplayString(action.label), 1)], 8, _hoisted_11$4);
5394
+ }, [isActionRunning(action.id) ? (openBlock(), createElementBlock("span", _hoisted_14$4, "progress_activity")) : action.icon ? (openBlock(), createElementBlock("span", _hoisted_15$4, toDisplayString(action.icon), 1)) : createCommentVNode("", true), createElementVNode("span", null, toDisplayString(action.label), 1)], 8, _hoisted_13$4);
5310
5395
  }), 128)),
5311
5396
  canCreate.value && !calendarActive.value ? (openBlock(), createElementBlock("button", {
5312
5397
  key: 5,
@@ -5314,7 +5399,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5314
5399
  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",
5315
5400
  "data-testid": "collections-add-item",
5316
5401
  onClick: openCreate
5317
- }, [_cache[28] || (_cache[28] = createElementVNode("span", { class: "material-icons text-sm" }, "add", -1)), createElementVNode("span", null, toDisplayString(unref(t)("common.add")), 1)])) : createCommentVNode("", true),
5402
+ }, [_cache[30] || (_cache[30] = createElementVNode("span", { class: "material-icons text-sm" }, "add", -1)), createElementVNode("span", null, toDisplayString(unref(t)("common.add")), 1)])) : createCommentVNode("", true),
5318
5403
  canDeleteCollection.value && !embedded.value ? (openBlock(), createElementBlock("button", {
5319
5404
  key: 6,
5320
5405
  type: "button",
@@ -5323,7 +5408,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5323
5408
  "aria-label": unref(t)("collectionsView.deleteCollection"),
5324
5409
  "data-testid": "collections-delete",
5325
5410
  onClick: confirmCollectionDelete
5326
- }, [..._cache[29] || (_cache[29] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_14$4)) : createCommentVNode("", true),
5411
+ }, [..._cache[31] || (_cache[31] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_16$4)) : createCommentVNode("", true),
5327
5412
  canDeleteFeed.value && !embedded.value ? (openBlock(), createElementBlock("button", {
5328
5413
  key: 7,
5329
5414
  type: "button",
@@ -5332,26 +5417,26 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5332
5417
  "aria-label": unref(t)("collectionsView.deleteFeed"),
5333
5418
  "data-testid": "feeds-delete",
5334
5419
  onClick: confirmFeedDelete
5335
- }, [..._cache[30] || (_cache[30] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_15$4)) : createCommentVNode("", true)
5420
+ }, [..._cache[32] || (_cache[32] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_17$4)) : createCommentVNode("", true)
5336
5421
  ])) : createCommentVNode("", true),
5337
- refreshNote.value ? (openBlock(), createElementBlock("div", _hoisted_16$4, [_cache[31] || (_cache[31] = createElementVNode("span", { class: "material-icons text-base text-indigo-600" }, "hourglass_top", -1)), createElementVNode("span", _hoisted_17$4, toDisplayString(refreshNote.value), 1)])) : createCommentVNode("", true),
5338
- collection.value && (!__props.hideSearch && items.value.length > 0 || !__props.hideViewToggle && (hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value)) ? (openBlock(), createElementBlock("div", _hoisted_18$4, [!__props.hideSearch && items.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_19$2, [
5339
- _cache[33] || (_cache[33] = 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)),
5422
+ refreshNote.value ? (openBlock(), createElementBlock("div", _hoisted_18$4, [_cache[33] || (_cache[33] = createElementVNode("span", { class: "material-icons text-base text-indigo-600" }, "hourglass_top", -1)), createElementVNode("span", _hoisted_19$3, toDisplayString(refreshNote.value), 1)])) : createCommentVNode("", true),
5423
+ collection.value && (!__props.hideSearch && items.value.length > 0 || !__props.hideViewToggle && (hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value)) ? (openBlock(), createElementBlock("div", _hoisted_20$3, [!__props.hideSearch && items.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_21$3, [
5424
+ _cache[35] || (_cache[35] = 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)),
5340
5425
  withDirectives(createElementVNode("input", {
5341
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchQuery.value = $event),
5426
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => searchQuery.value = $event),
5342
5427
  type: "text",
5343
5428
  placeholder: unref(t)("collectionsView.searchPlaceholder"),
5344
5429
  "aria-label": unref(t)("collectionsView.searchPlaceholder"),
5345
5430
  class: "w-full bg-slate-50 border border-slate-200/80 rounded-xl pl-9 pr-8 py-1.5 text-xs placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 focus:border-indigo-500 focus:bg-white transition-all font-medium"
5346
- }, null, 8, _hoisted_20$2), [[vModelText, searchQuery.value]]),
5431
+ }, null, 8, _hoisted_22$3), [[vModelText, searchQuery.value]]),
5347
5432
  searchQuery.value ? (openBlock(), createElementBlock("button", {
5348
5433
  key: 0,
5349
5434
  type: "button",
5350
5435
  "aria-label": unref(t)("collectionsView.clearSearch"),
5351
5436
  class: "absolute inset-y-0 right-0 flex items-center pr-2.5 text-slate-400 hover:text-slate-600",
5352
- onClick: _cache[1] || (_cache[1] = ($event) => searchQuery.value = "")
5353
- }, [..._cache[32] || (_cache[32] = [createElementVNode("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_21$2)) : createCommentVNode("", true)
5354
- ])) : createCommentVNode("", true), createElementVNode("div", _hoisted_22$2, [
5437
+ onClick: _cache[2] || (_cache[2] = ($event) => searchQuery.value = "")
5438
+ }, [..._cache[34] || (_cache[34] = [createElementVNode("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_23$2)) : createCommentVNode("", true)
5439
+ ])) : createCommentVNode("", true), createElementVNode("div", _hoisted_24$1, [
5355
5440
  !__props.hideViewToggle && (hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value) ? (openBlock(), createElementBlock("div", {
5356
5441
  key: 0,
5357
5442
  class: "flex gap-0.5",
@@ -5363,24 +5448,24 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5363
5448
  class: normalizeClass(["h-8 px-2.5 flex items-center gap-1 rounded text-xs font-bold transition-colors", activeView.value === "table" ? "bg-indigo-600 text-white" : "bg-white text-slate-500 border border-slate-200 hover:bg-slate-50"]),
5364
5449
  "aria-pressed": activeView.value === "table",
5365
5450
  "data-testid": "collection-view-toggle-table",
5366
- onClick: _cache[2] || (_cache[2] = ($event) => setView("table"))
5367
- }, [_cache[34] || (_cache[34] = createElementVNode("span", { class: "material-icons text-sm" }, "table_rows", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewTable")), 1)], 10, _hoisted_24$1),
5451
+ onClick: _cache[3] || (_cache[3] = ($event) => setView("table"))
5452
+ }, [_cache[36] || (_cache[36] = createElementVNode("span", { class: "material-icons text-sm" }, "table_rows", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewTable")), 1)], 10, _hoisted_26$1),
5368
5453
  hasCalendar.value ? (openBlock(), createElementBlock("button", {
5369
5454
  key: 0,
5370
5455
  type: "button",
5371
5456
  class: normalizeClass(["h-8 px-2.5 flex items-center gap-1 rounded text-xs font-bold transition-colors", activeView.value === "calendar" ? "bg-indigo-600 text-white" : "bg-white text-slate-500 border border-slate-200 hover:bg-slate-50"]),
5372
5457
  "aria-pressed": activeView.value === "calendar",
5373
5458
  "data-testid": "collection-view-toggle-calendar",
5374
- onClick: _cache[3] || (_cache[3] = ($event) => setView("calendar"))
5375
- }, [_cache[35] || (_cache[35] = createElementVNode("span", { class: "material-icons text-sm" }, "calendar_month", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewCalendar")), 1)], 10, _hoisted_25$1)) : createCommentVNode("", true),
5459
+ onClick: _cache[4] || (_cache[4] = ($event) => setView("calendar"))
5460
+ }, [_cache[37] || (_cache[37] = createElementVNode("span", { class: "material-icons text-sm" }, "calendar_month", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewCalendar")), 1)], 10, _hoisted_27$1)) : createCommentVNode("", true),
5376
5461
  hasKanban.value ? (openBlock(), createElementBlock("button", {
5377
5462
  key: 1,
5378
5463
  type: "button",
5379
5464
  class: normalizeClass(["h-8 px-2.5 flex items-center gap-1 rounded text-xs font-bold transition-colors", activeView.value === "kanban" ? "bg-indigo-600 text-white" : "bg-white text-slate-500 border border-slate-200 hover:bg-slate-50"]),
5380
5465
  "aria-pressed": activeView.value === "kanban",
5381
5466
  "data-testid": "collection-view-toggle-kanban",
5382
- onClick: _cache[4] || (_cache[4] = ($event) => setView("kanban"))
5383
- }, [_cache[36] || (_cache[36] = createElementVNode("span", { class: "material-icons text-sm" }, "view_kanban", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewKanban")), 1)], 10, _hoisted_26$1)) : createCommentVNode("", true),
5467
+ onClick: _cache[5] || (_cache[5] = ($event) => setView("kanban"))
5468
+ }, [_cache[38] || (_cache[38] = createElementVNode("span", { class: "material-icons text-sm" }, "view_kanban", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewKanban")), 1)], 10, _hoisted_28)) : createCommentVNode("", true),
5384
5469
  (openBlock(true), createElementBlock(Fragment, null, renderList(customViews.value, (cv) => {
5385
5470
  return openBlock(), createElementBlock("button", {
5386
5471
  key: cv.id,
@@ -5389,7 +5474,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5389
5474
  "aria-pressed": activeView.value === unref(customViewKey)(cv.id),
5390
5475
  "data-testid": `collection-view-custom-${cv.id}`,
5391
5476
  onClick: ($event) => setCustomView(cv.id)
5392
- }, [createElementVNode("span", _hoisted_28, toDisplayString(cv.icon || (cv.target === "mobile" ? "smartphone" : "dashboard_customize")), 1), createElementVNode("span", null, toDisplayString(cv.label), 1)], 10, _hoisted_27$1);
5477
+ }, [createElementVNode("span", _hoisted_30, toDisplayString(cv.icon || (cv.target === "mobile" ? "smartphone" : "dashboard_customize")), 1), createElementVNode("span", null, toDisplayString(cv.label), 1)], 10, _hoisted_29);
5393
5478
  }), 128)),
5394
5479
  canAddCustomView.value ? (openBlock(), createElementBlock("div", {
5395
5480
  key: 2,
@@ -5404,17 +5489,17 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5404
5489
  "aria-expanded": addMenuOpen.value,
5405
5490
  "data-testid": "collection-view-add",
5406
5491
  onClick: onAddViewClick
5407
- }, [..._cache[37] || (_cache[37] = [createElementVNode("span", { class: "material-icons text-sm" }, "add", -1)])], 8, _hoisted_29), addMenuOpen.value ? (openBlock(), createElementBlock("div", _hoisted_30, [createElementVNode("button", {
5492
+ }, [..._cache[39] || (_cache[39] = [createElementVNode("span", { class: "material-icons text-sm" }, "add", -1)])], 8, _hoisted_31), addMenuOpen.value ? (openBlock(), createElementBlock("div", _hoisted_32, [createElementVNode("button", {
5408
5493
  type: "button",
5409
5494
  class: "w-full h-8 px-3 flex items-center gap-2 text-xs font-bold text-slate-600 hover:bg-slate-50",
5410
5495
  "data-testid": "collection-view-add-desktop",
5411
- onClick: _cache[5] || (_cache[5] = ($event) => addCustomView("desktop"))
5412
- }, [_cache[38] || (_cache[38] = createElementVNode("span", { class: "material-icons text-sm" }, "dashboard_customize", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.addViewDesktop")), 1)]), createElementVNode("button", {
5496
+ onClick: _cache[6] || (_cache[6] = ($event) => addCustomView("desktop"))
5497
+ }, [_cache[40] || (_cache[40] = createElementVNode("span", { class: "material-icons text-sm" }, "dashboard_customize", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.addViewDesktop")), 1)]), createElementVNode("button", {
5413
5498
  type: "button",
5414
5499
  class: "w-full h-8 px-3 flex items-center gap-2 text-xs font-bold text-slate-600 hover:bg-slate-50",
5415
5500
  "data-testid": "collection-view-add-mobile",
5416
- onClick: _cache[6] || (_cache[6] = ($event) => addCustomView("mobile"))
5417
- }, [_cache[39] || (_cache[39] = createElementVNode("span", { class: "material-icons text-sm" }, "smartphone", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.addViewMobile")), 1)])])) : createCommentVNode("", true)], 512)) : createCommentVNode("", true),
5501
+ onClick: _cache[7] || (_cache[7] = ($event) => addCustomView("mobile"))
5502
+ }, [_cache[41] || (_cache[41] = createElementVNode("span", { class: "material-icons text-sm" }, "smartphone", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.addViewMobile")), 1)])])) : createCommentVNode("", true)], 512)) : createCommentVNode("", true),
5418
5503
  canConfigureViews.value ? (openBlock(), createElementBlock("button", {
5419
5504
  key: 3,
5420
5505
  type: "button",
@@ -5422,51 +5507,51 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5422
5507
  title: unref(t)("collectionsView.config.open"),
5423
5508
  "aria-label": unref(t)("collectionsView.config.open"),
5424
5509
  "data-testid": "collection-config-open",
5425
- onClick: _cache[7] || (_cache[7] = ($event) => configOpen.value = true)
5426
- }, [..._cache[40] || (_cache[40] = [createElementVNode("span", { class: "material-icons text-sm" }, "settings", -1)])], 8, _hoisted_31)) : createCommentVNode("", true)
5427
- ], 8, _hoisted_23$2)) : createCommentVNode("", true),
5510
+ onClick: _cache[8] || (_cache[8] = ($event) => configOpen.value = true)
5511
+ }, [..._cache[42] || (_cache[42] = [createElementVNode("span", { class: "material-icons text-sm" }, "settings", -1)])], 8, _hoisted_33)) : createCommentVNode("", true)
5512
+ ], 8, _hoisted_25$1)) : createCommentVNode("", true),
5428
5513
  calendarActive.value && dateFields.value.length > 1 ? (openBlock(), createElementBlock("select", {
5429
5514
  key: 1,
5430
5515
  value: calendarAnchorField.value,
5431
5516
  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",
5432
5517
  "aria-label": unref(t)("collectionsView.calendarFieldLabel"),
5433
5518
  "data-testid": "collection-calendar-field",
5434
- onChange: _cache[8] || (_cache[8] = ($event) => anchorOverride.value = $event.target.value)
5519
+ onChange: _cache[9] || (_cache[9] = ($event) => anchorOverride.value = $event.target.value)
5435
5520
  }, [(openBlock(true), createElementBlock(Fragment, null, renderList(dateFields.value, (key) => {
5436
5521
  return openBlock(), createElementBlock("option", {
5437
5522
  key,
5438
5523
  value: key
5439
- }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_33);
5440
- }), 128))], 40, _hoisted_32)) : createCommentVNode("", true),
5524
+ }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_35);
5525
+ }), 128))], 40, _hoisted_34)) : createCommentVNode("", true),
5441
5526
  kanbanActive.value && enumFields.value.length > 1 ? (openBlock(), createElementBlock("select", {
5442
5527
  key: 2,
5443
5528
  value: kanbanGroupField.value,
5444
5529
  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",
5445
5530
  "aria-label": unref(t)("collectionsView.kanbanFieldLabel"),
5446
5531
  "data-testid": "collection-kanban-field",
5447
- onChange: _cache[9] || (_cache[9] = ($event) => kanbanOverride.value = $event.target.value)
5532
+ onChange: _cache[10] || (_cache[10] = ($event) => kanbanOverride.value = $event.target.value)
5448
5533
  }, [(openBlock(true), createElementBlock(Fragment, null, renderList(enumFields.value, (key) => {
5449
5534
  return openBlock(), createElementBlock("option", {
5450
5535
  key,
5451
5536
  value: key
5452
- }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_35);
5453
- }), 128))], 40, _hoisted_34)) : createCommentVNode("", true),
5454
- items.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_36, toDisplayString(unref(t)("collectionsView.searchSummary", {
5537
+ }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_37);
5538
+ }), 128))], 40, _hoisted_36)) : createCommentVNode("", true),
5539
+ items.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_38, toDisplayString(unref(t)("collectionsView.searchSummary", {
5455
5540
  shown: filteredItems.value.length,
5456
5541
  total: items.value.length
5457
5542
  })), 1)) : createCommentVNode("", true)
5458
5543
  ])])) : createCommentVNode("", true),
5459
- collection.value && dataIssues.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_37, [
5460
- _cache[42] || (_cache[42] = createElementVNode("span", { class: "material-icons text-amber-600" }, "warning", -1)),
5461
- createElementVNode("span", _hoisted_38, toDisplayString(unref(t)("collectionsView.dataIssuesDetected", { count: dataIssues.value.length })), 1),
5544
+ collection.value && dataIssues.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_39, [
5545
+ _cache[44] || (_cache[44] = createElementVNode("span", { class: "material-icons text-amber-600" }, "warning", -1)),
5546
+ createElementVNode("span", _hoisted_40, toDisplayString(unref(t)("collectionsView.dataIssuesDetected", { count: dataIssues.value.length })), 1),
5462
5547
  createElementVNode("button", {
5463
5548
  type: "button",
5464
5549
  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",
5465
5550
  "data-testid": "collections-repair",
5466
5551
  onClick: repairCollection
5467
- }, [_cache[41] || (_cache[41] = createElementVNode("span", { class: "material-icons text-sm" }, "build", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.repair")), 1)])
5552
+ }, [_cache[43] || (_cache[43] = createElementVNode("span", { class: "material-icons text-sm" }, "build", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.repair")), 1)])
5468
5553
  ])) : createCommentVNode("", true),
5469
- createElementVNode("div", _hoisted_39, [loading.value ? (openBlock(), createElementBlock("div", _hoisted_40, [_cache[43] || (_cache[43] = 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_41, [_cache[44] || (_cache[44] = 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_42)) : calendarActive.value ? (openBlock(), createElementBlock("div", _hoisted_43, [createVNode(CollectionCalendarView_default, {
5554
+ createElementVNode("div", _hoisted_41, [loading.value ? (openBlock(), createElementBlock("div", _hoisted_42, [_cache[45] || (_cache[45] = 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_43, [_cache[46] || (_cache[46] = 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_44)) : calendarActive.value ? (openBlock(), createElementBlock("div", _hoisted_45, [createVNode(CollectionCalendarView_default, {
5470
5555
  schema: collection.value.schema,
5471
5556
  items: filteredItems.value,
5472
5557
  "anchor-field": calendarAnchorField.value,
@@ -5502,7 +5587,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5502
5587
  }, {
5503
5588
  detail: withCtx(() => [createVNode(CollectionRecordPanel_default, {
5504
5589
  editing: editing.value,
5505
- "onUpdate:editing": _cache[10] || (_cache[10] = ($event) => editing.value = $event),
5590
+ "onUpdate:editing": _cache[11] || (_cache[11] = ($event) => editing.value = $event),
5506
5591
  collection: collection.value,
5507
5592
  viewing: viewing.value,
5508
5593
  saving: saving.value,
@@ -5515,13 +5600,14 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5515
5600
  "live-derived": liveDerived.value,
5516
5601
  "view-title": viewTitle.value,
5517
5602
  "is-singleton": isSingleton.value,
5603
+ readonly: isReadOnly.value,
5518
5604
  render: unref(render),
5519
5605
  locale: unref(locale),
5520
5606
  onSubmit: saveEditor,
5521
5607
  onCancel: cancelEditor,
5522
5608
  onEdit: editFromView,
5523
5609
  onClose: onDayClose,
5524
- onDelete: _cache[11] || (_cache[11] = ($event) => viewing.value && confirmDelete(viewing.value)),
5610
+ onDelete: _cache[12] || (_cache[12] = ($event) => viewing.value && confirmDelete(viewing.value)),
5525
5611
  onRunAction: runAction,
5526
5612
  onItemChat
5527
5613
  }, null, 8, [
@@ -5538,6 +5624,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5538
5624
  "live-derived",
5539
5625
  "view-title",
5540
5626
  "is-singleton",
5627
+ "readonly",
5541
5628
  "render",
5542
5629
  "locale"
5543
5630
  ])]),
@@ -5553,21 +5640,22 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5553
5640
  "selected",
5554
5641
  "can-create",
5555
5642
  "show-detail"
5556
- ])) : createCommentVNode("", true)])) : kanbanActive.value ? (openBlock(), createElementBlock("div", _hoisted_44, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_45, [
5557
- _cache[46] || (_cache[46] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
5558
- createElementVNode("span", _hoisted_46, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5643
+ ])) : createCommentVNode("", true)])) : kanbanActive.value ? (openBlock(), createElementBlock("div", _hoisted_46, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_47, [
5644
+ _cache[48] || (_cache[48] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
5645
+ createElementVNode("span", _hoisted_48, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5559
5646
  createElementVNode("button", {
5560
5647
  type: "button",
5561
5648
  class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
5562
5649
  "aria-label": unref(t)("common.close"),
5563
- onClick: _cache[12] || (_cache[12] = ($event) => inlineError.value = null)
5564
- }, [..._cache[45] || (_cache[45] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_47)
5565
- ])) : createCommentVNode("", true), createElementVNode("div", _hoisted_48, [createVNode(CollectionKanbanView_default, {
5650
+ onClick: _cache[13] || (_cache[13] = ($event) => inlineError.value = null)
5651
+ }, [..._cache[47] || (_cache[47] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_49)
5652
+ ])) : createCommentVNode("", true), createElementVNode("div", _hoisted_50, [createVNode(CollectionKanbanView_default, {
5566
5653
  schema: collection.value.schema,
5567
5654
  items: filteredItems.value,
5568
5655
  "group-field": kanbanGroupField.value,
5569
5656
  selected: viewing.value ? String(viewing.value[collection.value.schema.primaryKey] ?? "") : void 0,
5570
5657
  notified: notifiedSeverities.value,
5658
+ readonly: isReadOnly.value,
5571
5659
  onSelect: onCalendarSelect,
5572
5660
  onMove: onKanbanMove
5573
5661
  }, null, 8, [
@@ -5575,8 +5663,9 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5575
5663
  "items",
5576
5664
  "group-field",
5577
5665
  "selected",
5578
- "notified"
5579
- ])])])) : activeCustomView.value ? (openBlock(), createElementBlock("div", _hoisted_49, [activeCustomView.value.target === "mobile" ? (openBlock(), createBlock(CollectionRemoteViewPreview_default, {
5666
+ "notified",
5667
+ "readonly"
5668
+ ])])])) : activeCustomView.value ? (openBlock(), createElementBlock("div", _hoisted_51, [activeCustomView.value.target === "mobile" ? (openBlock(), createBlock(CollectionRemoteViewPreview_default, {
5580
5669
  key: 0,
5581
5670
  slug: collection.value.slug,
5582
5671
  view: activeCustomView.value,
@@ -5587,32 +5676,32 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5587
5676
  view: activeCustomView.value,
5588
5677
  onOpenItem: onCustomViewOpenItem,
5589
5678
  onStartChat: onCustomViewStartChat
5590
- }, null, 8, ["slug", "view"]))])) : items.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_50, [_cache[47] || (_cache[47] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "folder_open", -1)), createElementVNode("p", _hoisted_51, toDisplayString(unref(t)("collectionsView.itemsEmpty")), 1)])) : filteredItems.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_52, [
5591
- _cache[48] || (_cache[48] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "search_off", -1)),
5592
- createElementVNode("p", _hoisted_53, toDisplayString(unref(t)("collectionsView.noMatchingItems")), 1),
5679
+ }, null, 8, ["slug", "view"]))])) : items.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_52, [_cache[49] || (_cache[49] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "folder_open", -1)), createElementVNode("p", _hoisted_53, toDisplayString(unref(t)(isReadOnly.value ? "collectionsView.itemsEmptyReadonly" : "collectionsView.itemsEmpty")), 1)])) : filteredItems.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_54, [
5680
+ _cache[50] || (_cache[50] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "search_off", -1)),
5681
+ createElementVNode("p", _hoisted_55, toDisplayString(unref(t)("collectionsView.noMatchingItems")), 1),
5593
5682
  createElementVNode("button", {
5594
5683
  type: "button",
5595
5684
  class: "text-xs text-indigo-600 font-semibold hover:underline",
5596
- onClick: _cache[13] || (_cache[13] = ($event) => searchQuery.value = "")
5685
+ onClick: _cache[14] || (_cache[14] = ($event) => searchQuery.value = "")
5597
5686
  }, toDisplayString(unref(t)("collectionsView.clearSearch")), 1)
5598
- ])) : (openBlock(), createElementBlock("div", _hoisted_54, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_55, [
5599
- _cache[50] || (_cache[50] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
5600
- createElementVNode("span", _hoisted_56, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5687
+ ])) : (openBlock(), createElementBlock("div", _hoisted_56, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_57, [
5688
+ _cache[52] || (_cache[52] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
5689
+ createElementVNode("span", _hoisted_58, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5601
5690
  createElementVNode("button", {
5602
5691
  type: "button",
5603
5692
  class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
5604
5693
  "aria-label": unref(t)("common.close"),
5605
- onClick: _cache[14] || (_cache[14] = ($event) => inlineError.value = null)
5606
- }, [..._cache[49] || (_cache[49] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_57)
5607
- ])) : createCommentVNode("", true), createElementVNode("table", _hoisted_58, [createElementVNode("thead", null, [createElementVNode("tr", _hoisted_59, [(openBlock(true), createElementBlock(Fragment, null, renderList(listColumnFields.value, ([key, field]) => {
5694
+ onClick: _cache[15] || (_cache[15] = ($event) => inlineError.value = null)
5695
+ }, [..._cache[51] || (_cache[51] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_59)
5696
+ ])) : createCommentVNode("", true), createElementVNode("table", _hoisted_60, [createElementVNode("thead", null, [createElementVNode("tr", _hoisted_61, [(openBlock(true), createElementBlock(Fragment, null, renderList(listColumnFields.value, ([key, field]) => {
5608
5697
  return openBlock(), createElementBlock("th", {
5609
5698
  key,
5610
5699
  "aria-sort": unref(isSortableField)(field) ? sortAriaValue(key) : void 0,
5611
5700
  class: "px-5 py-3 font-bold text-slate-500 text-left uppercase tracking-wider whitespace-nowrap"
5612
- }, [createElementVNode("div", _hoisted_61, [createElementVNode("span", {
5701
+ }, [createElementVNode("div", _hoisted_63, [createElementVNode("span", {
5613
5702
  class: "truncate max-w-[14rem]",
5614
5703
  title: field.label
5615
- }, toDisplayString(field.label), 9, _hoisted_62), unref(isSortableField)(field) ? (openBlock(), createElementBlock("button", {
5704
+ }, toDisplayString(field.label), 9, _hoisted_64), unref(isSortableField)(field) ? (openBlock(), createElementBlock("button", {
5616
5705
  key: 0,
5617
5706
  type: "button",
5618
5707
  class: normalizeClass(["inline-flex items-center justify-center rounded p-0.5 -my-1 leading-none transition-colors", sortButtonClass(key)]),
@@ -5620,9 +5709,9 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5620
5709
  "aria-label": unref(t)("collectionsView.sortBy", { field: field.label }),
5621
5710
  onClick: withModifiers(($event) => cycleSort(key), ["stop"]),
5622
5711
  onPointerenter: ($event) => hoveredSortKey.value = key,
5623
- onPointerleave: _cache[15] || (_cache[15] = ($event) => hoveredSortKey.value = null)
5624
- }, [createElementVNode("span", _hoisted_64, toDisplayString(sortIconName(key)), 1)], 42, _hoisted_63)) : createCommentVNode("", true)])], 8, _hoisted_60);
5625
- }), 128))])]), createElementVNode("tbody", _hoisted_65, [(openBlock(true), createElementBlock(Fragment, null, renderList(sortedItems.value, (item) => {
5712
+ onPointerleave: _cache[16] || (_cache[16] = ($event) => hoveredSortKey.value = null)
5713
+ }, [createElementVNode("span", _hoisted_66, toDisplayString(sortIconName(key)), 1)], 42, _hoisted_65)) : createCommentVNode("", true)])], 8, _hoisted_62);
5714
+ }), 128))])]), createElementVNode("tbody", _hoisted_67, [(openBlock(true), createElementBlock(Fragment, null, renderList(sortedItems.value, (item) => {
5626
5715
  return openBlock(), createElementBlock("tr", {
5627
5716
  key: String(item[collection.value.schema.primaryKey] ?? ""),
5628
5717
  class: 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" : ""]),
@@ -5640,23 +5729,23 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5640
5729
  key: 0,
5641
5730
  type: "checkbox",
5642
5731
  checked: toggleChecked(item, field),
5643
- disabled: isRowInlineSaving(item),
5732
+ disabled: isReadOnly.value || isRowInlineSaving(item),
5644
5733
  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",
5645
5734
  "data-testid": `collections-inline-toggle-${key}-${item[collection.value.schema.primaryKey]}`,
5646
5735
  "aria-label": field.label,
5647
- onClick: _cache[16] || (_cache[16] = withModifiers(() => {}, ["stop"])),
5736
+ onClick: _cache[17] || (_cache[17] = withModifiers(() => {}, ["stop"])),
5648
5737
  onChange: ($event) => commitToggle(item, field)
5649
- }, null, 40, _hoisted_67)) : field.type === "boolean" ? (openBlock(), createElementBlock("input", {
5738
+ }, null, 40, _hoisted_69)) : field.type === "boolean" ? (openBlock(), createElementBlock("input", {
5650
5739
  key: 1,
5651
5740
  type: "checkbox",
5652
5741
  checked: item[key] === true,
5653
- disabled: isRowInlineSaving(item),
5742
+ disabled: isReadOnly.value || isRowInlineSaving(item),
5654
5743
  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",
5655
5744
  "data-testid": `collections-inline-bool-${key}-${item[collection.value.schema.primaryKey]}`,
5656
5745
  "aria-label": field.label,
5657
- onClick: _cache[17] || (_cache[17] = withModifiers(() => {}, ["stop"])),
5746
+ onClick: _cache[18] || (_cache[18] = withModifiers(() => {}, ["stop"])),
5658
5747
  onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.checked)
5659
- }, null, 40, _hoisted_68)) : field.type === "ref" && field.to && typeof item[key] === "string" && item[key] ? (openBlock(), createElementBlock("span", _hoisted_69, [createElementVNode("a", {
5748
+ }, null, 40, _hoisted_70)) : field.type === "ref" && field.to && typeof item[key] === "string" && item[key] ? (openBlock(), createElementBlock("span", _hoisted_71, [createElementVNode("a", {
5660
5749
  href: unref(cui).recordHref?.(field.to, String(item[key])),
5661
5750
  tabindex: unref(cui).recordHref?.(field.to, String(item[key])) ? void 0 : 0,
5662
5751
  role: "link",
@@ -5664,48 +5753,48 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5664
5753
  "data-testid": `collections-ref-link-${key}-${item[key]}`,
5665
5754
  onClick: ($event) => unref(activateRefLink)($event, field.to, String(item[key]), true),
5666
5755
  onKeydown: [withKeys(($event) => unref(activateRefLink)($event, field.to, String(item[key]), true), ["enter"]), withKeys(($event) => unref(activateRefLink)($event, field.to, String(item[key]), true), ["space"])]
5667
- }, toDisplayString(unref(refDisplay)(field.to, String(item[key]))), 41, _hoisted_70)])) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? (openBlock(), createElementBlock("select", {
5756
+ }, toDisplayString(unref(refDisplay)(field.to, String(item[key]))), 41, _hoisted_72)])) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? (openBlock(), createElementBlock("select", {
5668
5757
  key: 3,
5669
5758
  value: item[key] == null ? "" : String(item[key]),
5670
- disabled: isRowInlineSaving(item),
5759
+ disabled: isReadOnly.value || isRowInlineSaving(item),
5671
5760
  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])]),
5672
5761
  "data-testid": `collections-inline-enum-${key}-${item[collection.value.schema.primaryKey]}`,
5673
5762
  "aria-label": field.label,
5674
- onClick: _cache[18] || (_cache[18] = withModifiers(() => {}, ["stop"])),
5763
+ onClick: _cache[19] || (_cache[19] = withModifiers(() => {}, ["stop"])),
5675
5764
  onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.value)
5676
- }, [showEnumPlaceholder(item, String(key)) ? (openBlock(), createElementBlock("option", _hoisted_72, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(field.values, (value) => {
5765
+ }, [showEnumPlaceholder(item, String(key)) ? (openBlock(), createElementBlock("option", _hoisted_74, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(field.values, (value) => {
5677
5766
  return openBlock(), createElementBlock("option", {
5678
5767
  key: value,
5679
5768
  value
5680
- }, toDisplayString(value), 9, _hoisted_73);
5681
- }), 128))], 42, _hoisted_71)) : field.type === "money" ? (openBlock(), createElementBlock("span", _hoisted_74, toDisplayString(unref(formatMoney)(item[key], unref(resolveCurrency)(field, item), unref(locale))), 1)) : field.type === "table" ? (openBlock(), createElementBlock("span", _hoisted_75, [_cache[51] || (_cache[51] = createElementVNode("span", { class: "material-icons text-[11px]" }, "list", -1)), createElementVNode("span", null, toDisplayString(tableSummary(item[key])), 1)])) : field.type === "derived" ? (openBlock(), createElementBlock("span", _hoisted_76, toDisplayString(unref(derivedDisplay)(field, unref(evaluateDerivedAgainstItem)(field, String(key), item), item)), 1)) : field.type === "rollup" ? (openBlock(), createElementBlock("span", {
5769
+ }, toDisplayString(value), 9, _hoisted_75);
5770
+ }), 128))], 42, _hoisted_73)) : field.type === "money" ? (openBlock(), createElementBlock("span", _hoisted_76, toDisplayString(unref(formatMoney)(item[key], unref(resolveCurrency)(field, item), unref(locale))), 1)) : field.type === "table" ? (openBlock(), createElementBlock("span", _hoisted_77, [_cache[53] || (_cache[53] = createElementVNode("span", { class: "material-icons text-[11px]" }, "list", -1)), createElementVNode("span", null, toDisplayString(tableSummary(item[key])), 1)])) : field.type === "derived" ? (openBlock(), createElementBlock("span", _hoisted_78, toDisplayString(unref(derivedDisplay)(field, unref(evaluateDerivedAgainstItem)(field, String(key), item), item)), 1)) : field.type === "rollup" ? (openBlock(), createElementBlock("span", {
5682
5771
  key: 7,
5683
5772
  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",
5684
5773
  "data-testid": `collections-rollup-${key}-${item[collection.value.schema.primaryKey]}`
5685
- }, toDisplayString(unref(render).rollupDisplay(field, item)), 9, _hoisted_77)) : field.type !== "file" && unref(isExternalUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
5774
+ }, toDisplayString(unref(render).rollupDisplay(field, item)), 9, _hoisted_79)) : field.type !== "file" && unref(isExternalUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
5686
5775
  key: 8,
5687
5776
  href: String(item[key]),
5688
5777
  target: "_blank",
5689
5778
  rel: "noopener noreferrer",
5690
5779
  class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
5691
5780
  "data-testid": `collections-url-link-${key}-${item[collection.value.schema.primaryKey]}`,
5692
- onClick: _cache[19] || (_cache[19] = withModifiers(() => {}, ["stop"]))
5693
- }, toDisplayString(String(item[key])), 9, _hoisted_78)) : field.type === "file" && unref(artifactUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
5781
+ onClick: _cache[20] || (_cache[20] = withModifiers(() => {}, ["stop"]))
5782
+ }, toDisplayString(String(item[key])), 9, _hoisted_80)) : field.type === "file" && unref(artifactUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
5694
5783
  key: 9,
5695
5784
  href: unref(artifactUrl)(item[key]) ?? void 0,
5696
5785
  target: "_blank",
5697
5786
  rel: "noopener noreferrer",
5698
5787
  class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
5699
5788
  "data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
5700
- onClick: _cache[20] || (_cache[20] = withModifiers(() => {}, ["stop"]))
5701
- }, toDisplayString(String(item[key])), 9, _hoisted_79)) : field.type === "file" && unref(fileRoutePath)(item[key]) ? (openBlock(), createElementBlock("a", {
5789
+ onClick: _cache[21] || (_cache[21] = withModifiers(() => {}, ["stop"]))
5790
+ }, toDisplayString(String(item[key])), 9, _hoisted_81)) : field.type === "file" && unref(fileRoutePath)(item[key]) ? (openBlock(), createElementBlock("a", {
5702
5791
  key: 10,
5703
5792
  href: unref(fileRoutePath)(item[key]) ?? void 0,
5704
5793
  class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
5705
5794
  "data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
5706
5795
  onClick: ($event) => unref(activatePathLink)($event, unref(fileRoutePath)(item[key]) ?? "", true)
5707
- }, toDisplayString(String(item[key])), 9, _hoisted_80)) : (openBlock(), createElementBlock("span", _hoisted_81, toDisplayString(unref(formatCell)(item[key], field.type)), 1))], 64)) : createCommentVNode("", true)]);
5708
- }), 128))], 42, _hoisted_66);
5796
+ }, toDisplayString(String(item[key])), 9, _hoisted_82)) : (openBlock(), createElementBlock("span", _hoisted_83, toDisplayString(unref(formatCell)(item[key], field.type)), 1))], 64)) : createCommentVNode("", true)]);
5797
+ }), 128))], 42, _hoisted_68);
5709
5798
  }), 128))])])]))]),
5710
5799
  collection.value && (viewing.value || editing.value) && !(calendarActive.value && openDay.value) ? (openBlock(), createBlock(CollectionRecordModal_default, {
5711
5800
  key: 4,
@@ -5713,7 +5802,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5713
5802
  }, {
5714
5803
  default: withCtx(() => [createVNode(CollectionRecordPanel_default, {
5715
5804
  editing: editing.value,
5716
- "onUpdate:editing": _cache[21] || (_cache[21] = ($event) => editing.value = $event),
5805
+ "onUpdate:editing": _cache[22] || (_cache[22] = ($event) => editing.value = $event),
5717
5806
  collection: collection.value,
5718
5807
  viewing: viewing.value,
5719
5808
  saving: saving.value,
@@ -5726,13 +5815,14 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5726
5815
  "live-derived": liveDerived.value,
5727
5816
  "view-title": viewTitle.value,
5728
5817
  "is-singleton": isSingleton.value,
5818
+ readonly: isReadOnly.value,
5729
5819
  render: unref(render),
5730
5820
  locale: unref(locale),
5731
5821
  onSubmit: saveEditor,
5732
5822
  onCancel: cancelEditor,
5733
5823
  onEdit: editFromView,
5734
5824
  onClose: closeView,
5735
- onDelete: _cache[22] || (_cache[22] = ($event) => viewing.value && confirmDelete(viewing.value)),
5825
+ onDelete: _cache[23] || (_cache[23] = ($event) => viewing.value && confirmDelete(viewing.value)),
5736
5826
  onRunAction: runAction,
5737
5827
  onItemChat
5738
5828
  }, null, 8, [
@@ -5749,6 +5839,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5749
5839
  "live-derived",
5750
5840
  "view-title",
5751
5841
  "is-singleton",
5842
+ "readonly",
5752
5843
  "render",
5753
5844
  "locale"
5754
5845
  ])]),
@@ -5759,7 +5850,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5759
5850
  action: mutateModal.value.action,
5760
5851
  pending: mutatePending.value,
5761
5852
  error: mutateError.value,
5762
- onClose: _cache[23] || (_cache[23] = ($event) => mutateModal.value = null),
5853
+ onClose: _cache[24] || (_cache[24] = ($event) => mutateModal.value = null),
5763
5854
  onSubmit: submitMutateParams
5764
5855
  }, null, 8, [
5765
5856
  "action",
@@ -5772,7 +5863,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5772
5863
  title: collection.value.title,
5773
5864
  views: customViews.value,
5774
5865
  onChanged: onViewsChanged,
5775
- onClose: _cache[24] || (_cache[24] = ($event) => configOpen.value = false)
5866
+ onClose: _cache[25] || (_cache[25] = ($event) => configOpen.value = false)
5776
5867
  }, null, 8, [
5777
5868
  "slug",
5778
5869
  "title",
@@ -5787,29 +5878,29 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5787
5878
  "data-testid": "collections-chat-modal",
5788
5879
  onClick: withModifiers(closeChat, ["self"]),
5789
5880
  onKeydown: withKeys(closeChat, ["esc"])
5790
- }, [createElementVNode("div", _hoisted_82, [
5791
- createElementVNode("header", _hoisted_83, [
5792
- _cache[53] || (_cache[53] = 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)),
5793
- createElementVNode("div", _hoisted_84, [createElementVNode("h2", _hoisted_85, toDisplayString(unref(t)("collectionsView.chatTitle")), 1), createElementVNode("span", _hoisted_86, toDisplayString(collection.value.title), 1)]),
5881
+ }, [createElementVNode("div", _hoisted_84, [
5882
+ createElementVNode("header", _hoisted_85, [
5883
+ _cache[55] || (_cache[55] = 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)),
5884
+ createElementVNode("div", _hoisted_86, [createElementVNode("h2", _hoisted_87, toDisplayString(unref(t)("collectionsView.chatTitle")), 1), createElementVNode("span", _hoisted_88, toDisplayString(collection.value.title), 1)]),
5794
5885
  createElementVNode("button", {
5795
5886
  type: "button",
5796
5887
  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",
5797
5888
  "aria-label": unref(t)("common.close"),
5798
5889
  "data-testid": "collections-chat-close",
5799
5890
  onClick: closeChat
5800
- }, [..._cache[52] || (_cache[52] = [createElementVNode("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_87)
5891
+ }, [..._cache[54] || (_cache[54] = [createElementVNode("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_89)
5801
5892
  ]),
5802
- createElementVNode("div", _hoisted_88, [withDirectives(createElementVNode("textarea", {
5893
+ createElementVNode("div", _hoisted_90, [withDirectives(createElementVNode("textarea", {
5803
5894
  ref_key: "chatInputEl",
5804
5895
  ref: chatInputEl,
5805
- "onUpdate:modelValue": _cache[25] || (_cache[25] = ($event) => chatMessage.value = $event),
5896
+ "onUpdate:modelValue": _cache[26] || (_cache[26] = ($event) => chatMessage.value = $event),
5806
5897
  rows: "4",
5807
5898
  placeholder: unref(t)("collectionsView.chatPlaceholder"),
5808
5899
  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",
5809
5900
  "data-testid": "collections-chat-input",
5810
5901
  onKeydown: [withKeys(withModifiers(submitChat, ["meta"]), ["enter"]), withKeys(withModifiers(submitChat, ["ctrl"]), ["enter"])]
5811
- }, null, 40, _hoisted_89), [[vModelText, chatMessage.value]])]),
5812
- createElementVNode("footer", _hoisted_90, [createElementVNode("button", {
5902
+ }, null, 40, _hoisted_91), [[vModelText, chatMessage.value]])]),
5903
+ createElementVNode("footer", _hoisted_92, [createElementVNode("button", {
5813
5904
  type: "button",
5814
5905
  class: "h-8 px-2.5 rounded text-xs font-bold text-slate-500 hover:bg-slate-200/50 transition-colors",
5815
5906
  "data-testid": "collections-chat-cancel",
@@ -5820,7 +5911,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5820
5911
  disabled: !chatMessage.value.trim(),
5821
5912
  "data-testid": "collections-chat-send",
5822
5913
  onClick: submitChat
5823
- }, toDisplayString(unref(t)("collectionsView.chatStart")), 9, _hoisted_91)])
5914
+ }, toDisplayString(unref(t)("collectionsView.chatStart")), 9, _hoisted_93)])
5824
5915
  ])], 32)) : createCommentVNode("", true)
5825
5916
  ]);
5826
5917
  };
@@ -5972,10 +6063,10 @@ var _hoisted_18$3 = {
5972
6063
  key: 0,
5973
6064
  class: "text-teal-600"
5974
6065
  };
5975
- var _hoisted_19$1 = { key: 1 };
5976
- var _hoisted_20$1 = { class: "flex items-center justify-between pt-1 border-t border-slate-100" };
5977
- var _hoisted_21$1 = { class: "text-[10px] text-slate-400 font-mono" };
5978
- var _hoisted_22$1 = { class: "flex items-center gap-2" };
6066
+ var _hoisted_19$2 = { key: 1 };
6067
+ var _hoisted_20$2 = { class: "flex items-center justify-between pt-1 border-t border-slate-100" };
6068
+ var _hoisted_21$2 = { class: "text-[10px] text-slate-400 font-mono" };
6069
+ var _hoisted_22$2 = { class: "flex items-center gap-2" };
5979
6070
  var _hoisted_23$1 = ["data-testid"];
5980
6071
  var _hoisted_24 = ["data-testid", "onClick"];
5981
6072
  var _hoisted_25 = [
@@ -6076,9 +6167,9 @@ var DiscoverPanel_default = /* @__PURE__ */ defineComponent({
6076
6167
  createElementVNode("div", _hoisted_17$3, [
6077
6168
  createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.discover.fields", { count: entry.fieldCount })), 1),
6078
6169
  entry.views.length ? (openBlock(), createElementBlock("span", _hoisted_18$3, "· " + toDisplayString(entry.views.join(" · ")), 1)) : createCommentVNode("", true),
6079
- entry.hasSeed ? (openBlock(), createElementBlock("span", _hoisted_19$1, "· " + toDisplayString(unref(t)("collectionsView.discover.samples", { count: entry.seedCount })), 1)) : createCommentVNode("", true)
6170
+ entry.hasSeed ? (openBlock(), createElementBlock("span", _hoisted_19$2, "· " + toDisplayString(unref(t)("collectionsView.discover.samples", { count: entry.seedCount })), 1)) : createCommentVNode("", true)
6080
6171
  ]),
6081
- createElementVNode("div", _hoisted_20$1, [createElementVNode("span", _hoisted_21$1, "v" + toDisplayString(entry.version), 1), createElementVNode("div", _hoisted_22$1, [stateOf(entry).status === "error" ? (openBlock(), createElementBlock("span", {
6172
+ createElementVNode("div", _hoisted_20$2, [createElementVNode("span", _hoisted_21$2, "v" + toDisplayString(entry.version), 1), createElementVNode("div", _hoisted_22$2, [stateOf(entry).status === "error" ? (openBlock(), createElementBlock("span", {
6082
6173
  key: 0,
6083
6174
  class: "text-[11px] text-red-600",
6084
6175
  "data-testid": `discover-error-${entry.slug}`
@@ -6329,22 +6420,27 @@ var _hoisted_9$1 = {
6329
6420
  class: "rounded-xl border border-slate-200 bg-white px-6 py-12 text-center text-sm text-slate-500 shadow-sm"
6330
6421
  };
6331
6422
  var _hoisted_10$1 = { class: "font-medium text-slate-700" };
6332
- var _hoisted_11$1 = {
6333
- key: 3,
6334
- class: "grid gap-4 sm:grid-cols-2"
6423
+ var _hoisted_11$1 = { key: 3 };
6424
+ var _hoisted_12$1 = {
6425
+ key: 0,
6426
+ class: "flex items-center gap-1.5 mb-4",
6427
+ "data-testid": "collections-filter-chips"
6335
6428
  };
6336
- var _hoisted_12$1 = [
6429
+ var _hoisted_13$1 = ["data-testid", "onClick"];
6430
+ var _hoisted_14$1 = { class: "grid gap-4 sm:grid-cols-2" };
6431
+ var _hoisted_15$1 = [
6337
6432
  "aria-label",
6338
6433
  "data-testid",
6339
6434
  "onClick",
6340
6435
  "onKeydown"
6341
6436
  ];
6342
- var _hoisted_13$1 = { class: "material-symbols-outlined text-2xl" };
6343
- var _hoisted_14$1 = { class: "flex-1 min-w-0" };
6344
- var _hoisted_15$1 = { class: "block font-semibold text-slate-800 text-[15px] group-hover:text-indigo-950 transition-colors truncate" };
6345
- var _hoisted_16$1 = { class: "block text-[10px] text-slate-400 mt-1 tracking-wider font-semibold uppercase flex items-center gap-1.5" };
6346
- var _hoisted_17$1 = { class: "text-[10px] bg-slate-100 px-1 rounded lowercase text-slate-500 font-mono font-normal" };
6347
- var _hoisted_18$1 = [
6437
+ var _hoisted_16$1 = { class: "material-symbols-outlined text-2xl" };
6438
+ var _hoisted_17$1 = { class: "flex-1 min-w-0" };
6439
+ var _hoisted_18$1 = { class: "block font-semibold text-slate-800 text-[15px] group-hover:text-indigo-950 transition-colors truncate" };
6440
+ var _hoisted_19$1 = { class: "block text-[10px] text-slate-400 mt-1 tracking-wider font-semibold uppercase flex items-center gap-1.5" };
6441
+ var _hoisted_20$1 = { class: "text-[10px] bg-slate-100 px-1 rounded lowercase text-slate-500 font-mono font-normal" };
6442
+ var _hoisted_21$1 = ["data-testid"];
6443
+ var _hoisted_22$1 = [
6348
6444
  "title",
6349
6445
  "aria-label",
6350
6446
  "data-testid",
@@ -6363,6 +6459,18 @@ var CollectionsIndexView_default = /* @__PURE__ */ defineComponent({
6363
6459
  const collections = ref([]);
6364
6460
  const loading = ref(true);
6365
6461
  const loadError = ref(null);
6462
+ const FILTER_CHIPS = [
6463
+ "all",
6464
+ "editable",
6465
+ "data"
6466
+ ];
6467
+ const filter = ref("all");
6468
+ const hasReadonlyCollections = computed(() => collections.value.some((collection) => collection.readonly === true));
6469
+ const filteredCollections = computed(() => {
6470
+ if (filter.value === "editable") return collections.value.filter((collection) => collection.readonly !== true);
6471
+ if (filter.value === "data") return collections.value.filter((collection) => collection.readonly === true);
6472
+ return collections.value;
6473
+ });
6366
6474
  async function loadCollections() {
6367
6475
  loading.value = true;
6368
6476
  loadError.value = null;
@@ -6425,7 +6533,15 @@ var CollectionsIndexView_default = /* @__PURE__ */ defineComponent({
6425
6533
  tab.value === "discover" ? (openBlock(), createBlock(DiscoverPanel_default, {
6426
6534
  key: 1,
6427
6535
  onImported: loadCollections
6428
- })) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [loading.value ? (openBlock(), createElementBlock("div", _hoisted_7$1, [_cache[5] || (_cache[5] = 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_8$1, [_cache[6] || (_cache[6] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.loadFailed")) + ": " + toDisplayString(loadError.value), 1)])) : collections.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_9$1, [_cache[7] || (_cache[7] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300 mb-2" }, "dashboard_customize", -1)), createElementVNode("p", _hoisted_10$1, toDisplayString(unref(t)("collectionsView.indexEmpty")), 1)])) : (openBlock(), createElementBlock("div", _hoisted_11$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(collections.value, (collection) => {
6536
+ })) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [loading.value ? (openBlock(), createElementBlock("div", _hoisted_7$1, [_cache[5] || (_cache[5] = 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_8$1, [_cache[6] || (_cache[6] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.loadFailed")) + ": " + toDisplayString(loadError.value), 1)])) : collections.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_9$1, [_cache[7] || (_cache[7] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300 mb-2" }, "dashboard_customize", -1)), createElementVNode("p", _hoisted_10$1, toDisplayString(unref(t)("collectionsView.indexEmpty")), 1)])) : (openBlock(), createElementBlock("div", _hoisted_11$1, [hasReadonlyCollections.value ? (openBlock(), createElementBlock("div", _hoisted_12$1, [(openBlock(), createElementBlock(Fragment, null, renderList(FILTER_CHIPS, (chip) => {
6537
+ return createElementVNode("button", {
6538
+ key: chip,
6539
+ type: "button",
6540
+ class: normalizeClass(["px-3 h-7 rounded-full text-xs font-semibold border transition-colors", filter.value === chip ? "bg-indigo-600 border-indigo-600 text-white" : "bg-white border-slate-200 text-slate-500 hover:text-slate-700 hover:bg-slate-50"]),
6541
+ "data-testid": `collections-filter-${chip}`,
6542
+ onClick: ($event) => filter.value = chip
6543
+ }, toDisplayString(unref(t)(`collectionsView.filter.${chip}`)), 11, _hoisted_13$1);
6544
+ }), 64))])) : createCommentVNode("", true), createElementVNode("div", _hoisted_14$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(filteredCollections.value, (collection) => {
6429
6545
  return openBlock(), createElementBlock("div", {
6430
6546
  key: collection.slug,
6431
6547
  class: "group relative rounded-xl border border-slate-200 bg-white p-5 shadow-sm hover:shadow-md hover:border-indigo-300 transition-all duration-300 cursor-pointer flex items-center gap-4 focus:outline-none focus:ring-2 focus:ring-indigo-500/20",
@@ -6437,11 +6553,16 @@ var CollectionsIndexView_default = /* @__PURE__ */ defineComponent({
6437
6553
  onKeydown: [withKeys(withModifiers(($event) => openCollection(collection.slug), ["self"]), ["enter"]), withKeys(withModifiers(($event) => openCollection(collection.slug), ["self", "prevent"]), ["space"])]
6438
6554
  }, [
6439
6555
  createElementVNode("div", { class: normalizeClass(["absolute left-0 top-0 bottom-0 w-1 rounded-l-xl transition-all duration-300 group-hover:w-1.5", collection.source === "project" ? "bg-indigo-600" : "bg-violet-600"]) }, null, 2),
6440
- createElementVNode("div", { class: normalizeClass(["h-12 w-12 flex items-center justify-center rounded-xl transition-all duration-300 group-hover:scale-105 shadow-sm", collection.source === "project" ? "bg-indigo-50 text-indigo-600 group-hover:bg-indigo-100/80 border border-indigo-100/50" : "bg-violet-50 text-violet-600 group-hover:bg-violet-100/80 border border-violet-100/50"]) }, [createElementVNode("span", _hoisted_13$1, toDisplayString(collection.icon), 1)], 2),
6441
- createElementVNode("div", _hoisted_14$1, [createElementVNode("span", _hoisted_15$1, toDisplayString(collection.title), 1), createElementVNode("span", _hoisted_16$1, [
6556
+ createElementVNode("div", { class: normalizeClass(["h-12 w-12 flex items-center justify-center rounded-xl transition-all duration-300 group-hover:scale-105 shadow-sm", collection.source === "project" ? "bg-indigo-50 text-indigo-600 group-hover:bg-indigo-100/80 border border-indigo-100/50" : "bg-violet-50 text-violet-600 group-hover:bg-violet-100/80 border border-violet-100/50"]) }, [createElementVNode("span", _hoisted_16$1, toDisplayString(collection.icon), 1)], 2),
6557
+ createElementVNode("div", _hoisted_17$1, [createElementVNode("span", _hoisted_18$1, toDisplayString(collection.title), 1), createElementVNode("span", _hoisted_19$1, [
6442
6558
  createElementVNode("span", { class: normalizeClass(["h-1.5 w-1.5 rounded-full", collection.source === "project" ? "bg-indigo-500" : "bg-violet-500"]) }, null, 2),
6443
6559
  createTextVNode(" " + toDisplayString(unref(t)(`collectionsView.source.${collection.source}`)) + " · ", 1),
6444
- createElementVNode("code", _hoisted_17$1, toDisplayString(collection.slug), 1)
6560
+ createElementVNode("code", _hoisted_20$1, toDisplayString(collection.slug), 1),
6561
+ collection.readonly ? (openBlock(), createElementBlock("span", {
6562
+ key: 0,
6563
+ class: "inline-flex items-center gap-0.5 px-1.5 py-px rounded bg-amber-50 text-amber-700 border border-amber-200 normal-case tracking-normal",
6564
+ "data-testid": `collections-readonly-badge-${collection.slug}`
6565
+ }, [_cache[8] || (_cache[8] = createElementVNode("span", { class: "material-icons text-[11px]" }, "lock", -1)), createTextVNode(" " + toDisplayString(unref(t)("collectionsView.readonlyChip")), 1)], 8, _hoisted_21$1)) : createCommentVNode("", true)
6445
6566
  ])]),
6446
6567
  (openBlock(), createBlock(resolveDynamicComponent(unref(pinToggle)), {
6447
6568
  kind: "collection",
@@ -6453,17 +6574,18 @@ var CollectionsIndexView_default = /* @__PURE__ */ defineComponent({
6453
6574
  "title",
6454
6575
  "icon"
6455
6576
  ])),
6456
- createElementVNode("button", {
6577
+ !collection.readonly ? (openBlock(), createElementBlock("button", {
6578
+ key: 0,
6457
6579
  type: "button",
6458
6580
  class: "h-8 w-8 flex items-center justify-center rounded-lg bg-slate-50 text-slate-400 hover:bg-teal-50 hover:text-teal-600 transition-all duration-300",
6459
6581
  title: unref(t)("collectionsView.contribute"),
6460
6582
  "aria-label": unref(t)("collectionsView.contribute"),
6461
6583
  "data-testid": `collections-contribute-${collection.slug}`,
6462
6584
  onClick: withModifiers(($event) => startContributeChat(collection), ["stop"])
6463
- }, [..._cache[8] || (_cache[8] = [createElementVNode("span", { class: "material-icons text-lg" }, "ios_share", -1)])], 8, _hoisted_18$1),
6464
- _cache[9] || (_cache[9] = createElementVNode("div", { class: "h-8 w-8 flex items-center justify-center rounded-lg bg-slate-50 group-hover:bg-indigo-50 text-slate-400 group-hover:text-indigo-600 transition-all duration-300" }, [createElementVNode("span", { class: "material-icons text-lg transition-transform duration-300 group-hover:translate-x-0.5" }, "chevron_right")], -1))
6465
- ], 40, _hoisted_12$1);
6466
- }), 128))]))], 64))
6585
+ }, [..._cache[9] || (_cache[9] = [createElementVNode("span", { class: "material-icons text-lg" }, "ios_share", -1)])], 8, _hoisted_22$1)) : createCommentVNode("", true),
6586
+ _cache[10] || (_cache[10] = createElementVNode("div", { class: "h-8 w-8 flex items-center justify-center rounded-lg bg-slate-50 group-hover:bg-indigo-50 text-slate-400 group-hover:text-indigo-600 transition-all duration-300" }, [createElementVNode("span", { class: "material-icons text-lg transition-transform duration-300 group-hover:translate-x-0.5" }, "chevron_right")], -1))
6587
+ ], 40, _hoisted_15$1);
6588
+ }), 128))])]))], 64))
6467
6589
  ])]);
6468
6590
  };
6469
6591
  }