@osdk/react-components 0.52.0 → 0.53.0-main-ae47ac3b73090d642693a992208ebd424b4a627f

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.
Files changed (105) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/build/browser/filter-list/FilterListApi.js.map +1 -1
  3. package/build/browser/filter-list/hooks/useFilterListState.js.map +1 -1
  4. package/build/browser/filter-list/types/LinkedFilterTypes.js +5 -4
  5. package/build/browser/filter-list/types/LinkedFilterTypes.js.map +1 -1
  6. package/build/browser/filter-list/types/WhereClauseTypes.js +2 -0
  7. package/build/browser/filter-list/types/WhereClauseTypes.js.map +1 -0
  8. package/build/browser/filter-list/types/index.js +1 -0
  9. package/build/browser/filter-list/types/index.js.map +1 -1
  10. package/build/browser/filter-list/utils/emptyFilterDisplayState.js +0 -1
  11. package/build/browser/filter-list/utils/emptyFilterDisplayState.js.map +1 -1
  12. package/build/browser/filter-list/utils/filterStateToWhereClause.js +45 -36
  13. package/build/browser/filter-list/utils/filterStateToWhereClause.js.map +1 -1
  14. package/build/browser/filter-list/utils/filterValues.js +1 -3
  15. package/build/browser/filter-list/utils/filterValues.js.map +1 -1
  16. package/build/browser/filter-list/utils/narrowObjectSet.js +38 -7
  17. package/build/browser/filter-list/utils/narrowObjectSet.js.map +1 -1
  18. package/build/browser/filter-list/utils/summarizeFilterValue.js +4 -1
  19. package/build/browser/filter-list/utils/summarizeFilterValue.js.map +1 -1
  20. package/build/browser/util/UserAgent.js +1 -1
  21. package/build/browser/util/UserAgent.js.map +1 -1
  22. package/build/cjs/{chunk-FYBZCMUF.cjs → chunk-5GMBJX2D.cjs} +4 -4
  23. package/build/cjs/{chunk-FYBZCMUF.cjs.map → chunk-5GMBJX2D.cjs.map} +1 -1
  24. package/build/cjs/{chunk-UGESYKH3.cjs → chunk-5J5JUNRW.cjs} +4 -4
  25. package/build/cjs/{chunk-UGESYKH3.cjs.map → chunk-5J5JUNRW.cjs.map} +1 -1
  26. package/build/cjs/{chunk-YGKL7TID.cjs → chunk-AT63MZL2.cjs} +4 -4
  27. package/build/cjs/{chunk-YGKL7TID.cjs.map → chunk-AT63MZL2.cjs.map} +1 -1
  28. package/build/cjs/{chunk-NGTL7TQZ.cjs → chunk-DHWHCVWR.cjs} +4 -4
  29. package/build/cjs/{chunk-NGTL7TQZ.cjs.map → chunk-DHWHCVWR.cjs.map} +1 -1
  30. package/build/cjs/{chunk-7FHBQLBY.cjs → chunk-FZESVNGN.cjs} +4 -4
  31. package/build/cjs/{chunk-7FHBQLBY.cjs.map → chunk-FZESVNGN.cjs.map} +1 -1
  32. package/build/cjs/{chunk-BLNDVUWD.cjs → chunk-KCVCEHB3.cjs} +3 -3
  33. package/build/cjs/chunk-KCVCEHB3.cjs.map +1 -0
  34. package/build/cjs/chunk-LXD3MPVY.cjs +11 -0
  35. package/build/cjs/{chunk-XYDSPBNS.cjs.map → chunk-LXD3MPVY.cjs.map} +1 -1
  36. package/build/cjs/chunk-NLEHDTLD.cjs +11 -0
  37. package/build/cjs/{chunk-6LZPFOET.cjs.map → chunk-NLEHDTLD.cjs.map} +1 -1
  38. package/build/cjs/{chunk-LWZPCGVX.cjs → chunk-P4UOERQV.cjs} +73 -42
  39. package/build/cjs/chunk-P4UOERQV.cjs.map +1 -0
  40. package/build/cjs/chunk-Q7IZY7DA.cjs +11 -0
  41. package/build/cjs/{chunk-CXM2AX2T.cjs.map → chunk-Q7IZY7DA.cjs.map} +1 -1
  42. package/build/cjs/chunk-R2NZYFIX.cjs +11 -0
  43. package/build/cjs/{chunk-ORNJMIXS.cjs.map → chunk-R2NZYFIX.cjs.map} +1 -1
  44. package/build/cjs/{chunk-SO3Q3MUX.cjs → chunk-U26FOYLG.cjs} +4 -4
  45. package/build/cjs/{chunk-SO3Q3MUX.cjs.map → chunk-U26FOYLG.cjs.map} +1 -1
  46. package/build/cjs/{chunk-HCRY7VLS.cjs → chunk-WTT2HAXA.cjs} +4 -4
  47. package/build/cjs/{chunk-HCRY7VLS.cjs.map → chunk-WTT2HAXA.cjs.map} +1 -1
  48. package/build/cjs/{chunk-OYVU5FTS.cjs → chunk-Z3CP5PY4.cjs} +4 -4
  49. package/build/cjs/{chunk-OYVU5FTS.cjs.map → chunk-Z3CP5PY4.cjs.map} +1 -1
  50. package/build/cjs/public/experimental/action-form.cjs +4 -4
  51. package/build/cjs/public/experimental/cbac-picker.cjs +11 -11
  52. package/build/cjs/public/experimental/document-viewer.cjs +4 -4
  53. package/build/cjs/public/experimental/email-viewer.cjs +3 -3
  54. package/build/cjs/public/experimental/filter-list.cjs +15 -15
  55. package/build/cjs/public/experimental/filter-list.d.cts +23 -20
  56. package/build/cjs/public/experimental/image-viewer.cjs +3 -3
  57. package/build/cjs/public/experimental/markdown-renderer.cjs +5 -5
  58. package/build/cjs/public/experimental/object-table.cjs +22 -22
  59. package/build/cjs/public/experimental/pdf-viewer.cjs +7 -7
  60. package/build/cjs/public/experimental/spreadsheet-viewer.cjs +3 -3
  61. package/build/cjs/public/experimental/tiff-renderer.cjs +5 -5
  62. package/build/cjs/public/experimental/video-viewer.cjs +3 -3
  63. package/build/cjs/public/experimental/xml-viewer.cjs +3 -3
  64. package/build/cjs/public/experimental.cjs +76 -76
  65. package/build/esm/filter-list/FilterListApi.js.map +1 -1
  66. package/build/esm/filter-list/hooks/useFilterListState.js.map +1 -1
  67. package/build/esm/filter-list/types/LinkedFilterTypes.js +5 -4
  68. package/build/esm/filter-list/types/LinkedFilterTypes.js.map +1 -1
  69. package/build/esm/filter-list/types/WhereClauseTypes.js +2 -0
  70. package/build/esm/filter-list/types/WhereClauseTypes.js.map +1 -0
  71. package/build/esm/filter-list/types/index.js +1 -0
  72. package/build/esm/filter-list/types/index.js.map +1 -1
  73. package/build/esm/filter-list/utils/emptyFilterDisplayState.js +0 -1
  74. package/build/esm/filter-list/utils/emptyFilterDisplayState.js.map +1 -1
  75. package/build/esm/filter-list/utils/filterStateToWhereClause.js +45 -36
  76. package/build/esm/filter-list/utils/filterStateToWhereClause.js.map +1 -1
  77. package/build/esm/filter-list/utils/filterValues.js +1 -3
  78. package/build/esm/filter-list/utils/filterValues.js.map +1 -1
  79. package/build/esm/filter-list/utils/narrowObjectSet.js +38 -7
  80. package/build/esm/filter-list/utils/narrowObjectSet.js.map +1 -1
  81. package/build/esm/filter-list/utils/summarizeFilterValue.js +4 -1
  82. package/build/esm/filter-list/utils/summarizeFilterValue.js.map +1 -1
  83. package/build/esm/util/UserAgent.js +1 -1
  84. package/build/esm/util/UserAgent.js.map +1 -1
  85. package/build/types/filter-list/FilterListApi.d.ts +6 -7
  86. package/build/types/filter-list/FilterListApi.d.ts.map +1 -1
  87. package/build/types/filter-list/hooks/useFilterListState.d.ts +1 -1
  88. package/build/types/filter-list/types/LinkedFilterTypes.d.ts +16 -12
  89. package/build/types/filter-list/types/LinkedFilterTypes.d.ts.map +1 -1
  90. package/build/types/filter-list/types/WhereClauseTypes.d.ts +15 -0
  91. package/build/types/filter-list/types/WhereClauseTypes.d.ts.map +1 -0
  92. package/build/types/filter-list/types/index.d.ts +1 -0
  93. package/build/types/filter-list/types/index.d.ts.map +1 -1
  94. package/build/types/filter-list/utils/filterStateToWhereClause.d.ts +5 -4
  95. package/build/types/filter-list/utils/filterStateToWhereClause.d.ts.map +1 -1
  96. package/build/types/filter-list/utils/filterValues.d.ts.map +1 -1
  97. package/build/types/filter-list/utils/narrowObjectSet.d.ts.map +1 -1
  98. package/docs/FilterList.md +19 -18
  99. package/package.json +7 -7
  100. package/build/cjs/chunk-6LZPFOET.cjs +0 -11
  101. package/build/cjs/chunk-BLNDVUWD.cjs.map +0 -1
  102. package/build/cjs/chunk-CXM2AX2T.cjs +0 -11
  103. package/build/cjs/chunk-LWZPCGVX.cjs.map +0 -1
  104. package/build/cjs/chunk-ORNJMIXS.cjs +0 -11
  105. package/build/cjs/chunk-XYDSPBNS.cjs +0 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @osdk/react-components
2
2
 
3
+ ## 0.53.0-main-ae47ac3b73090d642693a992208ebd424b4a627f
4
+
5
+ ### Minor Changes
6
+
7
+ - ae47ac3: Fix FilterList's `HAS_LINK` filter, which previously sent an unsupported `$isNotNull` operator and was silently rejected by the server. `HAS_LINK` and `LINKED_PROPERTY` now filter by deriving a `$count` of matching linked objects and no longer use object-set `intersect`.
8
+
9
+ Fix `LINKED_PROPERTY` excluding: source rows with no linked object at all are now retained (previously dropped).
10
+
11
+ Consumer notes:
12
+ - `HAS_LINK` and `LINKED_PROPERTY` do not appear in `onFilterClauseChanged` (they cannot be expressed as a `WhereClause`). Wire `onEffectiveObjectSet` and pass the returned `ObjectSet` to the table to see them applied.
13
+ - `LINKED_PROPERTY` no longer requires `reverseLinkName` — the count-based narrowing does not need the reverse traversal.
14
+ - Removed bad documentation `$isNotNull` in `useOsdkObjects` snippets.
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies [4ae6d8b]
19
+ - Updated dependencies [1aff7f4]
20
+ - @osdk/api@2.58.1-main-ae47ac3b73090d642693a992208ebd424b4a627f
21
+ - @osdk/client@2.58.1-main-ae47ac3b73090d642693a992208ebd424b4a627f
22
+ - @osdk/react@2.58.1-main-ae47ac3b73090d642693a992208ebd424b4a627f
23
+
3
24
  ## 0.52.0
4
25
 
5
26
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"FilterListApi.js","names":[],"sources":["FilterListApi.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n LinkNames,\n ObjectSet,\n ObjectTypeDefinition,\n WhereClause,\n} from \"@osdk/api\";\nimport type React from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport type {\n FilterState,\n PropertyFilterDefinition,\n} from \"./FilterListItemApi.js\";\nimport type { CustomFilterDefinition } from \"./types/CustomRendererTypes.js\";\nimport type { KeywordSearchFilterDefinition } from \"./types/KeywordSearchTypes.js\";\nimport type {\n HasLinkFilterDefinition,\n LinkedPropertyFilterDefinition,\n} from \"./types/LinkedFilterTypes.js\";\nimport type { StaticValuesFilterDefinition } from \"./types/StaticValuesTypes.js\";\n\n/**\n * Distributes LinkedPropertyFilterDefinition over each link name individually,\n * so that LinkedQ/LinkedK/LinkedC defaults resolve correctly per link.\n */\ntype DistributeLinkedProperty<\n Q extends ObjectTypeDefinition,\n L extends LinkNames<Q>,\n> = L extends LinkNames<Q> ? LinkedPropertyFilterDefinition<Q, L> : never;\n\n/**\n * Union type of all filter definition types\n */\nexport type FilterDefinitionUnion<Q extends ObjectTypeDefinition> =\n | PropertyFilterDefinition<Q>\n | HasLinkFilterDefinition<Q>\n | DistributeLinkedProperty<Q, LinkNames<Q>>\n | KeywordSearchFilterDefinition<Q>\n | CustomFilterDefinition<Q>\n | StaticValuesFilterDefinition<Q>;\n\n/**\n * Extract the key from a filter definition union\n */\ntype ExtractFilterKey<D> = D extends { key: infer K }\n ? K\n : D extends { linkName: infer L }\n ? L\n : never;\n\nexport type FilterKey<Q extends ObjectTypeDefinition> = ExtractFilterKey<\n FilterDefinitionUnion<Q>\n>;\n\nexport interface FilterListProps<Q extends ObjectTypeDefinition> {\n /**\n * The object type definition for the objects being filtered.\n * Used for metadata resolution (property types, display names).\n */\n objectType: Q;\n\n /**\n * Optional object set to scope aggregation queries. When omitted,\n * aggregations run against the full object type.\n */\n objectSet?: ObjectSet<Q>;\n\n /**\n * Called whenever the filter clause changes. FilterList owns filter state;\n * this is how you read it out, e.g. to feed an `ObjectTable`'s `filter`.\n *\n * `LINKED_PROPERTY` filters are not represented in the clause — use\n * `onEffectiveObjectSet` for those.\n *\n * @param newClause The updated filter clause\n */\n onFilterClauseChanged?: (newClause: WhereClause<Q>) => void;\n\n /**\n * Optional title to display in the filter list header\n */\n title?: ReactNode;\n\n /**\n * Optional icon to display next to the title\n */\n titleIcon?: React.ReactNode;\n\n /**\n * The definition for all supported filter items in the list\n * If not supplied, all filterable properties will be available\n */\n filterDefinitions?: Array<FilterDefinitionUnion<Q>>;\n\n /**\n * Called when filter state changes\n *\n * @param definition The filter definition whose state changed\n * @param newState The updated filter state\n */\n onFilterStateChanged?: (\n definition: FilterDefinitionUnion<Q>,\n newState: FilterState,\n ) => void;\n\n /**\n * Called with the narrowed `ObjectSet` whenever filters change. Requires\n * `objectSet` to be set.\n *\n * A linked filter only narrows the set when its definition has\n * `reverseLinkName`. Linked filters without it are skipped here; read their\n * state from `onFilterStateChanged` instead.\n */\n onEffectiveObjectSet?: (objectSet: ObjectSet<Q>) => void;\n\n /**\n * When `true`, facets render greyed-out count=0 rows for values present in\n * the unfiltered data but excluded by other active filters.\n * @default false\n */\n showFilteredOutValues?: boolean;\n\n /**\n * Controls how filter visibility (add/remove) is managed.\n *\n * - `\"uncontrolled\"` (default): FilterList manages visibility internally.\n * An \"Add filter\" popover is rendered for filters with `isVisible: false`,\n * and each visible filter shows a remove button.\n * - `\"controlled\"`: The consumer manages which filters are visible via\n * `filterDefinitions`. Filters with `isVisible: false` are excluded from\n * the rendered list.\n *\n * @default \"uncontrolled\"\n * @deprecated Going away; visibility will always be managed internally.\n * Seed it with `isVisible` on each `filterDefinitions` entry and observe\n * changes with `onFilterVisibilityChange`.\n */\n addFilterMode?: \"controlled\" | \"uncontrolled\";\n\n /**\n * Called after a filter is shown from the built-in \"Add filter\" popover.\n *\n * @param filterKey The key of the added filter\n * @param newDefinitions Deprecated. The `filterDefinitions` you passed in,\n * unchanged — not the post-add state. Use `onFilterVisibilityChange`.\n */\n onFilterAdded?: (\n filterKey: FilterKey<Q>,\n /** @deprecated Use `onFilterVisibilityChange`. */\n /* eslint-disable-next-line @typescript-eslint/no-deprecated */\n newDefinitions: Array<FilterDefinitionUnion<Q>>,\n ) => void;\n\n /**\n * Called after a filter's remove button is clicked, once the filter is\n * hidden and its state cleared.\n *\n * @param filterKey The key of the removed filter\n */\n onFilterRemoved?: (filterKey: FilterKey<Q>) => void;\n\n /**\n * Called when filter visibility or ordering changes, i.e. when filters are\n * reordered, added or removed via the built-in show/remove controls, or\n * reset.\n *\n * Visible filters come first, in display order, followed by the hidden ones.\n * Persist this array and feed it back as the order and `isVisible` of\n * `filterDefinitions` to make reordering survive a remount.\n *\n * @param newStates The filters in current display order with their visibility state\n */\n onFilterVisibilityChange?: (\n newStates: Array<{\n filterKey: FilterKey<Q>;\n isVisible: boolean;\n }>,\n ) => void;\n\n /**\n * Enable drag-and-drop reordering of filters. When `true`, drag handles are\n * rendered and filters can be reordered.\n *\n * Reorder state is managed internally; persist `onFilterVisibilityChange` to\n * track order across remounts.\n *\n * @default false\n */\n enableSorting?: boolean;\n\n /**\n * Whether the collapse/expand control is available. When `false` the panel is\n * always expanded, no collapse control is rendered, and `collapsed` /\n * `defaultCollapsed` are ignored.\n * @default true\n */\n enableCollapse?: boolean;\n\n /**\n * Controlled mode. When supplied, this prop is the source of truth for\n * whether the panel is collapsed and the component keeps no internal state;\n * re-render with a new value in response to `onCollapsedChange`.\n *\n * If both `collapsed` and `defaultCollapsed` are provided, `collapsed` takes\n * precedence. Ignored when `enableCollapse` is `false`.\n */\n collapsed?: boolean;\n\n /**\n * Uncontrolled mode. Seeds the panel's internal collapsed state; the\n * component continues to own the state after mount, so later changes to this\n * prop are ignored.\n *\n * If both `collapsed` and `defaultCollapsed` are provided, `collapsed` takes\n * precedence. Ignored when `enableCollapse` is `false`.\n * @default false\n */\n defaultCollapsed?: boolean;\n\n /**\n * Called whenever the collapsed state changes.\n *\n * @param collapsed The new collapsed state\n */\n onCollapsedChange?: (collapsed: boolean) => void;\n\n /**\n * Seeds filter states from external storage, keyed by `getFilterKey`.\n * Applied over the per-definition `defaultFilterState` seeds on mount, and\n * FilterList owns the states from then on. Also the state the reset button\n * restores to.\n * Use `onFilterStateChanged` to persist changes back out.\n *\n * @default undefined (filters seed from their definitions alone)\n */\n defaultFilterStates?: Map<string, FilterState>;\n\n /**\n * @deprecated Rename to `defaultFilterStates`.\n */\n initialFilterStates?: Map<string, FilterState>;\n\n /**\n * Show reset filters button in header\n */\n showResetButton?: boolean;\n\n /**\n * Called when reset button is clicked\n */\n onReset?: () => void;\n\n /**\n * Show count of active filters in header\n */\n showActiveFilterCount?: boolean;\n\n /**\n * Additional CSS class name\n */\n className?: string;\n\n /**\n * Custom render function for the \"Add filter\" button. Customizes the trigger\n * element for the built-in add-filter popover; the popover behavior is\n * handled automatically.\n */\n renderAddFilterButton?: () => React.ReactNode;\n}\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"FilterListApi.js","names":[],"sources":["FilterListApi.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n LinkNames,\n ObjectSet,\n ObjectTypeDefinition,\n WhereClause,\n} from \"@osdk/api\";\nimport type React from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport type {\n FilterState,\n PropertyFilterDefinition,\n} from \"./FilterListItemApi.js\";\nimport type { CustomFilterDefinition } from \"./types/CustomRendererTypes.js\";\nimport type { KeywordSearchFilterDefinition } from \"./types/KeywordSearchTypes.js\";\nimport type {\n HasLinkFilterDefinition,\n LinkedPropertyFilterDefinition,\n} from \"./types/LinkedFilterTypes.js\";\nimport type { StaticValuesFilterDefinition } from \"./types/StaticValuesTypes.js\";\n\n/**\n * Distributes LinkedPropertyFilterDefinition over each link name individually,\n * so that LinkedQ/LinkedK/LinkedC defaults resolve correctly per link.\n */\ntype DistributeLinkedProperty<\n Q extends ObjectTypeDefinition,\n L extends LinkNames<Q>,\n> = L extends LinkNames<Q> ? LinkedPropertyFilterDefinition<Q, L> : never;\n\n/**\n * Union type of all filter definition types\n */\nexport type FilterDefinitionUnion<Q extends ObjectTypeDefinition> =\n | PropertyFilterDefinition<Q>\n | HasLinkFilterDefinition<Q>\n | DistributeLinkedProperty<Q, LinkNames<Q>>\n | KeywordSearchFilterDefinition<Q>\n | CustomFilterDefinition<Q>\n | StaticValuesFilterDefinition<Q>;\n\n/**\n * Extract the key from a filter definition union\n */\ntype ExtractFilterKey<D> = D extends { key: infer K }\n ? K\n : D extends { linkName: infer L }\n ? L\n : never;\n\nexport type FilterKey<Q extends ObjectTypeDefinition> = ExtractFilterKey<\n FilterDefinitionUnion<Q>\n>;\n\nexport interface FilterListProps<Q extends ObjectTypeDefinition> {\n /**\n * The object type definition for the objects being filtered.\n * Used for metadata resolution (property types, display names).\n */\n objectType: Q;\n\n /**\n * Optional object set to scope aggregation queries. When omitted,\n * aggregations run against the full object type.\n *\n * Required for `HAS_LINK` and `LINKED_PROPERTY` filters to work.\n */\n objectSet?: ObjectSet<Q>;\n\n /**\n * Called whenever the filter clause changes. FilterList owns filter state;\n * this is how you read it out, e.g. to feed an `ObjectTable`'s `filter`.\n *\n * `HAS_LINK` and `LINKED_PROPERTY` filters are not represented in the clause\n * — use `onEffectiveObjectSet` for those.\n *\n * @param newClause The updated filter clause\n */\n onFilterClauseChanged?: (newClause: WhereClause<Q>) => void;\n\n /**\n * Optional title to display in the filter list header\n */\n title?: ReactNode;\n\n /**\n * Optional icon to display next to the title\n */\n titleIcon?: React.ReactNode;\n\n /**\n * The definition for all supported filter items in the list\n * If not supplied, all filterable properties will be available\n */\n filterDefinitions?: Array<FilterDefinitionUnion<Q>>;\n\n /**\n * Called when filter state changes\n *\n * @param definition The filter definition whose state changed\n * @param newState The updated filter state\n */\n onFilterStateChanged?: (\n definition: FilterDefinitionUnion<Q>,\n newState: FilterState,\n ) => void;\n\n /**\n * Called with the narrowed `ObjectSet` whenever filters change. Requires\n * `objectSet` to be set. `HAS_LINK` and `LINKED_PROPERTY` filters narrow only\n * here, never through the filter clause.\n */\n onEffectiveObjectSet?: (objectSet: ObjectSet<Q>) => void;\n\n /**\n * When `true`, facets render greyed-out count=0 rows for values present in\n * the unfiltered data but excluded by other active filters.\n * @default false\n */\n showFilteredOutValues?: boolean;\n\n /**\n * Controls how filter visibility (add/remove) is managed.\n *\n * - `\"uncontrolled\"` (default): FilterList manages visibility internally.\n * An \"Add filter\" popover is rendered for filters with `isVisible: false`,\n * and each visible filter shows a remove button.\n * - `\"controlled\"`: The consumer manages which filters are visible via\n * `filterDefinitions`. Filters with `isVisible: false` are excluded from\n * the rendered list.\n *\n * @default \"uncontrolled\"\n * @deprecated Going away; visibility will always be managed internally.\n * Seed it with `isVisible` on each `filterDefinitions` entry and observe\n * changes with `onFilterVisibilityChange`.\n */\n addFilterMode?: \"controlled\" | \"uncontrolled\";\n\n /**\n * Called after a filter is shown from the built-in \"Add filter\" popover.\n *\n * @param filterKey The key of the added filter\n * @param newDefinitions Deprecated. The `filterDefinitions` you passed in,\n * unchanged — not the post-add state. Use `onFilterVisibilityChange`.\n */\n onFilterAdded?: (\n filterKey: FilterKey<Q>,\n /** @deprecated Use `onFilterVisibilityChange`. */\n /* eslint-disable-next-line @typescript-eslint/no-deprecated */\n newDefinitions: Array<FilterDefinitionUnion<Q>>,\n ) => void;\n\n /**\n * Called after a filter's remove button is clicked, once the filter is\n * hidden and its state cleared.\n *\n * @param filterKey The key of the removed filter\n */\n onFilterRemoved?: (filterKey: FilterKey<Q>) => void;\n\n /**\n * Called when filter visibility or ordering changes, i.e. when filters are\n * reordered, added or removed via the built-in show/remove controls, or\n * reset.\n *\n * Visible filters come first, in display order, followed by the hidden ones.\n * Persist this array and feed it back as the order and `isVisible` of\n * `filterDefinitions` to make reordering survive a remount.\n *\n * @param newStates The filters in current display order with their visibility state\n */\n onFilterVisibilityChange?: (\n newStates: Array<{\n filterKey: FilterKey<Q>;\n isVisible: boolean;\n }>,\n ) => void;\n\n /**\n * Enable drag-and-drop reordering of filters. When `true`, drag handles are\n * rendered and filters can be reordered.\n *\n * Reorder state is managed internally; persist `onFilterVisibilityChange` to\n * track order across remounts.\n *\n * @default false\n */\n enableSorting?: boolean;\n\n /**\n * Whether the collapse/expand control is available. When `false` the panel is\n * always expanded, no collapse control is rendered, and `collapsed` /\n * `defaultCollapsed` are ignored.\n * @default true\n */\n enableCollapse?: boolean;\n\n /**\n * Controlled mode. When supplied, this prop is the source of truth for\n * whether the panel is collapsed and the component keeps no internal state;\n * re-render with a new value in response to `onCollapsedChange`.\n *\n * If both `collapsed` and `defaultCollapsed` are provided, `collapsed` takes\n * precedence. Ignored when `enableCollapse` is `false`.\n */\n collapsed?: boolean;\n\n /**\n * Uncontrolled mode. Seeds the panel's internal collapsed state; the\n * component continues to own the state after mount, so later changes to this\n * prop are ignored.\n *\n * If both `collapsed` and `defaultCollapsed` are provided, `collapsed` takes\n * precedence. Ignored when `enableCollapse` is `false`.\n * @default false\n */\n defaultCollapsed?: boolean;\n\n /**\n * Called whenever the collapsed state changes.\n *\n * @param collapsed The new collapsed state\n */\n onCollapsedChange?: (collapsed: boolean) => void;\n\n /**\n * Seeds filter states from external storage, keyed by `getFilterKey`.\n * Applied over the per-definition `defaultFilterState` seeds on mount, and\n * FilterList owns the states from then on. Also the state the reset button\n * restores to.\n * Use `onFilterStateChanged` to persist changes back out.\n *\n * @default undefined (filters seed from their definitions alone)\n */\n defaultFilterStates?: Map<string, FilterState>;\n\n /**\n * @deprecated Rename to `defaultFilterStates`.\n */\n initialFilterStates?: Map<string, FilterState>;\n\n /**\n * Show reset filters button in header\n */\n showResetButton?: boolean;\n\n /**\n * Called when reset button is clicked\n */\n onReset?: () => void;\n\n /**\n * Show count of active filters in header\n */\n showActiveFilterCount?: boolean;\n\n /**\n * Additional CSS class name\n */\n className?: string;\n\n /**\n * Custom render function for the \"Add filter\" button. Customizes the trigger\n * element for the built-in add-filter popover; the popover behavior is\n * handled automatically.\n */\n renderAddFilterButton?: () => React.ReactNode;\n}\n"],"mappings":"","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"useFilterListState.js","names":["useOsdkMetadata","isEqual","useCallback","useEffect","useMemo","useRef","useState","buildWhereClause","getActiveLinkedFilters","filterHasActiveState","getFilterKey","getSeedFilterState","narrowObjectSet","useStableMapEntries","buildInitialStates","definitions","states","Map","definition","state","set","useFilterListState","props","objectType","objectSet","filterDefinitions","onFilterStateChanged","onFilterClauseChanged","onEffectiveObjectSet","defaultFilterStates","initialFilterStates","seededFilterStates","metadata","onFilterClauseChangedRef","current","onEffectiveObjectSetRef","filterDefinitionsRef","propertyTypes","map","properties","key","prop","Object","entries","type","multiplicity","initialFilterStatesSnapshot","snapshot","filterStates","setFilterStates","setFilterState","filterKey","prev","next","find","d","clearFilterState","delete","reset","whereClause","linkedFilters","effectiveObjectSet","undefined","perFilterWhereClauses","perFilterLinkedFilters","activeFilterCount","count","get","clause","toWhereClause","keys","length","hasChangesFromInitial"],"sources":["useFilterListState.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ObjectSet, ObjectTypeDefinition, WhereClause } from \"@osdk/api\";\nimport { useOsdkMetadata } from \"@osdk/react\";\nimport { isEqual } from \"lodash-es\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport type { FilterListProps } from \"../FilterListApi.js\";\nimport type { FilterState } from \"../FilterListItemApi.js\";\nimport type { LinkedFilter } from \"../types/LinkedFilterTypes.js\";\nimport {\n buildWhereClause,\n getActiveLinkedFilters,\n type PropertyTypeInfo,\n} from \"../utils/filterStateToWhereClause.js\";\nimport { filterHasActiveState } from \"../utils/filterValues.js\";\nimport { getFilterKey } from \"../utils/getFilterKey.js\";\nimport { getSeedFilterState } from \"../utils/getSeedFilterState.js\";\nimport { narrowObjectSet } from \"../utils/narrowObjectSet.js\";\nimport { useStableMapEntries } from \"./useStableMapEntries.js\";\n\nexport interface UseFilterListStateResult<Q extends ObjectTypeDefinition> {\n filterStates: Map<string, FilterState>;\n setFilterState: (filterKey: string, state: FilterState) => void;\n clearFilterState: (filterKey: string) => void;\n /** Direct (non-link-traversing) filters combined into a `WhereClause<Q>`. */\n whereClause: WhereClause<Q>;\n /** Active linked-property records; apply via `narrowObjectSet`. */\n linkedFilters: ReadonlyArray<LinkedFilter<Q>>;\n /** Per-filter excluding-self where clauses keyed by `getFilterKey`. */\n perFilterWhereClauses: Map<string, WhereClause<Q>>;\n /** Per-filter excluding-self linked filters keyed by `getFilterKey`. */\n perFilterLinkedFilters: Map<string, ReadonlyArray<LinkedFilter<Q>>>;\n activeFilterCount: number;\n hasChangesFromInitial: boolean;\n reset: () => void;\n}\n\nfunction buildInitialStates<Q extends ObjectTypeDefinition>(\n definitions: FilterListProps<Q>[\"filterDefinitions\"],\n): Map<string, FilterState> {\n const states = new Map<string, FilterState>();\n\n if (!definitions) {\n return states;\n }\n\n for (const definition of definitions) {\n const state = getSeedFilterState(definition);\n if (state) {\n states.set(getFilterKey(definition), state);\n }\n }\n\n return states;\n}\n\nexport function useFilterListState<Q extends ObjectTypeDefinition>(\n props: FilterListProps<Q>,\n): UseFilterListStateResult<Q> {\n const {\n objectType,\n objectSet,\n filterDefinitions,\n onFilterStateChanged,\n onFilterClauseChanged,\n onEffectiveObjectSet,\n defaultFilterStates,\n // eslint-disable-next-line @typescript-eslint/no-deprecated -- back-compat fallback for the pre-rename prop\n initialFilterStates,\n } = props;\n const seededFilterStates = defaultFilterStates ?? initialFilterStates;\n const { metadata } = useOsdkMetadata(objectType);\n const onFilterClauseChangedRef = useRef(onFilterClauseChanged);\n onFilterClauseChangedRef.current = onFilterClauseChanged;\n const onEffectiveObjectSetRef = useRef(onEffectiveObjectSet);\n onEffectiveObjectSetRef.current = onEffectiveObjectSet;\n const filterDefinitionsRef = useRef(filterDefinitions);\n filterDefinitionsRef.current = filterDefinitions;\n\n const propertyTypes = useMemo(() => {\n const map = new Map<string, PropertyTypeInfo>();\n if (metadata?.properties) {\n for (const [key, prop] of Object.entries(metadata.properties)) {\n if (typeof prop.type === \"string\") {\n map.set(key, {\n type: prop.type,\n multiplicity: prop.multiplicity === true,\n });\n }\n }\n }\n return map;\n }, [metadata?.properties]);\n\n // Captured once on first render to provide a stable baseline for the reset\n // button's enabled state. `useState`'s lazy initializer pins the value for\n // the lifetime of the component (unlike `useMemo`, which React may discard).\n const [initialFilterStatesSnapshot] = useState<Map<string, FilterState>>(\n () => {\n const snapshot = buildInitialStates(filterDefinitions);\n if (seededFilterStates) {\n for (const [key, state] of seededFilterStates) {\n snapshot.set(key, state);\n }\n }\n return snapshot;\n },\n );\n\n const [filterStates, setFilterStates] = useState<Map<string, FilterState>>(\n () => new Map(initialFilterStatesSnapshot),\n );\n\n const setFilterState = useCallback(\n (filterKey: string, state: FilterState) => {\n setFilterStates((prev) => {\n const next = new Map(prev);\n next.set(filterKey, state);\n return next;\n });\n\n const definition = filterDefinitionsRef.current?.find(\n (d) => getFilterKey(d) === filterKey,\n );\n if (definition) {\n onFilterStateChanged?.(definition, state);\n }\n },\n [onFilterStateChanged],\n );\n\n const clearFilterState = useCallback((filterKey: string) => {\n setFilterStates((prev) => {\n const next = new Map(prev);\n next.delete(filterKey);\n return next;\n });\n }, []);\n\n const reset = useCallback(() => {\n setFilterStates(new Map(initialFilterStatesSnapshot));\n }, [initialFilterStatesSnapshot]);\n\n const whereClause = useMemo(\n () => buildWhereClause(filterDefinitions, filterStates, propertyTypes),\n [filterDefinitions, filterStates, propertyTypes],\n );\n\n const linkedFilters = useMemo(\n () => getActiveLinkedFilters(filterDefinitions, filterStates),\n [filterDefinitions, filterStates],\n );\n\n const effectiveObjectSet = useMemo<ObjectSet<Q> | undefined>(\n () =>\n objectSet == null\n ? undefined\n : narrowObjectSet(objectSet, whereClause, linkedFilters),\n [objectSet, whereClause, linkedFilters],\n );\n\n useEffect(() => {\n onFilterClauseChangedRef.current?.(whereClause);\n }, [whereClause]);\n\n useEffect(() => {\n if (effectiveObjectSet == null) {\n return;\n }\n onEffectiveObjectSetRef.current?.(effectiveObjectSet);\n }, [effectiveObjectSet]);\n\n const perFilterWhereClauses = useStableMapEntries(\n useMemo(() => {\n const map = new Map<string, WhereClause<Q>>();\n for (const definition of filterDefinitions ?? []) {\n const key = getFilterKey(definition);\n map.set(\n key,\n buildWhereClause(filterDefinitions, filterStates, propertyTypes, key),\n );\n }\n return map;\n }, [filterDefinitions, filterStates, propertyTypes]),\n );\n\n const perFilterLinkedFilters = useStableMapEntries(\n useMemo(() => {\n const map = new Map<string, ReadonlyArray<LinkedFilter<Q>>>();\n for (const definition of filterDefinitions ?? []) {\n const key = getFilterKey(definition);\n map.set(\n key,\n getActiveLinkedFilters(filterDefinitions, filterStates, key),\n );\n }\n return map;\n }, [filterDefinitions, filterStates]),\n );\n\n const activeFilterCount = useMemo(() => {\n let count = 0;\n for (const definition of filterDefinitions ?? []) {\n const state = filterStates.get(getFilterKey(definition));\n if (state == null) {\n continue;\n }\n // A custom filter's state is opaque, so `filterHasActiveState` can only\n // say \"some state exists\". Only its own `toWhereClause` knows whether\n // that state filters anything, so match what `buildWhereClause` keeps.\n if (definition.type === \"CUSTOM\") {\n if (state.type === \"custom\") {\n const clause = definition.toWhereClause(state);\n if (clause != null && Object.keys(clause).length > 0) {\n count++;\n }\n }\n continue;\n }\n if (filterHasActiveState(state)) {\n count++;\n }\n }\n return count;\n }, [filterDefinitions, filterStates]);\n\n const hasChangesFromInitial = useMemo(\n () => !isEqual(filterStates, initialFilterStatesSnapshot),\n [filterStates, initialFilterStatesSnapshot],\n );\n\n return useMemo(\n () => ({\n filterStates,\n setFilterState,\n clearFilterState,\n whereClause,\n linkedFilters,\n perFilterWhereClauses,\n perFilterLinkedFilters,\n activeFilterCount,\n hasChangesFromInitial,\n reset,\n }),\n [\n filterStates,\n setFilterState,\n clearFilterState,\n whereClause,\n linkedFilters,\n perFilterWhereClauses,\n perFilterLinkedFilters,\n activeFilterCount,\n hasChangesFromInitial,\n reset,\n ],\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"useFilterListState.js","names":["useOsdkMetadata","isEqual","useCallback","useEffect","useMemo","useRef","useState","buildWhereClause","getActiveLinkedFilters","filterHasActiveState","getFilterKey","getSeedFilterState","narrowObjectSet","useStableMapEntries","buildInitialStates","definitions","states","Map","definition","state","set","useFilterListState","props","objectType","objectSet","filterDefinitions","onFilterStateChanged","onFilterClauseChanged","onEffectiveObjectSet","defaultFilterStates","initialFilterStates","seededFilterStates","metadata","onFilterClauseChangedRef","current","onEffectiveObjectSetRef","filterDefinitionsRef","propertyTypes","map","properties","key","prop","Object","entries","type","multiplicity","initialFilterStatesSnapshot","snapshot","filterStates","setFilterStates","setFilterState","filterKey","prev","next","find","d","clearFilterState","delete","reset","whereClause","linkedFilters","effectiveObjectSet","undefined","perFilterWhereClauses","perFilterLinkedFilters","activeFilterCount","count","get","clause","toWhereClause","keys","length","hasChangesFromInitial"],"sources":["useFilterListState.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ObjectSet, ObjectTypeDefinition, WhereClause } from \"@osdk/api\";\nimport { useOsdkMetadata } from \"@osdk/react\";\nimport { isEqual } from \"lodash-es\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport type { FilterListProps } from \"../FilterListApi.js\";\nimport type { FilterState } from \"../FilterListItemApi.js\";\nimport type { LinkedFilter } from \"../types/LinkedFilterTypes.js\";\nimport {\n buildWhereClause,\n getActiveLinkedFilters,\n type PropertyTypeInfo,\n} from \"../utils/filterStateToWhereClause.js\";\nimport { filterHasActiveState } from \"../utils/filterValues.js\";\nimport { getFilterKey } from \"../utils/getFilterKey.js\";\nimport { getSeedFilterState } from \"../utils/getSeedFilterState.js\";\nimport { narrowObjectSet } from \"../utils/narrowObjectSet.js\";\nimport { useStableMapEntries } from \"./useStableMapEntries.js\";\n\nexport interface UseFilterListStateResult<Q extends ObjectTypeDefinition> {\n filterStates: Map<string, FilterState>;\n setFilterState: (filterKey: string, state: FilterState) => void;\n clearFilterState: (filterKey: string) => void;\n /** Direct (non-link-traversing) filters combined into a `WhereClause<Q>`. */\n whereClause: WhereClause<Q>;\n /** Active HAS_LINK and LINKED_PROPERTY records */\n linkedFilters: ReadonlyArray<LinkedFilter<Q>>;\n /** Per-filter excluding-self where clauses keyed by `getFilterKey`. */\n perFilterWhereClauses: Map<string, WhereClause<Q>>;\n /** Per-filter excluding-self linked filters keyed by `getFilterKey`. */\n perFilterLinkedFilters: Map<string, ReadonlyArray<LinkedFilter<Q>>>;\n activeFilterCount: number;\n hasChangesFromInitial: boolean;\n reset: () => void;\n}\n\nfunction buildInitialStates<Q extends ObjectTypeDefinition>(\n definitions: FilterListProps<Q>[\"filterDefinitions\"],\n): Map<string, FilterState> {\n const states = new Map<string, FilterState>();\n\n if (!definitions) {\n return states;\n }\n\n for (const definition of definitions) {\n const state = getSeedFilterState(definition);\n if (state) {\n states.set(getFilterKey(definition), state);\n }\n }\n\n return states;\n}\n\nexport function useFilterListState<Q extends ObjectTypeDefinition>(\n props: FilterListProps<Q>,\n): UseFilterListStateResult<Q> {\n const {\n objectType,\n objectSet,\n filterDefinitions,\n onFilterStateChanged,\n onFilterClauseChanged,\n onEffectiveObjectSet,\n defaultFilterStates,\n // eslint-disable-next-line @typescript-eslint/no-deprecated -- back-compat fallback for the pre-rename prop\n initialFilterStates,\n } = props;\n const seededFilterStates = defaultFilterStates ?? initialFilterStates;\n const { metadata } = useOsdkMetadata(objectType);\n const onFilterClauseChangedRef = useRef(onFilterClauseChanged);\n onFilterClauseChangedRef.current = onFilterClauseChanged;\n const onEffectiveObjectSetRef = useRef(onEffectiveObjectSet);\n onEffectiveObjectSetRef.current = onEffectiveObjectSet;\n const filterDefinitionsRef = useRef(filterDefinitions);\n filterDefinitionsRef.current = filterDefinitions;\n\n const propertyTypes = useMemo(() => {\n const map = new Map<string, PropertyTypeInfo>();\n if (metadata?.properties) {\n for (const [key, prop] of Object.entries(metadata.properties)) {\n if (typeof prop.type === \"string\") {\n map.set(key, {\n type: prop.type,\n multiplicity: prop.multiplicity === true,\n });\n }\n }\n }\n return map;\n }, [metadata?.properties]);\n\n // Captured once on first render to provide a stable baseline for the reset\n // button's enabled state. `useState`'s lazy initializer pins the value for\n // the lifetime of the component (unlike `useMemo`, which React may discard).\n const [initialFilterStatesSnapshot] = useState<Map<string, FilterState>>(\n () => {\n const snapshot = buildInitialStates(filterDefinitions);\n if (seededFilterStates) {\n for (const [key, state] of seededFilterStates) {\n snapshot.set(key, state);\n }\n }\n return snapshot;\n },\n );\n\n const [filterStates, setFilterStates] = useState<Map<string, FilterState>>(\n () => new Map(initialFilterStatesSnapshot),\n );\n\n const setFilterState = useCallback(\n (filterKey: string, state: FilterState) => {\n setFilterStates((prev) => {\n const next = new Map(prev);\n next.set(filterKey, state);\n return next;\n });\n\n const definition = filterDefinitionsRef.current?.find(\n (d) => getFilterKey(d) === filterKey,\n );\n if (definition) {\n onFilterStateChanged?.(definition, state);\n }\n },\n [onFilterStateChanged],\n );\n\n const clearFilterState = useCallback((filterKey: string) => {\n setFilterStates((prev) => {\n const next = new Map(prev);\n next.delete(filterKey);\n return next;\n });\n }, []);\n\n const reset = useCallback(() => {\n setFilterStates(new Map(initialFilterStatesSnapshot));\n }, [initialFilterStatesSnapshot]);\n\n const whereClause = useMemo(\n () => buildWhereClause(filterDefinitions, filterStates, propertyTypes),\n [filterDefinitions, filterStates, propertyTypes],\n );\n\n const linkedFilters = useMemo(\n () => getActiveLinkedFilters(filterDefinitions, filterStates),\n [filterDefinitions, filterStates],\n );\n\n const effectiveObjectSet = useMemo<ObjectSet<Q> | undefined>(\n () =>\n objectSet == null\n ? undefined\n : narrowObjectSet(objectSet, whereClause, linkedFilters),\n [objectSet, whereClause, linkedFilters],\n );\n\n useEffect(() => {\n onFilterClauseChangedRef.current?.(whereClause);\n }, [whereClause]);\n\n useEffect(() => {\n if (effectiveObjectSet == null) {\n return;\n }\n onEffectiveObjectSetRef.current?.(effectiveObjectSet);\n }, [effectiveObjectSet]);\n\n const perFilterWhereClauses = useStableMapEntries(\n useMemo(() => {\n const map = new Map<string, WhereClause<Q>>();\n for (const definition of filterDefinitions ?? []) {\n const key = getFilterKey(definition);\n map.set(\n key,\n buildWhereClause(filterDefinitions, filterStates, propertyTypes, key),\n );\n }\n return map;\n }, [filterDefinitions, filterStates, propertyTypes]),\n );\n\n const perFilterLinkedFilters = useStableMapEntries(\n useMemo(() => {\n const map = new Map<string, ReadonlyArray<LinkedFilter<Q>>>();\n for (const definition of filterDefinitions ?? []) {\n const key = getFilterKey(definition);\n map.set(\n key,\n getActiveLinkedFilters(filterDefinitions, filterStates, key),\n );\n }\n return map;\n }, [filterDefinitions, filterStates]),\n );\n\n const activeFilterCount = useMemo(() => {\n let count = 0;\n for (const definition of filterDefinitions ?? []) {\n const state = filterStates.get(getFilterKey(definition));\n if (state == null) {\n continue;\n }\n // A custom filter's state is opaque, so `filterHasActiveState` can only\n // say \"some state exists\". Only its own `toWhereClause` knows whether\n // that state filters anything, so match what `buildWhereClause` keeps.\n if (definition.type === \"CUSTOM\") {\n if (state.type === \"custom\") {\n const clause = definition.toWhereClause(state);\n if (clause != null && Object.keys(clause).length > 0) {\n count++;\n }\n }\n continue;\n }\n if (filterHasActiveState(state)) {\n count++;\n }\n }\n return count;\n }, [filterDefinitions, filterStates]);\n\n const hasChangesFromInitial = useMemo(\n () => !isEqual(filterStates, initialFilterStatesSnapshot),\n [filterStates, initialFilterStatesSnapshot],\n );\n\n return useMemo(\n () => ({\n filterStates,\n setFilterState,\n clearFilterState,\n whereClause,\n linkedFilters,\n perFilterWhereClauses,\n perFilterLinkedFilters,\n activeFilterCount,\n hasChangesFromInitial,\n reset,\n }),\n [\n filterStates,\n setFilterState,\n clearFilterState,\n whereClause,\n linkedFilters,\n perFilterWhereClauses,\n perFilterLinkedFilters,\n activeFilterCount,\n hasChangesFromInitial,\n reset,\n ],\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -15,9 +15,7 @@
15
15
  */
16
16
 
17
17
  /**
18
- * Runtime representation of an active linked-property filter. Each entry
19
- * binds a `linkName` to its `reverseLinkName` and an `innerWhere` typed
20
- * against the linked object type, so `narrowObjectSet` can pivot type-safely.
18
+ * Runtime representation of an active link-traversing filter
21
19
  */
22
20
 
23
21
  /** Shared empty default for `LinkedFilter` arrays — avoids new-array-per-render. */
@@ -34,7 +32,10 @@ export const EMPTY_LINKED_FILTERS = [];
34
32
 
35
33
  /**
36
34
  * Filter definition for "Has Link" filter
37
- * Filters objects based on whether they have any linked objects of the specified type
35
+ * Filters objects based on whether they have any linked objects of the specified
36
+ * type. Narrows `objectSet` and is emitted via `onEffectiveObjectSet`; link
37
+ * presence has no filter-clause form, so it never appears in
38
+ * `onFilterClauseChanged`.
38
39
  */
39
40
 
40
41
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"LinkedFilterTypes.js","names":["EMPTY_LINKED_FILTERS"],"sources":["LinkedFilterTypes.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n LinkedType,\n LinkNames,\n ObjectTypeDefinition,\n PropertyKeys,\n WhereClause,\n} from \"@osdk/api\";\nimport type { ReactNode } from \"react\";\n\nimport type {\n BaseFilterState,\n FilterDefinitionControls,\n FilterState,\n FilterStateByComponentType,\n PropertyTypeFromKey,\n ValidComponentsForPropertyType,\n} from \"../FilterListItemApi.js\";\n\n/**\n * Runtime representation of an active linked-property filter. Each entry\n * binds a `linkName` to its `reverseLinkName` and an `innerWhere` typed\n * against the linked object type, so `narrowObjectSet` can pivot type-safely.\n */\nexport type LinkedFilter<Q extends ObjectTypeDefinition> = {\n [L in LinkNames<Q>]: {\n linkName: L;\n reverseLinkName: LinkNames<LinkedType<Q, L>>;\n innerWhere: WhereClause<LinkedType<Q, L>>;\n };\n}[LinkNames<Q>];\n\n/** Shared empty default for `LinkedFilter` arrays — avoids new-array-per-render. */\nexport const EMPTY_LINKED_FILTERS: readonly never[] = [];\n\n/**\n * State for \"has link\" filter\n */\nexport interface HasLinkFilterState extends BaseFilterState {\n type: \"hasLink\";\n hasLink: boolean;\n}\n\n/**\n * State for linked property filter\n * Wraps the filter state of the linked property\n */\nexport interface LinkedPropertyFilterState<\n S extends FilterState = FilterState,\n> extends BaseFilterState {\n type: \"linkedProperty\";\n linkedFilterState: S;\n}\n\n/**\n * Filter definition for \"Has Link\" filter\n * Filters objects based on whether they have any linked objects of the specified type\n */\nexport interface HasLinkFilterDefinition<\n Q extends ObjectTypeDefinition,\n L extends LinkNames<Q> = LinkNames<Q>,\n> extends FilterDefinitionControls {\n type: \"HAS_LINK\";\n linkName: L;\n label?: string;\n\n /**\n * Seeds the filter's state on mount, FilterList owns the state from then on\n *\n * @default undefined (filter starts empty)\n */\n defaultFilterState?: HasLinkFilterState;\n\n /**\n * @deprecated Has no effect, remove it.\n */\n filterState?: HasLinkFilterState;\n}\n\n/**\n * Filter definition for filtering on a property of linked objects\n */\nexport interface LinkedPropertyFilterDefinition<\n Q extends ObjectTypeDefinition,\n L extends LinkNames<Q>,\n LinkedQ extends ObjectTypeDefinition = LinkedType<Q, L>,\n LinkedK extends PropertyKeys<LinkedQ> = PropertyKeys<LinkedQ>,\n LinkedC extends ValidComponentsForPropertyType<\n PropertyTypeFromKey<LinkedQ, LinkedK>\n > = ValidComponentsForPropertyType<PropertyTypeFromKey<LinkedQ, LinkedK>>,\n> extends FilterDefinitionControls {\n type: \"LINKED_PROPERTY\";\n linkName: L;\n /**\n * Set this to make the filter narrow `objectSet`; the result is emitted\n * via `onEffectiveObjectSet`. The value names the link on the linked\n * object type that points back to `Q` (the inverse of `linkName`).\n *\n * Leave unset to keep the filter UI-only. It still renders and fires\n * `onFilterStateChanged`, but FilterList won't narrow on it.\n */\n reverseLinkName?: LinkNames<LinkedQ>;\n linkedPropertyKey: LinkedK;\n\n /**\n * The filter component to render for the linked property. Must be\n * compatible with the linked property's type, see\n * ValidComponentsForPropertyType.\n *\n * Required in practice — a definition that sets neither this nor\n * `linkedFilterComponent` renders as unsupported.\n */\n // TODO: make this required, and drop the note above, when\n // `linkedFilterComponent` is removed.\n filterComponent?: LinkedC;\n\n /**\n * @deprecated Rename to `filterComponent`.\n */\n linkedFilterComponent?: LinkedC;\n\n /**\n * Seeds the state of the filter on the *linked* property. FilterList owns the\n * state from then on. `onFilterStateChanged` fires with the wrapper.\n *\n * @default undefined (filter starts empty)\n */\n defaultFilterState?: FilterStateByComponentType[LinkedC];\n\n /**\n * @deprecated Rename to `defaultFilterState`.\n */\n defaultLinkedFilterState?: FilterStateByComponentType[LinkedC];\n\n /**\n * @deprecated Has no effect, remove it.\n */\n linkedFilterState?: FilterStateByComponentType[LinkedC];\n\n /**\n * @deprecated Has no effect, remove it.\n */\n filterState?: LinkedPropertyFilterState<FilterStateByComponentType[LinkedC]>;\n\n label?: string;\n\n /**\n * Show aggregation counts next to filter option values.\n * Applies to LISTOGRAM, SINGLE_SELECT, and MULTI_SELECT linked components.\n * @default true for LISTOGRAM and MULTI_SELECT, false for SINGLE_SELECT\n */\n showCount?: boolean;\n\n /**\n * Custom display function for filter values.\n * Replaces the default string display in dropdown items, chips, and listogram rows.\n * When the function returns a string, that string is also used for search matching\n * within filter dropdowns. When it returns a non-string `ReactNode`, search falls\n * back to the raw value.\n */\n renderValue?: (value: string) => ReactNode;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAoBA;AACA;AACA;AACA;AACA;;AASA;AACA,OAAO,MAAMA,oBAAsC,GAAG,EAAE;;AAExD;AACA;AACA;;AAMA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;;AAsBA;AACA;AACA","ignoreList":[]}
1
+ {"version":3,"file":"LinkedFilterTypes.js","names":["EMPTY_LINKED_FILTERS"],"sources":["LinkedFilterTypes.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n LinkedType,\n LinkNames,\n ObjectTypeDefinition,\n PropertyKeys,\n WhereClause,\n} from \"@osdk/api\";\nimport type { ReactNode } from \"react\";\n\nimport type {\n BaseFilterState,\n FilterDefinitionControls,\n FilterState,\n FilterStateByComponentType,\n PropertyTypeFromKey,\n ValidComponentsForPropertyType,\n} from \"../FilterListItemApi.js\";\n\n/**\n * Runtime representation of an active link-traversing filter\n */\nexport type LinkedFilter<Q extends ObjectTypeDefinition> = {\n [L in LinkNames<Q>]: {\n /** Stable identity for the filter */\n id: string;\n\n linkName: L;\n /**\n * Predicate the linked objects must match to be counted.\n */\n innerWhere?: WhereClause<LinkedType<Q, L>>;\n /**\n * When true, keep source rows whose match-count is zero.\n */\n isExcluding?: boolean;\n };\n}[LinkNames<Q>];\n\n/** Shared empty default for `LinkedFilter` arrays — avoids new-array-per-render. */\nexport const EMPTY_LINKED_FILTERS: readonly never[] = [];\n\n/**\n * State for \"has link\" filter\n */\nexport interface HasLinkFilterState extends BaseFilterState {\n type: \"hasLink\";\n hasLink: boolean;\n}\n\n/**\n * State for linked property filter\n * Wraps the filter state of the linked property\n */\nexport interface LinkedPropertyFilterState<\n S extends FilterState = FilterState,\n> extends BaseFilterState {\n type: \"linkedProperty\";\n linkedFilterState: S;\n}\n\n/**\n * Filter definition for \"Has Link\" filter\n * Filters objects based on whether they have any linked objects of the specified\n * type. Narrows `objectSet` and is emitted via `onEffectiveObjectSet`; link\n * presence has no filter-clause form, so it never appears in\n * `onFilterClauseChanged`.\n */\nexport interface HasLinkFilterDefinition<\n Q extends ObjectTypeDefinition,\n L extends LinkNames<Q> = LinkNames<Q>,\n> extends FilterDefinitionControls {\n type: \"HAS_LINK\";\n linkName: L;\n label?: string;\n\n /**\n * Seeds the filter's state on mount, FilterList owns the state from then on\n *\n * @default undefined (filter starts empty)\n */\n defaultFilterState?: HasLinkFilterState;\n\n /**\n * @deprecated Has no effect, remove it.\n */\n filterState?: HasLinkFilterState;\n}\n\n/**\n * Filter definition for filtering on a property of linked objects\n */\nexport interface LinkedPropertyFilterDefinition<\n Q extends ObjectTypeDefinition,\n L extends LinkNames<Q>,\n LinkedQ extends ObjectTypeDefinition = LinkedType<Q, L>,\n LinkedK extends PropertyKeys<LinkedQ> = PropertyKeys<LinkedQ>,\n LinkedC extends ValidComponentsForPropertyType<\n PropertyTypeFromKey<LinkedQ, LinkedK>\n > = ValidComponentsForPropertyType<PropertyTypeFromKey<LinkedQ, LinkedK>>,\n> extends FilterDefinitionControls {\n type: \"LINKED_PROPERTY\";\n linkName: L;\n /**\n * @deprecated Has no effect, remove it.\n */\n reverseLinkName?: LinkNames<LinkedQ>;\n linkedPropertyKey: LinkedK;\n\n /**\n * The filter component to render for the linked property. Must be\n * compatible with the linked property's type, see\n * ValidComponentsForPropertyType.\n *\n * Required in practice — a definition that sets neither this nor\n * `linkedFilterComponent` renders as unsupported.\n */\n // TODO: make this required, and drop the note above, when\n // `linkedFilterComponent` is removed.\n filterComponent?: LinkedC;\n\n /**\n * @deprecated Rename to `filterComponent`.\n */\n linkedFilterComponent?: LinkedC;\n\n /**\n * Seeds the state of the filter on the *linked* property. FilterList owns the\n * state from then on. `onFilterStateChanged` fires with the wrapper.\n *\n * @default undefined (filter starts empty)\n */\n defaultFilterState?: FilterStateByComponentType[LinkedC];\n\n /**\n * @deprecated Rename to `defaultFilterState`.\n */\n defaultLinkedFilterState?: FilterStateByComponentType[LinkedC];\n\n /**\n * @deprecated Has no effect, remove it.\n */\n linkedFilterState?: FilterStateByComponentType[LinkedC];\n\n /**\n * @deprecated Has no effect, remove it.\n */\n filterState?: LinkedPropertyFilterState<FilterStateByComponentType[LinkedC]>;\n\n label?: string;\n\n /**\n * Show aggregation counts next to filter option values.\n * Applies to LISTOGRAM, SINGLE_SELECT, and MULTI_SELECT linked components.\n * @default true for LISTOGRAM and MULTI_SELECT, false for SINGLE_SELECT\n */\n showCount?: boolean;\n\n /**\n * Custom display function for filter values.\n * Replaces the default string display in dropdown items, chips, and listogram rows.\n * When the function returns a string, that string is also used for search matching\n * within filter dropdowns. When it returns a non-string `ReactNode`, search falls\n * back to the raw value.\n */\n renderValue?: (value: string) => ReactNode;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAoBA;AACA;AACA;;AAkBA;AACA,OAAO,MAAMA,oBAAsC,GAAG,EAAE;;AAExD;AACA;AACA;;AAMA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;;AAsBA;AACA;AACA","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=WhereClauseTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WhereClauseTypes.js","names":[],"sources":["WhereClauseTypes.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { PossibleWhereClauseFilters } from \"@osdk/api\";\n\n/**\n * Exactly one `$operator` key, drawn from the PossibleWhereClauseFilters\n */\nexport type OperatorFilter = {\n [K in PossibleWhereClauseFilters]: { [P in K]: unknown };\n}[PossibleWhereClauseFilters];\n\nexport type PropertyFilter = OperatorFilter | boolean | string | number;\n\nexport type WhereClauseFragment =\n | { $and: WhereClauseFragment[] }\n | { $or: WhereClauseFragment[] }\n | { $not: WhereClauseFragment }\n | { [propertyApiName: string]: PropertyFilter };\n"],"mappings":"","ignoreList":[]}
@@ -18,4 +18,5 @@ export * from "./CustomRendererTypes.js";
18
18
  export * from "./KeywordSearchTypes.js";
19
19
  export * from "./LinkedFilterTypes.js";
20
20
  export * from "./StaticValuesTypes.js";
21
+ export * from "./WhereClauseTypes.js";
21
22
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["index.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport * from \"./CustomRendererTypes.js\";\nexport * from \"./KeywordSearchTypes.js\";\nexport * from \"./LinkedFilterTypes.js\";\nexport * from \"./StaticValuesTypes.js\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAc,0BAA0B;AACxC,cAAc,yBAAyB;AACvC,cAAc,wBAAwB;AACtC,cAAc,wBAAwB","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":[],"sources":["index.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport * from \"./CustomRendererTypes.js\";\nexport * from \"./KeywordSearchTypes.js\";\nexport * from \"./LinkedFilterTypes.js\";\nexport * from \"./StaticValuesTypes.js\";\nexport * from \"./WhereClauseTypes.js\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAc,0BAA0B;AACxC,cAAc,yBAAyB;AACvC,cAAc,wBAAwB;AACtC,cAAc,wBAAwB;AACtC,cAAc,uBAAuB","ignoreList":[]}
@@ -85,7 +85,6 @@ export function getEmptyDisplayState(definition) {
85
85
  };
86
86
  }
87
87
  case "HAS_LINK":
88
- // hasLink supports the include/exclude overflow dropdown.
89
88
  return {
90
89
  type: "hasLink",
91
90
  hasLink: false
@@ -1 +1 @@
1
- {"version":3,"file":"emptyFilterDisplayState.js","names":["getLinkedFilterComponent","emptyOverflowStateForComponent","component","type","selectedValues","values","value","undefined","startDate","endDate","getEmptyDisplayState","definition","filterComponent","inner","linkedFilterState","hasLink"],"sources":["emptyFilterDisplayState.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ObjectTypeDefinition } from \"@osdk/api\";\n\nimport type { FilterDefinitionUnion } from \"../FilterListApi.js\";\nimport type { FilterComponentType, FilterState } from \"../FilterListItemApi.js\";\nimport { getLinkedFilterComponent } from \"./getLinkedFilterComponent.js\";\n\n/**\n * Filter components whose state supports the overflow (…) controls\n * (include/exclude, clear all) and/or in-filter search. Keep this in sync with\n * `supportsExcluding`/`supportsSearch` in `filterValues.ts` — these are exactly\n * the components that wrap their input in `FilterInputExcludeRow`.\n */\nfunction emptyOverflowStateForComponent(\n component: FilterComponentType,\n): FilterState | undefined {\n switch (component) {\n case \"MULTI_SELECT\":\n case \"SINGLE_SELECT\":\n return { type: \"SELECT\", selectedValues: [] };\n case \"LISTOGRAM\":\n case \"TEXT_TAGS\":\n return { type: \"EXACT_MATCH\", values: [] };\n case \"CONTAINS_TEXT\":\n return { type: \"CONTAINS_TEXT\", value: undefined };\n case \"TIMELINE\":\n return { type: \"TIMELINE\", startDate: undefined, endDate: undefined };\n case \"NUMBER_RANGE\":\n case \"DATE_RANGE\":\n case \"SINGLE_DATE\":\n case \"MULTI_DATE\":\n case \"TOGGLE\":\n return undefined;\n default: {\n const _exhaustive: never = component;\n return undefined;\n }\n }\n}\n\n/**\n * Returns a typed-but-empty `FilterState` to render for a filter that has no\n * stored state yet, so capability-driven header controls (the overflow … menu\n * and search) appear for empty/just-added filters without seeding the actual\n * filter state. Returns `undefined` for filter kinds/components that have no\n * such controls, leaving their display state empty.\n *\n * This is a *display-only* fallback — it is never written into the filter-state\n * map, so an untouched filter stays empty (no where-clause, not counted active).\n */\nexport function getEmptyDisplayState<Q extends ObjectTypeDefinition>(\n definition: FilterDefinitionUnion<Q>,\n): FilterState | undefined {\n switch (definition.type) {\n case \"PROPERTY\":\n case \"STATIC_VALUES\":\n return emptyOverflowStateForComponent(definition.filterComponent);\n case \"LINKED_PROPERTY\": {\n const component = getLinkedFilterComponent(definition);\n const inner =\n component == null\n ? undefined\n : emptyOverflowStateForComponent(component);\n return inner == null\n ? undefined\n : { type: \"linkedProperty\", linkedFilterState: inner };\n }\n case \"HAS_LINK\":\n // hasLink supports the include/exclude overflow dropdown.\n return { type: \"hasLink\", hasLink: false };\n case \"KEYWORD_SEARCH\":\n case \"CUSTOM\":\n return undefined;\n default: {\n const _exhaustive: never = definition;\n return undefined;\n }\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA,SAASA,wBAAwB,QAAQ,+BAA+B;;AAExE;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,8BAA8BA,CACrCC,SAA8B,EACL;EACzB,QAAQA,SAAS;IACf,KAAK,cAAc;IACnB,KAAK,eAAe;MAClB,OAAO;QAAEC,IAAI,EAAE,QAAQ;QAAEC,cAAc,EAAE;MAAG,CAAC;IAC/C,KAAK,WAAW;IAChB,KAAK,WAAW;MACd,OAAO;QAAED,IAAI,EAAE,aAAa;QAAEE,MAAM,EAAE;MAAG,CAAC;IAC5C,KAAK,eAAe;MAClB,OAAO;QAAEF,IAAI,EAAE,eAAe;QAAEG,KAAK,EAAEC;MAAU,CAAC;IACpD,KAAK,UAAU;MACb,OAAO;QAAEJ,IAAI,EAAE,UAAU;QAAEK,SAAS,EAAED,SAAS;QAAEE,OAAO,EAAEF;MAAU,CAAC;IACvE,KAAK,cAAc;IACnB,KAAK,YAAY;IACjB,KAAK,aAAa;IAClB,KAAK,YAAY;IACjB,KAAK,QAAQ;MACX,OAAOA,SAAS;IAClB;MAAS;QAEP,OAAOA,SAAS;MAClB;EACF;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,oBAAoBA,CAClCC,UAAoC,EACX;EACzB,QAAQA,UAAU,CAACR,IAAI;IACrB,KAAK,UAAU;IACf,KAAK,eAAe;MAClB,OAAOF,8BAA8B,CAACU,UAAU,CAACC,eAAe,CAAC;IACnE,KAAK,iBAAiB;MAAE;QACtB,MAAMV,SAAS,GAAGF,wBAAwB,CAACW,UAAU,CAAC;QACtD,MAAME,KAAK,GACTX,SAAS,IAAI,IAAI,GACbK,SAAS,GACTN,8BAA8B,CAACC,SAAS,CAAC;QAC/C,OAAOW,KAAK,IAAI,IAAI,GAChBN,SAAS,GACT;UAAEJ,IAAI,EAAE,gBAAgB;UAAEW,iBAAiB,EAAED;QAAM,CAAC;MAC1D;IACA,KAAK,UAAU;MACb;MACA,OAAO;QAAEV,IAAI,EAAE,SAAS;QAAEY,OAAO,EAAE;MAAM,CAAC;IAC5C,KAAK,gBAAgB;IACrB,KAAK,QAAQ;MACX,OAAOR,SAAS;IAClB;MAAS;QAEP,OAAOA,SAAS;MAClB;EACF;AACF","ignoreList":[]}
1
+ {"version":3,"file":"emptyFilterDisplayState.js","names":["getLinkedFilterComponent","emptyOverflowStateForComponent","component","type","selectedValues","values","value","undefined","startDate","endDate","getEmptyDisplayState","definition","filterComponent","inner","linkedFilterState","hasLink"],"sources":["emptyFilterDisplayState.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ObjectTypeDefinition } from \"@osdk/api\";\n\nimport type { FilterDefinitionUnion } from \"../FilterListApi.js\";\nimport type { FilterComponentType, FilterState } from \"../FilterListItemApi.js\";\nimport { getLinkedFilterComponent } from \"./getLinkedFilterComponent.js\";\n\n/**\n * Filter components whose state supports the overflow (…) controls\n * (include/exclude, clear all) and/or in-filter search. Keep this in sync with\n * `supportsExcluding`/`supportsSearch` in `filterValues.ts` — these are exactly\n * the components that wrap their input in `FilterInputExcludeRow`.\n */\nfunction emptyOverflowStateForComponent(\n component: FilterComponentType,\n): FilterState | undefined {\n switch (component) {\n case \"MULTI_SELECT\":\n case \"SINGLE_SELECT\":\n return { type: \"SELECT\", selectedValues: [] };\n case \"LISTOGRAM\":\n case \"TEXT_TAGS\":\n return { type: \"EXACT_MATCH\", values: [] };\n case \"CONTAINS_TEXT\":\n return { type: \"CONTAINS_TEXT\", value: undefined };\n case \"TIMELINE\":\n return { type: \"TIMELINE\", startDate: undefined, endDate: undefined };\n case \"NUMBER_RANGE\":\n case \"DATE_RANGE\":\n case \"SINGLE_DATE\":\n case \"MULTI_DATE\":\n case \"TOGGLE\":\n return undefined;\n default: {\n const _exhaustive: never = component;\n return undefined;\n }\n }\n}\n\n/**\n * Returns a typed-but-empty `FilterState` to render for a filter that has no\n * stored state yet, so capability-driven header controls (the overflow … menu\n * and search) appear for empty/just-added filters without seeding the actual\n * filter state. Returns `undefined` for filter kinds/components that have no\n * such controls, leaving their display state empty.\n *\n * This is a *display-only* fallback — it is never written into the filter-state\n * map, so an untouched filter stays empty (no where-clause, not counted active).\n */\nexport function getEmptyDisplayState<Q extends ObjectTypeDefinition>(\n definition: FilterDefinitionUnion<Q>,\n): FilterState | undefined {\n switch (definition.type) {\n case \"PROPERTY\":\n case \"STATIC_VALUES\":\n return emptyOverflowStateForComponent(definition.filterComponent);\n case \"LINKED_PROPERTY\": {\n const component = getLinkedFilterComponent(definition);\n const inner =\n component == null\n ? undefined\n : emptyOverflowStateForComponent(component);\n return inner == null\n ? undefined\n : { type: \"linkedProperty\", linkedFilterState: inner };\n }\n case \"HAS_LINK\":\n return { type: \"hasLink\", hasLink: false };\n case \"KEYWORD_SEARCH\":\n case \"CUSTOM\":\n return undefined;\n default: {\n const _exhaustive: never = definition;\n return undefined;\n }\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA,SAASA,wBAAwB,QAAQ,+BAA+B;;AAExE;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,8BAA8BA,CACrCC,SAA8B,EACL;EACzB,QAAQA,SAAS;IACf,KAAK,cAAc;IACnB,KAAK,eAAe;MAClB,OAAO;QAAEC,IAAI,EAAE,QAAQ;QAAEC,cAAc,EAAE;MAAG,CAAC;IAC/C,KAAK,WAAW;IAChB,KAAK,WAAW;MACd,OAAO;QAAED,IAAI,EAAE,aAAa;QAAEE,MAAM,EAAE;MAAG,CAAC;IAC5C,KAAK,eAAe;MAClB,OAAO;QAAEF,IAAI,EAAE,eAAe;QAAEG,KAAK,EAAEC;MAAU,CAAC;IACpD,KAAK,UAAU;MACb,OAAO;QAAEJ,IAAI,EAAE,UAAU;QAAEK,SAAS,EAAED,SAAS;QAAEE,OAAO,EAAEF;MAAU,CAAC;IACvE,KAAK,cAAc;IACnB,KAAK,YAAY;IACjB,KAAK,aAAa;IAClB,KAAK,YAAY;IACjB,KAAK,QAAQ;MACX,OAAOA,SAAS;IAClB;MAAS;QAEP,OAAOA,SAAS;MAClB;EACF;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,oBAAoBA,CAClCC,UAAoC,EACX;EACzB,QAAQA,UAAU,CAACR,IAAI;IACrB,KAAK,UAAU;IACf,KAAK,eAAe;MAClB,OAAOF,8BAA8B,CAACU,UAAU,CAACC,eAAe,CAAC;IACnE,KAAK,iBAAiB;MAAE;QACtB,MAAMV,SAAS,GAAGF,wBAAwB,CAACW,UAAU,CAAC;QACtD,MAAME,KAAK,GACTX,SAAS,IAAI,IAAI,GACbK,SAAS,GACTN,8BAA8B,CAACC,SAAS,CAAC;QAC/C,OAAOW,KAAK,IAAI,IAAI,GAChBN,SAAS,GACT;UAAEJ,IAAI,EAAE,gBAAgB;UAAEW,iBAAiB,EAAED;QAAM,CAAC;MAC1D;IACA,KAAK,UAAU;MACb,OAAO;QAAEV,IAAI,EAAE,SAAS;QAAEY,OAAO,EAAE;MAAM,CAAC;IAC5C,KAAK,gBAAgB;IACrB,KAAK,QAAQ;MACX,OAAOR,SAAS;IAClB;MAAS;QAEP,OAAOA,SAAS;MAClB;EACF;AACF","ignoreList":[]}
@@ -219,8 +219,8 @@ export function buildPropertyKeyClause(key, state, propertyType) {
219
219
  }
220
220
  /**
221
221
  * Builds a `WhereClause<Q>` from direct (non-link-traversing) filter
222
- * definitions and current states. LINKED_PROPERTY filters are excluded —
223
- * use `getActiveLinkedFilters` for those and apply via `narrowObjectSet`.
222
+ * definitions and current states. HAS_LINK and LINKED_PROPERTY filters are
223
+ * excluded as they are applied via `narrowObjectSet`.
224
224
  */
225
225
  export function buildWhereClause(definitions, filterStates, propertyTypes, excludeFilterKey) {
226
226
  if (!definitions || definitions.length === 0) {
@@ -247,31 +247,9 @@ export function buildWhereClause(definitions, filterStates, propertyTypes, exclu
247
247
  break;
248
248
  }
249
249
  case "HAS_LINK":
250
- {
251
- if (state.type !== "hasLink") {
252
- if (process.env.NODE_ENV !== "production") {
253
- // eslint-disable-next-line no-console
254
- console.warn(`[FilterList] State type mismatch for hasLink filter "${definition.linkName}": expected hasLink, got ${state.type}`);
255
- }
256
- break;
257
- }
258
- if (!state.hasLink) {
259
- break;
260
- }
261
- const hasLinkClause = {
262
- [definition.linkName]: {
263
- $isNotNull: true
264
- }
265
- };
266
- // "Excluding" keeps objects that do NOT have the link.
267
- clauses.push(state.isExcluding ? {
268
- $not: hasLinkClause
269
- } : hasLinkClause);
270
- break;
271
- }
272
250
  case "LINKED_PROPERTY":
273
- // Handled by getActiveLinkedFilters can't be expressed as a
274
- // WhereClause<Q>.
251
+ // Both traverse a link, which no `WhereClause` operator can express.
252
+ // Handled by getActiveLinkedFilters + narrowObjectSet.
275
253
  break;
276
254
  case "KEYWORD_SEARCH":
277
255
  {
@@ -313,10 +291,11 @@ export function buildWhereClause(definitions, filterStates, propertyTypes, exclu
313
291
  if (propertiesToSearch.length === 0) {
314
292
  break;
315
293
  }
316
- const containsOp = state.operator === "AND" ? "$containsAllTerms" : "$containsAnyTerm";
317
294
  const propertySearches = propertiesToSearch.map(prop => ({
318
- [prop]: {
319
- [containsOp]: searchTerm
295
+ [prop]: state.operator === "AND" ? {
296
+ $containsAllTerms: searchTerm
297
+ } : {
298
+ $containsAnyTerm: searchTerm
320
299
  }
321
300
  }));
322
301
  let searchClause;
@@ -384,7 +363,16 @@ export function buildWhereClause(definitions, filterStates, propertyTypes, exclu
384
363
  * predicate (e.g. empty selection).
385
364
  */
386
365
  export function buildLinkedInnerWhere(definition, state) {
387
- const record = buildPropertyKeyClause(definition.linkedPropertyKey, state.linkedFilterState);
366
+ const inner = state.linkedFilterState;
367
+ /**
368
+ * Ignoring the inner state's `isExcluding` here
369
+ * Excluding state is handled in `narrowObjectSet`
370
+ */
371
+ const positiveInner = "isExcluding" in inner && inner.isExcluding ? {
372
+ ...inner,
373
+ isExcluding: false
374
+ } : inner;
375
+ const record = buildPropertyKeyClause(definition.linkedPropertyKey, positiveInner);
388
376
  if (record === undefined) {
389
377
  return undefined;
390
378
  }
@@ -392,7 +380,7 @@ export function buildLinkedInnerWhere(definition, state) {
392
380
  }
393
381
 
394
382
  /**
395
- * Returns the active LINKED_PROPERTY filters as `LinkedFilter<Q>` records.
383
+ * Returns the active HAS_LINK and LINKED_PROPERTY filters
396
384
  */
397
385
  export function getActiveLinkedFilters(definitions, filterStates, excludeFilterKey) {
398
386
  if (!definitions || definitions.length === 0) {
@@ -400,7 +388,7 @@ export function getActiveLinkedFilters(definitions, filterStates, excludeFilterK
400
388
  }
401
389
  const result = [];
402
390
  for (const definition of definitions) {
403
- if (definition.type !== "LINKED_PROPERTY") {
391
+ if (definition.type !== "LINKED_PROPERTY" && definition.type !== "HAS_LINK") {
404
392
  continue;
405
393
  }
406
394
  const key = getFilterKey(definition);
@@ -408,20 +396,41 @@ export function getActiveLinkedFilters(definitions, filterStates, excludeFilterK
408
396
  continue;
409
397
  }
410
398
  const state = filterStates.get(key);
411
- if (!state || state.type !== "linkedProperty") {
399
+ if (state == null) {
400
+ continue;
401
+ }
402
+ if (definition.type === "HAS_LINK") {
403
+ if (state.type !== "hasLink") {
404
+ if (process.env.NODE_ENV !== "production") {
405
+ // eslint-disable-next-line no-console
406
+ console.warn(`[FilterList] State type mismatch for hasLink filter "${definition.linkName}": expected hasLink, got ${state.type}`);
407
+ }
408
+ continue;
409
+ }
410
+ if (!state.hasLink) {
411
+ continue;
412
+ }
413
+ result.push({
414
+ id: key,
415
+ linkName: definition.linkName,
416
+ isExcluding: state.isExcluding === true
417
+ });
412
418
  continue;
413
419
  }
414
- if (definition.reverseLinkName == null) {
420
+ if (state.type !== "linkedProperty") {
415
421
  continue;
416
422
  }
417
423
  const innerWhere = buildLinkedInnerWhere(definition, state);
418
424
  if (innerWhere === undefined) {
419
425
  continue;
420
426
  }
427
+ const inner = state.linkedFilterState;
428
+ const isExcluding = "isExcluding" in inner && inner.isExcluding === true;
421
429
  result.push({
430
+ id: key,
422
431
  linkName: definition.linkName,
423
- reverseLinkName: definition.reverseLinkName,
424
- innerWhere
432
+ innerWhere,
433
+ isExcluding
425
434
  });
426
435
  }
427
436
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"filterStateToWhereClause.js","names":["assertUnreachable","formatDateForInput","NO_VALUE","getFilterKey","isCompoundFilter","f","NUMERIC_BOUNDS","byte","min","max","short","integer","long","Number","MIN_SAFE_INTEGER","MAX_SAFE_INTEGER","clampToPropertyBounds","value","propertyType","undefined","bounds","Math","formatDateValue","date","toISOString","filterStateToPropertyFilter","state","type","$containsAnyTerm","enabled","conditions","minValue","push","$gte","maxValue","$lte","length","includeNull","$isNull","__compound","buildValueOrNullFilter","values","selectedValues","map","v","Date","startDate","endDate","buildPropertyKeyClause","key","filter","isExcluding","fieldClauses","c","rangeClause","$and","$or","$not","clause","buildWhereClause","definitions","filterStates","propertyTypes","excludeFilterKey","clauses","definition","get","process","env","NODE_ENV","console","warn","linkName","hasLink","hasLinkClause","$isNotNull","searchTerm","trim","properties","propertiesToSearch","size","info","multiplicity","containsOp","operator","propertySearches","prop","searchClause","customClause","toWhereClause","Object","keys","staticClause","buildLinkedInnerWhere","record","linkedPropertyKey","linkedFilterState","getActiveLinkedFilters","result","reverseLinkName","innerWhere","realValues","hasNoValue","valueClause","$in"],"sources":["filterStateToWhereClause.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n LinkedType,\n LinkNames,\n ObjectTypeDefinition,\n WhereClause,\n} from \"@osdk/api\";\n\nimport { assertUnreachable } from \"../../shared/assertUnreachable.js\";\nimport { formatDateForInput } from \"../../shared/dateUtils.js\";\nimport type { FilterDefinitionUnion } from \"../FilterListApi.js\";\nimport type { FilterState } from \"../FilterListItemApi.js\";\nimport type {\n LinkedFilter,\n LinkedPropertyFilterDefinition,\n LinkedPropertyFilterState,\n} from \"../types/LinkedFilterTypes.js\";\nimport { NO_VALUE } from \"./filterValues.js\";\nimport { getFilterKey } from \"./getFilterKey.js\";\n\ntype PropertyFilter = Record<string, unknown> | boolean | string | number;\n\ninterface CompoundFilter {\n __compound: true;\n conditions: PropertyFilter[];\n includeNull: boolean;\n}\n\nfunction isCompoundFilter(\n f: PropertyFilter | CompoundFilter,\n): f is CompoundFilter {\n return typeof f === \"object\" && f != null && \"__compound\" in f;\n}\n\nconst NUMERIC_BOUNDS: Record<string, { min: number; max: number }> = {\n byte: { min: -128, max: 127 },\n short: { min: -32_768, max: 32_767 },\n integer: { min: -2_147_483_648, max: 2_147_483_647 },\n long: { min: Number.MIN_SAFE_INTEGER, max: Number.MAX_SAFE_INTEGER },\n};\n\nfunction clampToPropertyBounds(\n value: number,\n propertyType: string | undefined,\n): number {\n if (propertyType === undefined) {\n return value;\n }\n const bounds = NUMERIC_BOUNDS[propertyType];\n if (bounds === undefined) {\n return value;\n }\n return Math.max(bounds.min, Math.min(bounds.max, value));\n}\n\nfunction formatDateValue(date: Date, propertyType: string | undefined): string {\n if (propertyType === \"datetime\") {\n return formatDateForInput(date);\n }\n return date.toISOString();\n}\n\nfunction filterStateToPropertyFilter(\n state: FilterState,\n propertyType?: string,\n): PropertyFilter | CompoundFilter | undefined {\n switch (state.type) {\n case \"CONTAINS_TEXT\": {\n if (!state.value) {\n return undefined;\n }\n return { $containsAnyTerm: state.value };\n }\n\n case \"TOGGLE\": {\n return state.enabled;\n }\n\n case \"DATE_RANGE\": {\n const conditions: PropertyFilter[] = [];\n\n if (state.minValue !== undefined) {\n conditions.push({\n $gte: formatDateValue(state.minValue, propertyType),\n });\n }\n if (state.maxValue !== undefined) {\n conditions.push({\n $lte: formatDateValue(state.maxValue, propertyType),\n });\n }\n\n if (conditions.length === 0 && !state.includeNull) {\n return undefined;\n }\n\n if (conditions.length === 0 && state.includeNull) {\n return { $isNull: true };\n }\n\n if (conditions.length === 1 && !state.includeNull) {\n return conditions[0];\n }\n\n return {\n __compound: true,\n conditions,\n includeNull: state.includeNull ?? false,\n };\n }\n\n case \"NUMBER_RANGE\": {\n const conditions: PropertyFilter[] = [];\n\n if (state.minValue !== undefined) {\n conditions.push({\n $gte: clampToPropertyBounds(state.minValue, propertyType),\n });\n }\n if (state.maxValue !== undefined) {\n conditions.push({\n $lte: clampToPropertyBounds(state.maxValue, propertyType),\n });\n }\n\n if (conditions.length === 0 && !state.includeNull) {\n return undefined;\n }\n\n if (conditions.length === 0 && state.includeNull) {\n return { $isNull: true };\n }\n\n if (conditions.length === 1 && !state.includeNull) {\n return conditions[0];\n }\n\n return {\n __compound: true,\n conditions,\n includeNull: state.includeNull ?? false,\n };\n }\n\n case \"EXACT_MATCH\": {\n return buildValueOrNullFilter(state.values);\n }\n\n case \"SELECT\": {\n if (state.selectedValues.length === 0) {\n return undefined;\n }\n const values: (string | number | boolean)[] = state.selectedValues.map(\n (v) =>\n v instanceof Date\n ? formatDateValue(v, propertyType)\n : (v as string | number | boolean),\n );\n return buildValueOrNullFilter(values);\n }\n\n case \"TIMELINE\": {\n const conditions: PropertyFilter[] = [];\n if (state.startDate !== undefined) {\n conditions.push({\n $gte: formatDateValue(state.startDate, propertyType),\n });\n }\n if (state.endDate !== undefined) {\n conditions.push({\n $lte: formatDateValue(state.endDate, propertyType),\n });\n }\n if (conditions.length === 0) {\n return undefined;\n }\n if (conditions.length === 1) {\n return conditions[0];\n }\n return {\n __compound: true,\n conditions,\n includeNull: false,\n };\n }\n\n // These filter types are handled separately in buildWhereClause\n // since they need access to the full definition, not just state\n case \"hasLink\":\n case \"linkedProperty\":\n case \"keywordSearch\":\n case \"custom\":\n return undefined;\n\n default:\n return assertUnreachable(state);\n }\n}\n\n/**\n * Builds a WHERE clause fragment for a single property key from filter state.\n */\nexport function buildPropertyKeyClause(\n key: string | number | symbol,\n state: FilterState,\n propertyType?: string,\n): Record<string, unknown> | undefined {\n const filter = filterStateToPropertyFilter(state, propertyType);\n if (filter === undefined) {\n return undefined;\n }\n const isExcluding = \"isExcluding\" in state && state.isExcluding;\n if (isCompoundFilter(filter)) {\n const fieldClauses = filter.conditions.map((c) => ({\n [key]: c,\n }));\n let rangeClause: Record<string, unknown> =\n fieldClauses.length === 1 ? fieldClauses[0] : { $and: fieldClauses };\n if (filter.includeNull) {\n rangeClause = {\n $or: [rangeClause, { [key]: { $isNull: true } }],\n };\n }\n return isExcluding ? { $not: rangeClause } : rangeClause;\n } else {\n const clause = { [key]: filter };\n return isExcluding ? { $not: clause } : clause;\n }\n}\n\nexport interface PropertyTypeInfo {\n type: string;\n multiplicity: boolean;\n}\n\n/**\n * Builds a `WhereClause<Q>` from direct (non-link-traversing) filter\n * definitions and current states. LINKED_PROPERTY filters are excluded —\n * use `getActiveLinkedFilters` for those and apply via `narrowObjectSet`.\n */\nexport function buildWhereClause<Q extends ObjectTypeDefinition>(\n definitions: Array<FilterDefinitionUnion<Q>> | undefined,\n filterStates: Map<string, FilterState>,\n propertyTypes?: Map<string, PropertyTypeInfo>,\n excludeFilterKey?: string,\n): WhereClause<Q> {\n if (!definitions || definitions.length === 0) {\n return {} as WhereClause<Q>;\n }\n\n const clauses: Array<Record<string, unknown>> = [];\n\n for (const definition of definitions) {\n const key = getFilterKey(definition);\n if (key === excludeFilterKey) {\n continue;\n }\n const state = filterStates.get(key);\n\n if (!state) {\n continue;\n }\n\n switch (definition.type) {\n case \"PROPERTY\": {\n const propertyType = propertyTypes?.get(definition.key as string)?.type;\n const clause = buildPropertyKeyClause(\n definition.key,\n state,\n propertyType,\n );\n if (clause !== undefined) {\n clauses.push(clause);\n }\n break;\n }\n\n case \"HAS_LINK\": {\n if (state.type !== \"hasLink\") {\n if (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\n `[FilterList] State type mismatch for hasLink filter \"${definition.linkName}\": expected hasLink, got ${state.type}`,\n );\n }\n break;\n }\n if (!state.hasLink) {\n break;\n }\n const hasLinkClause = { [definition.linkName]: { $isNotNull: true } };\n // \"Excluding\" keeps objects that do NOT have the link.\n clauses.push(\n state.isExcluding ? { $not: hasLinkClause } : hasLinkClause,\n );\n break;\n }\n\n case \"LINKED_PROPERTY\":\n // Handled by getActiveLinkedFilters — can't be expressed as a\n // WhereClause<Q>.\n break;\n\n case \"KEYWORD_SEARCH\": {\n if (state.type !== \"keywordSearch\") {\n if (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\n `[FilterList] State type mismatch for keywordSearch filter: expected keywordSearch, got ${state.type}`,\n );\n }\n break;\n }\n if (!state.searchTerm) {\n break;\n }\n // TypeScript narrows state to KeywordSearchFilterState\n const searchTerm = state.searchTerm.trim();\n if (!searchTerm) {\n break;\n }\n\n const properties = definition.properties;\n let propertiesToSearch: string[];\n\n if (properties === \"all\") {\n if (propertyTypes && propertyTypes.size > 0) {\n propertiesToSearch = [];\n for (const [key, info] of propertyTypes) {\n if (info.type === \"string\" && !info.multiplicity) {\n propertiesToSearch.push(key);\n }\n }\n } else {\n if (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\n \"[FilterList] Keyword search with properties: 'all' requires propertyTypes to be provided. Filter will be skipped.\",\n );\n }\n break;\n }\n } else {\n propertiesToSearch = properties;\n }\n\n if (propertiesToSearch.length === 0) {\n break;\n }\n\n const containsOp =\n state.operator === \"AND\" ? \"$containsAllTerms\" : \"$containsAnyTerm\";\n\n const propertySearches = propertiesToSearch.map((prop) => ({\n [prop]: { [containsOp]: searchTerm },\n }));\n\n let searchClause: Record<string, unknown>;\n if (propertySearches.length === 1) {\n searchClause = propertySearches[0];\n } else {\n searchClause = { $or: propertySearches };\n }\n clauses.push(state.isExcluding ? { $not: searchClause } : searchClause);\n break;\n }\n\n case \"CUSTOM\": {\n if (state.type !== \"custom\") {\n if (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\n `[FilterList] State type mismatch for custom filter \"${definition.key}\": expected custom, got ${state.type}`,\n );\n }\n break;\n }\n // TypeScript narrows state to CustomFilterState\n const customClause = definition.toWhereClause(state);\n if (customClause && Object.keys(customClause).length > 0) {\n clauses.push(customClause as Record<string, unknown>);\n }\n break;\n }\n\n case \"STATIC_VALUES\": {\n if (definition.toWhereClause) {\n const staticClause = definition.toWhereClause(state);\n if (staticClause && Object.keys(staticClause).length > 0) {\n clauses.push(staticClause as Record<string, unknown>);\n }\n } else {\n const clause = buildPropertyKeyClause(definition.key, state);\n if (clause !== undefined) {\n clauses.push(clause);\n }\n }\n break;\n }\n\n default:\n assertUnreachable(definition);\n }\n }\n\n if (clauses.length === 0) {\n return {} as WhereClause<Q>;\n }\n\n if (clauses.length === 1) {\n return clauses[0] as WhereClause<Q>;\n }\n\n return { $and: clauses } as WhereClause<Q>;\n}\n\n/**\n * Builds the inner `WhereClause` for a linked-property filter, typed against\n * the linked object type. Returns `undefined` when the state doesn't yield a\n * predicate (e.g. empty selection).\n */\nexport function buildLinkedInnerWhere<\n Q extends ObjectTypeDefinition,\n L extends LinkNames<Q>,\n>(\n definition: LinkedPropertyFilterDefinition<Q, L>,\n state: LinkedPropertyFilterState,\n): WhereClause<LinkedType<Q, L>> | undefined {\n const record = buildPropertyKeyClause(\n definition.linkedPropertyKey,\n state.linkedFilterState,\n );\n if (record === undefined) {\n return undefined;\n }\n return record as WhereClause<LinkedType<Q, L>>;\n}\n\n/**\n * Returns the active LINKED_PROPERTY filters as `LinkedFilter<Q>` records.\n */\nexport function getActiveLinkedFilters<Q extends ObjectTypeDefinition>(\n definitions: Array<FilterDefinitionUnion<Q>> | undefined,\n filterStates: Map<string, FilterState>,\n excludeFilterKey?: string,\n): Array<LinkedFilter<Q>> {\n if (!definitions || definitions.length === 0) {\n return [];\n }\n const result: Array<LinkedFilter<Q>> = [];\n for (const definition of definitions) {\n if (definition.type !== \"LINKED_PROPERTY\") {\n continue;\n }\n const key = getFilterKey(definition);\n if (key === excludeFilterKey) {\n continue;\n }\n const state = filterStates.get(key);\n if (!state || state.type !== \"linkedProperty\") {\n continue;\n }\n if (definition.reverseLinkName == null) {\n continue;\n }\n const innerWhere = buildLinkedInnerWhere(definition, state);\n if (innerWhere === undefined) {\n continue;\n }\n result.push({\n linkName: definition.linkName,\n reverseLinkName: definition.reverseLinkName,\n innerWhere,\n } as LinkedFilter<Q>);\n }\n return result;\n}\n\n/**\n * Splits values into real values and the NO_VALUE sentinel, returning $isNull\n * for the sentinel. A literal empty string `\"\"` is a real value and matches\n * via equality (`{ key: \"\" }`), not `$isNull`.\n */\nfunction buildValueOrNullFilter(\n values: (string | number | boolean)[],\n): PropertyFilter | CompoundFilter | undefined {\n if (values.length === 0) {\n return undefined;\n }\n\n const realValues = values.filter((v) => v !== NO_VALUE);\n const hasNoValue = realValues.length < values.length;\n\n const valueClause: PropertyFilter | undefined =\n realValues.length === 0\n ? undefined\n : realValues.length === 1\n ? realValues[0]\n : { $in: realValues };\n\n if (!hasNoValue) {\n return valueClause;\n }\n\n if (valueClause === undefined) {\n return { $isNull: true };\n }\n\n return {\n __compound: true,\n conditions: [valueClause],\n includeNull: true,\n };\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"filterStateToWhereClause.js","names":["assertUnreachable","formatDateForInput","NO_VALUE","getFilterKey","isCompoundFilter","f","NUMERIC_BOUNDS","byte","min","max","short","integer","long","Number","MIN_SAFE_INTEGER","MAX_SAFE_INTEGER","clampToPropertyBounds","value","propertyType","undefined","bounds","Math","formatDateValue","date","toISOString","filterStateToPropertyFilter","state","type","$containsAnyTerm","enabled","conditions","minValue","push","$gte","maxValue","$lte","length","includeNull","$isNull","__compound","buildValueOrNullFilter","values","selectedValues","map","v","Date","startDate","endDate","buildPropertyKeyClause","key","filter","isExcluding","fieldClauses","c","rangeClause","$and","$or","$not","clause","buildWhereClause","definitions","filterStates","propertyTypes","excludeFilterKey","clauses","definition","get","process","env","NODE_ENV","console","warn","searchTerm","trim","properties","propertiesToSearch","size","info","multiplicity","propertySearches","prop","operator","$containsAllTerms","searchClause","customClause","toWhereClause","Object","keys","staticClause","buildLinkedInnerWhere","inner","linkedFilterState","positiveInner","record","linkedPropertyKey","getActiveLinkedFilters","result","linkName","hasLink","id","innerWhere","realValues","hasNoValue","valueClause","$in"],"sources":["filterStateToWhereClause.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n LinkedType,\n LinkNames,\n ObjectTypeDefinition,\n WhereClause,\n} from \"@osdk/api\";\n\nimport { assertUnreachable } from \"../../shared/assertUnreachable.js\";\nimport { formatDateForInput } from \"../../shared/dateUtils.js\";\nimport type { FilterDefinitionUnion } from \"../FilterListApi.js\";\nimport type { FilterState } from \"../FilterListItemApi.js\";\nimport type {\n LinkedFilter,\n LinkedPropertyFilterDefinition,\n LinkedPropertyFilterState,\n} from \"../types/LinkedFilterTypes.js\";\nimport type {\n PropertyFilter,\n WhereClauseFragment,\n} from \"../types/WhereClauseTypes.js\";\nimport { NO_VALUE } from \"./filterValues.js\";\nimport { getFilterKey } from \"./getFilterKey.js\";\n\ninterface CompoundFilter {\n __compound: true;\n conditions: PropertyFilter[];\n includeNull: boolean;\n}\n\nfunction isCompoundFilter(\n f: PropertyFilter | CompoundFilter,\n): f is CompoundFilter {\n return typeof f === \"object\" && f != null && \"__compound\" in f;\n}\n\nconst NUMERIC_BOUNDS: Record<string, { min: number; max: number }> = {\n byte: { min: -128, max: 127 },\n short: { min: -32_768, max: 32_767 },\n integer: { min: -2_147_483_648, max: 2_147_483_647 },\n long: { min: Number.MIN_SAFE_INTEGER, max: Number.MAX_SAFE_INTEGER },\n};\n\nfunction clampToPropertyBounds(\n value: number,\n propertyType: string | undefined,\n): number {\n if (propertyType === undefined) {\n return value;\n }\n const bounds = NUMERIC_BOUNDS[propertyType];\n if (bounds === undefined) {\n return value;\n }\n return Math.max(bounds.min, Math.min(bounds.max, value));\n}\n\nfunction formatDateValue(date: Date, propertyType: string | undefined): string {\n if (propertyType === \"datetime\") {\n return formatDateForInput(date);\n }\n return date.toISOString();\n}\n\nfunction filterStateToPropertyFilter(\n state: FilterState,\n propertyType?: string,\n): PropertyFilter | CompoundFilter | undefined {\n switch (state.type) {\n case \"CONTAINS_TEXT\": {\n if (!state.value) {\n return undefined;\n }\n return { $containsAnyTerm: state.value };\n }\n\n case \"TOGGLE\": {\n return state.enabled;\n }\n\n case \"DATE_RANGE\": {\n const conditions: PropertyFilter[] = [];\n\n if (state.minValue !== undefined) {\n conditions.push({\n $gte: formatDateValue(state.minValue, propertyType),\n });\n }\n if (state.maxValue !== undefined) {\n conditions.push({\n $lte: formatDateValue(state.maxValue, propertyType),\n });\n }\n\n if (conditions.length === 0 && !state.includeNull) {\n return undefined;\n }\n\n if (conditions.length === 0 && state.includeNull) {\n return { $isNull: true };\n }\n\n if (conditions.length === 1 && !state.includeNull) {\n return conditions[0];\n }\n\n return {\n __compound: true,\n conditions,\n includeNull: state.includeNull ?? false,\n };\n }\n\n case \"NUMBER_RANGE\": {\n const conditions: PropertyFilter[] = [];\n\n if (state.minValue !== undefined) {\n conditions.push({\n $gte: clampToPropertyBounds(state.minValue, propertyType),\n });\n }\n if (state.maxValue !== undefined) {\n conditions.push({\n $lte: clampToPropertyBounds(state.maxValue, propertyType),\n });\n }\n\n if (conditions.length === 0 && !state.includeNull) {\n return undefined;\n }\n\n if (conditions.length === 0 && state.includeNull) {\n return { $isNull: true };\n }\n\n if (conditions.length === 1 && !state.includeNull) {\n return conditions[0];\n }\n\n return {\n __compound: true,\n conditions,\n includeNull: state.includeNull ?? false,\n };\n }\n\n case \"EXACT_MATCH\": {\n return buildValueOrNullFilter(state.values);\n }\n\n case \"SELECT\": {\n if (state.selectedValues.length === 0) {\n return undefined;\n }\n const values: (string | number | boolean)[] = state.selectedValues.map(\n (v) =>\n v instanceof Date\n ? formatDateValue(v, propertyType)\n : (v as string | number | boolean),\n );\n return buildValueOrNullFilter(values);\n }\n\n case \"TIMELINE\": {\n const conditions: PropertyFilter[] = [];\n if (state.startDate !== undefined) {\n conditions.push({\n $gte: formatDateValue(state.startDate, propertyType),\n });\n }\n if (state.endDate !== undefined) {\n conditions.push({\n $lte: formatDateValue(state.endDate, propertyType),\n });\n }\n if (conditions.length === 0) {\n return undefined;\n }\n if (conditions.length === 1) {\n return conditions[0];\n }\n return {\n __compound: true,\n conditions,\n includeNull: false,\n };\n }\n\n // These filter types are handled separately in buildWhereClause\n // since they need access to the full definition, not just state\n case \"hasLink\":\n case \"linkedProperty\":\n case \"keywordSearch\":\n case \"custom\":\n return undefined;\n\n default:\n return assertUnreachable(state);\n }\n}\n\n/**\n * Builds a WHERE clause fragment for a single property key from filter state.\n */\nexport function buildPropertyKeyClause(\n key: string | number | symbol,\n state: FilterState,\n propertyType?: string,\n): WhereClauseFragment | undefined {\n const filter = filterStateToPropertyFilter(state, propertyType);\n if (filter === undefined) {\n return undefined;\n }\n const isExcluding = \"isExcluding\" in state && state.isExcluding;\n if (isCompoundFilter(filter)) {\n const fieldClauses = filter.conditions.map((c) => ({\n [key]: c,\n }));\n let rangeClause: WhereClauseFragment =\n fieldClauses.length === 1 ? fieldClauses[0] : { $and: fieldClauses };\n if (filter.includeNull) {\n rangeClause = {\n $or: [rangeClause, { [key]: { $isNull: true } }],\n };\n }\n return isExcluding ? { $not: rangeClause } : rangeClause;\n } else {\n const clause = { [key]: filter };\n return isExcluding ? { $not: clause } : clause;\n }\n}\n\nexport interface PropertyTypeInfo {\n type: string;\n multiplicity: boolean;\n}\n\n/**\n * Builds a `WhereClause<Q>` from direct (non-link-traversing) filter\n * definitions and current states. HAS_LINK and LINKED_PROPERTY filters are\n * excluded as they are applied via `narrowObjectSet`.\n */\nexport function buildWhereClause<Q extends ObjectTypeDefinition>(\n definitions: Array<FilterDefinitionUnion<Q>> | undefined,\n filterStates: Map<string, FilterState>,\n propertyTypes?: Map<string, PropertyTypeInfo>,\n excludeFilterKey?: string,\n): WhereClause<Q> {\n if (!definitions || definitions.length === 0) {\n return {} as WhereClause<Q>;\n }\n\n const clauses: WhereClauseFragment[] = [];\n\n for (const definition of definitions) {\n const key = getFilterKey(definition);\n if (key === excludeFilterKey) {\n continue;\n }\n const state = filterStates.get(key);\n\n if (!state) {\n continue;\n }\n\n switch (definition.type) {\n case \"PROPERTY\": {\n const propertyType = propertyTypes?.get(definition.key as string)?.type;\n const clause = buildPropertyKeyClause(\n definition.key,\n state,\n propertyType,\n );\n if (clause !== undefined) {\n clauses.push(clause);\n }\n break;\n }\n\n case \"HAS_LINK\":\n case \"LINKED_PROPERTY\":\n // Both traverse a link, which no `WhereClause` operator can express.\n // Handled by getActiveLinkedFilters + narrowObjectSet.\n break;\n\n case \"KEYWORD_SEARCH\": {\n if (state.type !== \"keywordSearch\") {\n if (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\n `[FilterList] State type mismatch for keywordSearch filter: expected keywordSearch, got ${state.type}`,\n );\n }\n break;\n }\n if (!state.searchTerm) {\n break;\n }\n // TypeScript narrows state to KeywordSearchFilterState\n const searchTerm = state.searchTerm.trim();\n if (!searchTerm) {\n break;\n }\n\n const properties = definition.properties;\n let propertiesToSearch: string[];\n\n if (properties === \"all\") {\n if (propertyTypes && propertyTypes.size > 0) {\n propertiesToSearch = [];\n for (const [key, info] of propertyTypes) {\n if (info.type === \"string\" && !info.multiplicity) {\n propertiesToSearch.push(key);\n }\n }\n } else {\n if (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\n \"[FilterList] Keyword search with properties: 'all' requires propertyTypes to be provided. Filter will be skipped.\",\n );\n }\n break;\n }\n } else {\n propertiesToSearch = properties;\n }\n\n if (propertiesToSearch.length === 0) {\n break;\n }\n\n const propertySearches: WhereClauseFragment[] = propertiesToSearch.map(\n (prop) => ({\n [prop]:\n state.operator === \"AND\"\n ? { $containsAllTerms: searchTerm }\n : { $containsAnyTerm: searchTerm },\n }),\n );\n\n let searchClause: WhereClauseFragment;\n if (propertySearches.length === 1) {\n searchClause = propertySearches[0];\n } else {\n searchClause = { $or: propertySearches };\n }\n clauses.push(state.isExcluding ? { $not: searchClause } : searchClause);\n break;\n }\n\n case \"CUSTOM\": {\n if (state.type !== \"custom\") {\n if (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\n `[FilterList] State type mismatch for custom filter \"${definition.key}\": expected custom, got ${state.type}`,\n );\n }\n break;\n }\n // TypeScript narrows state to CustomFilterState\n const customClause = definition.toWhereClause(state);\n if (customClause && Object.keys(customClause).length > 0) {\n clauses.push(customClause as WhereClauseFragment);\n }\n break;\n }\n\n case \"STATIC_VALUES\": {\n if (definition.toWhereClause) {\n const staticClause = definition.toWhereClause(state);\n if (staticClause && Object.keys(staticClause).length > 0) {\n clauses.push(staticClause as WhereClauseFragment);\n }\n } else {\n const clause = buildPropertyKeyClause(definition.key, state);\n if (clause !== undefined) {\n clauses.push(clause);\n }\n }\n break;\n }\n\n default:\n assertUnreachable(definition);\n }\n }\n\n if (clauses.length === 0) {\n return {} as WhereClause<Q>;\n }\n\n if (clauses.length === 1) {\n return clauses[0] as WhereClause<Q>;\n }\n\n return { $and: clauses } as WhereClause<Q>;\n}\n\n/**\n * Builds the inner `WhereClause` for a linked-property filter, typed against\n * the linked object type. Returns `undefined` when the state doesn't yield a\n * predicate (e.g. empty selection).\n */\nexport function buildLinkedInnerWhere<\n Q extends ObjectTypeDefinition,\n L extends LinkNames<Q>,\n>(\n definition: LinkedPropertyFilterDefinition<Q, L>,\n state: LinkedPropertyFilterState,\n): WhereClause<LinkedType<Q, L>> | undefined {\n const inner = state.linkedFilterState;\n /**\n * Ignoring the inner state's `isExcluding` here\n * Excluding state is handled in `narrowObjectSet`\n */\n const positiveInner =\n \"isExcluding\" in inner && inner.isExcluding\n ? ({ ...inner, isExcluding: false } as FilterState)\n : inner;\n const record = buildPropertyKeyClause(\n definition.linkedPropertyKey,\n positiveInner,\n );\n if (record === undefined) {\n return undefined;\n }\n return record as WhereClause<LinkedType<Q, L>>;\n}\n\n/**\n * Returns the active HAS_LINK and LINKED_PROPERTY filters\n */\nexport function getActiveLinkedFilters<Q extends ObjectTypeDefinition>(\n definitions: Array<FilterDefinitionUnion<Q>> | undefined,\n filterStates: Map<string, FilterState>,\n excludeFilterKey?: string,\n): Array<LinkedFilter<Q>> {\n if (!definitions || definitions.length === 0) {\n return [];\n }\n const result: Array<LinkedFilter<Q>> = [];\n for (const definition of definitions) {\n if (\n definition.type !== \"LINKED_PROPERTY\" &&\n definition.type !== \"HAS_LINK\"\n ) {\n continue;\n }\n const key = getFilterKey(definition);\n if (key === excludeFilterKey) {\n continue;\n }\n const state = filterStates.get(key);\n if (state == null) {\n continue;\n }\n\n if (definition.type === \"HAS_LINK\") {\n if (state.type !== \"hasLink\") {\n if (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\n `[FilterList] State type mismatch for hasLink filter \"${definition.linkName}\": expected hasLink, got ${state.type}`,\n );\n }\n continue;\n }\n if (!state.hasLink) {\n continue;\n }\n result.push({\n id: key,\n linkName: definition.linkName,\n isExcluding: state.isExcluding === true,\n });\n continue;\n }\n\n if (state.type !== \"linkedProperty\") {\n continue;\n }\n const innerWhere = buildLinkedInnerWhere(definition, state);\n if (innerWhere === undefined) {\n continue;\n }\n const inner = state.linkedFilterState;\n const isExcluding = \"isExcluding\" in inner && inner.isExcluding === true;\n result.push({\n id: key,\n linkName: definition.linkName,\n innerWhere,\n isExcluding,\n } as LinkedFilter<Q>);\n }\n return result;\n}\n\n/**\n * Splits values into real values and the NO_VALUE sentinel, returning $isNull\n * for the sentinel. A literal empty string `\"\"` is a real value and matches\n * via equality (`{ key: \"\" }`), not `$isNull`.\n */\nfunction buildValueOrNullFilter(\n values: (string | number | boolean)[],\n): PropertyFilter | CompoundFilter | undefined {\n if (values.length === 0) {\n return undefined;\n }\n\n const realValues = values.filter((v) => v !== NO_VALUE);\n const hasNoValue = realValues.length < values.length;\n\n const valueClause: PropertyFilter | undefined =\n realValues.length === 0\n ? undefined\n : realValues.length === 1\n ? realValues[0]\n : { $in: realValues };\n\n if (!hasNoValue) {\n return valueClause;\n }\n\n if (valueClause === undefined) {\n return { $isNull: true };\n }\n\n return {\n __compound: true,\n conditions: [valueClause],\n includeNull: true,\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -62,8 +62,6 @@ export function supportsExcluding(state) {
62
62
  case "EXACT_MATCH":
63
63
  case "CONTAINS_TEXT":
64
64
  case "TIMELINE":
65
- // hasLink supports excluding via the overflow dropdown: "Keeping" filters
66
- // to objects that have the link, "Excluding" to those that do not.
67
65
  case "hasLink":
68
66
  return true;
69
67
  case "NUMBER_RANGE":
@@ -292,7 +290,7 @@ export function filterHasActiveState(state) {
292
290
  case "TOGGLE":
293
291
  return state.enabled;
294
292
  case "hasLink":
295
- return state.hasLink;
293
+ return state.hasLink === true;
296
294
  case "linkedProperty":
297
295
  return filterHasActiveState(state.linkedFilterState);
298
296
  case "keywordSearch":