@osdk/react-components 0.2.0-beta.16 → 0.2.0-beta.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/README.md +91 -3
- package/build/browser/action-form/ActionForm.js +109 -0
- package/build/browser/action-form/ActionForm.js.map +1 -0
- package/build/browser/action-form/ActionFormApi.js.map +1 -1
- package/build/browser/action-form/BaseForm.js +74 -0
- package/build/browser/action-form/BaseForm.js.map +1 -0
- package/build/browser/action-form/FormFieldApi.js.map +1 -1
- package/build/browser/action-form/fields/FieldBridge.js +45 -0
- package/build/browser/action-form/fields/FieldBridge.js.map +1 -0
- package/build/browser/action-form/fields/FormFieldRenderer.js +68 -0
- package/build/browser/action-form/fields/FormFieldRenderer.js.map +1 -0
- package/build/browser/action-form/fields/TextInputField.js +38 -0
- package/build/browser/action-form/fields/TextInputField.js.map +1 -0
- package/build/browser/action-form/utils/coerceFieldValue.js +93 -0
- package/build/browser/action-form/utils/coerceFieldValue.js.map +1 -0
- package/build/browser/action-form/utils/getDefaultFieldComponent.js +56 -0
- package/build/browser/action-form/utils/getDefaultFieldComponent.js.map +1 -0
- package/build/browser/action-form/utils/getDefaultFieldDefinitions.js +33 -0
- package/build/browser/action-form/utils/getDefaultFieldDefinitions.js.map +1 -0
- package/build/browser/base-components/tooltip/Tooltip.js +91 -0
- package/build/browser/base-components/tooltip/Tooltip.js.map +1 -0
- package/build/browser/base-components/tooltip/Tooltip.module.css +70 -0
- package/build/browser/base-components/tooltip/Tooltip.module.css.js +11 -0
- package/build/browser/base-components/tooltip/index.js +18 -0
- package/build/browser/base-components/tooltip/index.js.map +1 -0
- package/build/browser/filter-list/base/BaseFilterList.js +23 -11
- package/build/browser/filter-list/base/BaseFilterList.js.map +1 -1
- package/build/browser/filter-list/base/FilterIcons.js +48 -13
- package/build/browser/filter-list/base/FilterIcons.js.map +1 -1
- package/build/browser/filter-list/base/FilterList.module.css +57 -13
- package/build/browser/filter-list/base/FilterList.module.css.js +5 -2
- package/build/browser/filter-list/base/FilterListHeader.js +10 -15
- package/build/browser/filter-list/base/FilterListHeader.js.map +1 -1
- package/build/browser/filter-list/base/FilterListHeader.module.css +13 -41
- package/build/browser/filter-list/base/FilterListHeader.module.css.js +1 -4
- package/build/browser/filter-list/hooks/useFilterListState.js +25 -7
- package/build/browser/filter-list/hooks/useFilterListState.js.map +1 -1
- package/build/browser/filter-list/utils/assertUnreachable.js +1 -8
- package/build/browser/filter-list/utils/assertUnreachable.js.map +1 -1
- package/build/browser/filter-list/utils/filterStateToWhereClause.js +121 -91
- package/build/browser/filter-list/utils/filterStateToWhereClause.js.map +1 -1
- package/build/browser/object-table/DefaultCellRenderer.js +6 -1
- package/build/browser/object-table/DefaultCellRenderer.js.map +1 -1
- package/build/browser/object-table/EditableCell.js +76 -9
- package/build/browser/object-table/EditableCell.js.map +1 -1
- package/build/browser/object-table/EditableCell.module.css +47 -8
- package/build/browser/object-table/EditableCell.module.css.js +5 -1
- package/build/browser/object-table/MultiColumnSortDialog.js +4 -1
- package/build/browser/object-table/MultiColumnSortDialog.js.map +1 -1
- package/build/browser/object-table/ObjectTable.js +4 -1
- package/build/browser/object-table/ObjectTable.js.map +1 -1
- package/build/browser/object-table/ObjectTableApi.js.map +1 -1
- package/build/browser/object-table/SelectionCells.js +1 -0
- package/build/browser/object-table/SelectionCells.js.map +1 -1
- package/build/browser/object-table/Table.js +2 -2
- package/build/browser/object-table/Table.js.map +1 -1
- package/build/browser/object-table/TableBody.js +1 -1
- package/build/browser/object-table/TableBody.js.map +1 -1
- package/build/browser/object-table/TableEditContainer.js +27 -16
- package/build/browser/object-table/TableEditContainer.js.map +1 -1
- package/build/browser/object-table/TableEditContainer.module.css +27 -0
- package/build/browser/object-table/TableEditContainer.module.css.js +5 -1
- package/build/browser/object-table/TableHeader.js +4 -1
- package/build/browser/object-table/TableHeader.js.map +1 -1
- package/build/browser/object-table/TableHeader.module.css +2 -1
- package/build/browser/object-table/TableHeader.module.css.js +1 -0
- package/build/browser/object-table/TableRow.js +2 -2
- package/build/browser/object-table/TableRow.js.map +1 -1
- package/build/browser/object-table/hooks/useColumnDefs.js +2 -1
- package/build/browser/object-table/hooks/useColumnDefs.js.map +1 -1
- package/build/browser/object-table/hooks/useEditableTable.js +21 -2
- package/build/browser/object-table/hooks/useEditableTable.js.map +1 -1
- package/build/browser/object-table/utils/types.js.map +1 -1
- package/build/browser/shared/assertUnreachable.js +25 -0
- package/build/browser/shared/assertUnreachable.js.map +1 -0
- package/build/browser/shared/typedMemo.js +25 -0
- package/build/browser/shared/typedMemo.js.map +1 -0
- package/build/browser/styles.css +219 -63
- package/build/cjs/public/experimental.cjs +1212 -966
- package/build/cjs/public/experimental.cjs.map +1 -1
- package/build/cjs/public/experimental.css +167 -55
- package/build/cjs/public/experimental.css.map +1 -1
- package/build/cjs/public/experimental.d.cts +18 -4
- package/build/esm/action-form/ActionForm.js +109 -0
- package/build/esm/action-form/ActionForm.js.map +1 -0
- package/build/esm/action-form/ActionFormApi.js.map +1 -1
- package/build/esm/action-form/BaseForm.js +74 -0
- package/build/esm/action-form/BaseForm.js.map +1 -0
- package/build/esm/action-form/FormFieldApi.js.map +1 -1
- package/build/esm/action-form/fields/FieldBridge.js +45 -0
- package/build/esm/action-form/fields/FieldBridge.js.map +1 -0
- package/build/esm/action-form/fields/FormFieldRenderer.js +68 -0
- package/build/esm/action-form/fields/FormFieldRenderer.js.map +1 -0
- package/build/esm/action-form/fields/TextInputField.js +38 -0
- package/build/esm/action-form/fields/TextInputField.js.map +1 -0
- package/build/esm/action-form/utils/coerceFieldValue.js +93 -0
- package/build/esm/action-form/utils/coerceFieldValue.js.map +1 -0
- package/build/esm/action-form/utils/getDefaultFieldComponent.js +56 -0
- package/build/esm/action-form/utils/getDefaultFieldComponent.js.map +1 -0
- package/build/esm/action-form/utils/getDefaultFieldDefinitions.js +33 -0
- package/build/esm/action-form/utils/getDefaultFieldDefinitions.js.map +1 -0
- package/build/esm/base-components/tooltip/Tooltip.js +91 -0
- package/build/esm/base-components/tooltip/Tooltip.js.map +1 -0
- package/build/esm/base-components/tooltip/Tooltip.module.css +70 -0
- package/build/esm/base-components/tooltip/index.js +18 -0
- package/build/esm/base-components/tooltip/index.js.map +1 -0
- package/build/esm/filter-list/base/BaseFilterList.js +23 -11
- package/build/esm/filter-list/base/BaseFilterList.js.map +1 -1
- package/build/esm/filter-list/base/FilterIcons.js +48 -13
- package/build/esm/filter-list/base/FilterIcons.js.map +1 -1
- package/build/esm/filter-list/base/FilterList.module.css +57 -13
- package/build/esm/filter-list/base/FilterListHeader.js +10 -15
- package/build/esm/filter-list/base/FilterListHeader.js.map +1 -1
- package/build/esm/filter-list/base/FilterListHeader.module.css +13 -41
- package/build/esm/filter-list/hooks/useFilterListState.js +25 -7
- package/build/esm/filter-list/hooks/useFilterListState.js.map +1 -1
- package/build/esm/filter-list/utils/assertUnreachable.js +1 -8
- package/build/esm/filter-list/utils/assertUnreachable.js.map +1 -1
- package/build/esm/filter-list/utils/filterStateToWhereClause.js +121 -91
- package/build/esm/filter-list/utils/filterStateToWhereClause.js.map +1 -1
- package/build/esm/object-table/DefaultCellRenderer.js +6 -1
- package/build/esm/object-table/DefaultCellRenderer.js.map +1 -1
- package/build/esm/object-table/EditableCell.js +76 -9
- package/build/esm/object-table/EditableCell.js.map +1 -1
- package/build/esm/object-table/EditableCell.module.css +47 -8
- package/build/esm/object-table/MultiColumnSortDialog.js +4 -1
- package/build/esm/object-table/MultiColumnSortDialog.js.map +1 -1
- package/build/esm/object-table/ObjectTable.js +4 -1
- package/build/esm/object-table/ObjectTable.js.map +1 -1
- package/build/esm/object-table/ObjectTableApi.js.map +1 -1
- package/build/esm/object-table/SelectionCells.js +1 -0
- package/build/esm/object-table/SelectionCells.js.map +1 -1
- package/build/esm/object-table/Table.js +2 -2
- package/build/esm/object-table/Table.js.map +1 -1
- package/build/esm/object-table/TableBody.js +1 -1
- package/build/esm/object-table/TableBody.js.map +1 -1
- package/build/esm/object-table/TableEditContainer.js +27 -16
- package/build/esm/object-table/TableEditContainer.js.map +1 -1
- package/build/esm/object-table/TableEditContainer.module.css +27 -0
- package/build/esm/object-table/TableHeader.js +4 -1
- package/build/esm/object-table/TableHeader.js.map +1 -1
- package/build/esm/object-table/TableHeader.module.css +2 -1
- package/build/esm/object-table/TableRow.js +2 -2
- package/build/esm/object-table/TableRow.js.map +1 -1
- package/build/esm/object-table/hooks/useColumnDefs.js +2 -1
- package/build/esm/object-table/hooks/useColumnDefs.js.map +1 -1
- package/build/esm/object-table/hooks/useEditableTable.js +21 -2
- package/build/esm/object-table/hooks/useEditableTable.js.map +1 -1
- package/build/esm/object-table/utils/types.js.map +1 -1
- package/build/esm/shared/assertUnreachable.js +25 -0
- package/build/esm/shared/assertUnreachable.js.map +1 -0
- package/build/esm/shared/typedMemo.js +25 -0
- package/build/esm/shared/typedMemo.js.map +1 -0
- package/build/types/action-form/ActionForm.d.ts +4 -0
- package/build/types/action-form/ActionForm.d.ts.map +1 -0
- package/build/types/action-form/ActionFormApi.d.ts +48 -32
- package/build/types/action-form/ActionFormApi.d.ts.map +1 -1
- package/build/types/action-form/BaseForm.d.ts +3 -0
- package/build/types/action-form/BaseForm.d.ts.map +1 -0
- package/build/types/action-form/FormFieldApi.d.ts +58 -18
- package/build/types/action-form/FormFieldApi.d.ts.map +1 -1
- package/build/types/action-form/fields/FieldBridge.d.ts +9 -0
- package/build/types/action-form/fields/FieldBridge.d.ts.map +1 -0
- package/build/types/action-form/fields/FormFieldRenderer.d.ts +8 -0
- package/build/types/action-form/fields/FormFieldRenderer.d.ts.map +1 -0
- package/build/types/action-form/fields/TextInputField.d.ts +3 -0
- package/build/types/action-form/fields/TextInputField.d.ts.map +1 -0
- package/build/types/action-form/utils/coerceFieldValue.d.ts +10 -0
- package/build/types/action-form/utils/coerceFieldValue.d.ts.map +1 -0
- package/build/types/action-form/utils/getDefaultFieldComponent.d.ts +6 -0
- package/build/types/action-form/utils/getDefaultFieldComponent.d.ts.map +1 -0
- package/build/types/action-form/utils/getDefaultFieldDefinitions.d.ts +6 -0
- package/build/types/action-form/utils/getDefaultFieldDefinitions.d.ts.map +1 -0
- package/build/types/base-components/tooltip/Tooltip.d.ts +31 -0
- package/build/types/base-components/tooltip/Tooltip.d.ts.map +1 -0
- package/build/types/base-components/tooltip/index.d.ts +1 -0
- package/build/types/base-components/tooltip/index.d.ts.map +1 -0
- package/build/types/filter-list/base/BaseFilterList.d.ts.map +1 -1
- package/build/types/filter-list/base/FilterIcons.d.ts +7 -0
- package/build/types/filter-list/base/FilterIcons.d.ts.map +1 -1
- package/build/types/filter-list/base/FilterListHeader.d.ts.map +1 -1
- package/build/types/filter-list/hooks/useFilterListState.d.ts.map +1 -1
- package/build/types/filter-list/utils/assertUnreachable.d.ts +1 -6
- package/build/types/filter-list/utils/assertUnreachable.d.ts.map +1 -1
- package/build/types/filter-list/utils/filterStateToWhereClause.d.ts +5 -1
- package/build/types/filter-list/utils/filterStateToWhereClause.d.ts.map +1 -1
- package/build/types/object-table/EditableCell.d.ts +8 -2
- package/build/types/object-table/EditableCell.d.ts.map +1 -1
- package/build/types/object-table/ObjectTableApi.d.ts +7 -0
- package/build/types/object-table/ObjectTableApi.d.ts.map +1 -1
- package/build/types/object-table/Table.d.ts +4 -0
- package/build/types/object-table/Table.d.ts.map +1 -1
- package/build/types/object-table/TableEditContainer.d.ts +1 -1
- package/build/types/object-table/TableEditContainer.d.ts.map +1 -1
- package/build/types/object-table/TableHeader.d.ts.map +1 -1
- package/build/types/object-table/TableRow.d.ts +2 -2
- package/build/types/object-table/TableRow.d.ts.map +1 -1
- package/build/types/object-table/hooks/useEditableTable.d.ts.map +1 -1
- package/build/types/object-table/utils/types.d.ts +7 -4
- package/build/types/object-table/utils/types.d.ts.map +1 -1
- package/build/types/shared/assertUnreachable.d.ts +6 -0
- package/build/types/shared/assertUnreachable.d.ts.map +1 -0
- package/build/types/shared/typedMemo.d.ts +6 -0
- package/build/types/shared/typedMemo.d.ts.map +1 -0
- package/package.json +6 -5
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { Button } from "@base-ui/react/button";
|
|
18
|
-
import classnames from "classnames";
|
|
19
18
|
import React, { memo, useCallback } from "react";
|
|
19
|
+
import { CollapseIcon, ResetIcon } from "./FilterIcons.js";
|
|
20
20
|
import styles from "./FilterListHeader.module.css";
|
|
21
21
|
function FilterListHeaderInner({
|
|
22
22
|
title,
|
|
@@ -33,18 +33,6 @@ function FilterListHeaderInner({
|
|
|
33
33
|
}, [onCollapsedChange, collapsed]);
|
|
34
34
|
return /*#__PURE__*/React.createElement("div", {
|
|
35
35
|
className: styles.header
|
|
36
|
-
}, onCollapsedChange != null && /*#__PURE__*/React.createElement(Button, {
|
|
37
|
-
className: styles.collapseButton,
|
|
38
|
-
onClick: handleCollapseClick,
|
|
39
|
-
"aria-expanded": !collapsed,
|
|
40
|
-
"aria-label": collapsed ? "Expand filters" : "Collapse filters"
|
|
41
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
42
|
-
className: classnames(styles.collapseIcon, collapsed && styles.collapsed)
|
|
43
|
-
})), /*#__PURE__*/React.createElement("div", {
|
|
44
|
-
className: styles.headerContentWrapper,
|
|
45
|
-
"data-collapsed": collapsed
|
|
46
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
47
|
-
className: styles.headerContentInner
|
|
48
36
|
}, /*#__PURE__*/React.createElement("div", {
|
|
49
37
|
className: styles.titleContainer
|
|
50
38
|
}, titleIcon && /*#__PURE__*/React.createElement("span", {
|
|
@@ -53,11 +41,18 @@ function FilterListHeaderInner({
|
|
|
53
41
|
className: styles.title
|
|
54
42
|
}, title), showActiveFilterCount && activeFilterCount > 0 && /*#__PURE__*/React.createElement("span", {
|
|
55
43
|
className: styles.activeCount
|
|
56
|
-
}, "(", activeFilterCount, ")")),
|
|
44
|
+
}, "(", activeFilterCount, ")")), /*#__PURE__*/React.createElement("div", {
|
|
45
|
+
className: styles.actions
|
|
46
|
+
}, showResetButton && /*#__PURE__*/React.createElement(Button, {
|
|
57
47
|
className: styles.resetButton,
|
|
58
48
|
onClick: onReset,
|
|
59
49
|
disabled: activeFilterCount === 0
|
|
60
|
-
}, "Reset")
|
|
50
|
+
}, /*#__PURE__*/React.createElement(ResetIcon, null), " Reset"), onCollapsedChange != null && /*#__PURE__*/React.createElement(Button, {
|
|
51
|
+
className: styles.collapseButton,
|
|
52
|
+
onClick: handleCollapseClick,
|
|
53
|
+
"aria-expanded": !collapsed,
|
|
54
|
+
"aria-label": collapsed ? "Expand filters" : "Collapse filters"
|
|
55
|
+
}, /*#__PURE__*/React.createElement(CollapseIcon, null))));
|
|
61
56
|
}
|
|
62
57
|
export const FilterListHeader = /*#__PURE__*/memo(FilterListHeaderInner);
|
|
63
58
|
//# sourceMappingURL=FilterListHeader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterListHeader.js","names":["Button","
|
|
1
|
+
{"version":3,"file":"FilterListHeader.js","names":["Button","React","memo","useCallback","CollapseIcon","ResetIcon","styles","FilterListHeaderInner","title","titleIcon","collapsed","onCollapsedChange","showResetButton","onReset","showActiveFilterCount","activeFilterCount","handleCollapseClick","createElement","className","header","titleContainer","activeCount","actions","resetButton","onClick","disabled","collapseButton","FilterListHeader"],"sources":["FilterListHeader.tsx"],"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 { Button } from \"@base-ui/react/button\";\nimport React, { memo, type ReactNode, useCallback } from \"react\";\nimport { CollapseIcon, ResetIcon } from \"./FilterIcons.js\";\nimport styles from \"./FilterListHeader.module.css\";\n\ninterface FilterListHeaderProps {\n title?: string;\n titleIcon?: ReactNode;\n collapsed?: boolean;\n onCollapsedChange?: (collapsed: boolean) => void;\n showResetButton?: boolean;\n onReset?: () => void;\n showActiveFilterCount?: boolean;\n activeFilterCount?: number;\n}\n\nfunction FilterListHeaderInner({\n title,\n titleIcon,\n collapsed = false,\n onCollapsedChange,\n showResetButton,\n onReset,\n showActiveFilterCount,\n activeFilterCount = 0,\n}: FilterListHeaderProps): React.ReactElement {\n const showCollapseButton = onCollapsedChange != null;\n\n const handleCollapseClick = useCallback(() => {\n onCollapsedChange?.(!collapsed);\n }, [onCollapsedChange, collapsed]);\n\n return (\n <div className={styles.header}>\n <div className={styles.titleContainer}>\n {titleIcon && (\n <span className={styles.titleIcon}>\n {titleIcon}\n </span>\n )}\n {title && (\n <span className={styles.title}>\n {title}\n </span>\n )}\n {showActiveFilterCount && activeFilterCount > 0 && (\n <span className={styles.activeCount}>\n ({activeFilterCount})\n </span>\n )}\n </div>\n\n <div className={styles.actions}>\n {showResetButton && (\n <Button\n className={styles.resetButton}\n onClick={onReset}\n disabled={activeFilterCount === 0}\n >\n <ResetIcon /> Reset\n </Button>\n )}\n\n {showCollapseButton && (\n <Button\n className={styles.collapseButton}\n onClick={handleCollapseClick}\n aria-expanded={!collapsed}\n aria-label={collapsed ? \"Expand filters\" : \"Collapse filters\"}\n >\n <CollapseIcon />\n </Button>\n )}\n </div>\n </div>\n );\n}\n\nexport const FilterListHeader: React.MemoExoticComponent<\n typeof FilterListHeaderInner\n> = memo(FilterListHeaderInner);\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,MAAM,QAAQ,uBAAuB;AAC9C,OAAOC,KAAK,IAAIC,IAAI,EAAkBC,WAAW,QAAQ,OAAO;AAChE,SAASC,YAAY,EAAEC,SAAS,QAAQ,kBAAkB;AAC1D,OAAOC,MAAM,MAAM,+BAA+B;AAalD,SAASC,qBAAqBA,CAAC;EAC7BC,KAAK;EACLC,SAAS;EACTC,SAAS,GAAG,KAAK;EACjBC,iBAAiB;EACjBC,eAAe;EACfC,OAAO;EACPC,qBAAqB;EACrBC,iBAAiB,GAAG;AACC,CAAC,EAAsB;EAG5C,MAAMC,mBAAmB,GAAGb,WAAW,CAAC,MAAM;IAC5CQ,iBAAiB,GAAG,CAACD,SAAS,CAAC;EACjC,CAAC,EAAE,CAACC,iBAAiB,EAAED,SAAS,CAAC,CAAC;EAElC,oBACET,KAAA,CAAAgB,aAAA;IAAKC,SAAS,EAAEZ,MAAM,CAACa;EAAO,gBAC5BlB,KAAA,CAAAgB,aAAA;IAAKC,SAAS,EAAEZ,MAAM,CAACc;EAAe,GACnCX,SAAS,iBACRR,KAAA,CAAAgB,aAAA;IAAMC,SAAS,EAAEZ,MAAM,CAACG;EAAU,GAC/BA,SACG,CACP,EACAD,KAAK,iBACJP,KAAA,CAAAgB,aAAA;IAAMC,SAAS,EAAEZ,MAAM,CAACE;EAAM,GAC3BA,KACG,CACP,EACAM,qBAAqB,IAAIC,iBAAiB,GAAG,CAAC,iBAC7Cd,KAAA,CAAAgB,aAAA;IAAMC,SAAS,EAAEZ,MAAM,CAACe;EAAY,GAAC,GAClC,EAACN,iBAAiB,EAAC,GAChB,CAEL,CAAC,eAENd,KAAA,CAAAgB,aAAA;IAAKC,SAAS,EAAEZ,MAAM,CAACgB;EAAQ,GAC5BV,eAAe,iBACdX,KAAA,CAAAgB,aAAA,CAACjB,MAAM;IACLkB,SAAS,EAAEZ,MAAM,CAACiB,WAAY;IAC9BC,OAAO,EAAEX,OAAQ;IACjBY,QAAQ,EAAEV,iBAAiB,KAAK;EAAE,gBAElCd,KAAA,CAAAgB,aAAA,CAACZ,SAAS,MAAE,CAAC,UACP,CACT,EAnCoBM,iBAAiB,IAAI,IAAI,iBAsC5CV,KAAA,CAAAgB,aAAA,CAACjB,MAAM;IACLkB,SAAS,EAAEZ,MAAM,CAACoB,cAAe;IACjCF,OAAO,EAAER,mBAAoB;IAC7B,iBAAe,CAACN,SAAU;IAC1B,cAAYA,SAAS,GAAG,gBAAgB,GAAG;EAAmB,gBAE9DT,KAAA,CAAAgB,aAAA,CAACb,YAAY,MAAE,CACT,CAEP,CACF,CAAC;AAEV;AAEA,OAAO,MAAMuB,gBAEZ,gBAAGzB,IAAI,CAACK,qBAAqB,CAAC","ignoreList":[]}
|
|
@@ -49,6 +49,16 @@
|
|
|
49
49
|
font-variant-numeric: tabular-nums;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
.actions {
|
|
53
|
+
display: flex;
|
|
54
|
+
align-items: center;
|
|
55
|
+
gap: var(--osdk-surface-spacing);
|
|
56
|
+
|
|
57
|
+
&:empty {
|
|
58
|
+
display: none;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
52
62
|
.collapseButton {
|
|
53
63
|
display: flex;
|
|
54
64
|
align-items: center;
|
|
@@ -59,6 +69,7 @@
|
|
|
59
69
|
cursor: pointer;
|
|
60
70
|
border-radius: var(--osdk-filter-header-button-border-radius);
|
|
61
71
|
transition: background-color var(--osdk-filter-header-button-transition);
|
|
72
|
+
color: var(--osdk-filter-header-collapse-icon-color);
|
|
62
73
|
|
|
63
74
|
&:hover {
|
|
64
75
|
background: var(--osdk-filter-header-button-bg-hover);
|
|
@@ -78,49 +89,10 @@
|
|
|
78
89
|
}
|
|
79
90
|
}
|
|
80
91
|
|
|
81
|
-
.
|
|
82
|
-
display: block;
|
|
83
|
-
width: var(--osdk-filter-header-collapse-icon-size);
|
|
84
|
-
height: var(--osdk-filter-header-collapse-icon-size);
|
|
85
|
-
border-left: var(--osdk-filter-header-collapse-icon-border-width) solid var(--osdk-filter-header-collapse-icon-color);
|
|
86
|
-
border-bottom: var(--osdk-filter-header-collapse-icon-border-width) solid var(--osdk-filter-header-collapse-icon-color);
|
|
87
|
-
transform: rotate(-45deg);
|
|
88
|
-
transition: transform var(--osdk-filter-header-button-transition);
|
|
89
|
-
|
|
90
|
-
@media (prefers-reduced-motion: reduce) {
|
|
91
|
-
transition: none;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
.collapsed {
|
|
96
|
-
transform: rotate(-135deg);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.headerContentWrapper {
|
|
100
|
-
display: grid;
|
|
101
|
-
grid-template-columns: 1fr;
|
|
102
|
-
overflow: hidden;
|
|
103
|
-
transition: grid-template-columns var(--osdk-filter-list-collapse-transition);
|
|
104
|
-
|
|
105
|
-
@media (prefers-reduced-motion: reduce) {
|
|
106
|
-
transition: none;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.headerContentWrapper[data-collapsed="true"] {
|
|
111
|
-
grid-template-columns: 0fr;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
.headerContentInner {
|
|
92
|
+
.resetButton {
|
|
115
93
|
display: flex;
|
|
116
94
|
align-items: center;
|
|
117
|
-
|
|
118
|
-
flex: 1;
|
|
119
|
-
overflow: hidden;
|
|
120
|
-
min-width: 0;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.resetButton {
|
|
95
|
+
gap: calc(var(--osdk-surface-spacing) * 0.5);
|
|
124
96
|
font-family: var(--osdk-filter-header-font-family);
|
|
125
97
|
font-size: var(--osdk-filter-header-reset-font-size);
|
|
126
98
|
color: var(--osdk-filter-header-reset-color);
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import { useOsdkMetadata } from "@osdk/react";
|
|
17
18
|
import { useCallback, useMemo, useState } from "react";
|
|
18
19
|
import { assertUnreachable } from "../utils/assertUnreachable.js";
|
|
19
20
|
import { buildWhereClause } from "../utils/filterStateToWhereClause.js";
|
|
@@ -76,6 +77,23 @@ export function useFilterListState(props) {
|
|
|
76
77
|
initialFilterStates
|
|
77
78
|
} = props;
|
|
78
79
|
const objectType = objectSet.$objectSetInternals.def;
|
|
80
|
+
const {
|
|
81
|
+
metadata
|
|
82
|
+
} = useOsdkMetadata(objectType);
|
|
83
|
+
const propertyTypes = useMemo(() => {
|
|
84
|
+
const map = new Map();
|
|
85
|
+
if (metadata?.properties) {
|
|
86
|
+
for (const [key, prop] of Object.entries(metadata.properties)) {
|
|
87
|
+
if (typeof prop.type === "string") {
|
|
88
|
+
map.set(key, {
|
|
89
|
+
type: prop.type,
|
|
90
|
+
multiplicity: prop.multiplicity === true
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return map;
|
|
96
|
+
}, [metadata?.properties]);
|
|
79
97
|
const [filterStates, setFilterStates] = useState(() => {
|
|
80
98
|
const states = buildInitialStates(filterDefinitions);
|
|
81
99
|
if (initialFilterStates) {
|
|
@@ -90,7 +108,7 @@ export function useFilterListState(props) {
|
|
|
90
108
|
setFilterStates(prev => {
|
|
91
109
|
const next = new Map(prev);
|
|
92
110
|
next.set(filterKey, state);
|
|
93
|
-
newWhereClause = buildWhereClause(filterDefinitions, next, filterOperator,
|
|
111
|
+
newWhereClause = buildWhereClause(filterDefinitions, next, filterOperator, propertyTypes);
|
|
94
112
|
return next;
|
|
95
113
|
});
|
|
96
114
|
if (newWhereClause !== undefined) {
|
|
@@ -100,8 +118,8 @@ export function useFilterListState(props) {
|
|
|
100
118
|
if (definition) {
|
|
101
119
|
onFilterStateChanged?.(definition, state);
|
|
102
120
|
}
|
|
103
|
-
}, [filterDefinitions, filterOperator,
|
|
104
|
-
const whereClause = useMemo(() => buildWhereClause(filterDefinitions, filterStates, filterOperator,
|
|
121
|
+
}, [filterDefinitions, filterOperator, propertyTypes, onFilterClauseChanged, onFilterStateChanged]);
|
|
122
|
+
const whereClause = useMemo(() => buildWhereClause(filterDefinitions, filterStates, filterOperator, propertyTypes), [filterDefinitions, filterStates, filterOperator, propertyTypes]);
|
|
105
123
|
const perFilterWhereClauses = useMemo(() => {
|
|
106
124
|
const map = new Map();
|
|
107
125
|
if (!filterDefinitions) {
|
|
@@ -109,10 +127,10 @@ export function useFilterListState(props) {
|
|
|
109
127
|
}
|
|
110
128
|
for (const definition of filterDefinitions) {
|
|
111
129
|
const key = getFilterKey(definition);
|
|
112
|
-
map.set(key, buildWhereClause(filterDefinitions, filterStates, filterOperator,
|
|
130
|
+
map.set(key, buildWhereClause(filterDefinitions, filterStates, filterOperator, propertyTypes, key));
|
|
113
131
|
}
|
|
114
132
|
return map;
|
|
115
|
-
}, [filterDefinitions, filterStates, filterOperator,
|
|
133
|
+
}, [filterDefinitions, filterStates, filterOperator, propertyTypes]);
|
|
116
134
|
const activeFilterCount = useMemo(() => {
|
|
117
135
|
let count = 0;
|
|
118
136
|
for (const state of filterStates.values()) {
|
|
@@ -125,9 +143,9 @@ export function useFilterListState(props) {
|
|
|
125
143
|
const reset = useCallback(() => {
|
|
126
144
|
const initialStates = buildInitialStates(filterDefinitions);
|
|
127
145
|
setFilterStates(initialStates);
|
|
128
|
-
const newWhereClause = buildWhereClause(filterDefinitions, initialStates, filterOperator,
|
|
146
|
+
const newWhereClause = buildWhereClause(filterDefinitions, initialStates, filterOperator, propertyTypes);
|
|
129
147
|
onFilterClauseChanged?.(newWhereClause);
|
|
130
|
-
}, [filterDefinitions, filterOperator,
|
|
148
|
+
}, [filterDefinitions, filterOperator, propertyTypes, onFilterClauseChanged]);
|
|
131
149
|
return useMemo(() => ({
|
|
132
150
|
filterStates,
|
|
133
151
|
setFilterState,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFilterListState.js","names":["useCallback","useMemo","useState","assertUnreachable","buildWhereClause","filterHasActiveState","getFilterKey","buildInitialStates","definitions","states","Map","definition","key","type","state","filterState","set","defaultFilterState","innerState","defaultLinkedFilterState","linkedFilterState","useFilterListState","props","objectSet","filterDefinitions","filterOperator","onFilterStateChanged","onFilterClauseChanged","initialFilterStates","objectType","$objectSetInternals","def","filterStates","setFilterStates","setFilterState","filterKey","newWhereClause","prev","next","undefined","find","d","whereClause","perFilterWhereClauses","map","activeFilterCount","count","values","reset","initialStates"],"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 { ObjectTypeDefinition, WhereClause } from \"@osdk/api\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport type { FilterListProps } from \"../FilterListApi.js\";\nimport type { FilterState } from \"../FilterListItemApi.js\";\nimport type { LinkedPropertyFilterState } from \"../types/LinkedFilterTypes.js\";\nimport { assertUnreachable } from \"../utils/assertUnreachable.js\";\nimport { buildWhereClause } from \"../utils/filterStateToWhereClause.js\";\nimport { filterHasActiveState } from \"../utils/filterValues.js\";\nimport { getFilterKey } from \"../utils/getFilterKey.js\";\n\nexport interface UseFilterListStateResult<Q extends ObjectTypeDefinition> {\n filterStates: Map<string, FilterState>;\n setFilterState: (\n filterKey: string,\n state: FilterState,\n ) => void;\n whereClause: WhereClause<Q>;\n perFilterWhereClauses: Map<string, WhereClause<Q>>;\n activeFilterCount: number;\n reset: () => void;\n}\n\n/**\n * Build initial states from filter definitions.\n * Uses string keys derived from getFilterKey() for stable lookups.\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 key = getFilterKey(definition);\n switch (definition.type) {\n case \"PROPERTY\": {\n const state = definition.filterState;\n if (state) {\n states.set(key, state);\n }\n break;\n }\n case \"HAS_LINK\":\n case \"KEYWORD_SEARCH\":\n case \"CUSTOM\": {\n const state = definition.defaultFilterState;\n if (state) {\n states.set(key, state);\n }\n break;\n }\n case \"LINKED_PROPERTY\": {\n const innerState = definition.defaultLinkedFilterState;\n if (innerState) {\n const state: LinkedPropertyFilterState = {\n type: \"linkedProperty\",\n linkedFilterState: innerState,\n };\n states.set(key, state);\n }\n break;\n }\n default:\n assertUnreachable(definition);\n }\n }\n\n return states;\n}\n\nexport function useFilterListState<Q extends ObjectTypeDefinition>(\n props: FilterListProps<Q>,\n): UseFilterListStateResult<Q> {\n const {\n objectSet,\n filterDefinitions,\n filterOperator = \"and\",\n onFilterStateChanged,\n onFilterClauseChanged,\n initialFilterStates,\n } = props;\n\n const objectType = objectSet.$objectSetInternals.def;\n\n const [filterStates, setFilterStates] = useState<\n Map<string, FilterState>\n >(() => {\n const states = buildInitialStates(filterDefinitions);\n if (initialFilterStates) {\n for (const [key, state] of initialFilterStates) {\n states.set(key, state);\n }\n }\n return states;\n });\n\n const setFilterState = useCallback(\n (filterKey: string, state: FilterState) => {\n let newWhereClause: WhereClause<Q> | undefined;\n\n setFilterStates((prev) => {\n const next = new Map(prev);\n next.set(filterKey, state);\n\n newWhereClause = buildWhereClause(\n filterDefinitions,\n next,\n filterOperator,\n objectType,\n );\n\n return next;\n });\n\n if (newWhereClause !== undefined) {\n onFilterClauseChanged?.(newWhereClause);\n }\n const definition = filterDefinitions?.find(\n (d) => getFilterKey(d) === filterKey,\n );\n if (definition) {\n onFilterStateChanged?.(definition, state);\n }\n },\n [\n filterDefinitions,\n filterOperator,\n objectType,\n onFilterClauseChanged,\n onFilterStateChanged,\n ],\n );\n\n const whereClause = useMemo(\n () =>\n buildWhereClause(\n filterDefinitions,\n filterStates,\n filterOperator,\n objectType,\n ),\n [filterDefinitions, filterStates, filterOperator, objectType],\n );\n\n const perFilterWhereClauses = useMemo(() => {\n const map = new Map<string, WhereClause<Q>>();\n if (!filterDefinitions) {\n return map;\n }\n for (const definition of filterDefinitions) {\n const key = getFilterKey(definition);\n map.set(\n key,\n buildWhereClause(\n filterDefinitions,\n filterStates,\n filterOperator,\n objectType,\n key,\n ),\n );\n }\n return map;\n }, [filterDefinitions, filterStates, filterOperator, objectType]);\n\n const activeFilterCount = useMemo(() => {\n let count = 0;\n for (const state of filterStates.values()) {\n if (filterHasActiveState(state)) {\n count++;\n }\n }\n return count;\n }, [filterStates]);\n\n const reset = useCallback(() => {\n const initialStates = buildInitialStates(filterDefinitions);\n setFilterStates(initialStates);\n\n const newWhereClause = buildWhereClause(\n filterDefinitions,\n initialStates,\n filterOperator,\n objectType,\n );\n onFilterClauseChanged?.(newWhereClause);\n }, [filterDefinitions, filterOperator, objectType, onFilterClauseChanged]);\n\n return useMemo(() => ({\n filterStates,\n setFilterState,\n whereClause,\n perFilterWhereClauses,\n activeFilterCount,\n reset,\n }), [\n filterStates,\n setFilterState,\n whereClause,\n perFilterWhereClauses,\n activeFilterCount,\n reset,\n ]);\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"useFilterListState.js","names":["useOsdkMetadata","useCallback","useMemo","useState","assertUnreachable","buildWhereClause","filterHasActiveState","getFilterKey","buildInitialStates","definitions","states","Map","definition","key","type","state","filterState","set","defaultFilterState","innerState","defaultLinkedFilterState","linkedFilterState","useFilterListState","props","objectSet","filterDefinitions","filterOperator","onFilterStateChanged","onFilterClauseChanged","initialFilterStates","objectType","$objectSetInternals","def","metadata","propertyTypes","map","properties","prop","Object","entries","multiplicity","filterStates","setFilterStates","setFilterState","filterKey","newWhereClause","prev","next","undefined","find","d","whereClause","perFilterWhereClauses","activeFilterCount","count","values","reset","initialStates"],"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 { ObjectTypeDefinition, WhereClause } from \"@osdk/api\";\nimport { useOsdkMetadata } from \"@osdk/react\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport type { FilterListProps } from \"../FilterListApi.js\";\nimport type { FilterState } from \"../FilterListItemApi.js\";\nimport type { LinkedPropertyFilterState } from \"../types/LinkedFilterTypes.js\";\nimport { assertUnreachable } from \"../utils/assertUnreachable.js\";\nimport {\n buildWhereClause,\n type PropertyTypeInfo,\n} from \"../utils/filterStateToWhereClause.js\";\nimport { filterHasActiveState } from \"../utils/filterValues.js\";\nimport { getFilterKey } from \"../utils/getFilterKey.js\";\n\nexport interface UseFilterListStateResult<Q extends ObjectTypeDefinition> {\n filterStates: Map<string, FilterState>;\n setFilterState: (\n filterKey: string,\n state: FilterState,\n ) => void;\n whereClause: WhereClause<Q>;\n perFilterWhereClauses: Map<string, WhereClause<Q>>;\n activeFilterCount: number;\n reset: () => void;\n}\n\n/**\n * Build initial states from filter definitions.\n * Uses string keys derived from getFilterKey() for stable lookups.\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 key = getFilterKey(definition);\n switch (definition.type) {\n case \"PROPERTY\": {\n const state = definition.filterState;\n if (state) {\n states.set(key, state);\n }\n break;\n }\n case \"HAS_LINK\":\n case \"KEYWORD_SEARCH\":\n case \"CUSTOM\": {\n const state = definition.defaultFilterState;\n if (state) {\n states.set(key, state);\n }\n break;\n }\n case \"LINKED_PROPERTY\": {\n const innerState = definition.defaultLinkedFilterState;\n if (innerState) {\n const state: LinkedPropertyFilterState = {\n type: \"linkedProperty\",\n linkedFilterState: innerState,\n };\n states.set(key, state);\n }\n break;\n }\n default:\n assertUnreachable(definition);\n }\n }\n\n return states;\n}\n\nexport function useFilterListState<Q extends ObjectTypeDefinition>(\n props: FilterListProps<Q>,\n): UseFilterListStateResult<Q> {\n const {\n objectSet,\n filterDefinitions,\n filterOperator = \"and\",\n onFilterStateChanged,\n onFilterClauseChanged,\n initialFilterStates,\n } = props;\n\n const objectType = objectSet.$objectSetInternals.def;\n const { metadata } = useOsdkMetadata(objectType);\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 const [filterStates, setFilterStates] = useState<\n Map<string, FilterState>\n >(() => {\n const states = buildInitialStates(filterDefinitions);\n if (initialFilterStates) {\n for (const [key, state] of initialFilterStates) {\n states.set(key, state);\n }\n }\n return states;\n });\n\n const setFilterState = useCallback(\n (filterKey: string, state: FilterState) => {\n let newWhereClause: WhereClause<Q> | undefined;\n\n setFilterStates((prev) => {\n const next = new Map(prev);\n next.set(filterKey, state);\n\n newWhereClause = buildWhereClause(\n filterDefinitions,\n next,\n filterOperator,\n propertyTypes,\n );\n\n return next;\n });\n\n if (newWhereClause !== undefined) {\n onFilterClauseChanged?.(newWhereClause);\n }\n const definition = filterDefinitions?.find(\n (d) => getFilterKey(d) === filterKey,\n );\n if (definition) {\n onFilterStateChanged?.(definition, state);\n }\n },\n [\n filterDefinitions,\n filterOperator,\n propertyTypes,\n onFilterClauseChanged,\n onFilterStateChanged,\n ],\n );\n\n const whereClause = useMemo(\n () =>\n buildWhereClause(\n filterDefinitions,\n filterStates,\n filterOperator,\n propertyTypes,\n ),\n [filterDefinitions, filterStates, filterOperator, propertyTypes],\n );\n\n const perFilterWhereClauses = useMemo(() => {\n const map = new Map<string, WhereClause<Q>>();\n if (!filterDefinitions) {\n return map;\n }\n for (const definition of filterDefinitions) {\n const key = getFilterKey(definition);\n map.set(\n key,\n buildWhereClause(\n filterDefinitions,\n filterStates,\n filterOperator,\n propertyTypes,\n key,\n ),\n );\n }\n return map;\n }, [filterDefinitions, filterStates, filterOperator, propertyTypes]);\n\n const activeFilterCount = useMemo(() => {\n let count = 0;\n for (const state of filterStates.values()) {\n if (filterHasActiveState(state)) {\n count++;\n }\n }\n return count;\n }, [filterStates]);\n\n const reset = useCallback(() => {\n const initialStates = buildInitialStates(filterDefinitions);\n setFilterStates(initialStates);\n\n const newWhereClause = buildWhereClause(\n filterDefinitions,\n initialStates,\n filterOperator,\n propertyTypes,\n );\n onFilterClauseChanged?.(newWhereClause);\n }, [filterDefinitions, filterOperator, propertyTypes, onFilterClauseChanged]);\n\n return useMemo(() => ({\n filterStates,\n setFilterState,\n whereClause,\n perFilterWhereClauses,\n activeFilterCount,\n reset,\n }), [\n filterStates,\n setFilterState,\n whereClause,\n perFilterWhereClauses,\n activeFilterCount,\n reset,\n ]);\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -14,12 +14,5 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
* Exhaustive type checking helper.
|
|
19
|
-
* Use in default cases of switch statements to ensure all cases are handled.
|
|
20
|
-
* TypeScript will error if a case is missing.
|
|
21
|
-
*/
|
|
22
|
-
export function assertUnreachable(value) {
|
|
23
|
-
throw new Error(`Unhandled value: ${String(value)}`);
|
|
24
|
-
}
|
|
17
|
+
export { assertUnreachable } from "../../shared/assertUnreachable.js";
|
|
25
18
|
//# sourceMappingURL=assertUnreachable.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assertUnreachable.js","names":["assertUnreachable"
|
|
1
|
+
{"version":3,"file":"assertUnreachable.js","names":["assertUnreachable"],"sources":["assertUnreachable.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 { assertUnreachable } from \"../../shared/assertUnreachable.js\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB,QAAQ,mCAAmC","ignoreList":[]}
|
|
@@ -14,24 +14,56 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import { formatDateForInput } from "../base/inputs/dateUtils.js";
|
|
17
18
|
import { assertUnreachable } from "./assertUnreachable.js";
|
|
18
19
|
import { getFilterKey } from "./getFilterKey.js";
|
|
19
|
-
function
|
|
20
|
+
function isCompoundFilter(f) {
|
|
21
|
+
return typeof f === "object" && f != null && "__compound" in f;
|
|
22
|
+
}
|
|
23
|
+
const NUMERIC_BOUNDS = {
|
|
24
|
+
byte: {
|
|
25
|
+
min: -128,
|
|
26
|
+
max: 127
|
|
27
|
+
},
|
|
28
|
+
short: {
|
|
29
|
+
min: -32_768,
|
|
30
|
+
max: 32_767
|
|
31
|
+
},
|
|
32
|
+
integer: {
|
|
33
|
+
min: -2_147_483_648,
|
|
34
|
+
max: 2_147_483_647
|
|
35
|
+
},
|
|
36
|
+
long: {
|
|
37
|
+
min: Number.MIN_SAFE_INTEGER,
|
|
38
|
+
max: Number.MAX_SAFE_INTEGER
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
function clampToPropertyBounds(value, propertyType) {
|
|
42
|
+
if (propertyType === undefined) {
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
const bounds = NUMERIC_BOUNDS[propertyType];
|
|
46
|
+
if (bounds === undefined) {
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
return Math.max(bounds.min, Math.min(bounds.max, value));
|
|
50
|
+
}
|
|
51
|
+
function formatDateValue(date, propertyType) {
|
|
52
|
+
if (propertyType === "datetime") {
|
|
53
|
+
return formatDateForInput(date);
|
|
54
|
+
}
|
|
55
|
+
return date.toISOString();
|
|
56
|
+
}
|
|
57
|
+
function filterStateToPropertyFilter(state, propertyType) {
|
|
20
58
|
switch (state.type) {
|
|
21
59
|
case "CONTAINS_TEXT":
|
|
22
60
|
{
|
|
23
61
|
if (!state.value) {
|
|
24
62
|
return undefined;
|
|
25
63
|
}
|
|
26
|
-
|
|
64
|
+
return {
|
|
27
65
|
$containsAnyTerm: state.value
|
|
28
66
|
};
|
|
29
|
-
if (state.isExcluding) {
|
|
30
|
-
return {
|
|
31
|
-
$not: filter
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
return filter;
|
|
35
67
|
}
|
|
36
68
|
case "TOGGLE":
|
|
37
69
|
{
|
|
@@ -42,138 +74,104 @@ function filterStateToPropertyFilter(state) {
|
|
|
42
74
|
const conditions = [];
|
|
43
75
|
if (state.minValue !== undefined) {
|
|
44
76
|
conditions.push({
|
|
45
|
-
$gte: state.minValue
|
|
77
|
+
$gte: formatDateValue(state.minValue, propertyType)
|
|
46
78
|
});
|
|
47
79
|
}
|
|
48
80
|
if (state.maxValue !== undefined) {
|
|
49
81
|
conditions.push({
|
|
50
|
-
$lte: state.maxValue
|
|
82
|
+
$lte: formatDateValue(state.maxValue, propertyType)
|
|
51
83
|
});
|
|
52
84
|
}
|
|
53
85
|
if (conditions.length === 0 && !state.includeNull) {
|
|
54
86
|
return undefined;
|
|
55
87
|
}
|
|
56
|
-
|
|
57
|
-
if (conditions.length === 1) {
|
|
58
|
-
rangeFilter = conditions[0];
|
|
59
|
-
} else if (conditions.length > 1) {
|
|
60
|
-
rangeFilter = {
|
|
61
|
-
$and: conditions
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
if (state.includeNull) {
|
|
65
|
-
if (rangeFilter) {
|
|
66
|
-
return {
|
|
67
|
-
$or: [rangeFilter, {
|
|
68
|
-
$isNull: true
|
|
69
|
-
}]
|
|
70
|
-
};
|
|
71
|
-
}
|
|
88
|
+
if (conditions.length === 0 && state.includeNull) {
|
|
72
89
|
return {
|
|
73
90
|
$isNull: true
|
|
74
91
|
};
|
|
75
92
|
}
|
|
76
|
-
|
|
93
|
+
if (conditions.length === 1 && !state.includeNull) {
|
|
94
|
+
return conditions[0];
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
__compound: true,
|
|
98
|
+
conditions,
|
|
99
|
+
includeNull: state.includeNull ?? false
|
|
100
|
+
};
|
|
77
101
|
}
|
|
78
102
|
case "NUMBER_RANGE":
|
|
79
103
|
{
|
|
80
104
|
const conditions = [];
|
|
81
105
|
if (state.minValue !== undefined) {
|
|
82
106
|
conditions.push({
|
|
83
|
-
$gte: state.minValue
|
|
107
|
+
$gte: clampToPropertyBounds(state.minValue, propertyType)
|
|
84
108
|
});
|
|
85
109
|
}
|
|
86
110
|
if (state.maxValue !== undefined) {
|
|
87
111
|
conditions.push({
|
|
88
|
-
$lte: state.maxValue
|
|
112
|
+
$lte: clampToPropertyBounds(state.maxValue, propertyType)
|
|
89
113
|
});
|
|
90
114
|
}
|
|
91
115
|
if (conditions.length === 0 && !state.includeNull) {
|
|
92
116
|
return undefined;
|
|
93
117
|
}
|
|
94
|
-
|
|
95
|
-
if (conditions.length === 1) {
|
|
96
|
-
rangeFilter = conditions[0];
|
|
97
|
-
} else if (conditions.length > 1) {
|
|
98
|
-
rangeFilter = {
|
|
99
|
-
$and: conditions
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
if (state.includeNull) {
|
|
103
|
-
if (rangeFilter) {
|
|
104
|
-
return {
|
|
105
|
-
$or: [rangeFilter, {
|
|
106
|
-
$isNull: true
|
|
107
|
-
}]
|
|
108
|
-
};
|
|
109
|
-
}
|
|
118
|
+
if (conditions.length === 0 && state.includeNull) {
|
|
110
119
|
return {
|
|
111
120
|
$isNull: true
|
|
112
121
|
};
|
|
113
122
|
}
|
|
114
|
-
|
|
123
|
+
if (conditions.length === 1 && !state.includeNull) {
|
|
124
|
+
return conditions[0];
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
__compound: true,
|
|
128
|
+
conditions,
|
|
129
|
+
includeNull: state.includeNull ?? false
|
|
130
|
+
};
|
|
115
131
|
}
|
|
116
132
|
case "EXACT_MATCH":
|
|
117
133
|
{
|
|
118
134
|
if (state.values.length === 0) {
|
|
119
135
|
return undefined;
|
|
120
136
|
}
|
|
121
|
-
|
|
137
|
+
return state.values.length === 1 ? state.values[0] : {
|
|
122
138
|
$in: state.values
|
|
123
139
|
};
|
|
124
|
-
if (state.isExcluding) {
|
|
125
|
-
return {
|
|
126
|
-
$not: filter
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
return filter;
|
|
130
140
|
}
|
|
131
141
|
case "SELECT":
|
|
132
142
|
{
|
|
133
143
|
if (state.selectedValues.length === 0) {
|
|
134
144
|
return undefined;
|
|
135
145
|
}
|
|
136
|
-
const values = state.selectedValues.map(v => v instanceof Date ? v
|
|
137
|
-
|
|
146
|
+
const values = state.selectedValues.map(v => v instanceof Date ? formatDateValue(v, propertyType) : v);
|
|
147
|
+
return values.length === 1 ? values[0] : {
|
|
138
148
|
$in: values
|
|
139
149
|
};
|
|
140
|
-
if (state.isExcluding) {
|
|
141
|
-
return {
|
|
142
|
-
$not: filter
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
return filter;
|
|
146
150
|
}
|
|
147
151
|
case "TIMELINE":
|
|
148
152
|
{
|
|
149
153
|
const conditions = [];
|
|
150
154
|
if (state.startDate !== undefined) {
|
|
151
155
|
conditions.push({
|
|
152
|
-
$gte: state.startDate
|
|
156
|
+
$gte: formatDateValue(state.startDate, propertyType)
|
|
153
157
|
});
|
|
154
158
|
}
|
|
155
159
|
if (state.endDate !== undefined) {
|
|
156
160
|
conditions.push({
|
|
157
|
-
$lte: state.endDate
|
|
161
|
+
$lte: formatDateValue(state.endDate, propertyType)
|
|
158
162
|
});
|
|
159
163
|
}
|
|
160
164
|
if (conditions.length === 0) {
|
|
161
165
|
return undefined;
|
|
162
166
|
}
|
|
163
|
-
let rangeFilter;
|
|
164
167
|
if (conditions.length === 1) {
|
|
165
|
-
|
|
166
|
-
} else {
|
|
167
|
-
rangeFilter = {
|
|
168
|
-
$and: conditions
|
|
169
|
-
};
|
|
168
|
+
return conditions[0];
|
|
170
169
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
return rangeFilter;
|
|
170
|
+
return {
|
|
171
|
+
__compound: true,
|
|
172
|
+
conditions,
|
|
173
|
+
includeNull: false
|
|
174
|
+
};
|
|
177
175
|
}
|
|
178
176
|
|
|
179
177
|
// These filter types are handled separately in buildWhereClause
|
|
@@ -200,7 +198,8 @@ function filterStateToPropertyFilter(state) {
|
|
|
200
198
|
* cannot verify that the constructed clause structure matches the generic Q's
|
|
201
199
|
* expected shape, but the structure is guaranteed to be valid by construction.
|
|
202
200
|
*/
|
|
203
|
-
|
|
201
|
+
|
|
202
|
+
export function buildWhereClause(definitions, filterStates, operator, propertyTypes, excludeFilterKey) {
|
|
204
203
|
if (!definitions || definitions.length === 0) {
|
|
205
204
|
return {};
|
|
206
205
|
}
|
|
@@ -217,11 +216,37 @@ export function buildWhereClause(definitions, filterStates, operator, objectType
|
|
|
217
216
|
switch (definition.type) {
|
|
218
217
|
case "PROPERTY":
|
|
219
218
|
{
|
|
220
|
-
const
|
|
219
|
+
const propertyType = propertyTypes?.get(definition.key)?.type;
|
|
220
|
+
const filter = filterStateToPropertyFilter(state, propertyType);
|
|
221
221
|
if (filter !== undefined) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
const isExcluding = "isExcluding" in state && state.isExcluding;
|
|
223
|
+
if (isCompoundFilter(filter)) {
|
|
224
|
+
const fieldClauses = filter.conditions.map(c => ({
|
|
225
|
+
[definition.key]: c
|
|
226
|
+
}));
|
|
227
|
+
let rangeClause = fieldClauses.length === 1 ? fieldClauses[0] : {
|
|
228
|
+
$and: fieldClauses
|
|
229
|
+
};
|
|
230
|
+
if (filter.includeNull) {
|
|
231
|
+
rangeClause = {
|
|
232
|
+
$or: [rangeClause, {
|
|
233
|
+
[definition.key]: {
|
|
234
|
+
$isNull: true
|
|
235
|
+
}
|
|
236
|
+
}]
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
clauses.push(isExcluding ? {
|
|
240
|
+
$not: rangeClause
|
|
241
|
+
} : rangeClause);
|
|
242
|
+
} else {
|
|
243
|
+
const clause = {
|
|
244
|
+
[definition.key]: filter
|
|
245
|
+
};
|
|
246
|
+
clauses.push(isExcluding ? {
|
|
247
|
+
$not: clause
|
|
248
|
+
} : clause);
|
|
249
|
+
}
|
|
225
250
|
}
|
|
226
251
|
break;
|
|
227
252
|
}
|
|
@@ -273,12 +298,17 @@ export function buildWhereClause(definitions, filterStates, operator, objectType
|
|
|
273
298
|
const properties = definition.properties;
|
|
274
299
|
let propertiesToSearch;
|
|
275
300
|
if (properties === "all") {
|
|
276
|
-
if (
|
|
277
|
-
propertiesToSearch =
|
|
301
|
+
if (propertyTypes && propertyTypes.size > 0) {
|
|
302
|
+
propertiesToSearch = [];
|
|
303
|
+
for (const [key, info] of propertyTypes) {
|
|
304
|
+
if (info.type === "string" && !info.multiplicity) {
|
|
305
|
+
propertiesToSearch.push(key);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
278
308
|
} else {
|
|
279
309
|
if (process.env.NODE_ENV !== "production") {
|
|
280
310
|
// eslint-disable-next-line no-console
|
|
281
|
-
console.warn("[FilterList] Keyword search with properties: 'all' requires
|
|
311
|
+
console.warn("[FilterList] Keyword search with properties: 'all' requires propertyTypes to be provided. Filter will be skipped.");
|
|
282
312
|
}
|
|
283
313
|
break;
|
|
284
314
|
}
|
|
@@ -290,21 +320,21 @@ export function buildWhereClause(definitions, filterStates, operator, objectType
|
|
|
290
320
|
}
|
|
291
321
|
const containsOp = state.operator === "AND" ? "$containsAllTerms" : "$containsAnyTerm";
|
|
292
322
|
const propertySearches = propertiesToSearch.map(prop => ({
|
|
293
|
-
[prop]:
|
|
294
|
-
$not: {
|
|
295
|
-
[containsOp]: searchTerm
|
|
296
|
-
}
|
|
297
|
-
} : {
|
|
323
|
+
[prop]: {
|
|
298
324
|
[containsOp]: searchTerm
|
|
299
325
|
}
|
|
300
326
|
}));
|
|
327
|
+
let searchClause;
|
|
301
328
|
if (propertySearches.length === 1) {
|
|
302
|
-
|
|
329
|
+
searchClause = propertySearches[0];
|
|
303
330
|
} else {
|
|
304
|
-
|
|
331
|
+
searchClause = {
|
|
305
332
|
$or: propertySearches
|
|
306
|
-
}
|
|
333
|
+
};
|
|
307
334
|
}
|
|
335
|
+
clauses.push(state.isExcluding ? {
|
|
336
|
+
$not: searchClause
|
|
337
|
+
} : searchClause);
|
|
308
338
|
break;
|
|
309
339
|
}
|
|
310
340
|
case "CUSTOM":
|