@mulmoclaude/collection-plugin 0.13.0 → 0.13.2

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
@@ -90,7 +90,7 @@ var i18n = createI18n({
90
90
  searchSummary: "Showing {shown} of {total}",
91
91
  noMatchingItems: "No matching items",
92
92
  clearSearch: "Clear search",
93
- flagFilterGroup: "Flag filters",
93
+ flagFilterButton: "Filters",
94
94
  flagFilterAll: "Filter by {label}",
95
95
  flagFilterHide: "Hiding {label}",
96
96
  flagFilterOnly: "Only {label}",
@@ -238,7 +238,7 @@ var i18n = createI18n({
238
238
  searchSummary: "{total} 件中 {shown} 件を表示",
239
239
  noMatchingItems: "一致する項目がありません",
240
240
  clearSearch: "検索をクリア",
241
- flagFilterGroup: "フラグで絞り込み",
241
+ flagFilterButton: "絞り込み",
242
242
  flagFilterAll: "{label} で絞り込む",
243
243
  flagFilterHide: "{label} を非表示中",
244
244
  flagFilterOnly: "{label} のみ表示中",
@@ -386,7 +386,7 @@ var i18n = createI18n({
386
386
  searchSummary: "显示 {total} 条中的 {shown} 条",
387
387
  noMatchingItems: "没有匹配的项目",
388
388
  clearSearch: "清除搜索",
389
- flagFilterGroup: "标记筛选",
389
+ flagFilterButton: "筛选",
390
390
  flagFilterAll: "按{label}筛选",
391
391
  flagFilterHide: "已隐藏{label}",
392
392
  flagFilterOnly: "仅显示{label}",
@@ -534,7 +534,7 @@ var i18n = createI18n({
534
534
  searchSummary: "{total}개 중 {shown}개 표시",
535
535
  noMatchingItems: "일치하는 항목이 없습니다",
536
536
  clearSearch: "검색 지우기",
537
- flagFilterGroup: "플래그 필터",
537
+ flagFilterButton: "필터",
538
538
  flagFilterAll: "{label}(으)로 필터",
539
539
  flagFilterHide: "{label} 숨김",
540
540
  flagFilterOnly: "{label}만 표시",
@@ -682,7 +682,7 @@ var i18n = createI18n({
682
682
  searchSummary: "Mostrando {shown} de {total}",
683
683
  noMatchingItems: "No hay elementos coincidentes",
684
684
  clearSearch: "Borrar búsqueda",
685
- flagFilterGroup: "Filtros por indicador",
685
+ flagFilterButton: "Filtros",
686
686
  flagFilterAll: "Filtrar por {label}",
687
687
  flagFilterHide: "Ocultando {label}",
688
688
  flagFilterOnly: "Solo {label}",
@@ -830,7 +830,7 @@ var i18n = createI18n({
830
830
  searchSummary: "Mostrando {shown} de {total}",
831
831
  noMatchingItems: "Nenhum item correspondente",
832
832
  clearSearch: "Limpar busca",
833
- flagFilterGroup: "Filtros por marcador",
833
+ flagFilterButton: "Filtros",
834
834
  flagFilterAll: "Filtrar por {label}",
835
835
  flagFilterHide: "Ocultando {label}",
836
836
  flagFilterOnly: "Somente {label}",
@@ -978,7 +978,7 @@ var i18n = createI18n({
978
978
  searchSummary: "Affichage de {shown} sur {total}",
979
979
  noMatchingItems: "Aucun élément correspondant",
980
980
  clearSearch: "Effacer la recherche",
981
- flagFilterGroup: "Filtres par indicateur",
981
+ flagFilterButton: "Filtres",
982
982
  flagFilterAll: "Filtrer par {label}",
983
983
  flagFilterHide: "{label} masqué",
984
984
  flagFilterOnly: "Uniquement {label}",
@@ -1126,7 +1126,7 @@ var i18n = createI18n({
1126
1126
  searchSummary: "{shown} von {total} werden angezeigt",
1127
1127
  noMatchingItems: "Keine passenden Einträge",
1128
1128
  clearSearch: "Suche zurücksetzen",
1129
- flagFilterGroup: "Flag-Filter",
1129
+ flagFilterButton: "Filter",
1130
1130
  flagFilterAll: "Nach {label} filtern",
1131
1131
  flagFilterHide: "{label} ausgeblendet",
1132
1132
  flagFilterOnly: "Nur {label}",
@@ -4019,199 +4019,201 @@ var _hoisted_21$3 = {
4019
4019
  var _hoisted_22$3 = ["placeholder", "aria-label"];
4020
4020
  var _hoisted_23$2 = ["aria-label"];
4021
4021
  var _hoisted_24$1 = { class: "flex items-center gap-2" };
4022
- var _hoisted_25$1 = ["aria-label"];
4023
- var _hoisted_26$1 = [
4022
+ var _hoisted_25$1 = ["aria-label", "aria-expanded"];
4023
+ var _hoisted_26$1 = {
4024
+ key: 0,
4025
+ class: "min-w-4 h-4 px-1 flex items-center justify-center rounded-full bg-indigo-600 text-white text-[10px] font-bold"
4026
+ };
4027
+ var _hoisted_27$1 = ["aria-label"];
4028
+ var _hoisted_28 = [
4024
4029
  "title",
4025
4030
  "aria-label",
4026
4031
  "aria-pressed",
4027
4032
  "data-testid",
4028
4033
  "onClick"
4029
4034
  ];
4030
- var _hoisted_27$1 = {
4031
- class: "material-icons text-sm",
4032
- "aria-hidden": "true"
4033
- };
4034
- var _hoisted_28 = ["aria-label"];
4035
- var _hoisted_29 = ["aria-pressed"];
4036
- var _hoisted_30 = ["aria-pressed"];
4035
+ var _hoisted_29 = { class: "flex-1 text-left" };
4036
+ var _hoisted_30 = ["aria-label"];
4037
4037
  var _hoisted_31 = ["aria-pressed"];
4038
- var _hoisted_32 = [
4038
+ var _hoisted_32 = ["aria-pressed"];
4039
+ var _hoisted_33 = ["aria-pressed"];
4040
+ var _hoisted_34 = [
4039
4041
  "aria-pressed",
4040
4042
  "data-testid",
4041
4043
  "onClick"
4042
4044
  ];
4043
- var _hoisted_33 = { class: "material-icons text-sm" };
4044
- var _hoisted_34 = [
4045
+ var _hoisted_35 = { class: "material-icons text-sm" };
4046
+ var _hoisted_36 = [
4045
4047
  "title",
4046
4048
  "aria-label",
4047
4049
  "aria-expanded"
4048
4050
  ];
4049
- var _hoisted_35 = {
4051
+ var _hoisted_37 = {
4050
4052
  key: 0,
4051
4053
  class: "absolute left-0 top-full mt-1 z-20 min-w-max rounded border border-slate-200 bg-white shadow-lg py-1",
4052
4054
  "data-testid": "collection-view-add-menu"
4053
4055
  };
4054
- var _hoisted_36 = ["title", "aria-label"];
4055
- var _hoisted_37 = ["value", "aria-label"];
4056
- var _hoisted_38 = ["value"];
4056
+ var _hoisted_38 = ["title", "aria-label"];
4057
4057
  var _hoisted_39 = ["value", "aria-label"];
4058
4058
  var _hoisted_40 = ["value"];
4059
- var _hoisted_41 = {
4059
+ var _hoisted_41 = ["value", "aria-label"];
4060
+ var _hoisted_42 = ["value"];
4061
+ var _hoisted_43 = {
4060
4062
  key: 4,
4061
4063
  class: "text-[10px] text-slate-400 font-bold uppercase tracking-wider select-none"
4062
4064
  };
4063
- var _hoisted_42 = {
4065
+ var _hoisted_44 = {
4064
4066
  key: 3,
4065
4067
  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",
4066
4068
  "data-testid": "collections-data-issues"
4067
4069
  };
4068
- var _hoisted_43 = { class: "flex-1" };
4069
- var _hoisted_44 = { class: "flex-1 overflow-auto" };
4070
- var _hoisted_45 = {
4070
+ var _hoisted_45 = { class: "flex-1" };
4071
+ var _hoisted_46 = { class: "flex-1 overflow-auto" };
4072
+ var _hoisted_47 = {
4071
4073
  key: 0,
4072
4074
  class: "flex flex-col items-center justify-center py-20 text-sm text-slate-500 gap-3"
4073
4075
  };
4074
- var _hoisted_46 = {
4076
+ var _hoisted_48 = {
4075
4077
  key: 1,
4076
4078
  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"
4077
4079
  };
4078
- var _hoisted_47 = { key: 2 };
4079
- var _hoisted_48 = {
4080
+ var _hoisted_49 = { key: 2 };
4081
+ var _hoisted_50 = {
4080
4082
  key: 3,
4081
4083
  class: "p-4"
4082
4084
  };
4083
- var _hoisted_49 = {
4085
+ var _hoisted_51 = {
4084
4086
  key: 4,
4085
4087
  class: "h-full flex flex-col"
4086
4088
  };
4087
- var _hoisted_50 = {
4089
+ var _hoisted_52 = {
4088
4090
  key: 0,
4089
4091
  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",
4090
4092
  "data-testid": "collections-inline-error"
4091
4093
  };
4092
- var _hoisted_51 = { class: "flex-1" };
4093
- var _hoisted_52 = ["aria-label"];
4094
- var _hoisted_53 = { class: "flex-1 min-h-0 px-3 py-2" };
4095
- var _hoisted_54 = {
4094
+ var _hoisted_53 = { class: "flex-1" };
4095
+ var _hoisted_54 = ["aria-label"];
4096
+ var _hoisted_55 = { class: "flex-1 min-h-0 px-3 py-2" };
4097
+ var _hoisted_56 = {
4096
4098
  key: 5,
4097
4099
  class: "h-full",
4098
4100
  "data-testid": "collection-custom-view-body"
4099
4101
  };
4100
- var _hoisted_55 = {
4102
+ var _hoisted_57 = {
4101
4103
  key: 6,
4102
4104
  class: "flex flex-col items-center justify-center py-20 text-sm text-slate-400 gap-2"
4103
4105
  };
4104
- var _hoisted_56 = { class: "font-semibold text-slate-600" };
4105
- var _hoisted_57 = {
4106
+ var _hoisted_58 = { class: "font-semibold text-slate-600" };
4107
+ var _hoisted_59 = {
4106
4108
  key: 7,
4107
4109
  class: "flex flex-col items-center justify-center py-20 text-sm text-slate-400 gap-2"
4108
4110
  };
4109
- var _hoisted_58 = { class: "font-semibold text-slate-600" };
4110
- var _hoisted_59 = {
4111
+ var _hoisted_60 = { class: "font-semibold text-slate-600" };
4112
+ var _hoisted_61 = {
4111
4113
  key: 8,
4112
4114
  class: "overflow-x-auto [container-type:inline-size]"
4113
4115
  };
4114
- var _hoisted_60 = {
4116
+ var _hoisted_62 = {
4115
4117
  key: 0,
4116
4118
  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",
4117
4119
  "data-testid": "collections-inline-error"
4118
4120
  };
4119
- var _hoisted_61 = { class: "flex-1" };
4120
- var _hoisted_62 = ["aria-label"];
4121
- var _hoisted_63 = { class: "min-w-full text-xs" };
4122
- var _hoisted_64 = { class: "bg-slate-50 border-b border-slate-200" };
4123
- var _hoisted_65 = ["aria-sort"];
4124
- var _hoisted_66 = { class: "flex items-center gap-1" };
4125
- var _hoisted_67 = ["title"];
4126
- var _hoisted_68 = [
4121
+ var _hoisted_63 = { class: "flex-1" };
4122
+ var _hoisted_64 = ["aria-label"];
4123
+ var _hoisted_65 = { class: "min-w-full text-xs" };
4124
+ var _hoisted_66 = { class: "bg-slate-50 border-b border-slate-200" };
4125
+ var _hoisted_67 = ["aria-sort"];
4126
+ var _hoisted_68 = { class: "flex items-center gap-1" };
4127
+ var _hoisted_69 = ["title"];
4128
+ var _hoisted_70 = [
4127
4129
  "data-testid",
4128
4130
  "aria-label",
4129
4131
  "onClick",
4130
4132
  "onPointerenter"
4131
4133
  ];
4132
- var _hoisted_69 = { class: "material-icons text-base align-middle" };
4133
- var _hoisted_70 = { class: "divide-y divide-slate-100 bg-white" };
4134
- var _hoisted_71 = [
4134
+ var _hoisted_71 = { class: "material-icons text-base align-middle" };
4135
+ var _hoisted_72 = { class: "divide-y divide-slate-100 bg-white" };
4136
+ var _hoisted_73 = [
4135
4137
  "aria-label",
4136
4138
  "data-testid",
4137
4139
  "onClick",
4138
4140
  "onKeydown"
4139
4141
  ];
4140
- var _hoisted_72 = [
4142
+ var _hoisted_74 = [
4141
4143
  "checked",
4142
4144
  "disabled",
4143
4145
  "data-testid",
4144
4146
  "aria-label",
4145
4147
  "onChange"
4146
4148
  ];
4147
- var _hoisted_73 = [
4149
+ var _hoisted_75 = [
4148
4150
  "checked",
4149
4151
  "disabled",
4150
4152
  "data-testid",
4151
4153
  "aria-label",
4152
4154
  "onChange"
4153
4155
  ];
4154
- var _hoisted_74 = ["data-testid", "aria-label"];
4155
- var _hoisted_75 = {
4156
+ var _hoisted_76 = ["data-testid", "aria-label"];
4157
+ var _hoisted_77 = {
4156
4158
  key: 3,
4157
4159
  class: "block truncate"
4158
4160
  };
4159
- var _hoisted_76 = [
4161
+ var _hoisted_78 = [
4160
4162
  "href",
4161
4163
  "tabindex",
4162
4164
  "data-testid",
4163
4165
  "onClick",
4164
4166
  "onKeydown"
4165
4167
  ];
4166
- var _hoisted_77 = [
4168
+ var _hoisted_79 = [
4167
4169
  "value",
4168
4170
  "disabled",
4169
4171
  "data-testid",
4170
4172
  "aria-label",
4171
4173
  "onChange"
4172
4174
  ];
4173
- var _hoisted_78 = {
4175
+ var _hoisted_80 = {
4174
4176
  key: 0,
4175
4177
  value: ""
4176
4178
  };
4177
- var _hoisted_79 = ["value"];
4178
- var _hoisted_80 = {
4179
+ var _hoisted_81 = ["value"];
4180
+ var _hoisted_82 = {
4179
4181
  key: 5,
4180
4182
  class: "block truncate tabular-nums font-semibold text-slate-900"
4181
4183
  };
4182
- var _hoisted_81 = {
4184
+ var _hoisted_83 = {
4183
4185
  key: 6,
4184
4186
  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"
4185
4187
  };
4186
- var _hoisted_82 = {
4188
+ var _hoisted_84 = {
4187
4189
  key: 7,
4188
4190
  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"
4189
4191
  };
4190
- var _hoisted_83 = ["data-testid"];
4191
- var _hoisted_84 = ["href", "data-testid"];
4192
- var _hoisted_85 = ["href", "data-testid"];
4193
- var _hoisted_86 = [
4192
+ var _hoisted_85 = ["data-testid"];
4193
+ var _hoisted_86 = ["href", "data-testid"];
4194
+ var _hoisted_87 = ["href", "data-testid"];
4195
+ var _hoisted_88 = [
4194
4196
  "href",
4195
4197
  "data-testid",
4196
4198
  "onClick"
4197
4199
  ];
4198
- var _hoisted_87 = {
4200
+ var _hoisted_89 = {
4199
4201
  key: 12,
4200
4202
  class: "block truncate text-slate-600"
4201
4203
  };
4202
- var _hoisted_88 = { class: "bg-white rounded-2xl shadow-2xl w-full max-w-xl flex flex-col border border-slate-200 overflow-hidden" };
4203
- var _hoisted_89 = { class: "px-6 py-4 border-b border-slate-100 flex items-center gap-3 bg-slate-50/50" };
4204
- var _hoisted_90 = { class: "flex-1" };
4205
- var _hoisted_91 = {
4204
+ var _hoisted_90 = { class: "bg-white rounded-2xl shadow-2xl w-full max-w-xl flex flex-col border border-slate-200 overflow-hidden" };
4205
+ var _hoisted_91 = { class: "px-6 py-4 border-b border-slate-100 flex items-center gap-3 bg-slate-50/50" };
4206
+ var _hoisted_92 = { class: "flex-1" };
4207
+ var _hoisted_93 = {
4206
4208
  id: "collections-chat-title",
4207
4209
  class: "text-sm font-bold text-slate-800 uppercase tracking-wide"
4208
4210
  };
4209
- var _hoisted_92 = { class: "text-xs text-slate-400 font-semibold" };
4210
- var _hoisted_93 = ["aria-label"];
4211
- var _hoisted_94 = { class: "px-6 py-5" };
4212
- var _hoisted_95 = ["placeholder", "onKeydown"];
4213
- var _hoisted_96 = { class: "px-6 py-3.5 border-t border-slate-100 flex items-center justify-end gap-2 bg-slate-50/50" };
4214
- var _hoisted_97 = ["disabled"];
4211
+ var _hoisted_94 = { class: "text-xs text-slate-400 font-semibold" };
4212
+ var _hoisted_95 = ["aria-label"];
4213
+ var _hoisted_96 = { class: "px-6 py-5" };
4214
+ var _hoisted_97 = ["placeholder", "onKeydown"];
4215
+ var _hoisted_98 = { class: "px-6 py-3.5 border-t border-slate-100 flex items-center justify-end gap-2 bg-slate-50/50" };
4216
+ var _hoisted_99 = ["disabled"];
4215
4217
  /** `slug` / `selected` are supplied only in EMBEDDED mode (the
4216
4218
  * `presentCollection` chat card mounts this component and drives both
4217
4219
  * from the tool result). In standalone route mode (the
@@ -4223,6 +4225,10 @@ var _hoisted_97 = ["disabled"];
4223
4225
  * actions send into the current session instead of spawning a new
4224
4226
  * chat (see `runAction` / `submitChat`). */
4225
4227
  var COMPLETION_CHIP_KEY = "__completion";
4228
+ /** The field types that earn a filter-menu entry: declared predicates
4229
+ * (`flag`) plus the fields that ARE a predicate already — a stored
4230
+ * `boolean` and a `toggle`'s projected on/off state. Enums stay out:
4231
+ * they need a value picker, and kanban already slices by enum. */
4226
4232
  var LIVE_REFRESH_DEBOUNCE_MS = 150;
4227
4233
  //#endregion
4228
4234
  //#region src/vue/components/CollectionView.vue
@@ -4358,14 +4364,34 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
4358
4364
  return slug ? readCollectionFlagFilters(slug) : {};
4359
4365
  }
4360
4366
  const flagFilters = ref(storedFlagFiltersFor(activeSlug.value));
4367
+ const CHIP_FIELD_TYPES = /* @__PURE__ */ new Set([
4368
+ "flag",
4369
+ "boolean",
4370
+ "toggle"
4371
+ ]);
4372
+ /** True when an existing FIELD chip already expresses the legacy
4373
+ * completion predicate exactly, so a synthesized "done" chip would be a
4374
+ * duplicate: a boolean `completionField` (done ⇔ `"true"` ⇔ the
4375
+ * boolean's own chip), or a `toggle` projecting the `completionField`
4376
+ * whose `onValue` is the single done value (the todos-schema shape:
4377
+ * toggle "Done" on `status` + `completionDoneValues: ["done"]`). A
4378
+ * superset pair (extra done values) still synthesizes — no field chip
4379
+ * covers it. */
4380
+ function completionCoveredByFieldChip(schema) {
4381
+ const { completionField, completionDoneValues } = schema;
4382
+ if (completionDoneValues?.length !== 1) return false;
4383
+ const [doneValue] = completionDoneValues;
4384
+ if (schema.fields[completionField ?? ""]?.type === "boolean") return doneValue === "true";
4385
+ return Object.values(schema.fields).some((field) => field.type === "toggle" && field.field === completionField && field.onValue === doneValue);
4386
+ }
4361
4387
  const flagChips = computed(() => {
4362
4388
  const schema = collection.value?.schema;
4363
4389
  if (!schema) return [];
4364
- const chips = Object.entries(schema.fields).filter(([, field]) => field.type === "flag").map(([key, field]) => ({
4390
+ const chips = Object.entries(schema.fields).filter(([, field]) => CHIP_FIELD_TYPES.has(field.type)).map(([key, field]) => ({
4365
4391
  key,
4366
4392
  label: field.label ?? key
4367
4393
  }));
4368
- if (schema.completionField && schema.completionDoneValues && schema.fields[schema.completionField]?.type !== "flag" && schema.fields[COMPLETION_CHIP_KEY] === void 0) chips.push({
4394
+ if (schema.completionField && schema.completionDoneValues && schema.fields[schema.completionField]?.type !== "flag" && !completionCoveredByFieldChip(schema) && schema.fields[COMPLETION_CHIP_KEY] === void 0) chips.push({
4369
4395
  key: COMPLETION_CHIP_KEY,
4370
4396
  label: t("collectionsView.flagDoneChip"),
4371
4397
  synthetic: true
@@ -4388,11 +4414,16 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
4388
4414
  return render.deriveRecord(item)[key] === true;
4389
4415
  }
4390
4416
  /** The chip's boolean for one row — `itemIsDone` for the synthesized
4391
- * completion chip, the computed flag value otherwise. */
4417
+ * completion chip, the stored/projected value for `boolean`/`toggle`
4418
+ * fields, the computed flag value otherwise. */
4392
4419
  function chipMatches(chip, item) {
4393
4420
  const schema = collection.value?.schema;
4394
4421
  if (!schema) return false;
4395
- return chip.synthetic ? itemIsDone(schema, item) : flagValueOf(chip.key, item);
4422
+ if (chip.synthetic) return itemIsDone(schema, item);
4423
+ const field = schema.fields[chip.key];
4424
+ if (field?.type === "toggle") return toggleChecked(item, field);
4425
+ if (field?.type === "boolean") return item[chip.key] === true;
4426
+ return flagValueOf(chip.key, item);
4396
4427
  }
4397
4428
  /** `filteredItems` further narrowed by every ACTIVE chip (AND). Consumed
4398
4429
  * only by the table (sortedItems / count summary / empty state). */
@@ -4412,15 +4443,41 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
4412
4443
  } : rest;
4413
4444
  }
4414
4445
  function flagChipIcon(key) {
4446
+ return flagFilterMode(key) === "only" ? "check_box" : "check_box_outline_blank";
4447
+ }
4448
+ function flagChipIconClass(key) {
4415
4449
  const mode = flagFilterMode(key);
4416
- return mode === "hide" ? "visibility_off" : mode === "only" ? "filter_alt" : "visibility";
4450
+ if (mode === "hide") return "text-slate-600";
4451
+ if (mode === "only") return "text-indigo-600";
4452
+ return "text-slate-300";
4417
4453
  }
4418
4454
  function flagChipClass(key) {
4419
4455
  const mode = flagFilterMode(key);
4420
- if (mode === "hide") return "bg-slate-600 text-white";
4421
- if (mode === "only") return "bg-indigo-600 text-white";
4422
- return "bg-white text-slate-500 border border-slate-200 hover:bg-slate-50";
4423
- }
4456
+ if (mode === "hide") return "bg-slate-100 text-slate-700";
4457
+ if (mode === "only") return "bg-indigo-50 text-indigo-700";
4458
+ return "text-slate-500";
4459
+ }
4460
+ /** How many chips currently filter (badge on the menu trigger). */
4461
+ const activeFlagFilterCount = computed(() => flagChips.value.filter((chip) => flagFilterMode(chip.key) !== void 0).length);
4462
+ const filterMenuOpen = ref(false);
4463
+ const filterMenuRef = ref(null);
4464
+ /** Shadow-DOM-safe "did this event land inside the element?". A document-level
4465
+ * listener sees `event.target` retargeted to the shadow HOST when the
4466
+ * component is mounted in a shadow root (MulmoTerminal's PluginFrame), so
4467
+ * `element.contains()` is always false there and the menu closes on the
4468
+ * mousedown before the inner button's click can fire. `composedPath()` still
4469
+ * lists the element for open shadow trees — and in the light DOM too, so both
4470
+ * hosts share this one test. */
4471
+ function eventInsideElement(event, element) {
4472
+ return element !== null && event.composedPath().includes(element);
4473
+ }
4474
+ function closeFilterMenuOnOutsideClick(event) {
4475
+ if (!eventInsideElement(event, filterMenuRef.value)) filterMenuOpen.value = false;
4476
+ }
4477
+ watch(filterMenuOpen, (open) => {
4478
+ if (open) document.addEventListener("mousedown", closeFilterMenuOnOutsideClick);
4479
+ else document.removeEventListener("mousedown", closeFilterMenuOnOutsideClick);
4480
+ });
4424
4481
  function flagChipTitle(chip) {
4425
4482
  const mode = flagFilterMode(chip.key);
4426
4483
  if (mode === "hide") return t("collectionsView.flagFilterHide", { label: chip.label });
@@ -4944,7 +5001,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
4944
5001
  addMenuOpen.value = !addMenuOpen.value;
4945
5002
  }
4946
5003
  function closeAddMenuOnOutsideClick(event) {
4947
- if (!addMenuRef.value?.contains(event.target)) addMenuOpen.value = false;
5004
+ if (!eventInsideElement(event, addMenuRef.value)) addMenuOpen.value = false;
4948
5005
  }
4949
5006
  watch(addMenuOpen, (open) => {
4950
5007
  if (open) document.addEventListener("mousedown", closeAddMenuOnOutsideClick);
@@ -5439,6 +5496,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5439
5496
  anchorOverride.value = null;
5440
5497
  kanbanOverride.value = null;
5441
5498
  addMenuOpen.value = false;
5499
+ filterMenuOpen.value = false;
5442
5500
  sortState.value = storedSortFor(slug);
5443
5501
  flagFilters.value = storedFlagFiltersFor(slug);
5444
5502
  }
@@ -5489,6 +5547,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5489
5547
  clearLiveRefreshTimer();
5490
5548
  if (refreshNoteTimer !== void 0) clearTimeout(refreshNoteTimer);
5491
5549
  document.removeEventListener("mousedown", closeAddMenuOnOutsideClick);
5550
+ document.removeEventListener("mousedown", closeFilterMenuOnOutsideClick);
5492
5551
  });
5493
5552
  watch([
5494
5553
  activeView,
@@ -5525,9 +5584,9 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5525
5584
  "aria-label": unref(t)("collectionsView.backToIndex"),
5526
5585
  "data-testid": "collections-back",
5527
5586
  onClick: goBack
5528
- }, [..._cache[27] || (_cache[27] = [createElementVNode("span", { class: "material-icons text-lg" }, "arrow_back", -1)])], 8, _hoisted_3$5)) : createCommentVNode("", true),
5587
+ }, [..._cache[28] || (_cache[28] = [createElementVNode("span", { class: "material-icons text-lg" }, "arrow_back", -1)])], 8, _hoisted_3$5)) : createCommentVNode("", true),
5529
5588
  collection.value ? (openBlock(), createElementBlock("div", _hoisted_4$5, [createElementVNode("span", _hoisted_5$5, toDisplayString(collection.value.icon), 1)])) : createCommentVNode("", true),
5530
- 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", {
5589
+ 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[29] || (_cache[29] = createElementVNode("span", { class: "material-icons text-[11px]" }, "lock", -1)), createTextVNode(" " + toDisplayString(unref(t)("collectionsView.readonlyChip")), 1)]), dataSourceRoute.value ? (openBlock(), createElementBlock("a", {
5531
5590
  key: 0,
5532
5591
  href: dataSourceRoute.value ?? void 0,
5533
5592
  class: "ml-1 normal-case tracking-normal font-mono font-normal text-slate-500 hover:text-indigo-700 hover:underline",
@@ -5560,7 +5619,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5560
5619
  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",
5561
5620
  "data-testid": "collections-chat",
5562
5621
  onClick: openChat
5563
- }, [_cache[29] || (_cache[29] = createElementVNode("span", { class: "material-icons text-sm" }, "forum", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.chat")), 1)])) : createCommentVNode("", true),
5622
+ }, [_cache[30] || (_cache[30] = createElementVNode("span", { class: "material-icons text-sm" }, "forum", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.chat")), 1)])) : createCommentVNode("", true),
5564
5623
  (openBlock(true), createElementBlock(Fragment, null, renderList(collectionActions.value, (action) => {
5565
5624
  return openBlock(), createElementBlock("button", {
5566
5625
  key: action.id,
@@ -5577,7 +5636,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5577
5636
  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",
5578
5637
  "data-testid": "collections-add-item",
5579
5638
  onClick: openCreate
5580
- }, [_cache[30] || (_cache[30] = createElementVNode("span", { class: "material-icons text-sm" }, "add", -1)), createElementVNode("span", null, toDisplayString(unref(t)("common.add")), 1)])) : createCommentVNode("", true),
5639
+ }, [_cache[31] || (_cache[31] = createElementVNode("span", { class: "material-icons text-sm" }, "add", -1)), createElementVNode("span", null, toDisplayString(unref(t)("common.add")), 1)])) : createCommentVNode("", true),
5581
5640
  canDeleteCollection.value && !embedded.value ? (openBlock(), createElementBlock("button", {
5582
5641
  key: 6,
5583
5642
  type: "button",
@@ -5586,7 +5645,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5586
5645
  "aria-label": unref(t)("collectionsView.deleteCollection"),
5587
5646
  "data-testid": "collections-delete",
5588
5647
  onClick: confirmCollectionDelete
5589
- }, [..._cache[31] || (_cache[31] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_16$4)) : createCommentVNode("", true),
5648
+ }, [..._cache[32] || (_cache[32] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_16$4)) : createCommentVNode("", true),
5590
5649
  canDeleteFeed.value && !embedded.value ? (openBlock(), createElementBlock("button", {
5591
5650
  key: 7,
5592
5651
  type: "button",
@@ -5595,11 +5654,11 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5595
5654
  "aria-label": unref(t)("collectionsView.deleteFeed"),
5596
5655
  "data-testid": "feeds-delete",
5597
5656
  onClick: confirmFeedDelete
5598
- }, [..._cache[32] || (_cache[32] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_17$4)) : createCommentVNode("", true)
5657
+ }, [..._cache[33] || (_cache[33] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_17$4)) : createCommentVNode("", true)
5599
5658
  ])) : createCommentVNode("", true),
5600
- 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),
5659
+ refreshNote.value ? (openBlock(), createElementBlock("div", _hoisted_18$4, [_cache[34] || (_cache[34] = createElementVNode("span", { class: "material-icons text-base text-indigo-600" }, "hourglass_top", -1)), createElementVNode("span", _hoisted_19$3, toDisplayString(refreshNote.value), 1)])) : createCommentVNode("", true),
5601
5660
  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, [
5602
- _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)),
5661
+ _cache[36] || (_cache[36] = 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)),
5603
5662
  withDirectives(createElementVNode("input", {
5604
5663
  "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => searchQuery.value = $event),
5605
5664
  type: "text",
@@ -5613,25 +5672,48 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5613
5672
  "aria-label": unref(t)("collectionsView.clearSearch"),
5614
5673
  class: "absolute inset-y-0 right-0 flex items-center pr-2.5 text-slate-400 hover:text-slate-600",
5615
5674
  onClick: _cache[2] || (_cache[2] = ($event) => searchQuery.value = "")
5616
- }, [..._cache[34] || (_cache[34] = [createElementVNode("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_23$2)) : createCommentVNode("", true)
5675
+ }, [..._cache[35] || (_cache[35] = [createElementVNode("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_23$2)) : createCommentVNode("", true)
5617
5676
  ])) : createCommentVNode("", true), createElementVNode("div", _hoisted_24$1, [
5618
5677
  activeView.value === "table" && flagChips.value.length > 0 && items.value.length > 0 ? (openBlock(), createElementBlock("div", {
5619
5678
  key: 0,
5620
- class: "flex items-center gap-0.5",
5679
+ ref_key: "filterMenuRef",
5680
+ ref: filterMenuRef,
5681
+ class: "relative"
5682
+ }, [createElementVNode("button", {
5683
+ type: "button",
5684
+ class: normalizeClass(["h-8 px-2.5 flex items-center gap-1 rounded-full text-xs font-medium transition-colors", activeFlagFilterCount.value > 0 ? "bg-indigo-50 text-indigo-700 border border-indigo-300" : "bg-transparent text-slate-500 border border-dashed border-slate-300 hover:bg-slate-50"]),
5685
+ "aria-label": unref(t)("collectionsView.flagFilterButton"),
5686
+ "aria-expanded": filterMenuOpen.value,
5687
+ "data-testid": "collections-filter-menu",
5688
+ onClick: _cache[3] || (_cache[3] = ($event) => filterMenuOpen.value = !filterMenuOpen.value)
5689
+ }, [
5690
+ _cache[37] || (_cache[37] = createElementVNode("span", {
5691
+ class: "material-icons text-sm",
5692
+ "aria-hidden": "true"
5693
+ }, "filter_alt", -1)),
5694
+ createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.flagFilterButton")), 1),
5695
+ activeFlagFilterCount.value > 0 ? (openBlock(), createElementBlock("span", _hoisted_26$1, toDisplayString(activeFlagFilterCount.value), 1)) : createCommentVNode("", true)
5696
+ ], 10, _hoisted_25$1), filterMenuOpen.value ? (openBlock(), createElementBlock("div", {
5697
+ key: 0,
5698
+ class: "absolute left-0 top-full mt-1 z-20 min-w-max rounded border border-slate-200 bg-white shadow-lg py-1",
5621
5699
  role: "group",
5622
- "aria-label": unref(t)("collectionsView.flagFilterGroup")
5700
+ "aria-label": unref(t)("collectionsView.flagFilterButton"),
5701
+ "data-testid": "collections-filter-menu-panel"
5623
5702
  }, [(openBlock(true), createElementBlock(Fragment, null, renderList(flagChips.value, (chip) => {
5624
5703
  return openBlock(), createElementBlock("button", {
5625
5704
  key: chip.key,
5626
5705
  type: "button",
5627
- class: normalizeClass(["h-8 px-2.5 flex items-center gap-1 rounded text-xs font-bold transition-colors", flagChipClass(chip.key)]),
5706
+ class: normalizeClass(["w-full h-8 px-3 flex items-center gap-2 text-xs font-medium transition-colors hover:bg-slate-50", flagChipClass(chip.key)]),
5628
5707
  title: flagChipTitle(chip),
5629
5708
  "aria-label": flagChipTitle(chip),
5630
5709
  "aria-pressed": flagFilterMode(chip.key) !== void 0,
5631
5710
  "data-testid": `collections-flag-chip-${chip.key}`,
5632
5711
  onClick: ($event) => cycleFlagFilter(chip.key)
5633
- }, [createElementVNode("span", _hoisted_27$1, toDisplayString(flagChipIcon(chip.key)), 1), createElementVNode("span", null, toDisplayString(chip.label), 1)], 10, _hoisted_26$1);
5634
- }), 128))], 8, _hoisted_25$1)) : createCommentVNode("", true),
5712
+ }, [createElementVNode("span", {
5713
+ class: normalizeClass(["material-icons text-sm", flagChipIconClass(chip.key)]),
5714
+ "aria-hidden": "true"
5715
+ }, toDisplayString(flagChipIcon(chip.key)), 3), createElementVNode("span", _hoisted_29, toDisplayString(chip.label), 1)], 10, _hoisted_28);
5716
+ }), 128))], 8, _hoisted_27$1)) : createCommentVNode("", true)], 512)) : createCommentVNode("", true),
5635
5717
  !__props.hideViewToggle && (hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value) ? (openBlock(), createElementBlock("div", {
5636
5718
  key: 1,
5637
5719
  class: "flex gap-0.5",
@@ -5643,24 +5725,24 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5643
5725
  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"]),
5644
5726
  "aria-pressed": activeView.value === "table",
5645
5727
  "data-testid": "collection-view-toggle-table",
5646
- onClick: _cache[3] || (_cache[3] = ($event) => setView("table"))
5647
- }, [_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_29),
5728
+ onClick: _cache[4] || (_cache[4] = ($event) => setView("table"))
5729
+ }, [_cache[38] || (_cache[38] = createElementVNode("span", { class: "material-icons text-sm" }, "table_rows", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewTable")), 1)], 10, _hoisted_31),
5648
5730
  hasCalendar.value ? (openBlock(), createElementBlock("button", {
5649
5731
  key: 0,
5650
5732
  type: "button",
5651
5733
  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"]),
5652
5734
  "aria-pressed": activeView.value === "calendar",
5653
5735
  "data-testid": "collection-view-toggle-calendar",
5654
- onClick: _cache[4] || (_cache[4] = ($event) => setView("calendar"))
5655
- }, [_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_30)) : createCommentVNode("", true),
5736
+ onClick: _cache[5] || (_cache[5] = ($event) => setView("calendar"))
5737
+ }, [_cache[39] || (_cache[39] = createElementVNode("span", { class: "material-icons text-sm" }, "calendar_month", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewCalendar")), 1)], 10, _hoisted_32)) : createCommentVNode("", true),
5656
5738
  hasKanban.value ? (openBlock(), createElementBlock("button", {
5657
5739
  key: 1,
5658
5740
  type: "button",
5659
5741
  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"]),
5660
5742
  "aria-pressed": activeView.value === "kanban",
5661
5743
  "data-testid": "collection-view-toggle-kanban",
5662
- onClick: _cache[5] || (_cache[5] = ($event) => setView("kanban"))
5663
- }, [_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_31)) : createCommentVNode("", true),
5744
+ onClick: _cache[6] || (_cache[6] = ($event) => setView("kanban"))
5745
+ }, [_cache[40] || (_cache[40] = createElementVNode("span", { class: "material-icons text-sm" }, "view_kanban", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewKanban")), 1)], 10, _hoisted_33)) : createCommentVNode("", true),
5664
5746
  (openBlock(true), createElementBlock(Fragment, null, renderList(customViews.value, (cv) => {
5665
5747
  return openBlock(), createElementBlock("button", {
5666
5748
  key: cv.id,
@@ -5669,7 +5751,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5669
5751
  "aria-pressed": activeView.value === unref(customViewKey)(cv.id),
5670
5752
  "data-testid": `collection-view-custom-${cv.id}`,
5671
5753
  onClick: ($event) => setCustomView(cv.id)
5672
- }, [createElementVNode("span", _hoisted_33, toDisplayString(cv.icon || (cv.target === "mobile" ? "smartphone" : "dashboard_customize")), 1), createElementVNode("span", null, toDisplayString(cv.label), 1)], 10, _hoisted_32);
5754
+ }, [createElementVNode("span", _hoisted_35, toDisplayString(cv.icon || (cv.target === "mobile" ? "smartphone" : "dashboard_customize")), 1), createElementVNode("span", null, toDisplayString(cv.label), 1)], 10, _hoisted_34);
5673
5755
  }), 128)),
5674
5756
  canAddCustomView.value ? (openBlock(), createElementBlock("div", {
5675
5757
  key: 2,
@@ -5684,17 +5766,17 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5684
5766
  "aria-expanded": addMenuOpen.value,
5685
5767
  "data-testid": "collection-view-add",
5686
5768
  onClick: onAddViewClick
5687
- }, [..._cache[39] || (_cache[39] = [createElementVNode("span", { class: "material-icons text-sm" }, "add", -1)])], 8, _hoisted_34), addMenuOpen.value ? (openBlock(), createElementBlock("div", _hoisted_35, [createElementVNode("button", {
5769
+ }, [..._cache[41] || (_cache[41] = [createElementVNode("span", { class: "material-icons text-sm" }, "add", -1)])], 8, _hoisted_36), addMenuOpen.value ? (openBlock(), createElementBlock("div", _hoisted_37, [createElementVNode("button", {
5688
5770
  type: "button",
5689
5771
  class: "w-full h-8 px-3 flex items-center gap-2 text-xs font-bold text-slate-600 hover:bg-slate-50",
5690
5772
  "data-testid": "collection-view-add-desktop",
5691
- onClick: _cache[6] || (_cache[6] = ($event) => addCustomView("desktop"))
5692
- }, [_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", {
5773
+ onClick: _cache[7] || (_cache[7] = ($event) => addCustomView("desktop"))
5774
+ }, [_cache[42] || (_cache[42] = createElementVNode("span", { class: "material-icons text-sm" }, "dashboard_customize", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.addViewDesktop")), 1)]), createElementVNode("button", {
5693
5775
  type: "button",
5694
5776
  class: "w-full h-8 px-3 flex items-center gap-2 text-xs font-bold text-slate-600 hover:bg-slate-50",
5695
5777
  "data-testid": "collection-view-add-mobile",
5696
- onClick: _cache[7] || (_cache[7] = ($event) => addCustomView("mobile"))
5697
- }, [_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),
5778
+ onClick: _cache[8] || (_cache[8] = ($event) => addCustomView("mobile"))
5779
+ }, [_cache[43] || (_cache[43] = createElementVNode("span", { class: "material-icons text-sm" }, "smartphone", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.addViewMobile")), 1)])])) : createCommentVNode("", true)], 512)) : createCommentVNode("", true),
5698
5780
  canConfigureViews.value ? (openBlock(), createElementBlock("button", {
5699
5781
  key: 3,
5700
5782
  type: "button",
@@ -5702,51 +5784,51 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5702
5784
  title: unref(t)("collectionsView.config.open"),
5703
5785
  "aria-label": unref(t)("collectionsView.config.open"),
5704
5786
  "data-testid": "collection-config-open",
5705
- onClick: _cache[8] || (_cache[8] = ($event) => configOpen.value = true)
5706
- }, [..._cache[42] || (_cache[42] = [createElementVNode("span", { class: "material-icons text-sm" }, "settings", -1)])], 8, _hoisted_36)) : createCommentVNode("", true)
5707
- ], 8, _hoisted_28)) : createCommentVNode("", true),
5787
+ onClick: _cache[9] || (_cache[9] = ($event) => configOpen.value = true)
5788
+ }, [..._cache[44] || (_cache[44] = [createElementVNode("span", { class: "material-icons text-sm" }, "settings", -1)])], 8, _hoisted_38)) : createCommentVNode("", true)
5789
+ ], 8, _hoisted_30)) : createCommentVNode("", true),
5708
5790
  calendarActive.value && dateFields.value.length > 1 ? (openBlock(), createElementBlock("select", {
5709
5791
  key: 2,
5710
5792
  value: calendarAnchorField.value,
5711
5793
  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",
5712
5794
  "aria-label": unref(t)("collectionsView.calendarFieldLabel"),
5713
5795
  "data-testid": "collection-calendar-field",
5714
- onChange: _cache[9] || (_cache[9] = ($event) => anchorOverride.value = $event.target.value)
5796
+ onChange: _cache[10] || (_cache[10] = ($event) => anchorOverride.value = $event.target.value)
5715
5797
  }, [(openBlock(true), createElementBlock(Fragment, null, renderList(dateFields.value, (key) => {
5716
5798
  return openBlock(), createElementBlock("option", {
5717
5799
  key,
5718
5800
  value: key
5719
- }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_38);
5720
- }), 128))], 40, _hoisted_37)) : createCommentVNode("", true),
5801
+ }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_40);
5802
+ }), 128))], 40, _hoisted_39)) : createCommentVNode("", true),
5721
5803
  kanbanActive.value && enumFields.value.length > 1 ? (openBlock(), createElementBlock("select", {
5722
5804
  key: 3,
5723
5805
  value: kanbanGroupField.value,
5724
5806
  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",
5725
5807
  "aria-label": unref(t)("collectionsView.kanbanFieldLabel"),
5726
5808
  "data-testid": "collection-kanban-field",
5727
- onChange: _cache[10] || (_cache[10] = ($event) => kanbanOverride.value = $event.target.value)
5809
+ onChange: _cache[11] || (_cache[11] = ($event) => kanbanOverride.value = $event.target.value)
5728
5810
  }, [(openBlock(true), createElementBlock(Fragment, null, renderList(enumFields.value, (key) => {
5729
5811
  return openBlock(), createElementBlock("option", {
5730
5812
  key,
5731
5813
  value: key
5732
- }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_40);
5733
- }), 128))], 40, _hoisted_39)) : createCommentVNode("", true),
5734
- items.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_41, toDisplayString(unref(t)("collectionsView.searchSummary", {
5814
+ }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_42);
5815
+ }), 128))], 40, _hoisted_41)) : createCommentVNode("", true),
5816
+ items.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_43, toDisplayString(unref(t)("collectionsView.searchSummary", {
5735
5817
  shown: activeView.value === "table" ? tableFilteredItems.value.length : filteredItems.value.length,
5736
5818
  total: items.value.length
5737
5819
  })), 1)) : createCommentVNode("", true)
5738
5820
  ])])) : createCommentVNode("", true),
5739
- collection.value && dataIssues.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_42, [
5740
- _cache[44] || (_cache[44] = createElementVNode("span", { class: "material-icons text-amber-600" }, "warning", -1)),
5741
- createElementVNode("span", _hoisted_43, toDisplayString(unref(t)("collectionsView.dataIssuesDetected", { count: dataIssues.value.length })), 1),
5821
+ collection.value && dataIssues.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_44, [
5822
+ _cache[46] || (_cache[46] = createElementVNode("span", { class: "material-icons text-amber-600" }, "warning", -1)),
5823
+ createElementVNode("span", _hoisted_45, toDisplayString(unref(t)("collectionsView.dataIssuesDetected", { count: dataIssues.value.length })), 1),
5742
5824
  createElementVNode("button", {
5743
5825
  type: "button",
5744
5826
  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",
5745
5827
  "data-testid": "collections-repair",
5746
5828
  onClick: repairCollection
5747
- }, [_cache[43] || (_cache[43] = createElementVNode("span", { class: "material-icons text-sm" }, "build", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.repair")), 1)])
5829
+ }, [_cache[45] || (_cache[45] = createElementVNode("span", { class: "material-icons text-sm" }, "build", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.repair")), 1)])
5748
5830
  ])) : createCommentVNode("", true),
5749
- createElementVNode("div", _hoisted_44, [loading.value ? (openBlock(), createElementBlock("div", _hoisted_45, [_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_46, [_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_47)) : calendarActive.value ? (openBlock(), createElementBlock("div", _hoisted_48, [createVNode(CollectionCalendarView_default, {
5831
+ createElementVNode("div", _hoisted_46, [loading.value ? (openBlock(), createElementBlock("div", _hoisted_47, [_cache[47] || (_cache[47] = 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_48, [_cache[48] || (_cache[48] = 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_49)) : calendarActive.value ? (openBlock(), createElementBlock("div", _hoisted_50, [createVNode(CollectionCalendarView_default, {
5750
5832
  schema: collection.value.schema,
5751
5833
  items: filteredItems.value,
5752
5834
  "anchor-field": calendarAnchorField.value,
@@ -5782,7 +5864,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5782
5864
  }, {
5783
5865
  detail: withCtx(() => [createVNode(CollectionRecordPanel_default, {
5784
5866
  editing: editing.value,
5785
- "onUpdate:editing": _cache[11] || (_cache[11] = ($event) => editing.value = $event),
5867
+ "onUpdate:editing": _cache[12] || (_cache[12] = ($event) => editing.value = $event),
5786
5868
  collection: collection.value,
5787
5869
  viewing: viewing.value,
5788
5870
  saving: saving.value,
@@ -5802,7 +5884,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5802
5884
  onCancel: cancelEditor,
5803
5885
  onEdit: editFromView,
5804
5886
  onClose: onDayClose,
5805
- onDelete: _cache[12] || (_cache[12] = ($event) => viewing.value && confirmDelete(viewing.value)),
5887
+ onDelete: _cache[13] || (_cache[13] = ($event) => viewing.value && confirmDelete(viewing.value)),
5806
5888
  onRunAction: runAction,
5807
5889
  onItemChat
5808
5890
  }, null, 8, [
@@ -5835,16 +5917,16 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5835
5917
  "selected",
5836
5918
  "can-create",
5837
5919
  "show-detail"
5838
- ])) : createCommentVNode("", true)])) : kanbanActive.value ? (openBlock(), createElementBlock("div", _hoisted_49, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_50, [
5839
- _cache[48] || (_cache[48] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
5840
- createElementVNode("span", _hoisted_51, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5920
+ ])) : createCommentVNode("", true)])) : kanbanActive.value ? (openBlock(), createElementBlock("div", _hoisted_51, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_52, [
5921
+ _cache[50] || (_cache[50] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
5922
+ createElementVNode("span", _hoisted_53, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5841
5923
  createElementVNode("button", {
5842
5924
  type: "button",
5843
5925
  class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
5844
5926
  "aria-label": unref(t)("common.close"),
5845
- onClick: _cache[13] || (_cache[13] = ($event) => inlineError.value = null)
5846
- }, [..._cache[47] || (_cache[47] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_52)
5847
- ])) : createCommentVNode("", true), createElementVNode("div", _hoisted_53, [createVNode(CollectionKanbanView_default, {
5927
+ onClick: _cache[14] || (_cache[14] = ($event) => inlineError.value = null)
5928
+ }, [..._cache[49] || (_cache[49] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_54)
5929
+ ])) : createCommentVNode("", true), createElementVNode("div", _hoisted_55, [createVNode(CollectionKanbanView_default, {
5848
5930
  schema: collection.value.schema,
5849
5931
  items: filteredItems.value,
5850
5932
  "group-field": kanbanGroupField.value,
@@ -5860,7 +5942,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5860
5942
  "selected",
5861
5943
  "notified",
5862
5944
  "readonly"
5863
- ])])])) : activeCustomView.value ? (openBlock(), createElementBlock("div", _hoisted_54, [activeCustomView.value.target === "mobile" ? (openBlock(), createBlock(CollectionRemoteViewPreview_default, {
5945
+ ])])])) : activeCustomView.value ? (openBlock(), createElementBlock("div", _hoisted_56, [activeCustomView.value.target === "mobile" ? (openBlock(), createBlock(CollectionRemoteViewPreview_default, {
5864
5946
  key: 0,
5865
5947
  slug: collection.value.slug,
5866
5948
  view: activeCustomView.value,
@@ -5871,32 +5953,32 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5871
5953
  view: activeCustomView.value,
5872
5954
  onOpenItem: onCustomViewOpenItem,
5873
5955
  onStartChat: onCustomViewStartChat
5874
- }, null, 8, ["slug", "view"]))])) : items.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_55, [_cache[49] || (_cache[49] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "folder_open", -1)), createElementVNode("p", _hoisted_56, toDisplayString(unref(t)(isReadOnly.value ? "collectionsView.itemsEmptyReadonly" : "collectionsView.itemsEmpty")), 1)])) : tableFilteredItems.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_57, [
5875
- _cache[50] || (_cache[50] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "search_off", -1)),
5876
- createElementVNode("p", _hoisted_58, toDisplayString(unref(t)("collectionsView.noMatchingItems")), 1),
5956
+ }, null, 8, ["slug", "view"]))])) : items.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_57, [_cache[51] || (_cache[51] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "folder_open", -1)), createElementVNode("p", _hoisted_58, toDisplayString(unref(t)(isReadOnly.value ? "collectionsView.itemsEmptyReadonly" : "collectionsView.itemsEmpty")), 1)])) : tableFilteredItems.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_59, [
5957
+ _cache[52] || (_cache[52] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "search_off", -1)),
5958
+ createElementVNode("p", _hoisted_60, toDisplayString(unref(t)("collectionsView.noMatchingItems")), 1),
5877
5959
  createElementVNode("button", {
5878
5960
  type: "button",
5879
5961
  class: "text-xs text-indigo-600 font-semibold hover:underline",
5880
- onClick: _cache[14] || (_cache[14] = ($event) => (searchQuery.value = "", flagFilters.value = {}))
5962
+ onClick: _cache[15] || (_cache[15] = ($event) => (searchQuery.value = "", flagFilters.value = {}))
5881
5963
  }, toDisplayString(unref(t)("collectionsView.clearSearch")), 1)
5882
- ])) : (openBlock(), createElementBlock("div", _hoisted_59, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_60, [
5883
- _cache[52] || (_cache[52] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
5884
- createElementVNode("span", _hoisted_61, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5964
+ ])) : (openBlock(), createElementBlock("div", _hoisted_61, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_62, [
5965
+ _cache[54] || (_cache[54] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
5966
+ createElementVNode("span", _hoisted_63, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5885
5967
  createElementVNode("button", {
5886
5968
  type: "button",
5887
5969
  class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
5888
5970
  "aria-label": unref(t)("common.close"),
5889
- onClick: _cache[15] || (_cache[15] = ($event) => inlineError.value = null)
5890
- }, [..._cache[51] || (_cache[51] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_62)
5891
- ])) : createCommentVNode("", true), createElementVNode("table", _hoisted_63, [createElementVNode("thead", null, [createElementVNode("tr", _hoisted_64, [(openBlock(true), createElementBlock(Fragment, null, renderList(listColumnFields.value, ([key, field]) => {
5971
+ onClick: _cache[16] || (_cache[16] = ($event) => inlineError.value = null)
5972
+ }, [..._cache[53] || (_cache[53] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_64)
5973
+ ])) : createCommentVNode("", true), createElementVNode("table", _hoisted_65, [createElementVNode("thead", null, [createElementVNode("tr", _hoisted_66, [(openBlock(true), createElementBlock(Fragment, null, renderList(listColumnFields.value, ([key, field]) => {
5892
5974
  return openBlock(), createElementBlock("th", {
5893
5975
  key,
5894
5976
  "aria-sort": unref(isSortableField)(field) ? sortAriaValue(key) : void 0,
5895
5977
  class: "px-5 py-3 font-bold text-slate-500 text-left uppercase tracking-wider whitespace-nowrap"
5896
- }, [createElementVNode("div", _hoisted_66, [createElementVNode("span", {
5978
+ }, [createElementVNode("div", _hoisted_68, [createElementVNode("span", {
5897
5979
  class: "truncate max-w-[14rem]",
5898
5980
  title: field.label
5899
- }, toDisplayString(field.label), 9, _hoisted_67), unref(isSortableField)(field) ? (openBlock(), createElementBlock("button", {
5981
+ }, toDisplayString(field.label), 9, _hoisted_69), unref(isSortableField)(field) ? (openBlock(), createElementBlock("button", {
5900
5982
  key: 0,
5901
5983
  type: "button",
5902
5984
  class: normalizeClass(["inline-flex items-center justify-center rounded p-0.5 -my-1 leading-none transition-colors", sortButtonClass(key)]),
@@ -5904,9 +5986,9 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5904
5986
  "aria-label": unref(t)("collectionsView.sortBy", { field: field.label }),
5905
5987
  onClick: withModifiers(($event) => cycleSort(key), ["stop"]),
5906
5988
  onPointerenter: ($event) => hoveredSortKey.value = key,
5907
- onPointerleave: _cache[16] || (_cache[16] = ($event) => hoveredSortKey.value = null)
5908
- }, [createElementVNode("span", _hoisted_69, toDisplayString(sortIconName(key)), 1)], 42, _hoisted_68)) : createCommentVNode("", true)])], 8, _hoisted_65);
5909
- }), 128))])]), createElementVNode("tbody", _hoisted_70, [(openBlock(true), createElementBlock(Fragment, null, renderList(sortedItems.value, (item) => {
5989
+ onPointerleave: _cache[17] || (_cache[17] = ($event) => hoveredSortKey.value = null)
5990
+ }, [createElementVNode("span", _hoisted_71, toDisplayString(sortIconName(key)), 1)], 42, _hoisted_70)) : createCommentVNode("", true)])], 8, _hoisted_67);
5991
+ }), 128))])]), createElementVNode("tbody", _hoisted_72, [(openBlock(true), createElementBlock(Fragment, null, renderList(sortedItems.value, (item) => {
5910
5992
  return openBlock(), createElementBlock("tr", {
5911
5993
  key: String(item[collection.value.schema.primaryKey] ?? ""),
5912
5994
  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" : ""]),
@@ -5928,9 +6010,9 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5928
6010
  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",
5929
6011
  "data-testid": `collections-inline-toggle-${key}-${item[collection.value.schema.primaryKey]}`,
5930
6012
  "aria-label": field.label,
5931
- onClick: _cache[17] || (_cache[17] = withModifiers(() => {}, ["stop"])),
6013
+ onClick: _cache[18] || (_cache[18] = withModifiers(() => {}, ["stop"])),
5932
6014
  onChange: ($event) => commitToggle(item, field)
5933
- }, null, 40, _hoisted_72)) : field.type === "boolean" ? (openBlock(), createElementBlock("input", {
6015
+ }, null, 40, _hoisted_74)) : field.type === "boolean" ? (openBlock(), createElementBlock("input", {
5934
6016
  key: 1,
5935
6017
  type: "checkbox",
5936
6018
  checked: item[key] === true,
@@ -5938,15 +6020,15 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5938
6020
  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",
5939
6021
  "data-testid": `collections-inline-bool-${key}-${item[collection.value.schema.primaryKey]}`,
5940
6022
  "aria-label": field.label,
5941
- onClick: _cache[18] || (_cache[18] = withModifiers(() => {}, ["stop"])),
6023
+ onClick: _cache[19] || (_cache[19] = withModifiers(() => {}, ["stop"])),
5942
6024
  onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.checked)
5943
- }, null, 40, _hoisted_73)) : field.type === "flag" ? (openBlock(), createElementBlock("span", {
6025
+ }, null, 40, _hoisted_75)) : field.type === "flag" ? (openBlock(), createElementBlock("span", {
5944
6026
  key: 2,
5945
6027
  class: normalizeClass(["material-icons text-lg align-middle", flagValueOf(String(key), item) ? "text-emerald-600" : "text-slate-300"]),
5946
6028
  "data-testid": `collections-flag-${key}-${item[collection.value.schema.primaryKey]}`,
5947
6029
  "aria-label": `${field.label}: ${unref(t)(flagValueOf(String(key), item) ? "common.yes" : "common.no")}`,
5948
6030
  role: "img"
5949
- }, toDisplayString(flagValueOf(String(key), item) ? "check_circle" : "radio_button_unchecked"), 11, _hoisted_74)) : field.type === "ref" && field.to && typeof item[key] === "string" && item[key] ? (openBlock(), createElementBlock("span", _hoisted_75, [createElementVNode("a", {
6031
+ }, toDisplayString(flagValueOf(String(key), item) ? "check_circle" : "radio_button_unchecked"), 11, _hoisted_76)) : field.type === "ref" && field.to && typeof item[key] === "string" && item[key] ? (openBlock(), createElementBlock("span", _hoisted_77, [createElementVNode("a", {
5950
6032
  href: unref(cui).recordHref?.(field.to, String(item[key])),
5951
6033
  tabindex: unref(cui).recordHref?.(field.to, String(item[key])) ? void 0 : 0,
5952
6034
  role: "link",
@@ -5954,48 +6036,48 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5954
6036
  "data-testid": `collections-ref-link-${key}-${item[key]}`,
5955
6037
  onClick: ($event) => unref(activateRefLink)($event, field.to, String(item[key]), true),
5956
6038
  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"])]
5957
- }, toDisplayString(unref(refDisplay)(field.to, String(item[key]))), 41, _hoisted_76)])) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? (openBlock(), createElementBlock("select", {
6039
+ }, toDisplayString(unref(refDisplay)(field.to, String(item[key]))), 41, _hoisted_78)])) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? (openBlock(), createElementBlock("select", {
5958
6040
  key: 4,
5959
6041
  value: item[key] == null ? "" : String(item[key]),
5960
6042
  disabled: isReadOnly.value || isRowInlineSaving(item),
5961
6043
  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])]),
5962
6044
  "data-testid": `collections-inline-enum-${key}-${item[collection.value.schema.primaryKey]}`,
5963
6045
  "aria-label": field.label,
5964
- onClick: _cache[19] || (_cache[19] = withModifiers(() => {}, ["stop"])),
6046
+ onClick: _cache[20] || (_cache[20] = withModifiers(() => {}, ["stop"])),
5965
6047
  onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.value)
5966
- }, [showEnumPlaceholder(item, String(key)) ? (openBlock(), createElementBlock("option", _hoisted_78, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(field.values, (value) => {
6048
+ }, [showEnumPlaceholder(item, String(key)) ? (openBlock(), createElementBlock("option", _hoisted_80, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(field.values, (value) => {
5967
6049
  return openBlock(), createElementBlock("option", {
5968
6050
  key: value,
5969
6051
  value
5970
- }, toDisplayString(value), 9, _hoisted_79);
5971
- }), 128))], 42, _hoisted_77)) : field.type === "money" ? (openBlock(), createElementBlock("span", _hoisted_80, toDisplayString(unref(formatMoney)(item[key], unref(resolveCurrency)(field, item), unref(locale))), 1)) : field.type === "table" ? (openBlock(), createElementBlock("span", _hoisted_81, [_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_82, toDisplayString(unref(derivedDisplay)(field, unref(evaluateDerivedAgainstItem)(field, String(key), item), item)), 1)) : field.type === "rollup" ? (openBlock(), createElementBlock("span", {
6052
+ }, toDisplayString(value), 9, _hoisted_81);
6053
+ }), 128))], 42, _hoisted_79)) : field.type === "money" ? (openBlock(), createElementBlock("span", _hoisted_82, toDisplayString(unref(formatMoney)(item[key], unref(resolveCurrency)(field, item), unref(locale))), 1)) : field.type === "table" ? (openBlock(), createElementBlock("span", _hoisted_83, [_cache[55] || (_cache[55] = createElementVNode("span", { class: "material-icons text-[11px]" }, "list", -1)), createElementVNode("span", null, toDisplayString(tableSummary(item[key])), 1)])) : field.type === "derived" ? (openBlock(), createElementBlock("span", _hoisted_84, toDisplayString(unref(derivedDisplay)(field, unref(evaluateDerivedAgainstItem)(field, String(key), item), item)), 1)) : field.type === "rollup" ? (openBlock(), createElementBlock("span", {
5972
6054
  key: 8,
5973
6055
  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",
5974
6056
  "data-testid": `collections-rollup-${key}-${item[collection.value.schema.primaryKey]}`
5975
- }, toDisplayString(unref(render).rollupDisplay(field, item)), 9, _hoisted_83)) : field.type !== "file" && unref(isExternalUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
6057
+ }, toDisplayString(unref(render).rollupDisplay(field, item)), 9, _hoisted_85)) : field.type !== "file" && unref(isExternalUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
5976
6058
  key: 9,
5977
6059
  href: String(item[key]),
5978
6060
  target: "_blank",
5979
6061
  rel: "noopener noreferrer",
5980
6062
  class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
5981
6063
  "data-testid": `collections-url-link-${key}-${item[collection.value.schema.primaryKey]}`,
5982
- onClick: _cache[20] || (_cache[20] = withModifiers(() => {}, ["stop"]))
5983
- }, toDisplayString(String(item[key])), 9, _hoisted_84)) : field.type === "file" && unref(artifactUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
6064
+ onClick: _cache[21] || (_cache[21] = withModifiers(() => {}, ["stop"]))
6065
+ }, toDisplayString(String(item[key])), 9, _hoisted_86)) : field.type === "file" && unref(artifactUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
5984
6066
  key: 10,
5985
6067
  href: unref(artifactUrl)(item[key]) ?? void 0,
5986
6068
  target: "_blank",
5987
6069
  rel: "noopener noreferrer",
5988
6070
  class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
5989
6071
  "data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
5990
- onClick: _cache[21] || (_cache[21] = withModifiers(() => {}, ["stop"]))
5991
- }, toDisplayString(String(item[key])), 9, _hoisted_85)) : field.type === "file" && unref(fileRoutePath)(item[key]) ? (openBlock(), createElementBlock("a", {
6072
+ onClick: _cache[22] || (_cache[22] = withModifiers(() => {}, ["stop"]))
6073
+ }, toDisplayString(String(item[key])), 9, _hoisted_87)) : field.type === "file" && unref(fileRoutePath)(item[key]) ? (openBlock(), createElementBlock("a", {
5992
6074
  key: 11,
5993
6075
  href: unref(fileRoutePath)(item[key]) ?? void 0,
5994
6076
  class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
5995
6077
  "data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
5996
6078
  onClick: ($event) => unref(activatePathLink)($event, unref(fileRoutePath)(item[key]) ?? "", true)
5997
- }, toDisplayString(String(item[key])), 9, _hoisted_86)) : (openBlock(), createElementBlock("span", _hoisted_87, toDisplayString(unref(formatCell)(item[key], field.type)), 1))], 64)) : createCommentVNode("", true)]);
5998
- }), 128))], 42, _hoisted_71);
6079
+ }, toDisplayString(String(item[key])), 9, _hoisted_88)) : (openBlock(), createElementBlock("span", _hoisted_89, toDisplayString(unref(formatCell)(item[key], field.type)), 1))], 64)) : createCommentVNode("", true)]);
6080
+ }), 128))], 42, _hoisted_73);
5999
6081
  }), 128))])])]))]),
6000
6082
  collection.value && (viewing.value || editing.value) && !(calendarActive.value && openDay.value) ? (openBlock(), createBlock(CollectionRecordModal_default, {
6001
6083
  key: 4,
@@ -6003,7 +6085,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
6003
6085
  }, {
6004
6086
  default: withCtx(() => [createVNode(CollectionRecordPanel_default, {
6005
6087
  editing: editing.value,
6006
- "onUpdate:editing": _cache[22] || (_cache[22] = ($event) => editing.value = $event),
6088
+ "onUpdate:editing": _cache[23] || (_cache[23] = ($event) => editing.value = $event),
6007
6089
  collection: collection.value,
6008
6090
  viewing: viewing.value,
6009
6091
  saving: saving.value,
@@ -6023,7 +6105,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
6023
6105
  onCancel: cancelEditor,
6024
6106
  onEdit: editFromView,
6025
6107
  onClose: closeView,
6026
- onDelete: _cache[23] || (_cache[23] = ($event) => viewing.value && confirmDelete(viewing.value)),
6108
+ onDelete: _cache[24] || (_cache[24] = ($event) => viewing.value && confirmDelete(viewing.value)),
6027
6109
  onRunAction: runAction,
6028
6110
  onItemChat
6029
6111
  }, null, 8, [
@@ -6051,7 +6133,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
6051
6133
  action: mutateModal.value.action,
6052
6134
  pending: mutatePending.value,
6053
6135
  error: mutateError.value,
6054
- onClose: _cache[24] || (_cache[24] = ($event) => mutateModal.value = null),
6136
+ onClose: _cache[25] || (_cache[25] = ($event) => mutateModal.value = null),
6055
6137
  onSubmit: submitMutateParams
6056
6138
  }, null, 8, [
6057
6139
  "action",
@@ -6064,7 +6146,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
6064
6146
  title: collection.value.title,
6065
6147
  views: customViews.value,
6066
6148
  onChanged: onViewsChanged,
6067
- onClose: _cache[25] || (_cache[25] = ($event) => configOpen.value = false)
6149
+ onClose: _cache[26] || (_cache[26] = ($event) => configOpen.value = false)
6068
6150
  }, null, 8, [
6069
6151
  "slug",
6070
6152
  "title",
@@ -6079,29 +6161,29 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
6079
6161
  "data-testid": "collections-chat-modal",
6080
6162
  onClick: withModifiers(closeChat, ["self"]),
6081
6163
  onKeydown: withKeys(closeChat, ["esc"])
6082
- }, [createElementVNode("div", _hoisted_88, [
6083
- createElementVNode("header", _hoisted_89, [
6084
- _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)),
6085
- createElementVNode("div", _hoisted_90, [createElementVNode("h2", _hoisted_91, toDisplayString(unref(t)("collectionsView.chatTitle")), 1), createElementVNode("span", _hoisted_92, toDisplayString(collection.value.title), 1)]),
6164
+ }, [createElementVNode("div", _hoisted_90, [
6165
+ createElementVNode("header", _hoisted_91, [
6166
+ _cache[57] || (_cache[57] = 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)),
6167
+ createElementVNode("div", _hoisted_92, [createElementVNode("h2", _hoisted_93, toDisplayString(unref(t)("collectionsView.chatTitle")), 1), createElementVNode("span", _hoisted_94, toDisplayString(collection.value.title), 1)]),
6086
6168
  createElementVNode("button", {
6087
6169
  type: "button",
6088
6170
  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",
6089
6171
  "aria-label": unref(t)("common.close"),
6090
6172
  "data-testid": "collections-chat-close",
6091
6173
  onClick: closeChat
6092
- }, [..._cache[54] || (_cache[54] = [createElementVNode("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_93)
6174
+ }, [..._cache[56] || (_cache[56] = [createElementVNode("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_95)
6093
6175
  ]),
6094
- createElementVNode("div", _hoisted_94, [withDirectives(createElementVNode("textarea", {
6176
+ createElementVNode("div", _hoisted_96, [withDirectives(createElementVNode("textarea", {
6095
6177
  ref_key: "chatInputEl",
6096
6178
  ref: chatInputEl,
6097
- "onUpdate:modelValue": _cache[26] || (_cache[26] = ($event) => chatMessage.value = $event),
6179
+ "onUpdate:modelValue": _cache[27] || (_cache[27] = ($event) => chatMessage.value = $event),
6098
6180
  rows: "4",
6099
6181
  placeholder: unref(t)("collectionsView.chatPlaceholder"),
6100
6182
  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",
6101
6183
  "data-testid": "collections-chat-input",
6102
6184
  onKeydown: [withKeys(withModifiers(submitChat, ["meta"]), ["enter"]), withKeys(withModifiers(submitChat, ["ctrl"]), ["enter"])]
6103
- }, null, 40, _hoisted_95), [[vModelText, chatMessage.value]])]),
6104
- createElementVNode("footer", _hoisted_96, [createElementVNode("button", {
6185
+ }, null, 40, _hoisted_97), [[vModelText, chatMessage.value]])]),
6186
+ createElementVNode("footer", _hoisted_98, [createElementVNode("button", {
6105
6187
  type: "button",
6106
6188
  class: "h-8 px-2.5 rounded text-xs font-bold text-slate-500 hover:bg-slate-200/50 transition-colors",
6107
6189
  "data-testid": "collections-chat-cancel",
@@ -6112,7 +6194,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
6112
6194
  disabled: !chatMessage.value.trim(),
6113
6195
  "data-testid": "collections-chat-send",
6114
6196
  onClick: submitChat
6115
- }, toDisplayString(unref(t)("collectionsView.chatStart")), 9, _hoisted_97)])
6197
+ }, toDisplayString(unref(t)("collectionsView.chatStart")), 9, _hoisted_99)])
6116
6198
  ])], 32)) : createCommentVNode("", true)
6117
6199
  ]);
6118
6200
  };