@mulmoclaude/collection-plugin 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vue.js CHANGED
@@ -1,4 +1,4 @@
1
- import { COMPUTED_TYPES, MINUTES_PER_DAY, TOOL_DEFINITION, actionVisible, agentActionRunKey, assignLanes, backlinkRows, boolSortValue, bucketRecords, buildMonthGrid, buildUpdatedRecord, coerceInlineValue, dateOf, dateSortValue, daySlice, defangForPrompt, deriveAll, draftToRecord, embedTargetId, emptyRow, enumSortValue, errorMessage, executePresentCollection, fieldVisible, firstMissingRequiredField, isSortableField, itemIdOf, itemLabelOf, labelFieldFor, nextSortDirection, numericSortValue, resolveEnumColor, rollupValue, rowFromItem, shortHexId, sortItems, stringSortValue, ymdKey } from "@mulmoclaude/core/collection";
1
+ import { COMPUTED_TYPES, MINUTES_PER_DAY, TOOL_DEFINITION, actionVisible, agentActionRunKey, assignLanes, backlinkRows, boolSortValue, bucketRecords, buildMonthGrid, buildUpdatedRecord, coerceInlineValue, dateOf, dateSortValue, daySlice, defangForPrompt, deriveAll, draftToRecord, embedTargetId, emptyRow, enumSortValue, errorMessage, executePresentCollection, fieldVisible, firstMissingRequiredField, isSortableField, itemIdOf, itemIsDone, itemLabelOf, labelFieldFor, nextSortDirection, numericSortValue, resolveEnumColor, rollupValue, rowFromItem, shortHexId, sortItems, stringSortValue, ymdKey } from "@mulmoclaude/core/collection";
2
2
  import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, effectScope, mergeModels, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, onUnmounted, openBlock, reactive, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useModel, vModelCheckbox, vModelDynamic, vModelSelect, vModelText, watch, watchEffect, withCtx, withDirectives, withKeys, withModifiers } from "vue";
3
3
  import { createI18n } from "vue-i18n";
4
4
  import draggable from "vuedraggable";
@@ -90,6 +90,11 @@ 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",
94
+ flagFilterAll: "Filter by {label}",
95
+ flagFilterHide: "Hiding {label}",
96
+ flagFilterOnly: "Only {label}",
97
+ flagDoneChip: "Done",
93
98
  sortBy: "Sort by {field}",
94
99
  openCollection: "Open {title}",
95
100
  createTitle: "Add new",
@@ -233,6 +238,11 @@ var i18n = createI18n({
233
238
  searchSummary: "{total} 件中 {shown} 件を表示",
234
239
  noMatchingItems: "一致する項目がありません",
235
240
  clearSearch: "検索をクリア",
241
+ flagFilterGroup: "フラグで絞り込み",
242
+ flagFilterAll: "{label} で絞り込む",
243
+ flagFilterHide: "{label} を非表示中",
244
+ flagFilterOnly: "{label} のみ表示中",
245
+ flagDoneChip: "完了",
236
246
  sortBy: "{field}で並べ替え",
237
247
  openCollection: "{title} を開く",
238
248
  createTitle: "新規追加",
@@ -376,6 +386,11 @@ var i18n = createI18n({
376
386
  searchSummary: "显示 {total} 条中的 {shown} 条",
377
387
  noMatchingItems: "没有匹配的项目",
378
388
  clearSearch: "清除搜索",
389
+ flagFilterGroup: "标记筛选",
390
+ flagFilterAll: "按{label}筛选",
391
+ flagFilterHide: "已隐藏{label}",
392
+ flagFilterOnly: "仅显示{label}",
393
+ flagDoneChip: "已完成",
379
394
  sortBy: "按{field}排序",
380
395
  openCollection: "打开 {title}",
381
396
  createTitle: "新增",
@@ -519,6 +534,11 @@ var i18n = createI18n({
519
534
  searchSummary: "{total}개 중 {shown}개 표시",
520
535
  noMatchingItems: "일치하는 항목이 없습니다",
521
536
  clearSearch: "검색 지우기",
537
+ flagFilterGroup: "플래그 필터",
538
+ flagFilterAll: "{label}(으)로 필터",
539
+ flagFilterHide: "{label} 숨김",
540
+ flagFilterOnly: "{label}만 표시",
541
+ flagDoneChip: "완료",
522
542
  sortBy: "{field} 기준 정렬",
523
543
  openCollection: "{title} 열기",
524
544
  createTitle: "새로 추가",
@@ -662,6 +682,11 @@ var i18n = createI18n({
662
682
  searchSummary: "Mostrando {shown} de {total}",
663
683
  noMatchingItems: "No hay elementos coincidentes",
664
684
  clearSearch: "Borrar búsqueda",
685
+ flagFilterGroup: "Filtros por indicador",
686
+ flagFilterAll: "Filtrar por {label}",
687
+ flagFilterHide: "Ocultando {label}",
688
+ flagFilterOnly: "Solo {label}",
689
+ flagDoneChip: "Hecho",
665
690
  sortBy: "Ordenar por {field}",
666
691
  openCollection: "Abrir {title}",
667
692
  createTitle: "Añadir nuevo",
@@ -805,6 +830,11 @@ var i18n = createI18n({
805
830
  searchSummary: "Mostrando {shown} de {total}",
806
831
  noMatchingItems: "Nenhum item correspondente",
807
832
  clearSearch: "Limpar busca",
833
+ flagFilterGroup: "Filtros por marcador",
834
+ flagFilterAll: "Filtrar por {label}",
835
+ flagFilterHide: "Ocultando {label}",
836
+ flagFilterOnly: "Somente {label}",
837
+ flagDoneChip: "Concluído",
808
838
  sortBy: "Ordenar por {field}",
809
839
  openCollection: "Abrir {title}",
810
840
  createTitle: "Adicionar novo",
@@ -948,6 +978,11 @@ var i18n = createI18n({
948
978
  searchSummary: "Affichage de {shown} sur {total}",
949
979
  noMatchingItems: "Aucun élément correspondant",
950
980
  clearSearch: "Effacer la recherche",
981
+ flagFilterGroup: "Filtres par indicateur",
982
+ flagFilterAll: "Filtrer par {label}",
983
+ flagFilterHide: "{label} masqué",
984
+ flagFilterOnly: "Uniquement {label}",
985
+ flagDoneChip: "Terminé",
951
986
  sortBy: "Trier par {field}",
952
987
  openCollection: "Ouvrir {title}",
953
988
  createTitle: "Ajouter",
@@ -1091,6 +1126,11 @@ var i18n = createI18n({
1091
1126
  searchSummary: "{shown} von {total} werden angezeigt",
1092
1127
  noMatchingItems: "Keine passenden Einträge",
1093
1128
  clearSearch: "Suche zurücksetzen",
1129
+ flagFilterGroup: "Flag-Filter",
1130
+ flagFilterAll: "Nach {label} filtern",
1131
+ flagFilterHide: "{label} ausgeblendet",
1132
+ flagFilterOnly: "Nur {label}",
1133
+ flagDoneChip: "Erledigt",
1094
1134
  sortBy: "Nach {field} sortieren",
1095
1135
  openCollection: "{title} öffnen",
1096
1136
  createTitle: "Neu hinzufügen",
@@ -2571,77 +2611,79 @@ var _hoisted_57$1 = {
2571
2611
  key: 2,
2572
2612
  class: "text-slate-300"
2573
2613
  };
2574
- var _hoisted_58$1 = [
2614
+ var _hoisted_58$1 = ["data-testid"];
2615
+ var _hoisted_59$1 = ["data-testid"];
2616
+ var _hoisted_60$1 = [
2575
2617
  "href",
2576
2618
  "tabindex",
2577
2619
  "data-testid",
2578
2620
  "onClick",
2579
2621
  "onKeydown"
2580
2622
  ];
2581
- var _hoisted_59$1 = {
2582
- key: 3,
2623
+ var _hoisted_61$1 = {
2624
+ key: 4,
2583
2625
  class: "font-semibold text-slate-900 tabular-nums text-sm"
2584
2626
  };
2585
- var _hoisted_60$1 = {
2586
- key: 4,
2627
+ var _hoisted_62$1 = {
2628
+ key: 5,
2587
2629
  class: "inline-block truncate tabular-nums font-bold text-indigo-900 bg-indigo-50/50 px-2 py-0.5 rounded border border-indigo-100/50"
2588
2630
  };
2589
- var _hoisted_61$1 = ["data-testid"];
2590
- var _hoisted_62$1 = {
2591
- key: 6,
2631
+ var _hoisted_63$1 = ["data-testid"];
2632
+ var _hoisted_64$1 = {
2633
+ key: 7,
2592
2634
  class: "border border-slate-200/80 rounded-xl overflow-hidden shadow-sm mt-1"
2593
2635
  };
2594
- var _hoisted_63$1 = { class: "w-full text-[11px] text-slate-600 bg-white" };
2595
- var _hoisted_64$1 = { class: "bg-slate-50 border-b border-slate-200 text-slate-500 font-bold uppercase tracking-wider" };
2596
- var _hoisted_65$1 = { class: "divide-y divide-slate-100" };
2597
- var _hoisted_66$1 = {
2636
+ var _hoisted_65$1 = { class: "w-full text-[11px] text-slate-600 bg-white" };
2637
+ var _hoisted_66$1 = { class: "bg-slate-50 border-b border-slate-200 text-slate-500 font-bold uppercase tracking-wider" };
2638
+ var _hoisted_67$1 = { class: "divide-y divide-slate-100" };
2639
+ var _hoisted_68$1 = {
2598
2640
  key: 0,
2599
2641
  class: "material-icons text-emerald-600 text-base"
2600
2642
  };
2601
- var _hoisted_67$1 = {
2643
+ var _hoisted_69$1 = {
2602
2644
  key: 1,
2603
2645
  class: "text-slate-300"
2604
2646
  };
2605
- var _hoisted_68$1 = {
2606
- key: 7,
2647
+ var _hoisted_70$1 = {
2648
+ key: 8,
2607
2649
  class: "text-slate-400 italic"
2608
2650
  };
2609
- var _hoisted_69$1 = {
2610
- key: 8,
2651
+ var _hoisted_71$1 = {
2652
+ key: 9,
2611
2653
  class: "bg-slate-50 rounded-xl p-4 border border-slate-200/60 text-slate-600 text-xs whitespace-pre-wrap leading-relaxed max-h-[30vh] overflow-y-auto"
2612
2654
  };
2613
- var _hoisted_70$1 = [
2655
+ var _hoisted_72$1 = [
2614
2656
  "src",
2615
2657
  "alt",
2616
2658
  "data-testid"
2617
2659
  ];
2618
- var _hoisted_71$1 = ["href", "data-testid"];
2619
- var _hoisted_72$1 = ["href", "data-testid"];
2620
- var _hoisted_73$1 = [
2660
+ var _hoisted_73$1 = ["href", "data-testid"];
2661
+ var _hoisted_74$1 = ["href", "data-testid"];
2662
+ var _hoisted_75$1 = [
2621
2663
  "href",
2622
2664
  "data-testid",
2623
2665
  "onClick"
2624
2666
  ];
2625
- var _hoisted_74$1 = {
2626
- key: 15,
2667
+ var _hoisted_76$1 = {
2668
+ key: 16,
2627
2669
  class: "text-slate-800 font-semibold"
2628
2670
  };
2629
- var _hoisted_75$1 = {
2671
+ var _hoisted_77$1 = {
2630
2672
  key: 0,
2631
2673
  class: "col-span-full text-xs font-semibold text-red-600 bg-red-50 border border-red-100 p-2.5 rounded-xl"
2632
2674
  };
2633
- var _hoisted_76$1 = {
2675
+ var _hoisted_78$1 = {
2634
2676
  key: 1,
2635
2677
  class: "mt-5 pt-4 border-t border-slate-200/60",
2636
2678
  "data-testid": "collections-detail-chat"
2637
2679
  };
2638
- var _hoisted_77$1 = {
2680
+ var _hoisted_79$1 = {
2639
2681
  class: "block text-[10px] font-bold text-slate-400 uppercase tracking-wider mb-1.5",
2640
2682
  for: "collections-detail-chat-input"
2641
2683
  };
2642
- var _hoisted_78$1 = { class: "flex items-end gap-2" };
2643
- var _hoisted_79$1 = ["placeholder", "onKeydown"];
2644
- var _hoisted_80$1 = ["disabled"];
2684
+ var _hoisted_80$1 = { class: "flex items-end gap-2" };
2685
+ var _hoisted_81$1 = ["placeholder", "onKeydown"];
2686
+ var _hoisted_82$1 = ["disabled"];
2645
2687
  //#endregion
2646
2688
  //#region src/vue/components/CollectionRecordPanel.vue
2647
2689
  var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
@@ -3003,8 +3045,16 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
3003
3045
  key: 3,
3004
3046
  class: "text-xs font-medium text-slate-700 break-words",
3005
3047
  "data-testid": `collections-detail-value-${key}`
3006
- }, [field.type === "toggle" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [field.field !== void 0 && String(detailRecord.value[field.field] ?? "") === field.onValue ? (openBlock(), createElementBlock("span", _hoisted_53$1, [_cache[12] || (_cache[12] = createElementVNode("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), createTextVNode(" " + toDisplayString(unref(t)("common.yes")), 1)])) : (openBlock(), createElementBlock("span", _hoisted_54$1, toDisplayString(unref(t)("common.no")), 1))], 64)) : field.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [detailRecord.value[key] === true ? (openBlock(), createElementBlock("span", _hoisted_55$1, [_cache[13] || (_cache[13] = createElementVNode("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), createTextVNode(" " + toDisplayString(unref(t)("common.yes")), 1)])) : detailRecord.value[key] === false ? (openBlock(), createElementBlock("span", _hoisted_56$1, toDisplayString(unref(t)("common.no")), 1)) : (openBlock(), createElementBlock("span", _hoisted_57$1, "—"))], 64)) : field.type === "ref" && field.to && typeof detailRecord.value[key] === "string" && detailRecord.value[key] ? (openBlock(), createElementBlock("a", {
3007
- key: 2,
3048
+ }, [field.type === "toggle" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [field.field !== void 0 && String(detailRecord.value[field.field] ?? "") === field.onValue ? (openBlock(), createElementBlock("span", _hoisted_53$1, [_cache[12] || (_cache[12] = createElementVNode("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), createTextVNode(" " + toDisplayString(unref(t)("common.yes")), 1)])) : (openBlock(), createElementBlock("span", _hoisted_54$1, toDisplayString(unref(t)("common.no")), 1))], 64)) : field.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [detailRecord.value[key] === true ? (openBlock(), createElementBlock("span", _hoisted_55$1, [_cache[13] || (_cache[13] = createElementVNode("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), createTextVNode(" " + toDisplayString(unref(t)("common.yes")), 1)])) : detailRecord.value[key] === false ? (openBlock(), createElementBlock("span", _hoisted_56$1, toDisplayString(unref(t)("common.no")), 1)) : (openBlock(), createElementBlock("span", _hoisted_57$1, "—"))], 64)) : field.type === "flag" ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [__props.render.deriveRecord(detailRecord.value)[key] === true ? (openBlock(), createElementBlock("span", {
3049
+ key: 0,
3050
+ class: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-200/40",
3051
+ "data-testid": `collections-detail-flag-${key}`
3052
+ }, [_cache[14] || (_cache[14] = createElementVNode("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), createTextVNode(" " + toDisplayString(unref(t)("common.yes")), 1)], 8, _hoisted_58$1)) : (openBlock(), createElementBlock("span", {
3053
+ key: 1,
3054
+ class: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-semibold bg-slate-50 text-slate-400 border border-slate-200/20",
3055
+ "data-testid": `collections-detail-flag-${key}`
3056
+ }, toDisplayString(unref(t)("common.no")), 9, _hoisted_59$1))], 64)) : field.type === "ref" && field.to && typeof detailRecord.value[key] === "string" && detailRecord.value[key] ? (openBlock(), createElementBlock("a", {
3057
+ key: 3,
3008
3058
  href: unref(cui).recordHref?.(field.to, String(detailRecord.value[key])),
3009
3059
  tabindex: unref(cui).recordHref?.(field.to, String(detailRecord.value[key])) ? void 0 : 0,
3010
3060
  role: "link",
@@ -3012,16 +3062,16 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
3012
3062
  "data-testid": `collections-detail-ref-${key}`,
3013
3063
  onClick: ($event) => unref(activateRefLink)($event, field.to, String(detailRecord.value[key])),
3014
3064
  onKeydown: [withKeys(($event) => unref(activateRefLink)($event, field.to, String(detailRecord.value[key])), ["enter"]), withKeys(($event) => unref(activateRefLink)($event, field.to, String(detailRecord.value[key])), ["space"])]
3015
- }, toDisplayString(__props.render.refDisplay(field.to, String(detailRecord.value[key]))), 41, _hoisted_58$1)) : field.type === "money" ? (openBlock(), createElementBlock("span", _hoisted_59$1, toDisplayString(__props.render.formatMoney(detailRecord.value[key], __props.render.resolveCurrency(field, detailRecord.value), __props.locale)), 1)) : field.type === "derived" ? (openBlock(), createElementBlock("span", _hoisted_60$1, toDisplayString(__props.render.derivedDisplay(field, __props.render.evaluateDerivedAgainstItem(field, String(key), detailRecord.value), detailRecord.value)), 1)) : field.type === "rollup" ? (openBlock(), createElementBlock("span", {
3016
- key: 5,
3065
+ }, toDisplayString(__props.render.refDisplay(field.to, String(detailRecord.value[key]))), 41, _hoisted_60$1)) : field.type === "money" ? (openBlock(), createElementBlock("span", _hoisted_61$1, toDisplayString(__props.render.formatMoney(detailRecord.value[key], __props.render.resolveCurrency(field, detailRecord.value), __props.locale)), 1)) : field.type === "derived" ? (openBlock(), createElementBlock("span", _hoisted_62$1, toDisplayString(__props.render.derivedDisplay(field, __props.render.evaluateDerivedAgainstItem(field, String(key), detailRecord.value), detailRecord.value)), 1)) : field.type === "rollup" ? (openBlock(), createElementBlock("span", {
3066
+ key: 6,
3017
3067
  class: "inline-block truncate tabular-nums font-bold text-indigo-900 bg-indigo-50/50 px-2 py-0.5 rounded border border-indigo-100/50",
3018
3068
  "data-testid": `collections-detail-rollup-${key}`
3019
- }, toDisplayString(__props.render.rollupDisplay(field, detailRecord.value)), 9, _hoisted_61$1)) : field.type === "table" && field.of && __props.render.hasTableRows(detailRecord.value[key]) ? (openBlock(), createElementBlock("div", _hoisted_62$1, [createElementVNode("table", _hoisted_63$1, [createElementVNode("thead", _hoisted_64$1, [createElementVNode("tr", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(field.of, (subField, subKey) => {
3069
+ }, toDisplayString(__props.render.rollupDisplay(field, detailRecord.value)), 9, _hoisted_63$1)) : field.type === "table" && field.of && __props.render.hasTableRows(detailRecord.value[key]) ? (openBlock(), createElementBlock("div", _hoisted_64$1, [createElementVNode("table", _hoisted_65$1, [createElementVNode("thead", _hoisted_66$1, [createElementVNode("tr", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(field.of, (subField, subKey) => {
3020
3070
  return openBlock(), createElementBlock("th", {
3021
3071
  key: subKey,
3022
3072
  class: "text-left px-4 py-2 font-bold"
3023
3073
  }, toDisplayString(subField.label), 1);
3024
- }), 128))])]), createElementVNode("tbody", _hoisted_65$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.render.tableRows(detailRecord.value[key]), (row, rowIdx) => {
3074
+ }), 128))])]), createElementVNode("tbody", _hoisted_67$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.render.tableRows(detailRecord.value[key]), (row, rowIdx) => {
3025
3075
  return openBlock(), createElementBlock("tr", {
3026
3076
  key: rowIdx,
3027
3077
  class: "hover:bg-slate-50/50"
@@ -3029,48 +3079,48 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
3029
3079
  return openBlock(), createElementBlock("td", {
3030
3080
  key: subKey,
3031
3081
  class: "px-4 py-2 align-middle font-medium"
3032
- }, [subField.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [row[subKey] === true ? (openBlock(), createElementBlock("span", _hoisted_66$1, "check_circle")) : (openBlock(), createElementBlock("span", _hoisted_67$1, "—"))], 64)) : (openBlock(), createElementBlock("span", {
3082
+ }, [subField.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [row[subKey] === true ? (openBlock(), createElementBlock("span", _hoisted_68$1, "check_circle")) : (openBlock(), createElementBlock("span", _hoisted_69$1, "—"))], 64)) : (openBlock(), createElementBlock("span", {
3033
3083
  key: 1,
3034
3084
  class: normalizeClass([subField.type === "money" ? "font-bold text-slate-800 tabular-nums" : ""])
3035
3085
  }, toDisplayString(__props.render.formatSubCell(subField, row[subKey], detailRecord.value)), 3))]);
3036
3086
  }), 128))]);
3037
- }), 128))])])])) : field.type === "table" ? (openBlock(), createElementBlock("span", _hoisted_68$1, toDisplayString(unref(t)("collectionsView.noRows")), 1)) : field.type === "markdown" ? (openBlock(), createElementBlock("div", _hoisted_69$1, toDisplayString(__props.render.detailText(detailRecord.value[key])), 1)) : field.type === "embed" && embedViews.value[key] ? (openBlock(), createBlock(CollectionEmbedView_default, {
3038
- key: 9,
3087
+ }), 128))])])])) : field.type === "table" ? (openBlock(), createElementBlock("span", _hoisted_70$1, toDisplayString(unref(t)("collectionsView.noRows")), 1)) : field.type === "markdown" ? (openBlock(), createElementBlock("div", _hoisted_71$1, toDisplayString(__props.render.detailText(detailRecord.value[key])), 1)) : field.type === "embed" && embedViews.value[key] ? (openBlock(), createBlock(CollectionEmbedView_default, {
3088
+ key: 10,
3039
3089
  view: embedViews.value[key],
3040
3090
  "field-key": String(key)
3041
3091
  }, null, 8, ["view", "field-key"])) : field.type === "backlinks" && backlinksViews.value[key] ? (openBlock(), createBlock(CollectionBacklinksView_default, {
3042
- key: 10,
3092
+ key: 11,
3043
3093
  view: backlinksViews.value[key],
3044
3094
  "field-key": String(key)
3045
3095
  }, null, 8, ["view", "field-key"])) : field.type === "image" && typeof detailRecord.value[key] === "string" && detailRecord.value[key] ? (openBlock(), createElementBlock("img", {
3046
- key: 11,
3096
+ key: 12,
3047
3097
  src: unref(resolveImageSrc)(String(detailRecord.value[key])),
3048
3098
  alt: field.label,
3049
3099
  class: "max-h-64 max-w-full object-contain rounded-lg border border-slate-200 bg-slate-50",
3050
3100
  "data-testid": `collections-detail-image-${key}`
3051
- }, null, 8, _hoisted_70$1)) : field.type !== "file" && __props.render.isExternalUrl(detailRecord.value[key]) ? (openBlock(), createElementBlock("a", {
3052
- key: 12,
3101
+ }, null, 8, _hoisted_72$1)) : field.type !== "file" && __props.render.isExternalUrl(detailRecord.value[key]) ? (openBlock(), createElementBlock("a", {
3102
+ key: 13,
3053
3103
  href: String(detailRecord.value[key]),
3054
3104
  target: "_blank",
3055
3105
  rel: "noopener noreferrer",
3056
3106
  class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
3057
3107
  "data-testid": `collections-detail-url-${key}`
3058
- }, toDisplayString(String(detailRecord.value[key])), 9, _hoisted_71$1)) : field.type === "file" && __props.render.artifactUrl(detailRecord.value[key]) ? (openBlock(), createElementBlock("a", {
3059
- key: 13,
3108
+ }, toDisplayString(String(detailRecord.value[key])), 9, _hoisted_73$1)) : field.type === "file" && __props.render.artifactUrl(detailRecord.value[key]) ? (openBlock(), createElementBlock("a", {
3109
+ key: 14,
3060
3110
  href: __props.render.artifactUrl(detailRecord.value[key]) ?? void 0,
3061
3111
  target: "_blank",
3062
3112
  rel: "noopener noreferrer",
3063
3113
  class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
3064
3114
  "data-testid": `collections-detail-file-${key}`
3065
- }, toDisplayString(String(detailRecord.value[key])), 9, _hoisted_72$1)) : field.type === "file" && __props.render.fileRoutePath(detailRecord.value[key]) ? (openBlock(), createElementBlock("a", {
3066
- key: 14,
3115
+ }, toDisplayString(String(detailRecord.value[key])), 9, _hoisted_74$1)) : field.type === "file" && __props.render.fileRoutePath(detailRecord.value[key]) ? (openBlock(), createElementBlock("a", {
3116
+ key: 15,
3067
3117
  href: __props.render.fileRoutePath(detailRecord.value[key]) ?? void 0,
3068
3118
  class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
3069
3119
  "data-testid": `collections-detail-file-${key}`,
3070
3120
  onClick: ($event) => unref(activatePathLink)($event, __props.render.fileRoutePath(detailRecord.value[key]) ?? "")
3071
- }, toDisplayString(String(detailRecord.value[key])), 9, _hoisted_73$1)) : (openBlock(), createElementBlock("span", _hoisted_74$1, toDisplayString(__props.render.formatCell(detailRecord.value[key], field.type)), 1))], 8, _hoisted_52$1))], 2)) : createCommentVNode("", true)], 64);
3072
- }), 128)), editing.value && __props.saveError ? (openBlock(), createElementBlock("p", _hoisted_75$1, toDisplayString(__props.saveError), 1)) : createCommentVNode("", true)]),
3073
- !editing.value ? (openBlock(), createElementBlock("div", _hoisted_76$1, [createElementVNode("label", _hoisted_77$1, toDisplayString(unref(t)("collectionsView.itemChatLabel")), 1), createElementVNode("div", _hoisted_78$1, [withDirectives(createElementVNode("textarea", {
3121
+ }, toDisplayString(String(detailRecord.value[key])), 9, _hoisted_75$1)) : (openBlock(), createElementBlock("span", _hoisted_76$1, toDisplayString(__props.render.formatCell(detailRecord.value[key], field.type)), 1))], 8, _hoisted_52$1))], 2)) : createCommentVNode("", true)], 64);
3122
+ }), 128)), editing.value && __props.saveError ? (openBlock(), createElementBlock("p", _hoisted_77$1, toDisplayString(__props.saveError), 1)) : createCommentVNode("", true)]),
3123
+ !editing.value ? (openBlock(), createElementBlock("div", _hoisted_78$1, [createElementVNode("label", _hoisted_79$1, toDisplayString(unref(t)("collectionsView.itemChatLabel")), 1), createElementVNode("div", _hoisted_80$1, [withDirectives(createElementVNode("textarea", {
3074
3124
  id: "collections-detail-chat-input",
3075
3125
  "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => chatMessage.value = $event),
3076
3126
  rows: "2",
@@ -3078,13 +3128,13 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
3078
3128
  class: "flex-1 bg-slate-50 border border-slate-200/80 rounded-xl px-3 py-2 text-xs placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 focus:border-indigo-500 focus:bg-white transition-all resize-none",
3079
3129
  "data-testid": "collections-detail-chat-input",
3080
3130
  onKeydown: [withKeys(withModifiers(submitItemChat, ["meta"]), ["enter"]), withKeys(withModifiers(submitItemChat, ["ctrl"]), ["enter"])]
3081
- }, null, 40, _hoisted_79$1), [[vModelText, chatMessage.value]]), createElementVNode("button", {
3131
+ }, null, 40, _hoisted_81$1), [[vModelText, chatMessage.value]]), createElementVNode("button", {
3082
3132
  type: "button",
3083
3133
  class: "h-8 px-2.5 rounded bg-indigo-600 text-white font-bold text-xs hover:bg-indigo-700 disabled:opacity-50 transition-all shadow-sm shadow-indigo-600/10 flex items-center gap-1 shrink-0",
3084
3134
  disabled: !chatMessage.value.trim(),
3085
3135
  "data-testid": "collections-detail-chat-send",
3086
3136
  onClick: submitItemChat
3087
- }, [_cache[14] || (_cache[14] = createElementVNode("span", { class: "material-icons text-sm" }, "forum", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.chat")), 1)], 8, _hoisted_80$1)])])) : createCommentVNode("", true)
3137
+ }, [_cache[15] || (_cache[15] = createElementVNode("span", { class: "material-icons text-sm" }, "forum", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.chat")), 1)], 8, _hoisted_82$1)])])) : createCommentVNode("", true)
3088
3138
  ]),
3089
3139
  _: 1
3090
3140
  }, 40, ["data-testid"]);
@@ -3879,6 +3929,38 @@ function writeCollectionSort(slug, sort) {
3879
3929
  localStorage.setItem(SORT_STORAGE_KEY, JSON.stringify(all));
3880
3930
  } catch {}
3881
3931
  }
3932
+ var FLAG_FILTER_STORAGE_KEY = "collection_flag_filters";
3933
+ function isFlagFilterState(value) {
3934
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
3935
+ return Object.values(value).every((mode) => mode === "hide" || mode === "only");
3936
+ }
3937
+ function readAllFlagFilters() {
3938
+ try {
3939
+ const raw = localStorage.getItem(FLAG_FILTER_STORAGE_KEY);
3940
+ if (!raw) return {};
3941
+ const parsed = JSON.parse(raw);
3942
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
3943
+ const out = {};
3944
+ for (const [slug, value] of Object.entries(parsed)) if (isFlagFilterState(value)) out[slug] = value;
3945
+ return out;
3946
+ } catch {
3947
+ return {};
3948
+ }
3949
+ }
3950
+ /** The slug's persisted chip states ({} when none). A key whose flag no
3951
+ * longer exists in the schema is harmless — the chip list is derived
3952
+ * from the live schema, so a stale entry just never renders/filters. */
3953
+ function readCollectionFlagFilters(slug) {
3954
+ return readAllFlagFilters()[slug] ?? {};
3955
+ }
3956
+ /** Persist the slug's chip states; an empty state clears the entry. */
3957
+ function writeCollectionFlagFilters(slug, filters) {
3958
+ try {
3959
+ const all = Object.fromEntries(Object.entries(readAllFlagFilters()).filter(([key]) => key !== slug));
3960
+ if (Object.keys(filters).length > 0) all[slug] = filters;
3961
+ localStorage.setItem(FLAG_FILTER_STORAGE_KEY, JSON.stringify(all));
3962
+ } catch {}
3963
+ }
3882
3964
  //#endregion
3883
3965
  //#region src/vue/components/CollectionView.vue?vue&type=script&setup=true&lang.ts
3884
3966
  var _hoisted_1$6 = { class: "h-full flex flex-col bg-slate-50/30" };
@@ -3938,185 +4020,198 @@ var _hoisted_22$3 = ["placeholder", "aria-label"];
3938
4020
  var _hoisted_23$2 = ["aria-label"];
3939
4021
  var _hoisted_24$1 = { class: "flex items-center gap-2" };
3940
4022
  var _hoisted_25$1 = ["aria-label"];
3941
- var _hoisted_26$1 = ["aria-pressed"];
3942
- var _hoisted_27$1 = ["aria-pressed"];
3943
- var _hoisted_28 = ["aria-pressed"];
3944
- var _hoisted_29 = [
4023
+ var _hoisted_26$1 = [
4024
+ "title",
4025
+ "aria-label",
3945
4026
  "aria-pressed",
3946
4027
  "data-testid",
3947
4028
  "onClick"
3948
4029
  ];
3949
- var _hoisted_30 = { class: "material-icons text-sm" };
3950
- var _hoisted_31 = [
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"];
4037
+ var _hoisted_31 = ["aria-pressed"];
4038
+ var _hoisted_32 = [
4039
+ "aria-pressed",
4040
+ "data-testid",
4041
+ "onClick"
4042
+ ];
4043
+ var _hoisted_33 = { class: "material-icons text-sm" };
4044
+ var _hoisted_34 = [
3951
4045
  "title",
3952
4046
  "aria-label",
3953
4047
  "aria-expanded"
3954
4048
  ];
3955
- var _hoisted_32 = {
4049
+ var _hoisted_35 = {
3956
4050
  key: 0,
3957
4051
  class: "absolute left-0 top-full mt-1 z-20 min-w-max rounded border border-slate-200 bg-white shadow-lg py-1",
3958
4052
  "data-testid": "collection-view-add-menu"
3959
4053
  };
3960
- var _hoisted_33 = ["title", "aria-label"];
3961
- var _hoisted_34 = ["value", "aria-label"];
3962
- var _hoisted_35 = ["value"];
3963
- var _hoisted_36 = ["value", "aria-label"];
3964
- var _hoisted_37 = ["value"];
3965
- var _hoisted_38 = {
3966
- key: 3,
4054
+ var _hoisted_36 = ["title", "aria-label"];
4055
+ var _hoisted_37 = ["value", "aria-label"];
4056
+ var _hoisted_38 = ["value"];
4057
+ var _hoisted_39 = ["value", "aria-label"];
4058
+ var _hoisted_40 = ["value"];
4059
+ var _hoisted_41 = {
4060
+ key: 4,
3967
4061
  class: "text-[10px] text-slate-400 font-bold uppercase tracking-wider select-none"
3968
4062
  };
3969
- var _hoisted_39 = {
4063
+ var _hoisted_42 = {
3970
4064
  key: 3,
3971
4065
  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",
3972
4066
  "data-testid": "collections-data-issues"
3973
4067
  };
3974
- var _hoisted_40 = { class: "flex-1" };
3975
- var _hoisted_41 = { class: "flex-1 overflow-auto" };
3976
- var _hoisted_42 = {
4068
+ var _hoisted_43 = { class: "flex-1" };
4069
+ var _hoisted_44 = { class: "flex-1 overflow-auto" };
4070
+ var _hoisted_45 = {
3977
4071
  key: 0,
3978
4072
  class: "flex flex-col items-center justify-center py-20 text-sm text-slate-500 gap-3"
3979
4073
  };
3980
- var _hoisted_43 = {
4074
+ var _hoisted_46 = {
3981
4075
  key: 1,
3982
4076
  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"
3983
4077
  };
3984
- var _hoisted_44 = { key: 2 };
3985
- var _hoisted_45 = {
4078
+ var _hoisted_47 = { key: 2 };
4079
+ var _hoisted_48 = {
3986
4080
  key: 3,
3987
4081
  class: "p-4"
3988
4082
  };
3989
- var _hoisted_46 = {
4083
+ var _hoisted_49 = {
3990
4084
  key: 4,
3991
4085
  class: "h-full flex flex-col"
3992
4086
  };
3993
- var _hoisted_47 = {
4087
+ var _hoisted_50 = {
3994
4088
  key: 0,
3995
4089
  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",
3996
4090
  "data-testid": "collections-inline-error"
3997
4091
  };
3998
- var _hoisted_48 = { class: "flex-1" };
3999
- var _hoisted_49 = ["aria-label"];
4000
- var _hoisted_50 = { class: "flex-1 min-h-0 px-3 py-2" };
4001
- var _hoisted_51 = {
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 = {
4002
4096
  key: 5,
4003
4097
  class: "h-full",
4004
4098
  "data-testid": "collection-custom-view-body"
4005
4099
  };
4006
- var _hoisted_52 = {
4100
+ var _hoisted_55 = {
4007
4101
  key: 6,
4008
4102
  class: "flex flex-col items-center justify-center py-20 text-sm text-slate-400 gap-2"
4009
4103
  };
4010
- var _hoisted_53 = { class: "font-semibold text-slate-600" };
4011
- var _hoisted_54 = {
4104
+ var _hoisted_56 = { class: "font-semibold text-slate-600" };
4105
+ var _hoisted_57 = {
4012
4106
  key: 7,
4013
4107
  class: "flex flex-col items-center justify-center py-20 text-sm text-slate-400 gap-2"
4014
4108
  };
4015
- var _hoisted_55 = { class: "font-semibold text-slate-600" };
4016
- var _hoisted_56 = {
4109
+ var _hoisted_58 = { class: "font-semibold text-slate-600" };
4110
+ var _hoisted_59 = {
4017
4111
  key: 8,
4018
4112
  class: "overflow-x-auto [container-type:inline-size]"
4019
4113
  };
4020
- var _hoisted_57 = {
4114
+ var _hoisted_60 = {
4021
4115
  key: 0,
4022
4116
  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",
4023
4117
  "data-testid": "collections-inline-error"
4024
4118
  };
4025
- var _hoisted_58 = { class: "flex-1" };
4026
- var _hoisted_59 = ["aria-label"];
4027
- var _hoisted_60 = { class: "min-w-full text-xs" };
4028
- var _hoisted_61 = { class: "bg-slate-50 border-b border-slate-200" };
4029
- var _hoisted_62 = ["aria-sort"];
4030
- var _hoisted_63 = { class: "flex items-center gap-1" };
4031
- var _hoisted_64 = ["title"];
4032
- var _hoisted_65 = [
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 = [
4033
4127
  "data-testid",
4034
4128
  "aria-label",
4035
4129
  "onClick",
4036
4130
  "onPointerenter"
4037
4131
  ];
4038
- var _hoisted_66 = { class: "material-icons text-base align-middle" };
4039
- var _hoisted_67 = { class: "divide-y divide-slate-100 bg-white" };
4040
- var _hoisted_68 = [
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 = [
4041
4135
  "aria-label",
4042
4136
  "data-testid",
4043
4137
  "onClick",
4044
4138
  "onKeydown"
4045
4139
  ];
4046
- var _hoisted_69 = [
4140
+ var _hoisted_72 = [
4047
4141
  "checked",
4048
4142
  "disabled",
4049
4143
  "data-testid",
4050
4144
  "aria-label",
4051
4145
  "onChange"
4052
4146
  ];
4053
- var _hoisted_70 = [
4147
+ var _hoisted_73 = [
4054
4148
  "checked",
4055
4149
  "disabled",
4056
4150
  "data-testid",
4057
4151
  "aria-label",
4058
4152
  "onChange"
4059
4153
  ];
4060
- var _hoisted_71 = {
4061
- key: 2,
4154
+ var _hoisted_74 = ["data-testid", "aria-label"];
4155
+ var _hoisted_75 = {
4156
+ key: 3,
4062
4157
  class: "block truncate"
4063
4158
  };
4064
- var _hoisted_72 = [
4159
+ var _hoisted_76 = [
4065
4160
  "href",
4066
4161
  "tabindex",
4067
4162
  "data-testid",
4068
4163
  "onClick",
4069
4164
  "onKeydown"
4070
4165
  ];
4071
- var _hoisted_73 = [
4166
+ var _hoisted_77 = [
4072
4167
  "value",
4073
4168
  "disabled",
4074
4169
  "data-testid",
4075
4170
  "aria-label",
4076
4171
  "onChange"
4077
4172
  ];
4078
- var _hoisted_74 = {
4173
+ var _hoisted_78 = {
4079
4174
  key: 0,
4080
4175
  value: ""
4081
4176
  };
4082
- var _hoisted_75 = ["value"];
4083
- var _hoisted_76 = {
4084
- key: 4,
4177
+ var _hoisted_79 = ["value"];
4178
+ var _hoisted_80 = {
4179
+ key: 5,
4085
4180
  class: "block truncate tabular-nums font-semibold text-slate-900"
4086
4181
  };
4087
- var _hoisted_77 = {
4088
- key: 5,
4182
+ var _hoisted_81 = {
4183
+ key: 6,
4089
4184
  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"
4090
4185
  };
4091
- var _hoisted_78 = {
4092
- key: 6,
4186
+ var _hoisted_82 = {
4187
+ key: 7,
4093
4188
  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"
4094
4189
  };
4095
- var _hoisted_79 = ["data-testid"];
4096
- var _hoisted_80 = ["href", "data-testid"];
4097
- var _hoisted_81 = ["href", "data-testid"];
4098
- var _hoisted_82 = [
4190
+ var _hoisted_83 = ["data-testid"];
4191
+ var _hoisted_84 = ["href", "data-testid"];
4192
+ var _hoisted_85 = ["href", "data-testid"];
4193
+ var _hoisted_86 = [
4099
4194
  "href",
4100
4195
  "data-testid",
4101
4196
  "onClick"
4102
4197
  ];
4103
- var _hoisted_83 = {
4104
- key: 11,
4198
+ var _hoisted_87 = {
4199
+ key: 12,
4105
4200
  class: "block truncate text-slate-600"
4106
4201
  };
4107
- var _hoisted_84 = { class: "bg-white rounded-2xl shadow-2xl w-full max-w-xl flex flex-col border border-slate-200 overflow-hidden" };
4108
- var _hoisted_85 = { class: "px-6 py-4 border-b border-slate-100 flex items-center gap-3 bg-slate-50/50" };
4109
- var _hoisted_86 = { class: "flex-1" };
4110
- var _hoisted_87 = {
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 = {
4111
4206
  id: "collections-chat-title",
4112
4207
  class: "text-sm font-bold text-slate-800 uppercase tracking-wide"
4113
4208
  };
4114
- var _hoisted_88 = { class: "text-xs text-slate-400 font-semibold" };
4115
- var _hoisted_89 = ["aria-label"];
4116
- var _hoisted_90 = { class: "px-6 py-5" };
4117
- var _hoisted_91 = ["placeholder", "onKeydown"];
4118
- var _hoisted_92 = { class: "px-6 py-3.5 border-t border-slate-100 flex items-center justify-end gap-2 bg-slate-50/50" };
4119
- var _hoisted_93 = ["disabled"];
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"];
4120
4215
  /** `slug` / `selected` are supplied only in EMBEDDED mode (the
4121
4216
  * `presentCollection` chat card mounts this component and drives both
4122
4217
  * from the tool result). In standalone route mode (the
@@ -4127,6 +4222,7 @@ var _hoisted_93 = ["disabled"];
4127
4222
  * is our "rendered inside a chat" signal. When set, chat-triggering
4128
4223
  * actions send into the current session instead of spawning a new
4129
4224
  * chat (see `runAction` / `submitChat`). */
4225
+ var COMPLETION_CHIP_KEY = "__completion";
4130
4226
  var LIVE_REFRESH_DEBOUNCE_MS = 150;
4131
4227
  //#endregion
4132
4228
  //#region src/vue/components/CollectionView.vue
@@ -4253,6 +4349,84 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
4253
4349
  if (!query) return items.value;
4254
4350
  return items.value.filter((item) => itemMatchesQuery(item, query));
4255
4351
  });
4352
+ /** Chip key (state/testid/localStorage) for the synthesized
4353
+ * legacy-completion chip. Field names are unrestricted strings, so a
4354
+ * schema COULD declare a field with this exact name — the chip list
4355
+ * below skips synthesizing in that case, and the predicate dispatch
4356
+ * keys off the structural `synthetic` marker, never this string. */
4357
+ function storedFlagFiltersFor(slug) {
4358
+ return slug ? readCollectionFlagFilters(slug) : {};
4359
+ }
4360
+ const flagFilters = ref(storedFlagFiltersFor(activeSlug.value));
4361
+ const flagChips = computed(() => {
4362
+ const schema = collection.value?.schema;
4363
+ if (!schema) return [];
4364
+ const chips = Object.entries(schema.fields).filter(([, field]) => field.type === "flag").map(([key, field]) => ({
4365
+ key,
4366
+ label: field.label ?? key
4367
+ }));
4368
+ if (schema.completionField && schema.completionDoneValues && schema.fields[schema.completionField]?.type !== "flag" && schema.fields[COMPLETION_CHIP_KEY] === void 0) chips.push({
4369
+ key: COMPLETION_CHIP_KEY,
4370
+ label: t("collectionsView.flagDoneChip"),
4371
+ synthetic: true
4372
+ });
4373
+ return chips;
4374
+ });
4375
+ /** Own-property read of a chip's active mode. Field names may shadow
4376
+ * `Object.prototype` members (`toString`, `valueOf`, …) — a plain
4377
+ * `filters[key]` on such a key reads the inherited function, which
4378
+ * renders as an "active" chip that can never cycle (Codex review on
4379
+ * PR #2176). Every chip-state read goes through here. */
4380
+ function flagFilterMode(key) {
4381
+ const filters = flagFilters.value;
4382
+ return Object.hasOwn(filters, key) ? filters[key] : void 0;
4383
+ }
4384
+ /** A flag FIELD's computed boolean for one row (list cells + sort):
4385
+ * the enriched record's value, so a flag over derived/rollup inputs
4386
+ * reads correctly. */
4387
+ function flagValueOf(key, item) {
4388
+ return render.deriveRecord(item)[key] === true;
4389
+ }
4390
+ /** The chip's boolean for one row — `itemIsDone` for the synthesized
4391
+ * completion chip, the computed flag value otherwise. */
4392
+ function chipMatches(chip, item) {
4393
+ const schema = collection.value?.schema;
4394
+ if (!schema) return false;
4395
+ return chip.synthetic ? itemIsDone(schema, item) : flagValueOf(chip.key, item);
4396
+ }
4397
+ /** `filteredItems` further narrowed by every ACTIVE chip (AND). Consumed
4398
+ * only by the table (sortedItems / count summary / empty state). */
4399
+ const tableFilteredItems = computed(() => {
4400
+ const active = flagChips.value.filter((chip) => flagFilterMode(chip.key) !== void 0);
4401
+ if (active.length === 0) return filteredItems.value;
4402
+ return filteredItems.value.filter((item) => active.every((chip) => chipMatches(chip, item) === (flagFilterMode(chip.key) === "only")));
4403
+ });
4404
+ /** Cycle a chip all → hide → only → all. */
4405
+ function cycleFlagFilter(key) {
4406
+ const current = flagFilterMode(key);
4407
+ const next = current === void 0 ? "hide" : current === "hide" ? "only" : void 0;
4408
+ const rest = Object.fromEntries(Object.entries(flagFilters.value).filter(([entry]) => entry !== key));
4409
+ flagFilters.value = next ? {
4410
+ ...rest,
4411
+ [key]: next
4412
+ } : rest;
4413
+ }
4414
+ function flagChipIcon(key) {
4415
+ const mode = flagFilterMode(key);
4416
+ return mode === "hide" ? "visibility_off" : mode === "only" ? "filter_alt" : "visibility";
4417
+ }
4418
+ function flagChipClass(key) {
4419
+ 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
+ }
4424
+ function flagChipTitle(chip) {
4425
+ const mode = flagFilterMode(chip.key);
4426
+ if (mode === "hide") return t("collectionsView.flagFilterHide", { label: chip.label });
4427
+ if (mode === "only") return t("collectionsView.flagFilterOnly", { label: chip.label });
4428
+ return t("collectionsView.flagFilterAll", { label: chip.label });
4429
+ }
4256
4430
  function storedSortFor(slug) {
4257
4431
  return slug && readCollectionSort(slug) || null;
4258
4432
  }
@@ -4299,10 +4473,11 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
4299
4473
  default: return stringSortValue(raw);
4300
4474
  }
4301
4475
  }
4302
- /** Comparable value for one row under the active field. Toggle and derived
4303
- * need the whole record; every other type keys off the raw cell. */
4476
+ /** Comparable value for one row under the active field. Toggle, flag, and
4477
+ * derived need the whole record; every other type keys off the raw cell. */
4304
4478
  function sortValueOf(field, key, item) {
4305
4479
  if (field.type === "toggle") return boolSortValue(toggleChecked(item, field));
4480
+ if (field.type === "flag") return boolSortValue(flagValueOf(key, item));
4306
4481
  if (field.type === "derived") return derivedSortValue(field, key, item);
4307
4482
  return scalarSortValue(field, item[key]);
4308
4483
  }
@@ -4318,8 +4493,8 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
4318
4493
  const sortedItems = computed(() => {
4319
4494
  const state = sortState.value;
4320
4495
  const field = state ? collection.value?.schema.fields[state.field] : void 0;
4321
- if (!state || !field) return filteredItems.value;
4322
- return sortItems(filteredItems.value, state.direction, (item) => sortValueOf(field, state.field, item));
4496
+ if (!state || !field) return tableFilteredItems.value;
4497
+ return sortItems(tableFilteredItems.value, state.direction, (item) => sortValueOf(field, state.field, item));
4323
4498
  });
4324
4499
  /** Stringified primary-key value for a row (the row's stable identity). */
4325
4500
  function rowId(item) {
@@ -5265,6 +5440,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5265
5440
  kanbanOverride.value = null;
5266
5441
  addMenuOpen.value = false;
5267
5442
  sortState.value = storedSortFor(slug);
5443
+ flagFilters.value = storedFlagFiltersFor(slug);
5268
5444
  }
5269
5445
  if (slug) loadCollection(slug);
5270
5446
  else {
@@ -5319,6 +5495,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5319
5495
  calendarAnchorField,
5320
5496
  kanbanGroupField,
5321
5497
  sortState,
5498
+ flagFilters,
5322
5499
  loading
5323
5500
  ], () => {
5324
5501
  if (embedded.value) emit("viewStateChange", {
@@ -5329,6 +5506,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5329
5506
  if (activeSlug.value && !loading.value && collection.value) {
5330
5507
  if (!embedded.value) writeCollectionViewMode(activeSlug.value, activeView.value);
5331
5508
  writeCollectionSort(activeSlug.value, sortState.value);
5509
+ writeCollectionFlagFilters(activeSlug.value, flagFilters.value);
5332
5510
  }
5333
5511
  });
5334
5512
  watch(activeSelected, () => {
@@ -5437,8 +5615,25 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5437
5615
  onClick: _cache[2] || (_cache[2] = ($event) => searchQuery.value = "")
5438
5616
  }, [..._cache[34] || (_cache[34] = [createElementVNode("span", { class: "material-icons text-sm" }, "close", -1)])], 8, _hoisted_23$2)) : createCommentVNode("", true)
5439
5617
  ])) : createCommentVNode("", true), createElementVNode("div", _hoisted_24$1, [
5440
- !__props.hideViewToggle && (hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value) ? (openBlock(), createElementBlock("div", {
5618
+ activeView.value === "table" && flagChips.value.length > 0 && items.value.length > 0 ? (openBlock(), createElementBlock("div", {
5441
5619
  key: 0,
5620
+ class: "flex items-center gap-0.5",
5621
+ role: "group",
5622
+ "aria-label": unref(t)("collectionsView.flagFilterGroup")
5623
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(flagChips.value, (chip) => {
5624
+ return openBlock(), createElementBlock("button", {
5625
+ key: chip.key,
5626
+ 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)]),
5628
+ title: flagChipTitle(chip),
5629
+ "aria-label": flagChipTitle(chip),
5630
+ "aria-pressed": flagFilterMode(chip.key) !== void 0,
5631
+ "data-testid": `collections-flag-chip-${chip.key}`,
5632
+ 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),
5635
+ !__props.hideViewToggle && (hasCalendar.value || hasKanban.value || hasCustomViews.value || canAddCustomView.value) ? (openBlock(), createElementBlock("div", {
5636
+ key: 1,
5442
5637
  class: "flex gap-0.5",
5443
5638
  role: "group",
5444
5639
  "aria-label": unref(t)("collectionsView.viewToggle")
@@ -5449,7 +5644,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5449
5644
  "aria-pressed": activeView.value === "table",
5450
5645
  "data-testid": "collection-view-toggle-table",
5451
5646
  onClick: _cache[3] || (_cache[3] = ($event) => setView("table"))
5452
- }, [_cache[36] || (_cache[36] = createElementVNode("span", { class: "material-icons text-sm" }, "table_rows", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewTable")), 1)], 10, _hoisted_26$1),
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),
5453
5648
  hasCalendar.value ? (openBlock(), createElementBlock("button", {
5454
5649
  key: 0,
5455
5650
  type: "button",
@@ -5457,7 +5652,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5457
5652
  "aria-pressed": activeView.value === "calendar",
5458
5653
  "data-testid": "collection-view-toggle-calendar",
5459
5654
  onClick: _cache[4] || (_cache[4] = ($event) => setView("calendar"))
5460
- }, [_cache[37] || (_cache[37] = createElementVNode("span", { class: "material-icons text-sm" }, "calendar_month", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewCalendar")), 1)], 10, _hoisted_27$1)) : createCommentVNode("", true),
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),
5461
5656
  hasKanban.value ? (openBlock(), createElementBlock("button", {
5462
5657
  key: 1,
5463
5658
  type: "button",
@@ -5465,7 +5660,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5465
5660
  "aria-pressed": activeView.value === "kanban",
5466
5661
  "data-testid": "collection-view-toggle-kanban",
5467
5662
  onClick: _cache[5] || (_cache[5] = ($event) => setView("kanban"))
5468
- }, [_cache[38] || (_cache[38] = createElementVNode("span", { class: "material-icons text-sm" }, "view_kanban", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.viewKanban")), 1)], 10, _hoisted_28)) : createCommentVNode("", true),
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),
5469
5664
  (openBlock(true), createElementBlock(Fragment, null, renderList(customViews.value, (cv) => {
5470
5665
  return openBlock(), createElementBlock("button", {
5471
5666
  key: cv.id,
@@ -5474,7 +5669,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5474
5669
  "aria-pressed": activeView.value === unref(customViewKey)(cv.id),
5475
5670
  "data-testid": `collection-view-custom-${cv.id}`,
5476
5671
  onClick: ($event) => setCustomView(cv.id)
5477
- }, [createElementVNode("span", _hoisted_30, toDisplayString(cv.icon || (cv.target === "mobile" ? "smartphone" : "dashboard_customize")), 1), createElementVNode("span", null, toDisplayString(cv.label), 1)], 10, _hoisted_29);
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);
5478
5673
  }), 128)),
5479
5674
  canAddCustomView.value ? (openBlock(), createElementBlock("div", {
5480
5675
  key: 2,
@@ -5489,7 +5684,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5489
5684
  "aria-expanded": addMenuOpen.value,
5490
5685
  "data-testid": "collection-view-add",
5491
5686
  onClick: onAddViewClick
5492
- }, [..._cache[39] || (_cache[39] = [createElementVNode("span", { class: "material-icons text-sm" }, "add", -1)])], 8, _hoisted_31), addMenuOpen.value ? (openBlock(), createElementBlock("div", _hoisted_32, [createElementVNode("button", {
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", {
5493
5688
  type: "button",
5494
5689
  class: "w-full h-8 px-3 flex items-center gap-2 text-xs font-bold text-slate-600 hover:bg-slate-50",
5495
5690
  "data-testid": "collection-view-add-desktop",
@@ -5508,10 +5703,10 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5508
5703
  "aria-label": unref(t)("collectionsView.config.open"),
5509
5704
  "data-testid": "collection-config-open",
5510
5705
  onClick: _cache[8] || (_cache[8] = ($event) => configOpen.value = true)
5511
- }, [..._cache[42] || (_cache[42] = [createElementVNode("span", { class: "material-icons text-sm" }, "settings", -1)])], 8, _hoisted_33)) : createCommentVNode("", true)
5512
- ], 8, _hoisted_25$1)) : createCommentVNode("", true),
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),
5513
5708
  calendarActive.value && dateFields.value.length > 1 ? (openBlock(), createElementBlock("select", {
5514
- key: 1,
5709
+ key: 2,
5515
5710
  value: calendarAnchorField.value,
5516
5711
  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",
5517
5712
  "aria-label": unref(t)("collectionsView.calendarFieldLabel"),
@@ -5521,10 +5716,10 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5521
5716
  return openBlock(), createElementBlock("option", {
5522
5717
  key,
5523
5718
  value: key
5524
- }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_35);
5525
- }), 128))], 40, _hoisted_34)) : createCommentVNode("", true),
5719
+ }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_38);
5720
+ }), 128))], 40, _hoisted_37)) : createCommentVNode("", true),
5526
5721
  kanbanActive.value && enumFields.value.length > 1 ? (openBlock(), createElementBlock("select", {
5527
- key: 2,
5722
+ key: 3,
5528
5723
  value: kanbanGroupField.value,
5529
5724
  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",
5530
5725
  "aria-label": unref(t)("collectionsView.kanbanFieldLabel"),
@@ -5534,16 +5729,16 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5534
5729
  return openBlock(), createElementBlock("option", {
5535
5730
  key,
5536
5731
  value: key
5537
- }, toDisplayString(collection.value?.schema.fields[key]?.label ?? key), 9, _hoisted_37);
5538
- }), 128))], 40, _hoisted_36)) : createCommentVNode("", true),
5539
- items.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_38, toDisplayString(unref(t)("collectionsView.searchSummary", {
5540
- shown: filteredItems.value.length,
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", {
5735
+ shown: activeView.value === "table" ? tableFilteredItems.value.length : filteredItems.value.length,
5541
5736
  total: items.value.length
5542
5737
  })), 1)) : createCommentVNode("", true)
5543
5738
  ])])) : createCommentVNode("", true),
5544
- collection.value && dataIssues.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_39, [
5739
+ collection.value && dataIssues.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_42, [
5545
5740
  _cache[44] || (_cache[44] = createElementVNode("span", { class: "material-icons text-amber-600" }, "warning", -1)),
5546
- createElementVNode("span", _hoisted_40, toDisplayString(unref(t)("collectionsView.dataIssuesDetected", { count: dataIssues.value.length })), 1),
5741
+ createElementVNode("span", _hoisted_43, toDisplayString(unref(t)("collectionsView.dataIssuesDetected", { count: dataIssues.value.length })), 1),
5547
5742
  createElementVNode("button", {
5548
5743
  type: "button",
5549
5744
  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",
@@ -5551,7 +5746,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5551
5746
  onClick: repairCollection
5552
5747
  }, [_cache[43] || (_cache[43] = createElementVNode("span", { class: "material-icons text-sm" }, "build", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.repair")), 1)])
5553
5748
  ])) : createCommentVNode("", true),
5554
- createElementVNode("div", _hoisted_41, [loading.value ? (openBlock(), createElementBlock("div", _hoisted_42, [_cache[45] || (_cache[45] = createElementVNode("div", { class: "h-8 w-8 border-2 border-indigo-600/20 border-t-indigo-600 rounded-full animate-spin" }, null, -1)), createElementVNode("span", null, toDisplayString(unref(t)("common.loading")), 1)])) : loadError.value ? (openBlock(), createElementBlock("div", _hoisted_43, [_cache[46] || (_cache[46] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)), createElementVNode("span", null, toDisplayString(loadError.value === "not-found" ? unref(t)("collectionsView.notFound") : `${unref(t)("collectionsView.loadFailed")}: ${loadError.value}`), 1)])) : !collection.value ? (openBlock(), createElementBlock("div", _hoisted_44)) : calendarActive.value ? (openBlock(), createElementBlock("div", _hoisted_45, [createVNode(CollectionCalendarView_default, {
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, {
5555
5750
  schema: collection.value.schema,
5556
5751
  items: filteredItems.value,
5557
5752
  "anchor-field": calendarAnchorField.value,
@@ -5640,16 +5835,16 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5640
5835
  "selected",
5641
5836
  "can-create",
5642
5837
  "show-detail"
5643
- ])) : createCommentVNode("", true)])) : kanbanActive.value ? (openBlock(), createElementBlock("div", _hoisted_46, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_47, [
5838
+ ])) : createCommentVNode("", true)])) : kanbanActive.value ? (openBlock(), createElementBlock("div", _hoisted_49, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_50, [
5644
5839
  _cache[48] || (_cache[48] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
5645
- createElementVNode("span", _hoisted_48, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5840
+ createElementVNode("span", _hoisted_51, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5646
5841
  createElementVNode("button", {
5647
5842
  type: "button",
5648
5843
  class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
5649
5844
  "aria-label": unref(t)("common.close"),
5650
5845
  onClick: _cache[13] || (_cache[13] = ($event) => inlineError.value = null)
5651
- }, [..._cache[47] || (_cache[47] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_49)
5652
- ])) : createCommentVNode("", true), createElementVNode("div", _hoisted_50, [createVNode(CollectionKanbanView_default, {
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, {
5653
5848
  schema: collection.value.schema,
5654
5849
  items: filteredItems.value,
5655
5850
  "group-field": kanbanGroupField.value,
@@ -5665,7 +5860,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5665
5860
  "selected",
5666
5861
  "notified",
5667
5862
  "readonly"
5668
- ])])])) : activeCustomView.value ? (openBlock(), createElementBlock("div", _hoisted_51, [activeCustomView.value.target === "mobile" ? (openBlock(), createBlock(CollectionRemoteViewPreview_default, {
5863
+ ])])])) : activeCustomView.value ? (openBlock(), createElementBlock("div", _hoisted_54, [activeCustomView.value.target === "mobile" ? (openBlock(), createBlock(CollectionRemoteViewPreview_default, {
5669
5864
  key: 0,
5670
5865
  slug: collection.value.slug,
5671
5866
  view: activeCustomView.value,
@@ -5676,32 +5871,32 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5676
5871
  view: activeCustomView.value,
5677
5872
  onOpenItem: onCustomViewOpenItem,
5678
5873
  onStartChat: onCustomViewStartChat
5679
- }, null, 8, ["slug", "view"]))])) : items.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_52, [_cache[49] || (_cache[49] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "folder_open", -1)), createElementVNode("p", _hoisted_53, toDisplayString(unref(t)(isReadOnly.value ? "collectionsView.itemsEmptyReadonly" : "collectionsView.itemsEmpty")), 1)])) : filteredItems.value.length === 0 && editing.value?.mode !== "create" ? (openBlock(), createElementBlock("div", _hoisted_54, [
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, [
5680
5875
  _cache[50] || (_cache[50] = createElementVNode("span", { class: "material-icons text-4xl text-slate-300" }, "search_off", -1)),
5681
- createElementVNode("p", _hoisted_55, toDisplayString(unref(t)("collectionsView.noMatchingItems")), 1),
5876
+ createElementVNode("p", _hoisted_58, toDisplayString(unref(t)("collectionsView.noMatchingItems")), 1),
5682
5877
  createElementVNode("button", {
5683
5878
  type: "button",
5684
5879
  class: "text-xs text-indigo-600 font-semibold hover:underline",
5685
- onClick: _cache[14] || (_cache[14] = ($event) => searchQuery.value = "")
5880
+ onClick: _cache[14] || (_cache[14] = ($event) => (searchQuery.value = "", flagFilters.value = {}))
5686
5881
  }, toDisplayString(unref(t)("collectionsView.clearSearch")), 1)
5687
- ])) : (openBlock(), createElementBlock("div", _hoisted_56, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_57, [
5882
+ ])) : (openBlock(), createElementBlock("div", _hoisted_59, [inlineError.value ? (openBlock(), createElementBlock("div", _hoisted_60, [
5688
5883
  _cache[52] || (_cache[52] = createElementVNode("span", { class: "material-icons text-red-600" }, "error", -1)),
5689
- createElementVNode("span", _hoisted_58, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5884
+ createElementVNode("span", _hoisted_61, toDisplayString(unref(t)("collectionsView.inlineSaveFailed", { error: inlineError.value })), 1),
5690
5885
  createElementVNode("button", {
5691
5886
  type: "button",
5692
5887
  class: "h-8 w-8 flex items-center justify-center rounded text-red-600 hover:bg-red-100",
5693
5888
  "aria-label": unref(t)("common.close"),
5694
5889
  onClick: _cache[15] || (_cache[15] = ($event) => inlineError.value = null)
5695
- }, [..._cache[51] || (_cache[51] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_59)
5696
- ])) : createCommentVNode("", true), createElementVNode("table", _hoisted_60, [createElementVNode("thead", null, [createElementVNode("tr", _hoisted_61, [(openBlock(true), createElementBlock(Fragment, null, renderList(listColumnFields.value, ([key, field]) => {
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]) => {
5697
5892
  return openBlock(), createElementBlock("th", {
5698
5893
  key,
5699
5894
  "aria-sort": unref(isSortableField)(field) ? sortAriaValue(key) : void 0,
5700
5895
  class: "px-5 py-3 font-bold text-slate-500 text-left uppercase tracking-wider whitespace-nowrap"
5701
- }, [createElementVNode("div", _hoisted_63, [createElementVNode("span", {
5896
+ }, [createElementVNode("div", _hoisted_66, [createElementVNode("span", {
5702
5897
  class: "truncate max-w-[14rem]",
5703
5898
  title: field.label
5704
- }, toDisplayString(field.label), 9, _hoisted_64), unref(isSortableField)(field) ? (openBlock(), createElementBlock("button", {
5899
+ }, toDisplayString(field.label), 9, _hoisted_67), unref(isSortableField)(field) ? (openBlock(), createElementBlock("button", {
5705
5900
  key: 0,
5706
5901
  type: "button",
5707
5902
  class: normalizeClass(["inline-flex items-center justify-center rounded p-0.5 -my-1 leading-none transition-colors", sortButtonClass(key)]),
@@ -5710,8 +5905,8 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5710
5905
  onClick: withModifiers(($event) => cycleSort(key), ["stop"]),
5711
5906
  onPointerenter: ($event) => hoveredSortKey.value = key,
5712
5907
  onPointerleave: _cache[16] || (_cache[16] = ($event) => hoveredSortKey.value = null)
5713
- }, [createElementVNode("span", _hoisted_66, toDisplayString(sortIconName(key)), 1)], 42, _hoisted_65)) : createCommentVNode("", true)])], 8, _hoisted_62);
5714
- }), 128))])]), createElementVNode("tbody", _hoisted_67, [(openBlock(true), createElementBlock(Fragment, null, renderList(sortedItems.value, (item) => {
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) => {
5715
5910
  return openBlock(), createElementBlock("tr", {
5716
5911
  key: String(item[collection.value.schema.primaryKey] ?? ""),
5717
5912
  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" : ""]),
@@ -5735,7 +5930,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5735
5930
  "aria-label": field.label,
5736
5931
  onClick: _cache[17] || (_cache[17] = withModifiers(() => {}, ["stop"])),
5737
5932
  onChange: ($event) => commitToggle(item, field)
5738
- }, null, 40, _hoisted_69)) : field.type === "boolean" ? (openBlock(), createElementBlock("input", {
5933
+ }, null, 40, _hoisted_72)) : field.type === "boolean" ? (openBlock(), createElementBlock("input", {
5739
5934
  key: 1,
5740
5935
  type: "checkbox",
5741
5936
  checked: item[key] === true,
@@ -5745,7 +5940,13 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5745
5940
  "aria-label": field.label,
5746
5941
  onClick: _cache[18] || (_cache[18] = withModifiers(() => {}, ["stop"])),
5747
5942
  onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.checked)
5748
- }, null, 40, _hoisted_70)) : field.type === "ref" && field.to && typeof item[key] === "string" && item[key] ? (openBlock(), createElementBlock("span", _hoisted_71, [createElementVNode("a", {
5943
+ }, null, 40, _hoisted_73)) : field.type === "flag" ? (openBlock(), createElementBlock("span", {
5944
+ key: 2,
5945
+ class: normalizeClass(["material-icons text-lg align-middle", flagValueOf(String(key), item) ? "text-emerald-600" : "text-slate-300"]),
5946
+ "data-testid": `collections-flag-${key}-${item[collection.value.schema.primaryKey]}`,
5947
+ "aria-label": `${field.label}: ${unref(t)(flagValueOf(String(key), item) ? "common.yes" : "common.no")}`,
5948
+ 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", {
5749
5950
  href: unref(cui).recordHref?.(field.to, String(item[key])),
5750
5951
  tabindex: unref(cui).recordHref?.(field.to, String(item[key])) ? void 0 : 0,
5751
5952
  role: "link",
@@ -5753,8 +5954,8 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5753
5954
  "data-testid": `collections-ref-link-${key}-${item[key]}`,
5754
5955
  onClick: ($event) => unref(activateRefLink)($event, field.to, String(item[key]), true),
5755
5956
  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"])]
5756
- }, toDisplayString(unref(refDisplay)(field.to, String(item[key]))), 41, _hoisted_72)])) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? (openBlock(), createElementBlock("select", {
5757
- key: 3,
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", {
5958
+ key: 4,
5758
5959
  value: item[key] == null ? "" : String(item[key]),
5759
5960
  disabled: isReadOnly.value || isRowInlineSaving(item),
5760
5961
  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])]),
@@ -5762,39 +5963,39 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5762
5963
  "aria-label": field.label,
5763
5964
  onClick: _cache[19] || (_cache[19] = withModifiers(() => {}, ["stop"])),
5764
5965
  onChange: ($event) => commitInlineEdit(item, String(key), field, $event.target.value)
5765
- }, [showEnumPlaceholder(item, String(key)) ? (openBlock(), createElementBlock("option", _hoisted_74, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(field.values, (value) => {
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) => {
5766
5967
  return openBlock(), createElementBlock("option", {
5767
5968
  key: value,
5768
5969
  value
5769
- }, toDisplayString(value), 9, _hoisted_75);
5770
- }), 128))], 42, _hoisted_73)) : field.type === "money" ? (openBlock(), createElementBlock("span", _hoisted_76, toDisplayString(unref(formatMoney)(item[key], unref(resolveCurrency)(field, item), unref(locale))), 1)) : field.type === "table" ? (openBlock(), createElementBlock("span", _hoisted_77, [_cache[53] || (_cache[53] = createElementVNode("span", { class: "material-icons text-[11px]" }, "list", -1)), createElementVNode("span", null, toDisplayString(tableSummary(item[key])), 1)])) : field.type === "derived" ? (openBlock(), createElementBlock("span", _hoisted_78, toDisplayString(unref(derivedDisplay)(field, unref(evaluateDerivedAgainstItem)(field, String(key), item), item)), 1)) : field.type === "rollup" ? (openBlock(), createElementBlock("span", {
5771
- key: 7,
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", {
5972
+ key: 8,
5772
5973
  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",
5773
5974
  "data-testid": `collections-rollup-${key}-${item[collection.value.schema.primaryKey]}`
5774
- }, toDisplayString(unref(render).rollupDisplay(field, item)), 9, _hoisted_79)) : field.type !== "file" && unref(isExternalUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
5775
- key: 8,
5975
+ }, toDisplayString(unref(render).rollupDisplay(field, item)), 9, _hoisted_83)) : field.type !== "file" && unref(isExternalUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
5976
+ key: 9,
5776
5977
  href: String(item[key]),
5777
5978
  target: "_blank",
5778
5979
  rel: "noopener noreferrer",
5779
5980
  class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
5780
5981
  "data-testid": `collections-url-link-${key}-${item[collection.value.schema.primaryKey]}`,
5781
5982
  onClick: _cache[20] || (_cache[20] = withModifiers(() => {}, ["stop"]))
5782
- }, toDisplayString(String(item[key])), 9, _hoisted_80)) : field.type === "file" && unref(artifactUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
5783
- key: 9,
5983
+ }, toDisplayString(String(item[key])), 9, _hoisted_84)) : field.type === "file" && unref(artifactUrl)(item[key]) ? (openBlock(), createElementBlock("a", {
5984
+ key: 10,
5784
5985
  href: unref(artifactUrl)(item[key]) ?? void 0,
5785
5986
  target: "_blank",
5786
5987
  rel: "noopener noreferrer",
5787
5988
  class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
5788
5989
  "data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
5789
5990
  onClick: _cache[21] || (_cache[21] = withModifiers(() => {}, ["stop"]))
5790
- }, toDisplayString(String(item[key])), 9, _hoisted_81)) : field.type === "file" && unref(fileRoutePath)(item[key]) ? (openBlock(), createElementBlock("a", {
5791
- key: 10,
5991
+ }, toDisplayString(String(item[key])), 9, _hoisted_85)) : field.type === "file" && unref(fileRoutePath)(item[key]) ? (openBlock(), createElementBlock("a", {
5992
+ key: 11,
5792
5993
  href: unref(fileRoutePath)(item[key]) ?? void 0,
5793
5994
  class: "block truncate text-blue-600 hover:text-blue-800 hover:underline font-semibold",
5794
5995
  "data-testid": `collections-file-link-${key}-${item[collection.value.schema.primaryKey]}`,
5795
5996
  onClick: ($event) => unref(activatePathLink)($event, unref(fileRoutePath)(item[key]) ?? "", true)
5796
- }, toDisplayString(String(item[key])), 9, _hoisted_82)) : (openBlock(), createElementBlock("span", _hoisted_83, toDisplayString(unref(formatCell)(item[key], field.type)), 1))], 64)) : createCommentVNode("", true)]);
5797
- }), 128))], 42, _hoisted_68);
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);
5798
5999
  }), 128))])])]))]),
5799
6000
  collection.value && (viewing.value || editing.value) && !(calendarActive.value && openDay.value) ? (openBlock(), createBlock(CollectionRecordModal_default, {
5800
6001
  key: 4,
@@ -5878,19 +6079,19 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5878
6079
  "data-testid": "collections-chat-modal",
5879
6080
  onClick: withModifiers(closeChat, ["self"]),
5880
6081
  onKeydown: withKeys(closeChat, ["esc"])
5881
- }, [createElementVNode("div", _hoisted_84, [
5882
- createElementVNode("header", _hoisted_85, [
6082
+ }, [createElementVNode("div", _hoisted_88, [
6083
+ createElementVNode("header", _hoisted_89, [
5883
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)),
5884
- createElementVNode("div", _hoisted_86, [createElementVNode("h2", _hoisted_87, toDisplayString(unref(t)("collectionsView.chatTitle")), 1), createElementVNode("span", _hoisted_88, toDisplayString(collection.value.title), 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)]),
5885
6086
  createElementVNode("button", {
5886
6087
  type: "button",
5887
6088
  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",
5888
6089
  "aria-label": unref(t)("common.close"),
5889
6090
  "data-testid": "collections-chat-close",
5890
6091
  onClick: closeChat
5891
- }, [..._cache[54] || (_cache[54] = [createElementVNode("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_89)
6092
+ }, [..._cache[54] || (_cache[54] = [createElementVNode("span", { class: "material-icons text-lg" }, "close", -1)])], 8, _hoisted_93)
5892
6093
  ]),
5893
- createElementVNode("div", _hoisted_90, [withDirectives(createElementVNode("textarea", {
6094
+ createElementVNode("div", _hoisted_94, [withDirectives(createElementVNode("textarea", {
5894
6095
  ref_key: "chatInputEl",
5895
6096
  ref: chatInputEl,
5896
6097
  "onUpdate:modelValue": _cache[26] || (_cache[26] = ($event) => chatMessage.value = $event),
@@ -5899,8 +6100,8 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5899
6100
  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",
5900
6101
  "data-testid": "collections-chat-input",
5901
6102
  onKeydown: [withKeys(withModifiers(submitChat, ["meta"]), ["enter"]), withKeys(withModifiers(submitChat, ["ctrl"]), ["enter"])]
5902
- }, null, 40, _hoisted_91), [[vModelText, chatMessage.value]])]),
5903
- createElementVNode("footer", _hoisted_92, [createElementVNode("button", {
6103
+ }, null, 40, _hoisted_95), [[vModelText, chatMessage.value]])]),
6104
+ createElementVNode("footer", _hoisted_96, [createElementVNode("button", {
5904
6105
  type: "button",
5905
6106
  class: "h-8 px-2.5 rounded text-xs font-bold text-slate-500 hover:bg-slate-200/50 transition-colors",
5906
6107
  "data-testid": "collections-chat-cancel",
@@ -5911,7 +6112,7 @@ var CollectionView_default = /* @__PURE__ */ defineComponent({
5911
6112
  disabled: !chatMessage.value.trim(),
5912
6113
  "data-testid": "collections-chat-send",
5913
6114
  onClick: submitChat
5914
- }, toDisplayString(unref(t)("collectionsView.chatStart")), 9, _hoisted_93)])
6115
+ }, toDisplayString(unref(t)("collectionsView.chatStart")), 9, _hoisted_97)])
5915
6116
  ])], 32)) : createCommentVNode("", true)
5916
6117
  ]);
5917
6118
  };
@@ -6797,6 +6998,6 @@ var plugin = {
6797
6998
  previewComponent: Preview_default
6798
6999
  };
6799
7000
  //#endregion
6800
- export { CollectionCalendarView_default as CollectionCalendarView, CollectionCustomView_default as CollectionCustomView, CollectionDayView_default as CollectionDayView, CollectionEmbedView_default as CollectionEmbedView, CollectionKanbanView_default as CollectionKanbanView, CollectionRecordModal_default as CollectionRecordModal, CollectionRecordPanel_default as CollectionRecordPanel, CollectionView_default as CollectionView, CollectionViewConfigModal_default as CollectionViewConfigModal, CollectionsIndexView_default as CollectionsIndexView, FeedsView_default as FeedsView, Preview_default as PresentCollectionPreview, View_default as PresentCollectionView, applicableViewModes, collectionUi, configureCollectionUi, customViewKey, plugin, readCollectionSort, readCollectionViewMode, useCollectionRendering, writeCollectionSort, writeCollectionViewMode };
7001
+ export { CollectionCalendarView_default as CollectionCalendarView, CollectionCustomView_default as CollectionCustomView, CollectionDayView_default as CollectionDayView, CollectionEmbedView_default as CollectionEmbedView, CollectionKanbanView_default as CollectionKanbanView, CollectionRecordModal_default as CollectionRecordModal, CollectionRecordPanel_default as CollectionRecordPanel, CollectionView_default as CollectionView, CollectionViewConfigModal_default as CollectionViewConfigModal, CollectionsIndexView_default as CollectionsIndexView, FeedsView_default as FeedsView, Preview_default as PresentCollectionPreview, View_default as PresentCollectionView, applicableViewModes, collectionUi, configureCollectionUi, customViewKey, plugin, readCollectionFlagFilters, readCollectionSort, readCollectionViewMode, useCollectionRendering, writeCollectionFlagFilters, writeCollectionSort, writeCollectionViewMode };
6801
7002
 
6802
7003
  //# sourceMappingURL=vue.js.map