@mulmoclaude/collection-plugin 0.13.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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,31 @@ 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
+ function closeFilterMenuOnOutsideClick(event) {
4465
+ if (!filterMenuRef.value?.contains(event.target)) filterMenuOpen.value = false;
4466
+ }
4467
+ watch(filterMenuOpen, (open) => {
4468
+ if (open) document.addEventListener("mousedown", closeFilterMenuOnOutsideClick);
4469
+ else document.removeEventListener("mousedown", closeFilterMenuOnOutsideClick);
4470
+ });
4424
4471
  function flagChipTitle(chip) {
4425
4472
  const mode = flagFilterMode(chip.key);
4426
4473
  if (mode === "hide") return t("collectionsView.flagFilterHide", { label: chip.label });
@@ -5439,6 +5486,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5439
5486
  anchorOverride.value = null;
5440
5487
  kanbanOverride.value = null;
5441
5488
  addMenuOpen.value = false;
5489
+ filterMenuOpen.value = false;
5442
5490
  sortState.value = storedSortFor(slug);
5443
5491
  flagFilters.value = storedFlagFiltersFor(slug);
5444
5492
  }
@@ -5489,6 +5537,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5489
5537
  clearLiveRefreshTimer();
5490
5538
  if (refreshNoteTimer !== void 0) clearTimeout(refreshNoteTimer);
5491
5539
  document.removeEventListener("mousedown", closeAddMenuOnOutsideClick);
5540
+ document.removeEventListener("mousedown", closeFilterMenuOnOutsideClick);
5492
5541
  });
5493
5542
  watch([
5494
5543
  activeView,
@@ -5525,9 +5574,9 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5525
5574
  "aria-label": unref(t)("collectionsView.backToIndex"),
5526
5575
  "data-testid": "collections-back",
5527
5576
  onClick: goBack
5528
- }, [..._cache[27] || (_cache[27] = [createElementVNode("span", { class: "material-icons text-lg" }, "arrow_back", -1)])], 8, _hoisted_3$5)) : createCommentVNode("", true),
5577
+ }, [..._cache[28] || (_cache[28] = [createElementVNode("span", { class: "material-icons text-lg" }, "arrow_back", -1)])], 8, _hoisted_3$5)) : createCommentVNode("", true),
5529
5578
  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", {
5579
+ 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
5580
  key: 0,
5532
5581
  href: dataSourceRoute.value ?? void 0,
5533
5582
  class: "ml-1 normal-case tracking-normal font-mono font-normal text-slate-500 hover:text-indigo-700 hover:underline",
@@ -5560,7 +5609,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5560
5609
  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
5610
  "data-testid": "collections-chat",
5562
5611
  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),
5612
+ }, [_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
5613
  (openBlock(true), createElementBlock(Fragment, null, renderList(collectionActions.value, (action) => {
5565
5614
  return openBlock(), createElementBlock("button", {
5566
5615
  key: action.id,
@@ -5577,7 +5626,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5577
5626
  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
5627
  "data-testid": "collections-add-item",
5579
5628
  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),
5629
+ }, [_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
5630
  canDeleteCollection.value && !embedded.value ? (openBlock(), createElementBlock("button", {
5582
5631
  key: 6,
5583
5632
  type: "button",
@@ -5586,7 +5635,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5586
5635
  "aria-label": unref(t)("collectionsView.deleteCollection"),
5587
5636
  "data-testid": "collections-delete",
5588
5637
  onClick: confirmCollectionDelete
5589
- }, [..._cache[31] || (_cache[31] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_16$4)) : createCommentVNode("", true),
5638
+ }, [..._cache[32] || (_cache[32] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_16$4)) : createCommentVNode("", true),
5590
5639
  canDeleteFeed.value && !embedded.value ? (openBlock(), createElementBlock("button", {
5591
5640
  key: 7,
5592
5641
  type: "button",
@@ -5595,11 +5644,11 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5595
5644
  "aria-label": unref(t)("collectionsView.deleteFeed"),
5596
5645
  "data-testid": "feeds-delete",
5597
5646
  onClick: confirmFeedDelete
5598
- }, [..._cache[32] || (_cache[32] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_17$4)) : createCommentVNode("", true)
5647
+ }, [..._cache[33] || (_cache[33] = [createElementVNode("span", { class: "material-icons text-sm" }, "delete_forever", -1)])], 8, _hoisted_17$4)) : createCommentVNode("", true)
5599
5648
  ])) : 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),
5649
+ 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
5650
  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)),
5651
+ _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
5652
  withDirectives(createElementVNode("input", {
5604
5653
  "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => searchQuery.value = $event),
5605
5654
  type: "text",
@@ -5613,25 +5662,48 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5613
5662
  "aria-label": unref(t)("collectionsView.clearSearch"),
5614
5663
  class: "absolute inset-y-0 right-0 flex items-center pr-2.5 text-slate-400 hover:text-slate-600",
5615
5664
  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)
5665
+ }, [..._cache[35] || (_cache[35] = [createElementVNode("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_23$2)) : createCommentVNode("", true)
5617
5666
  ])) : createCommentVNode("", true), createElementVNode("div", _hoisted_24$1, [
5618
5667
  activeView.value === "table" && flagChips.value.length > 0 && items.value.length > 0 ? (openBlock(), createElementBlock("div", {
5619
5668
  key: 0,
5620
- class: "flex items-center gap-0.5",
5669
+ ref_key: "filterMenuRef",
5670
+ ref: filterMenuRef,
5671
+ class: "relative"
5672
+ }, [createElementVNode("button", {
5673
+ type: "button",
5674
+ 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"]),
5675
+ "aria-label": unref(t)("collectionsView.flagFilterButton"),
5676
+ "aria-expanded": filterMenuOpen.value,
5677
+ "data-testid": "collections-filter-menu",
5678
+ onClick: _cache[3] || (_cache[3] = ($event) => filterMenuOpen.value = !filterMenuOpen.value)
5679
+ }, [
5680
+ _cache[37] || (_cache[37] = createElementVNode("span", {
5681
+ class: "material-icons text-sm",
5682
+ "aria-hidden": "true"
5683
+ }, "filter_alt", -1)),
5684
+ createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.flagFilterButton")), 1),
5685
+ activeFlagFilterCount.value > 0 ? (openBlock(), createElementBlock("span", _hoisted_26$1, toDisplayString(activeFlagFilterCount.value), 1)) : createCommentVNode("", true)
5686
+ ], 10, _hoisted_25$1), filterMenuOpen.value ? (openBlock(), createElementBlock("div", {
5687
+ key: 0,
5688
+ 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
5689
  role: "group",
5622
- "aria-label": unref(t)("collectionsView.flagFilterGroup")
5690
+ "aria-label": unref(t)("collectionsView.flagFilterButton"),
5691
+ "data-testid": "collections-filter-menu-panel"
5623
5692
  }, [(openBlock(true), createElementBlock(Fragment, null, renderList(flagChips.value, (chip) => {
5624
5693
  return openBlock(), createElementBlock("button", {
5625
5694
  key: chip.key,
5626
5695
  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)]),
5696
+ 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
5697
  title: flagChipTitle(chip),
5629
5698
  "aria-label": flagChipTitle(chip),
5630
5699
  "aria-pressed": flagFilterMode(chip.key) !== void 0,
5631
5700
  "data-testid": `collections-flag-chip-${chip.key}`,
5632
5701
  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),
5702
+ }, [createElementVNode("span", {
5703
+ class: normalizeClass(["material-icons text-sm", flagChipIconClass(chip.key)]),
5704
+ "aria-hidden": "true"
5705
+ }, toDisplayString(flagChipIcon(chip.key)), 3), createElementVNode("span", _hoisted_29, toDisplayString(chip.label), 1)], 10, _hoisted_28);
5706
+ }), 128))], 8, _hoisted_27$1)) : createCommentVNode("", true)], 512)) : createCommentVNode("", true),
5635
5707
  !__props.hideViewToggle && (hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value) ? (openBlock(), createElementBlock("div", {
5636
5708
  key: 1,
5637
5709
  class: "flex gap-0.5",
@@ -5643,24 +5715,24 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5643
5715
  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
5716
  "aria-pressed": activeView.value === "table",
5645
5717
  "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),
5718
+ onClick: _cache[4] || (_cache[4] = ($event) => setView("table"))
5719
+ }, [_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
5720
  hasCalendar.value ? (openBlock(), createElementBlock("button", {
5649
5721
  key: 0,
5650
5722
  type: "button",
5651
5723
  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
5724
  "aria-pressed": activeView.value === "calendar",
5653
5725
  "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),
5726
+ onClick: _cache[5] || (_cache[5] = ($event) => setView("calendar"))
5727
+ }, [_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
5728
  hasKanban.value ? (openBlock(), createElementBlock("button", {
5657
5729
  key: 1,
5658
5730
  type: "button",
5659
5731
  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
5732
  "aria-pressed": activeView.value === "kanban",
5661
5733
  "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),
5734
+ onClick: _cache[6] || (_cache[6] = ($event) => setView("kanban"))
5735
+ }, [_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
5736
  (openBlock(true), createElementBlock(Fragment, null, renderList(customViews.value, (cv) => {
5665
5737
  return openBlock(), createElementBlock("button", {
5666
5738
  key: cv.id,
@@ -5669,7 +5741,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5669
5741
  "aria-pressed": activeView.value === unref(customViewKey)(cv.id),
5670
5742
  "data-testid": `collection-view-custom-${cv.id}`,
5671
5743
  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);
5744
+ }, [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
5745
  }), 128)),
5674
5746
  canAddCustomView.value ? (openBlock(), createElementBlock("div", {
5675
5747
  key: 2,
@@ -5684,17 +5756,17 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5684
5756
  "aria-expanded": addMenuOpen.value,
5685
5757
  "data-testid": "collection-view-add",
5686
5758
  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", {
5759
+ }, [..._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
5760
  type: "button",
5689
5761
  class: "w-full h-8 px-3 flex items-center gap-2 text-xs font-bold text-slate-600 hover:bg-slate-50",
5690
5762
  "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", {
5763
+ onClick: _cache[7] || (_cache[7] = ($event) => addCustomView("desktop"))
5764
+ }, [_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
5765
  type: "button",
5694
5766
  class: "w-full h-8 px-3 flex items-center gap-2 text-xs font-bold text-slate-600 hover:bg-slate-50",
5695
5767
  "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),
5768
+ onClick: _cache[8] || (_cache[8] = ($event) => addCustomView("mobile"))
5769
+ }, [_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
5770
  canConfigureViews.value ? (openBlock(), createElementBlock("button", {
5699
5771
  key: 3,
5700
5772
  type: "button",
@@ -5702,51 +5774,51 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5702
5774
  title: unref(t)("collectionsView.config.open"),
5703
5775
  "aria-label": unref(t)("collectionsView.config.open"),
5704
5776
  "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),
5777
+ onClick: _cache[9] || (_cache[9] = ($event) => configOpen.value = true)
5778
+ }, [..._cache[44] || (_cache[44] = [createElementVNode("span", { class: "material-icons text-sm" }, "settings", -1)])], 8, _hoisted_38)) : createCommentVNode("", true)
5779
+ ], 8, _hoisted_30)) : createCommentVNode("", true),
5708
5780
  calendarActive.value && dateFields.value.length > 1 ? (openBlock(), createElementBlock("select", {
5709
5781
  key: 2,
5710
5782
  value: calendarAnchorField.value,
5711
5783
  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
5784
  "aria-label": unref(t)("collectionsView.calendarFieldLabel"),
5713
5785
  "data-testid": "collection-calendar-field",
5714
- onChange: _cache[9] || (_cache[9] = ($event) => anchorOverride.value = $event.target.value)
5786
+ onChange: _cache[10] || (_cache[10] = ($event) => anchorOverride.value = $event.target.value)
5715
5787
  }, [(openBlock(true), createElementBlock(Fragment, null, renderList(dateFields.value, (key) => {
5716
5788
  return openBlock(), createElementBlock("option", {
5717
5789
  key,
5718
5790
  value: key
5719
- }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_38);
5720
- }), 128))], 40, _hoisted_37)) : createCommentVNode("", true),
5791
+ }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_40);
5792
+ }), 128))], 40, _hoisted_39)) : createCommentVNode("", true),
5721
5793
  kanbanActive.value && enumFields.value.length > 1 ? (openBlock(), createElementBlock("select", {
5722
5794
  key: 3,
5723
5795
  value: kanbanGroupField.value,
5724
5796
  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
5797
  "aria-label": unref(t)("collectionsView.kanbanFieldLabel"),
5726
5798
  "data-testid": "collection-kanban-field",
5727
- onChange: _cache[10] || (_cache[10] = ($event) => kanbanOverride.value = $event.target.value)
5799
+ onChange: _cache[11] || (_cache[11] = ($event) => kanbanOverride.value = $event.target.value)
5728
5800
  }, [(openBlock(true), createElementBlock(Fragment, null, renderList(enumFields.value, (key) => {
5729
5801
  return openBlock(), createElementBlock("option", {
5730
5802
  key,
5731
5803
  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", {
5804
+ }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_42);
5805
+ }), 128))], 40, _hoisted_41)) : createCommentVNode("", true),
5806
+ items.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_43, toDisplayString(unref(t)("collectionsView.searchSummary", {
5735
5807
  shown: activeView.value === "table" ? tableFilteredItems.value.length : filteredItems.value.length,
5736
5808
  total: items.value.length
5737
5809
  })), 1)) : createCommentVNode("", true)
5738
5810
  ])])) : 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),
5811
+ collection.value && dataIssues.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_44, [
5812
+ _cache[46] || (_cache[46] = createElementVNode("span", { class: "material-icons text-amber-600" }, "warning", -1)),
5813
+ createElementVNode("span", _hoisted_45, toDisplayString(unref(t)("collectionsView.dataIssuesDetected", { count: dataIssues.value.length })), 1),
5742
5814
  createElementVNode("button", {
5743
5815
  type: "button",
5744
5816
  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
5817
  "data-testid": "collections-repair",
5746
5818
  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)])
5819
+ }, [_cache[45] || (_cache[45] = createElementVNode("span", { class: "material-icons text-sm" }, "build", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.repair")), 1)])
5748
5820
  ])) : 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, {
5821
+ 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
5822
  schema: collection.value.schema,
5751
5823
  items: filteredItems.value,
5752
5824
  "anchor-field": calendarAnchorField.value,
@@ -5782,7 +5854,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5782
5854
  }, {
5783
5855
  detail: withCtx(() => [createVNode(CollectionRecordPanel_default, {
5784
5856
  editing: editing.value,
5785
- "onUpdate:editing": _cache[11] || (_cache[11] = ($event) => editing.value = $event),
5857
+ "onUpdate:editing": _cache[12] || (_cache[12] = ($event) => editing.value = $event),
5786
5858
  collection: collection.value,
5787
5859
  viewing: viewing.value,
5788
5860
  saving: saving.value,
@@ -5802,7 +5874,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5802
5874
  onCancel: cancelEditor,
5803
5875
  onEdit: editFromView,
5804
5876
  onClose: onDayClose,
5805
- onDelete: _cache[12] || (_cache[12] = ($event) => viewing.value && confirmDelete(viewing.value)),
5877
+ onDelete: _cache[13] || (_cache[13] = ($event) => viewing.value && confirmDelete(viewing.value)),
5806
5878
  onRunAction: runAction,
5807
5879
  onItemChat
5808
5880
  }, null, 8, [
@@ -5835,16 +5907,16 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5835
5907
  "selected",
5836
5908
  "can-create",
5837
5909
  "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),
5910
+ ])) : createCommentVNode("", true)])) : kanbanActive.value ? (openBlock(), createElementBlock("div", _hoisted_51, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_52, [
5911
+ _cache[50] || (_cache[50] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
5912
+ createElementVNode("span", _hoisted_53, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5841
5913
  createElementVNode("button", {
5842
5914
  type: "button",
5843
5915
  class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
5844
5916
  "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, {
5917
+ onClick: _cache[14] || (_cache[14] = ($event) => inlineError.value = null)
5918
+ }, [..._cache[49] || (_cache[49] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_54)
5919
+ ])) : createCommentVNode("", true), createElementVNode("div", _hoisted_55, [createVNode(CollectionKanbanView_default, {
5848
5920
  schema: collection.value.schema,
5849
5921
  items: filteredItems.value,
5850
5922
  "group-field": kanbanGroupField.value,
@@ -5860,7 +5932,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5860
5932
  "selected",
5861
5933
  "notified",
5862
5934
  "readonly"
5863
- ])])])) : activeCustomView.value ? (openBlock(), createElementBlock("div", _hoisted_54, [activeCustomView.value.target === "mobile" ? (openBlock(), createBlock(CollectionRemoteViewPreview_default, {
5935
+ ])])])) : activeCustomView.value ? (openBlock(), createElementBlock("div", _hoisted_56, [activeCustomView.value.target === "mobile" ? (openBlock(), createBlock(CollectionRemoteViewPreview_default, {
5864
5936
  key: 0,
5865
5937
  slug: collection.value.slug,
5866
5938
  view: activeCustomView.value,
@@ -5871,32 +5943,32 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5871
5943
  view: activeCustomView.value,
5872
5944
  onOpenItem: onCustomViewOpenItem,
5873
5945
  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),
5946
+ }, 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, [
5947
+ _cache[52] || (_cache[52] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "search_off", -1)),
5948
+ createElementVNode("p", _hoisted_60, toDisplayString(unref(t)("collectionsView.noMatchingItems")), 1),
5877
5949
  createElementVNode("button", {
5878
5950
  type: "button",
5879
5951
  class: "text-xs text-indigo-600 font-semibold hover:underline",
5880
- onClick: _cache[14] || (_cache[14] = ($event) => (searchQuery.value = "", flagFilters.value = {}))
5952
+ onClick: _cache[15] || (_cache[15] = ($event) => (searchQuery.value = "", flagFilters.value = {}))
5881
5953
  }, 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),
5954
+ ])) : (openBlock(), createElementBlock("div", _hoisted_61, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_62, [
5955
+ _cache[54] || (_cache[54] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
5956
+ createElementVNode("span", _hoisted_63, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5885
5957
  createElementVNode("button", {
5886
5958
  type: "button",
5887
5959
  class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
5888
5960
  "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]) => {
5961
+ onClick: _cache[16] || (_cache[16] = ($event) => inlineError.value = null)
5962
+ }, [..._cache[53] || (_cache[53] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_64)
5963
+ ])) : createCommentVNode("", true), createElementVNode("table", _hoisted_65, [createElementVNode("thead", null, [createElementVNode("tr", _hoisted_66, [(openBlock(true), createElementBlock(Fragment, null, renderList(listColumnFields.value, ([key, field]) => {
5892
5964
  return openBlock(), createElementBlock("th", {
5893
5965
  key,
5894
5966
  "aria-sort": unref(isSortableField)(field) ? sortAriaValue(key) : void 0,
5895
5967
  class: "px-5 py-3 font-bold text-slate-500 text-left uppercase tracking-wider whitespace-nowrap"
5896
- }, [createElementVNode("div", _hoisted_66, [createElementVNode("span", {
5968
+ }, [createElementVNode("div", _hoisted_68, [createElementVNode("span", {
5897
5969
  class: "truncate max-w-[14rem]",
5898
5970
  title: field.label
5899
- }, toDisplayString(field.label), 9, _hoisted_67), unref(isSortableField)(field) ? (openBlock(), createElementBlock("button", {
5971
+ }, toDisplayString(field.label), 9, _hoisted_69), unref(isSortableField)(field) ? (openBlock(), createElementBlock("button", {
5900
5972
  key: 0,
5901
5973
  type: "button",
5902
5974
  class: normalizeClass(["inline-flex items-center justify-center rounded p-0.5 -my-1 leading-none transition-colors", sortButtonClass(key)]),
@@ -5904,9 +5976,9 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5904
5976
  "aria-label": unref(t)("collectionsView.sortBy", { field: field.label }),
5905
5977
  onClick: withModifiers(($event) => cycleSort(key), ["stop"]),
5906
5978
  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) => {
5979
+ onPointerleave: _cache[17] || (_cache[17] = ($event) => hoveredSortKey.value = null)
5980
+ }, [createElementVNode("span", _hoisted_71, toDisplayString(sortIconName(key)), 1)], 42, _hoisted_70)) : createCommentVNode("", true)])], 8, _hoisted_67);
5981
+ }), 128))])]), createElementVNode("tbody", _hoisted_72, [(openBlock(true), createElementBlock(Fragment, null, renderList(sortedItems.value, (item) => {
5910
5982
  return openBlock(), createElementBlock("tr", {
5911
5983
  key: String(item[collection.value.schema.primaryKey] ?? ""),
5912
5984
  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 +6000,9 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5928
6000
  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
6001
  "data-testid": `collections-inline-toggle-${key}-${item[collection.value.schema.primaryKey]}`,
5930
6002
  "aria-label": field.label,
5931
- onClick: _cache[17] || (_cache[17] = withModifiers(() => {}, ["stop"])),
6003
+ onClick: _cache[18] || (_cache[18] = withModifiers(() => {}, ["stop"])),
5932
6004
  onChange: ($event) => commitToggle(item, field)
5933
- }, null, 40, _hoisted_72)) : field.type === "boolean" ? (openBlock(), createElementBlock("input", {
6005
+ }, null, 40, _hoisted_74)) : field.type === "boolean" ? (openBlock(), createElementBlock("input", {
5934
6006
  key: 1,
5935
6007
  type: "checkbox",
5936
6008
  checked: item[key] === true,
@@ -5938,15 +6010,15 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5938
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",
5939
6011
  "data-testid": `collections-inline-bool-${key}-${item[collection.value.schema.primaryKey]}`,
5940
6012
  "aria-label": field.label,
5941
- onClick: _cache[18] || (_cache[18] = withModifiers(() => {}, ["stop"])),
6013
+ onClick: _cache[19] || (_cache[19] = withModifiers(() => {}, ["stop"])),
5942
6014
  onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.checked)
5943
- }, null, 40, _hoisted_73)) : field.type === "flag" ? (openBlock(), createElementBlock("span", {
6015
+ }, null, 40, _hoisted_75)) : field.type === "flag" ? (openBlock(), createElementBlock("span", {
5944
6016
  key: 2,
5945
6017
  class: normalizeClass(["material-icons text-lg align-middle", flagValueOf(String(key), item) ? "text-emerald-600" : "text-slate-300"]),
5946
6018
  "data-testid": `collections-flag-${key}-${item[collection.value.schema.primaryKey]}`,
5947
6019
  "aria-label": `${field.label}: ${unref(t)(flagValueOf(String(key), item) ? "common.yes" : "common.no")}`,
5948
6020
  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", {
6021
+ }, 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
6022
  href: unref(cui).recordHref?.(field.to, String(item[key])),
5951
6023
  tabindex: unref(cui).recordHref?.(field.to, String(item[key])) ? void 0 : 0,
5952
6024
  role: "link",
@@ -5954,48 +6026,48 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5954
6026
  "data-testid": `collections-ref-link-${key}-${item[key]}`,
5955
6027
  onClick: ($event) => unref(activateRefLink)($event, field.to, String(item[key]), true),
5956
6028
  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", {
6029
+ }, 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
6030
  key: 4,
5959
6031
  value: item[key] == null ? "" : String(item[key]),
5960
6032
  disabled: isReadOnly.value || isRowInlineSaving(item),
5961
6033
  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
6034
  "data-testid": `collections-inline-enum-${key}-${item[collection.value.schema.primaryKey]}`,
5963
6035
  "aria-label": field.label,
5964
- onClick: _cache[19] || (_cache[19] = withModifiers(() => {}, ["stop"])),
6036
+ onClick: _cache[20] || (_cache[20] = withModifiers(() => {}, ["stop"])),
5965
6037
  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) => {
6038
+ }, [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
6039
  return openBlock(), createElementBlock("option", {
5968
6040
  key: value,
5969
6041
  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", {
6042
+ }, toDisplayString(value), 9, _hoisted_81);
6043
+ }), 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
6044
  key: 8,
5973
6045
  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
6046
  "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", {
6047
+ }, toDisplayString(unref(render).rollupDisplay(field, item)), 9, _hoisted_85)) : field.type !== "file" && unref(isExternalUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
5976
6048
  key: 9,
5977
6049
  href: String(item[key]),
5978
6050
  target: "_blank",
5979
6051
  rel: "noopener noreferrer",
5980
6052
  class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
5981
6053
  "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", {
6054
+ onClick: _cache[21] || (_cache[21] = withModifiers(() => {}, ["stop"]))
6055
+ }, toDisplayString(String(item[key])), 9, _hoisted_86)) : field.type === "file" && unref(artifactUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
5984
6056
  key: 10,
5985
6057
  href: unref(artifactUrl)(item[key]) ?? void 0,
5986
6058
  target: "_blank",
5987
6059
  rel: "noopener noreferrer",
5988
6060
  class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
5989
6061
  "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", {
6062
+ onClick: _cache[22] || (_cache[22] = withModifiers(() => {}, ["stop"]))
6063
+ }, toDisplayString(String(item[key])), 9, _hoisted_87)) : field.type === "file" && unref(fileRoutePath)(item[key]) ? (openBlock(), createElementBlock("a", {
5992
6064
  key: 11,
5993
6065
  href: unref(fileRoutePath)(item[key]) ?? void 0,
5994
6066
  class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
5995
6067
  "data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
5996
6068
  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);
6069
+ }, toDisplayString(String(item[key])), 9, _hoisted_88)) : (openBlock(), createElementBlock("span", _hoisted_89, toDisplayString(unref(formatCell)(item[key], field.type)), 1))], 64)) : createCommentVNode("", true)]);
6070
+ }), 128))], 42, _hoisted_73);
5999
6071
  }), 128))])])]))]),
6000
6072
  collection.value && (viewing.value || editing.value) && !(calendarActive.value && openDay.value) ? (openBlock(), createBlock(CollectionRecordModal_default, {
6001
6073
  key: 4,
@@ -6003,7 +6075,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
6003
6075
  }, {
6004
6076
  default: withCtx(() => [createVNode(CollectionRecordPanel_default, {
6005
6077
  editing: editing.value,
6006
- "onUpdate:editing": _cache[22] || (_cache[22] = ($event) => editing.value = $event),
6078
+ "onUpdate:editing": _cache[23] || (_cache[23] = ($event) => editing.value = $event),
6007
6079
  collection: collection.value,
6008
6080
  viewing: viewing.value,
6009
6081
  saving: saving.value,
@@ -6023,7 +6095,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
6023
6095
  onCancel: cancelEditor,
6024
6096
  onEdit: editFromView,
6025
6097
  onClose: closeView,
6026
- onDelete: _cache[23] || (_cache[23] = ($event) => viewing.value && confirmDelete(viewing.value)),
6098
+ onDelete: _cache[24] || (_cache[24] = ($event) => viewing.value && confirmDelete(viewing.value)),
6027
6099
  onRunAction: runAction,
6028
6100
  onItemChat
6029
6101
  }, null, 8, [
@@ -6051,7 +6123,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
6051
6123
  action: mutateModal.value.action,
6052
6124
  pending: mutatePending.value,
6053
6125
  error: mutateError.value,
6054
- onClose: _cache[24] || (_cache[24] = ($event) => mutateModal.value = null),
6126
+ onClose: _cache[25] || (_cache[25] = ($event) => mutateModal.value = null),
6055
6127
  onSubmit: submitMutateParams
6056
6128
  }, null, 8, [
6057
6129
  "action",
@@ -6064,7 +6136,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
6064
6136
  title: collection.value.title,
6065
6137
  views: customViews.value,
6066
6138
  onChanged: onViewsChanged,
6067
- onClose: _cache[25] || (_cache[25] = ($event) => configOpen.value = false)
6139
+ onClose: _cache[26] || (_cache[26] = ($event) => configOpen.value = false)
6068
6140
  }, null, 8, [
6069
6141
  "slug",
6070
6142
  "title",
@@ -6079,29 +6151,29 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
6079
6151
  "data-testid": "collections-chat-modal",
6080
6152
  onClick: withModifiers(closeChat, ["self"]),
6081
6153
  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)]),
6154
+ }, [createElementVNode("div", _hoisted_90, [
6155
+ createElementVNode("header", _hoisted_91, [
6156
+ _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)),
6157
+ createElementVNode("div", _hoisted_92, [createElementVNode("h2", _hoisted_93, toDisplayString(unref(t)("collectionsView.chatTitle")), 1), createElementVNode("span", _hoisted_94, toDisplayString(collection.value.title), 1)]),
6086
6158
  createElementVNode("button", {
6087
6159
  type: "button",
6088
6160
  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
6161
  "aria-label": unref(t)("common.close"),
6090
6162
  "data-testid": "collections-chat-close",
6091
6163
  onClick: closeChat
6092
- }, [..._cache[54] || (_cache[54] = [createElementVNode("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_93)
6164
+ }, [..._cache[56] || (_cache[56] = [createElementVNode("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_95)
6093
6165
  ]),
6094
- createElementVNode("div", _hoisted_94, [withDirectives(createElementVNode("textarea", {
6166
+ createElementVNode("div", _hoisted_96, [withDirectives(createElementVNode("textarea", {
6095
6167
  ref_key: "chatInputEl",
6096
6168
  ref: chatInputEl,
6097
- "onUpdate:modelValue": _cache[26] || (_cache[26] = ($event) => chatMessage.value = $event),
6169
+ "onUpdate:modelValue": _cache[27] || (_cache[27] = ($event) => chatMessage.value = $event),
6098
6170
  rows: "4",
6099
6171
  placeholder: unref(t)("collectionsView.chatPlaceholder"),
6100
6172
  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
6173
  "data-testid": "collections-chat-input",
6102
6174
  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", {
6175
+ }, null, 40, _hoisted_97), [[vModelText, chatMessage.value]])]),
6176
+ createElementVNode("footer", _hoisted_98, [createElementVNode("button", {
6105
6177
  type: "button",
6106
6178
  class: "h-8 px-2.5 rounded text-xs font-bold text-slate-500 hover:bg-slate-200/50 transition-colors",
6107
6179
  "data-testid": "collections-chat-cancel",
@@ -6112,7 +6184,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
6112
6184
  disabled: !chatMessage.value.trim(),
6113
6185
  "data-testid": "collections-chat-send",
6114
6186
  onClick: submitChat
6115
- }, toDisplayString(unref(t)("collectionsView.chatStart")), 9, _hoisted_97)])
6187
+ }, toDisplayString(unref(t)("collectionsView.chatStart")), 9, _hoisted_99)])
6116
6188
  ])], 32)) : createCommentVNode("", true)
6117
6189
  ]);
6118
6190
  };