synapse-react-client 4.0.38 → 4.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SWC.index.js +1 -1
- package/dist/aridhia-queries/useAridhiaQuery.d.ts +6 -2
- package/dist/aridhia-queries/useAridhiaQuery.d.ts.map +1 -1
- package/dist/aridhia-queries/useAridhiaQuery.js +3 -0
- package/dist/aridhia-queries/useAridhiaQuery.js.map +1 -1
- package/dist/components/Aridhia/AridhiaAccessStatus.d.ts +2 -1
- package/dist/components/Aridhia/AridhiaAccessStatus.d.ts.map +1 -1
- package/dist/components/Aridhia/AridhiaAccessStatus.js +60 -37
- package/dist/components/Aridhia/AridhiaAccessStatus.js.map +1 -1
- package/dist/components/Aridhia/AridhiaDarStatusPopover.d.ts +12 -0
- package/dist/components/Aridhia/AridhiaDarStatusPopover.d.ts.map +1 -0
- package/dist/components/Aridhia/AridhiaDarStatusPopover.js +56 -0
- package/dist/components/Aridhia/AridhiaDarStatusPopover.js.map +1 -0
- package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.d.ts.map +1 -1
- package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.js +38 -30
- package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.js.map +1 -1
- package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.js +15 -14
- package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.js.map +1 -1
- package/dist/components/Aridhia/RdcaDapEligibilityDialog.d.ts +11 -0
- package/dist/components/Aridhia/RdcaDapEligibilityDialog.d.ts.map +1 -0
- package/dist/components/Aridhia/RdcaDapEligibilityDialog.js +37 -0
- package/dist/components/Aridhia/RdcaDapEligibilityDialog.js.map +1 -0
- package/dist/components/Aridhia/aridhiaAccessStatusUtils.js +2 -2
- package/dist/components/Aridhia/aridhiaAccessStatusUtils.js.map +1 -1
- package/dist/components/Aridhia/aridhiaFairPortalUrls.d.ts +10 -0
- package/dist/components/Aridhia/aridhiaFairPortalUrls.d.ts.map +1 -0
- package/dist/components/Aridhia/aridhiaFairPortalUrls.js +11 -0
- package/dist/components/Aridhia/aridhiaFairPortalUrls.js.map +1 -0
- package/dist/components/Aridhia/rdcaDapConstants.d.ts +3 -0
- package/dist/components/Aridhia/rdcaDapConstants.d.ts.map +1 -0
- package/dist/components/Aridhia/rdcaDapConstants.js +6 -0
- package/dist/components/Aridhia/rdcaDapConstants.js.map +1 -0
- package/dist/components/DataExplorer/DataExplorer.css +1 -1
- package/dist/components/DataExplorer/DataExplorer.d.ts.map +1 -1
- package/dist/components/DataExplorer/DataExplorer.js +50 -50
- package/dist/components/DataExplorer/DataExplorer.js.map +1 -1
- package/dist/components/DataExplorer/DataExplorer.module.js +16 -16
- package/dist/components/DataExplorer/DataExplorer.module.js.map +1 -1
- package/dist/components/DataExplorer/DataExplorer.module.scss +29 -6
- package/dist/components/DataGrid/columns/DateTimeColumn.d.ts +16 -7
- package/dist/components/DataGrid/columns/DateTimeColumn.d.ts.map +1 -1
- package/dist/components/DataGrid/columns/DateTimeColumn.js +79 -57
- package/dist/components/DataGrid/columns/DateTimeColumn.js.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.d.ts.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.js +11 -8
- package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
- package/dist/components/DatePicker/DatePicker.d.ts +10 -0
- package/dist/components/DatePicker/DatePicker.d.ts.map +1 -0
- package/dist/components/DatePicker/DatePicker.js +18 -0
- package/dist/components/DatePicker/DatePicker.js.map +1 -0
- package/dist/components/EntityCitation/EntityCitation.d.ts.map +1 -1
- package/dist/components/EntityCitation/EntityCitation.js +8 -5
- package/dist/components/EntityCitation/EntityCitation.js.map +1 -1
- package/dist/components/HasAccess/AccessIcon.d.ts +3 -1
- package/dist/components/HasAccess/AccessIcon.d.ts.map +1 -1
- package/dist/components/HasAccess/AccessIcon.js +11 -1
- package/dist/components/HasAccess/AccessIcon.js.map +1 -1
- package/dist/components/PortalHomePageHeader/PortalHomePageHeader.d.ts +2 -1
- package/dist/components/PortalHomePageHeader/PortalHomePageHeader.d.ts.map +1 -1
- package/dist/components/PortalHomePageHeader/PortalHomePageHeader.js +81 -53
- package/dist/components/PortalHomePageHeader/PortalHomePageHeader.js.map +1 -1
- package/dist/components/ProjectInfo/ProjectInfo.d.ts.map +1 -1
- package/dist/components/ProjectInfo/ProjectInfo.js +3 -2
- package/dist/components/ProjectInfo/ProjectInfo.js.map +1 -1
- package/dist/components/QueryBuilder/FilterConditionRow.css +1 -0
- package/dist/components/QueryBuilder/FilterConditionRow.d.ts +6 -0
- package/dist/components/QueryBuilder/FilterConditionRow.d.ts.map +1 -0
- package/dist/components/QueryBuilder/FilterConditionRow.js +257 -0
- package/dist/components/QueryBuilder/FilterConditionRow.js.map +1 -0
- package/dist/components/QueryBuilder/FilterConditionRow.module.js +17 -0
- package/dist/components/QueryBuilder/FilterConditionRow.module.js.map +1 -0
- package/dist/components/QueryBuilder/FilterConditionRow.module.scss +106 -0
- package/dist/components/QueryBuilder/FilterGroupNode.css +1 -0
- package/dist/components/QueryBuilder/FilterGroupNode.d.ts +7 -0
- package/dist/components/QueryBuilder/FilterGroupNode.d.ts.map +1 -0
- package/dist/components/QueryBuilder/FilterGroupNode.js +100 -0
- package/dist/components/QueryBuilder/FilterGroupNode.js.map +1 -0
- package/dist/components/QueryBuilder/FilterGroupNode.module.js +15 -0
- package/dist/components/QueryBuilder/FilterGroupNode.module.js.map +1 -0
- package/dist/components/QueryBuilder/FilterGroupNode.module.scss +83 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.css +1 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.d.ts +21 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.d.ts.map +1 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.js +138 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.js.map +1 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.module.js +17 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.module.js.map +1 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.module.scss +79 -0
- package/dist/components/QueryBuilder/QueryBuilderInternalContext.d.ts +39 -0
- package/dist/components/QueryBuilder/QueryBuilderInternalContext.d.ts.map +1 -0
- package/dist/components/QueryBuilder/QueryBuilderInternalContext.js +19 -0
- package/dist/components/QueryBuilder/QueryBuilderInternalContext.js.map +1 -0
- package/dist/components/QueryBuilder/qbTreeToReadable.d.ts +14 -0
- package/dist/components/QueryBuilder/qbTreeToReadable.d.ts.map +1 -0
- package/dist/components/QueryBuilder/qbTreeToReadable.js +89 -0
- package/dist/components/QueryBuilder/qbTreeToReadable.js.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderId.d.ts +2 -0
- package/dist/components/QueryBuilder/queryBuilderId.d.ts.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderId.js +9 -0
- package/dist/components/QueryBuilder/queryBuilderId.js.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderMetadata.d.ts +24 -0
- package/dist/components/QueryBuilder/queryBuilderMetadata.d.ts.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderMetadata.js +91 -0
- package/dist/components/QueryBuilder/queryBuilderMetadata.js.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderOperations.d.ts +58 -0
- package/dist/components/QueryBuilder/queryBuilderOperations.d.ts.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderOperations.js +200 -0
- package/dist/components/QueryBuilder/queryBuilderOperations.js.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderTranslation.d.ts +3 -2
- package/dist/components/QueryBuilder/queryBuilderTranslation.d.ts.map +1 -1
- package/dist/components/QueryBuilder/queryBuilderTranslation.js +82 -84
- package/dist/components/QueryBuilder/queryBuilderTranslation.js.map +1 -1
- package/dist/components/QueryBuilder/useQBCombinedSql.d.ts +11 -0
- package/dist/components/QueryBuilder/useQBCombinedSql.d.ts.map +1 -0
- package/dist/components/QueryBuilder/useQBCombinedSql.js +29 -0
- package/dist/components/QueryBuilder/useQBCombinedSql.js.map +1 -0
- package/dist/components/QueryBuilder/useQBFacetSourceMetadata.d.ts +18 -0
- package/dist/components/QueryBuilder/useQBFacetSourceMetadata.d.ts.map +1 -0
- package/dist/components/QueryBuilder/useQBFacetSourceMetadata.js +27 -0
- package/dist/components/QueryBuilder/useQBFacetSourceMetadata.js.map +1 -0
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts +14 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js +185 -120
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
- package/dist/components/RssFeedCards/RssFeedCards.d.ts +1 -0
- package/dist/components/RssFeedCards/RssFeedCards.d.ts.map +1 -1
- package/dist/components/RssFeedCards/RssFeedCards.js +11 -11
- package/dist/components/RssFeedCards/RssFeedCards.js.map +1 -1
- package/dist/components/SynapseChat/SynapseChat.d.ts +7 -1
- package/dist/components/SynapseChat/SynapseChat.d.ts.map +1 -1
- package/dist/components/SynapseChat/SynapseChat.js +76 -71
- package/dist/components/SynapseChat/SynapseChat.js.map +1 -1
- package/dist/components/SynapseChat/SynapsePortalChatDialog.d.ts +3 -1
- package/dist/components/SynapseChat/SynapsePortalChatDialog.d.ts.map +1 -1
- package/dist/components/SynapseChat/SynapsePortalChatDialog.js +24 -13
- package/dist/components/SynapseChat/SynapsePortalChatDialog.js.map +1 -1
- package/dist/components/SynapseChat/portalChatSessionStorage.d.ts +23 -0
- package/dist/components/SynapseChat/portalChatSessionStorage.d.ts.map +1 -0
- package/dist/components/SynapseChat/portalChatSessionStorage.js +29 -0
- package/dist/components/SynapseChat/portalChatSessionStorage.js.map +1 -0
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.d.ts +6 -0
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.d.ts.map +1 -1
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.js +92 -79
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.js.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.d.ts +3 -4
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.d.ts.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js +2 -2
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.js +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.js.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.d.ts.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.js +9 -2
- package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
- package/dist/components/entity/page/title_bar/EntityPageTitleBar.js +1 -1
- package/dist/components/entity/page/title_bar/EntityPageTitleBar.js.map +1 -1
- package/dist/components/menu/ComplexMenu.js +1 -1
- package/dist/components/menu/ComplexMenu.js.map +1 -1
- package/dist/components/menu/DropdownMenu.d.ts.map +1 -1
- package/dist/components/menu/DropdownMenu.js +4 -0
- package/dist/components/menu/DropdownMenu.js.map +1 -1
- package/dist/features/entity/metadata-task/hooks/useMarkCurationTaskInProgress.d.ts +10 -0
- package/dist/features/entity/metadata-task/hooks/useMarkCurationTaskInProgress.d.ts.map +1 -0
- package/dist/features/entity/metadata-task/hooks/useMarkCurationTaskInProgress.js +20 -0
- package/dist/features/entity/metadata-task/hooks/useMarkCurationTaskInProgress.js.map +1 -0
- package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.js +29 -20
- package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.js.map +1 -1
- package/dist/mocks/accessRequirement/mockFormTemplates.d.ts +16 -0
- package/dist/mocks/accessRequirement/mockFormTemplates.d.ts.map +1 -0
- package/dist/mocks/accessRequirement/mockFormTemplates.js +70 -0
- package/dist/mocks/accessRequirement/mockFormTemplates.js.map +1 -0
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.d.ts +7 -0
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.d.ts.map +1 -0
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.js +47 -0
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.js.map +1 -0
- package/dist/mocks/accessRequirement/mockJsonSchemas.d.ts +24 -0
- package/dist/mocks/accessRequirement/mockJsonSchemas.d.ts.map +1 -0
- package/dist/mocks/accessRequirement/mockJsonSchemas.js +62 -0
- package/dist/mocks/accessRequirement/mockJsonSchemas.js.map +1 -0
- package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts +18 -1
- package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/aridhiaHandlers.js +39 -33
- package/dist/mocks/msw/handlers/aridhiaHandlers.js.map +1 -1
- package/dist/mocks/msw/handlers/formTemplateHandlers.d.ts +5 -0
- package/dist/mocks/msw/handlers/formTemplateHandlers.d.ts.map +1 -0
- package/dist/mocks/msw/handlers/formTemplateHandlers.js +65 -0
- package/dist/mocks/msw/handlers/formTemplateHandlers.js.map +1 -0
- package/dist/mocks/msw/handlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers.js +49 -47
- package/dist/mocks/msw/handlers.js.map +1 -1
- package/dist/style/abstracts/_cssVariables.scss +7 -0
- package/dist/style/components/_query-wrapper-plot-nav.scss +9 -0
- package/dist/style/main.css +1 -1
- package/dist/synapse-queries/KeyFactory.d.ts +6 -1
- package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
- package/dist/synapse-queries/KeyFactory.js +17 -2
- package/dist/synapse-queries/KeyFactory.js.map +1 -1
- package/dist/synapse-queries/chat/useChat.d.ts.map +1 -1
- package/dist/synapse-queries/chat/useChat.js +2 -4
- package/dist/synapse-queries/chat/useChat.js.map +1 -1
- package/dist/synapse-queries/dataaccess/index.d.ts +2 -0
- package/dist/synapse-queries/dataaccess/index.d.ts.map +1 -1
- package/dist/synapse-queries/dataaccess/index.js +5 -3
- package/dist/synapse-queries/dataaccess/useFormTemplate.d.ts +41 -0
- package/dist/synapse-queries/dataaccess/useFormTemplate.d.ts.map +1 -0
- package/dist/synapse-queries/dataaccess/useFormTemplate.js +63 -0
- package/dist/synapse-queries/dataaccess/useFormTemplate.js.map +1 -0
- package/dist/synapse-queries/dataaccess/useGenerateDataAccessSchema.d.ts +21 -0
- package/dist/synapse-queries/dataaccess/useGenerateDataAccessSchema.d.ts.map +1 -0
- package/dist/synapse-queries/dataaccess/useGenerateDataAccessSchema.js +34 -0
- package/dist/synapse-queries/dataaccess/useGenerateDataAccessSchema.js.map +1 -0
- package/dist/synapse-queries/index.js +190 -180
- package/dist/testutils/ReactQueryMockUtils.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/featureflag/FeatureFlags.d.ts +0 -1
- package/dist/utils/featureflag/FeatureFlags.d.ts.map +1 -1
- package/dist/utils/featureflag/FeatureFlags.js +1 -1
- package/dist/utils/featureflag/FeatureFlags.js.map +1 -1
- package/dist/utils/jsonschema/getType.d.ts.map +1 -1
- package/dist/utils/jsonschema/getType.js +4 -1
- package/dist/utils/jsonschema/getType.js.map +1 -1
- package/package.json +7 -7
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { isColumnMultiValueFunctionQueryFilter as e, isColumnSingleValueQueryFilter as t, isFacetColumnRangeRequest as n, isFacetColumnValuesRequest as r, isFilterGroup as i } from "../../utils/types/IsType.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { newQBNodeId as a } from "./queryBuilderId.js";
|
|
3
|
+
import { isQBGroup as o } from "./QueryBuilderTypes.js";
|
|
4
|
+
import { ColumnMultiValueFunction as s, ColumnSingleValueFilterOperator as c, FILTER_GROUP_CONCRETE_TYPE_VALUE as l } from "@sage-bionetworks/synapse-types";
|
|
4
5
|
//#region src/components/QueryBuilder/queryBuilderTranslation.ts
|
|
5
|
-
var
|
|
6
|
-
function
|
|
6
|
+
var u = "org.sagebionetworks.repo.model.table.ColumnSingleValueQueryFilter", d = "org.sagebionetworks.repo.model.table.ColumnMultiValueFunctionQueryFilter";
|
|
7
|
+
function f(e) {
|
|
7
8
|
return e?.endsWith("_LIST") ?? !1;
|
|
8
9
|
}
|
|
9
|
-
function
|
|
10
|
+
function p(e) {
|
|
10
11
|
return e.replace(/[\\%_]/g, (e) => "\\" + e);
|
|
11
12
|
}
|
|
12
|
-
function
|
|
13
|
+
function m(e) {
|
|
13
14
|
return e.replace(/\\([\\%_])/g, "$1");
|
|
14
15
|
}
|
|
15
|
-
function
|
|
16
|
-
let t = e.startsWith("%"), n = /(?<!\\)%$/.test(e), r =
|
|
16
|
+
function h(e) {
|
|
17
|
+
let t = e.startsWith("%"), n = /(?<!\\)%$/.test(e), r = m(e.slice(+!!t, n ? -1 : void 0));
|
|
17
18
|
return t && n ? {
|
|
18
19
|
op: "contains",
|
|
19
20
|
text: r
|
|
@@ -28,89 +29,89 @@ function m(e) {
|
|
|
28
29
|
text: r
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
|
-
function
|
|
32
|
-
if (
|
|
33
|
-
let t = e.children.map(
|
|
32
|
+
function g(e) {
|
|
33
|
+
if (o(e)) {
|
|
34
|
+
let t = e.children.map(g).filter((e) => e !== null);
|
|
34
35
|
return t.length === 0 ? null : {
|
|
35
|
-
concreteType:
|
|
36
|
+
concreteType: l,
|
|
36
37
|
operator: e.combinator,
|
|
37
38
|
not: e.not || void 0,
|
|
38
39
|
children: t
|
|
39
40
|
};
|
|
40
41
|
}
|
|
41
|
-
return
|
|
42
|
+
return _(e);
|
|
42
43
|
}
|
|
43
|
-
function
|
|
44
|
-
let { columnName: t, columnType: n, op: r, values: i, rangeMin: a, rangeMax: o, text:
|
|
44
|
+
function _(e) {
|
|
45
|
+
let { columnName: t, columnType: n, op: r, values: i, rangeMin: a, rangeMax: o, text: s } = e;
|
|
45
46
|
if (t === null) return null;
|
|
46
47
|
switch (r) {
|
|
47
|
-
case "is_any_of": return
|
|
48
|
-
case "is_all_of": return i.length === 0 ? null :
|
|
49
|
-
case "between": return
|
|
50
|
-
case "gt": return
|
|
51
|
-
case "gte": return
|
|
52
|
-
case "lt": return
|
|
53
|
-
case "lte": return
|
|
54
|
-
case "equal": return
|
|
55
|
-
case "not_equal": return
|
|
56
|
-
case "has_value": return
|
|
57
|
-
case "no_value": return
|
|
58
|
-
case "contains": return
|
|
59
|
-
case "starts_with": return
|
|
60
|
-
case "ends_with": return
|
|
61
|
-
case "is_exactly": return
|
|
48
|
+
case "is_any_of": return y(t, n, i);
|
|
49
|
+
case "is_all_of": return i.length === 0 ? null : w(t, i);
|
|
50
|
+
case "between": return b(t, a, o);
|
|
51
|
+
case "gt": return T(t, a, c.GREATER_THAN);
|
|
52
|
+
case "gte": return T(t, a, c.GREATER_THAN_OR_EQUAL);
|
|
53
|
+
case "lt": return T(t, o, c.LESS_THAN);
|
|
54
|
+
case "lte": return T(t, o, c.LESS_THAN_OR_EQUAL);
|
|
55
|
+
case "equal": return x(t, i, c.EQUAL);
|
|
56
|
+
case "not_equal": return x(t, i, c.NOT_EQUAL);
|
|
57
|
+
case "has_value": return C(t, c.IS_NOT_NULL, []);
|
|
58
|
+
case "no_value": return C(t, c.IS_NULL, []);
|
|
59
|
+
case "contains": return S(t, s, (e) => `%${e}%`);
|
|
60
|
+
case "starts_with": return S(t, s, (e) => `${e}%`);
|
|
61
|
+
case "ends_with": return S(t, s, (e) => `%${e}`);
|
|
62
|
+
case "is_exactly": return v(s) ? null : C(t, c.EQUAL, [s]);
|
|
62
63
|
default: return console.warn(`conditionToApiFilter: unrecognized QB op, skipping condition for column "${t}"`, { op: r }), null;
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
|
-
function
|
|
66
|
+
function v(e) {
|
|
66
67
|
return e == null || e === "";
|
|
67
68
|
}
|
|
68
|
-
function v(e, t, n) {
|
|
69
|
-
return n.length === 0 ? null : d(t) ? C(e, n) : S(e, s.IN, n);
|
|
70
|
-
}
|
|
71
69
|
function y(e, t, n) {
|
|
72
|
-
return
|
|
70
|
+
return n.length === 0 ? null : f(t) ? w(e, n) : C(e, c.IN, n);
|
|
73
71
|
}
|
|
74
72
|
function b(e, t, n) {
|
|
75
|
-
return t
|
|
73
|
+
return v(t) || v(n) ? null : C(e, c.BETWEEN, [t, n]);
|
|
76
74
|
}
|
|
77
75
|
function x(e, t, n) {
|
|
78
|
-
return
|
|
76
|
+
return t.length === 0 ? null : C(e, n, [t[0]]);
|
|
79
77
|
}
|
|
80
78
|
function S(e, t, n) {
|
|
79
|
+
return v(t) ? null : C(e, c.LIKE, [n(p(t))]);
|
|
80
|
+
}
|
|
81
|
+
function C(e, t, n) {
|
|
81
82
|
return {
|
|
82
|
-
concreteType:
|
|
83
|
+
concreteType: u,
|
|
83
84
|
columnName: e,
|
|
84
85
|
operator: t,
|
|
85
86
|
values: n
|
|
86
87
|
};
|
|
87
88
|
}
|
|
88
|
-
function
|
|
89
|
+
function w(e, t) {
|
|
89
90
|
return {
|
|
90
|
-
concreteType:
|
|
91
|
+
concreteType: d,
|
|
91
92
|
columnName: e,
|
|
92
|
-
function:
|
|
93
|
-
_function:
|
|
93
|
+
function: s.HAS,
|
|
94
|
+
_function: s.HAS,
|
|
94
95
|
values: t
|
|
95
96
|
};
|
|
96
97
|
}
|
|
97
|
-
function
|
|
98
|
-
return t == null || t === "" ? null :
|
|
98
|
+
function T(e, t, n) {
|
|
99
|
+
return t == null || t === "" ? null : C(e, n, [t]);
|
|
99
100
|
}
|
|
100
|
-
function
|
|
101
|
+
function E(n) {
|
|
101
102
|
if (i(n)) {
|
|
102
|
-
let e = (n.children ?? []).map(
|
|
103
|
+
let e = (n.children ?? []).map(E).filter((e) => e !== null);
|
|
103
104
|
return {
|
|
104
105
|
kind: "group",
|
|
105
|
-
id:
|
|
106
|
+
id: a(),
|
|
106
107
|
combinator: n.operator ?? "AND",
|
|
107
108
|
not: n.not ?? !1,
|
|
108
109
|
children: e
|
|
109
110
|
};
|
|
110
111
|
}
|
|
111
|
-
return t(n) ?
|
|
112
|
+
return t(n) ? D(n) : e(n) ? {
|
|
112
113
|
kind: "condition",
|
|
113
|
-
id:
|
|
114
|
+
id: a(),
|
|
114
115
|
columnName: n.columnName,
|
|
115
116
|
columnType: null,
|
|
116
117
|
op: "is_any_of",
|
|
@@ -120,10 +121,10 @@ function T(n) {
|
|
|
120
121
|
text: null
|
|
121
122
|
} : null;
|
|
122
123
|
}
|
|
123
|
-
function
|
|
124
|
+
function D(e) {
|
|
124
125
|
let t = {
|
|
125
126
|
kind: "condition",
|
|
126
|
-
id:
|
|
127
|
+
id: a(),
|
|
127
128
|
columnName: e.columnName,
|
|
128
129
|
columnType: null,
|
|
129
130
|
values: [],
|
|
@@ -132,57 +133,57 @@ function E(e) {
|
|
|
132
133
|
text: null
|
|
133
134
|
}, [n] = e.values;
|
|
134
135
|
switch (e.operator) {
|
|
135
|
-
case
|
|
136
|
+
case c.IN: return {
|
|
136
137
|
...t,
|
|
137
138
|
op: "is_any_of",
|
|
138
139
|
values: [...e.values]
|
|
139
140
|
};
|
|
140
|
-
case
|
|
141
|
+
case c.EQUAL: return {
|
|
141
142
|
...t,
|
|
142
143
|
op: "equal",
|
|
143
144
|
values: [...e.values]
|
|
144
145
|
};
|
|
145
|
-
case
|
|
146
|
+
case c.NOT_EQUAL: return {
|
|
146
147
|
...t,
|
|
147
148
|
op: "not_equal",
|
|
148
149
|
values: [...e.values]
|
|
149
150
|
};
|
|
150
|
-
case
|
|
151
|
+
case c.GREATER_THAN: return {
|
|
151
152
|
...t,
|
|
152
153
|
op: "gt",
|
|
153
154
|
rangeMin: n ?? null
|
|
154
155
|
};
|
|
155
|
-
case
|
|
156
|
+
case c.GREATER_THAN_OR_EQUAL: return {
|
|
156
157
|
...t,
|
|
157
158
|
op: "gte",
|
|
158
159
|
rangeMin: n ?? null
|
|
159
160
|
};
|
|
160
|
-
case
|
|
161
|
+
case c.LESS_THAN: return {
|
|
161
162
|
...t,
|
|
162
163
|
op: "lt",
|
|
163
164
|
rangeMax: n ?? null
|
|
164
165
|
};
|
|
165
|
-
case
|
|
166
|
+
case c.LESS_THAN_OR_EQUAL: return {
|
|
166
167
|
...t,
|
|
167
168
|
op: "lte",
|
|
168
169
|
rangeMax: n ?? null
|
|
169
170
|
};
|
|
170
|
-
case
|
|
171
|
+
case c.BETWEEN: return {
|
|
171
172
|
...t,
|
|
172
173
|
op: "between",
|
|
173
174
|
rangeMin: e.values[0] ?? null,
|
|
174
175
|
rangeMax: e.values[1] ?? null
|
|
175
176
|
};
|
|
176
|
-
case
|
|
177
|
+
case c.IS_NULL: return {
|
|
177
178
|
...t,
|
|
178
179
|
op: "no_value"
|
|
179
180
|
};
|
|
180
|
-
case
|
|
181
|
+
case c.IS_NOT_NULL: return {
|
|
181
182
|
...t,
|
|
182
183
|
op: "has_value"
|
|
183
184
|
};
|
|
184
|
-
case
|
|
185
|
-
let e =
|
|
185
|
+
case c.LIKE: {
|
|
186
|
+
let e = h(n ?? "");
|
|
186
187
|
return {
|
|
187
188
|
...t,
|
|
188
189
|
op: e.op,
|
|
@@ -195,21 +196,22 @@ function E(e) {
|
|
|
195
196
|
};
|
|
196
197
|
}
|
|
197
198
|
}
|
|
198
|
-
function
|
|
199
|
+
function O(e, t) {
|
|
200
|
+
let n = new Map((t ?? []).map((e) => [e.name, e.columnType]));
|
|
199
201
|
return {
|
|
200
202
|
kind: "group",
|
|
201
|
-
id:
|
|
203
|
+
id: a(),
|
|
202
204
|
combinator: "AND",
|
|
203
205
|
not: !1,
|
|
204
|
-
children: e.map(
|
|
206
|
+
children: e.map((e) => k(e, n.get(e.columnName) ?? null)).filter((e) => e !== null)
|
|
205
207
|
};
|
|
206
208
|
}
|
|
207
|
-
function
|
|
209
|
+
function k(e, t) {
|
|
208
210
|
if (r(e)) return !e.facetValues || e.facetValues.length === 0 ? null : {
|
|
209
211
|
kind: "condition",
|
|
210
|
-
id:
|
|
212
|
+
id: a(),
|
|
211
213
|
columnName: e.columnName,
|
|
212
|
-
columnType:
|
|
214
|
+
columnType: t,
|
|
213
215
|
op: "is_any_of",
|
|
214
216
|
values: [...e.facetValues],
|
|
215
217
|
rangeMin: null,
|
|
@@ -217,28 +219,28 @@ function O(e) {
|
|
|
217
219
|
text: null
|
|
218
220
|
};
|
|
219
221
|
if (n(e)) {
|
|
220
|
-
let
|
|
221
|
-
if (!
|
|
222
|
-
let
|
|
222
|
+
let n = e.min != null && e.min !== "", r = e.max != null && e.max !== "";
|
|
223
|
+
if (!n && !r) return null;
|
|
224
|
+
let i = {
|
|
223
225
|
kind: "condition",
|
|
224
|
-
id:
|
|
226
|
+
id: a(),
|
|
225
227
|
columnName: e.columnName,
|
|
226
|
-
columnType:
|
|
228
|
+
columnType: t,
|
|
227
229
|
values: [],
|
|
228
230
|
text: null
|
|
229
231
|
};
|
|
230
|
-
return
|
|
231
|
-
...
|
|
232
|
+
return n && r ? {
|
|
233
|
+
...i,
|
|
232
234
|
op: "between",
|
|
233
235
|
rangeMin: e.min,
|
|
234
236
|
rangeMax: e.max
|
|
235
|
-
} :
|
|
236
|
-
...
|
|
237
|
+
} : n ? {
|
|
238
|
+
...i,
|
|
237
239
|
op: "gte",
|
|
238
240
|
rangeMin: e.min,
|
|
239
241
|
rangeMax: null
|
|
240
242
|
} : {
|
|
241
|
-
...
|
|
243
|
+
...i,
|
|
242
244
|
op: "lte",
|
|
243
245
|
rangeMin: null,
|
|
244
246
|
rangeMax: e.max
|
|
@@ -246,11 +248,7 @@ function O(e) {
|
|
|
246
248
|
}
|
|
247
249
|
return null;
|
|
248
250
|
}
|
|
249
|
-
var k = 0;
|
|
250
|
-
function A() {
|
|
251
|
-
return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : (k += 1, `qb-${k}`);
|
|
252
|
-
}
|
|
253
251
|
//#endregion
|
|
254
|
-
export {
|
|
252
|
+
export { E as apiFilterToQBNode, h as classifyLikePattern, p as escapeLike, f as isListColumn, g as qbNodeToApiFilter, O as selectedFacetsToQBGroup, m as unescapeLike };
|
|
255
253
|
|
|
256
254
|
//# sourceMappingURL=queryBuilderTranslation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryBuilderTranslation.js","names":[],"sources":["../../../src/components/QueryBuilder/queryBuilderTranslation.ts"],"sourcesContent":["import {\n ColumnMultiValueFunction,\n ColumnMultiValueFunctionQueryFilter,\n ColumnSingleValueFilterOperator,\n ColumnSingleValueQueryFilter,\n FacetColumnRequest,\n FILTER_GROUP_CONCRETE_TYPE_VALUE,\n FilterGroup,\n QueryFilter,\n} from '@sage-bionetworks/synapse-types'\nimport {\n isColumnMultiValueFunctionQueryFilter,\n isColumnSingleValueQueryFilter,\n isFacetColumnRangeRequest,\n isFacetColumnValuesRequest,\n isFilterGroup,\n} from '../../utils/types/IsType'\nimport { isQBGroup, QBCondition, QBGroup, QBNode } from './QueryBuilderTypes'\n\nconst COLUMN_SINGLE_VALUE_QUERY_FILTER =\n 'org.sagebionetworks.repo.model.table.ColumnSingleValueQueryFilter' as const\nconst COLUMN_MULTI_VALUE_FUNCTION_QUERY_FILTER =\n 'org.sagebionetworks.repo.model.table.ColumnMultiValueFunctionQueryFilter' as const\n\n// -----------------------------------------------------------------------------\n// Column-kind classification\n// -----------------------------------------------------------------------------\n\n/** A multi-value list column is one whose column type ends in `_LIST`. */\nexport function isListColumn(columnType: string | null): boolean {\n return columnType?.endsWith('_LIST') ?? false\n}\n\n// -----------------------------------------------------------------------------\n// LIKE escaping / classification\n// -----------------------------------------------------------------------------\n\n/**\n * Escape SQL LIKE metacharacters (`%` and `_`) plus the escape character itself\n * (`\\`) so a user's literal `50%` isn't treated as a wildcard match.\n */\nexport function escapeLike(input: string): string {\n return input.replace(/[\\\\%_]/g, ch => '\\\\' + ch)\n}\n\n/**\n * Inverse of {@link escapeLike}: strip the backslash escapes that\n * {@link escapeLike} added.\n */\nexport function unescapeLike(input: string): string {\n return input.replace(/\\\\([\\\\%_])/g, '$1')\n}\n\n/**\n * Classify a LIKE pattern string produced by {@link qbNodeToApiFilter} back\n * into a QB op + un-escaped text. Handles the four wildcard shapes\n * produced by that function (`%val%`, `val%`, `%val`, `val`).\n */\nexport function classifyLikePattern(pattern: string): {\n op: 'contains' | 'starts_with' | 'ends_with' | 'is_exactly'\n text: string\n} {\n const startsPct = pattern.startsWith('%')\n // Only treat a trailing '%' as a wildcard if it isn't itself escaped\n const endsPct = /(?<!\\\\)%$/.test(pattern)\n const core = pattern.slice(startsPct ? 1 : 0, endsPct ? -1 : undefined)\n const text = unescapeLike(core)\n if (startsPct && endsPct) return { op: 'contains', text }\n if (endsPct) return { op: 'starts_with', text }\n if (startsPct) return { op: 'ends_with', text }\n return { op: 'is_exactly', text }\n}\n\n// -----------------------------------------------------------------------------\n// QB → API\n// -----------------------------------------------------------------------------\n\n/**\n * Convert a QB tree node into a `QueryFilter`. Returns `null` when the node\n * (or an entire subtree) has no complete conditions — an incomplete leaf and\n * an empty group are both treated as \"no constraint\" so partial user input\n * never contributes to the outgoing query.\n */\nexport function qbNodeToApiFilter(node: QBNode): QueryFilter | null {\n if (isQBGroup(node)) {\n const children = node.children\n .map(qbNodeToApiFilter)\n .filter((f): f is QueryFilter => f !== null)\n if (children.length === 0) return null\n const filter: FilterGroup = {\n concreteType: FILTER_GROUP_CONCRETE_TYPE_VALUE,\n operator: node.combinator,\n not: node.not || undefined,\n children,\n }\n return filter\n }\n return conditionToApiFilter(node)\n}\n\nfunction conditionToApiFilter(\n node: QBCondition,\n): ColumnSingleValueQueryFilter | ColumnMultiValueFunctionQueryFilter | null {\n const { columnName, columnType, op, values, rangeMin, rangeMax, text } = node\n if (columnName === null) return null\n\n switch (op) {\n case 'is_any_of':\n return anyOfFilter(columnName, columnType, values)\n case 'is_all_of':\n return values.length === 0\n ? null\n : makeMultiValueFilter(columnName, values)\n case 'between':\n return betweenFilter(columnName, rangeMin, rangeMax)\n case 'gt':\n return rangeBoundFilter(\n columnName,\n rangeMin,\n ColumnSingleValueFilterOperator.GREATER_THAN,\n )\n case 'gte':\n return rangeBoundFilter(\n columnName,\n rangeMin,\n ColumnSingleValueFilterOperator.GREATER_THAN_OR_EQUAL,\n )\n case 'lt':\n return rangeBoundFilter(\n columnName,\n rangeMax,\n ColumnSingleValueFilterOperator.LESS_THAN,\n )\n case 'lte':\n return rangeBoundFilter(\n columnName,\n rangeMax,\n ColumnSingleValueFilterOperator.LESS_THAN_OR_EQUAL,\n )\n case 'equal':\n return equalityFilter(\n columnName,\n values,\n ColumnSingleValueFilterOperator.EQUAL,\n )\n case 'not_equal':\n return equalityFilter(\n columnName,\n values,\n ColumnSingleValueFilterOperator.NOT_EQUAL,\n )\n case 'has_value':\n return makeSingleValueFilter(\n columnName,\n ColumnSingleValueFilterOperator.IS_NOT_NULL,\n [],\n )\n case 'no_value':\n return makeSingleValueFilter(\n columnName,\n ColumnSingleValueFilterOperator.IS_NULL,\n [],\n )\n case 'contains':\n return likeFilter(columnName, text, escaped => `%${escaped}%`)\n case 'starts_with':\n return likeFilter(columnName, text, escaped => `${escaped}%`)\n case 'ends_with':\n return likeFilter(columnName, text, escaped => `%${escaped}`)\n case 'is_exactly':\n return isBlank(text)\n ? null\n : makeSingleValueFilter(\n columnName,\n ColumnSingleValueFilterOperator.EQUAL,\n [text!],\n )\n default: {\n // Compile-time exhaustiveness guard; the log fires only if a new op is\n // added to QBConditionOp without a case here.\n op satisfies never\n console.warn(\n `conditionToApiFilter: unrecognized QB op, skipping condition for column \"${columnName}\"`,\n { op },\n )\n return null\n }\n }\n}\n\nfunction isBlank(value: string | null | undefined): boolean {\n return value == null || value === ''\n}\n\nfunction anyOfFilter(\n columnName: string,\n columnType: string | null,\n values: string[],\n): ColumnSingleValueQueryFilter | ColumnMultiValueFunctionQueryFilter | null {\n if (values.length === 0) return null\n if (isListColumn(columnType)) return makeMultiValueFilter(columnName, values)\n return makeSingleValueFilter(\n columnName,\n ColumnSingleValueFilterOperator.IN,\n values,\n )\n}\n\nfunction betweenFilter(\n columnName: string,\n rangeMin: string | null,\n rangeMax: string | null,\n): ColumnSingleValueQueryFilter | null {\n if (isBlank(rangeMin) || isBlank(rangeMax)) return null\n return makeSingleValueFilter(\n columnName,\n ColumnSingleValueFilterOperator.BETWEEN,\n [rangeMin!, rangeMax!],\n )\n}\n\nfunction equalityFilter(\n columnName: string,\n values: string[],\n operator: ColumnSingleValueFilterOperator,\n): ColumnSingleValueQueryFilter | null {\n if (values.length === 0) return null\n return makeSingleValueFilter(columnName, operator, [values[0]])\n}\n\nfunction likeFilter(\n columnName: string,\n text: string | null,\n wrap: (escapedText: string) => string,\n): ColumnSingleValueQueryFilter | null {\n if (isBlank(text)) return null\n return makeSingleValueFilter(\n columnName,\n ColumnSingleValueFilterOperator.LIKE,\n [wrap(escapeLike(text!))],\n )\n}\n\nfunction makeSingleValueFilter(\n columnName: string,\n operator: ColumnSingleValueFilterOperator,\n values: string[],\n): ColumnSingleValueQueryFilter {\n return {\n concreteType: COLUMN_SINGLE_VALUE_QUERY_FILTER,\n columnName,\n operator,\n values,\n }\n}\n\nfunction makeMultiValueFilter(\n columnName: string,\n values: string[],\n): ColumnMultiValueFunctionQueryFilter {\n return {\n concreteType: COLUMN_MULTI_VALUE_FUNCTION_QUERY_FILTER,\n columnName,\n function: ColumnMultiValueFunction.HAS,\n _function: ColumnMultiValueFunction.HAS,\n values,\n }\n}\n\nfunction rangeBoundFilter(\n columnName: string,\n bound: string | null,\n operator: ColumnSingleValueFilterOperator,\n): ColumnSingleValueQueryFilter | null {\n if (bound == null || bound === '') return null\n return makeSingleValueFilter(columnName, operator, [bound])\n}\n\n// -----------------------------------------------------------------------------\n// API → QB (initial hydration)\n// -----------------------------------------------------------------------------\n\n/**\n * Convert an API `QueryFilter` back into a QB node. Used when the initial\n * query already contains a `FilterGroup` (see filterMode auto-detect) so the\n * QB tree can be reconstructed on mount.\n *\n * Some conversions are lossy — `HAS` always deserializes as `is_any_of` (we\n * can't distinguish it from an `is_all_of` at the API layer), and `EQUAL` on\n * text columns deserializes as `equal` (not `is_exactly`) because they share\n * the same wire representation. Users can adjust the operator picker.\n */\nexport function apiFilterToQBNode(filter: QueryFilter): QBNode | null {\n if (isFilterGroup(filter)) {\n const children = (filter.children ?? [])\n .map(apiFilterToQBNode)\n .filter((n): n is QBNode => n !== null)\n return {\n kind: 'group',\n id: newId(),\n combinator: filter.operator ?? 'AND',\n not: filter.not ?? false,\n children,\n }\n }\n if (isColumnSingleValueQueryFilter(filter)) {\n return singleValueToCondition(filter)\n }\n if (isColumnMultiValueFunctionQueryFilter(filter)) {\n return {\n kind: 'condition',\n id: newId(),\n columnName: filter.columnName,\n columnType: null,\n op: 'is_any_of',\n values: [...filter.values],\n rangeMin: null,\n rangeMax: null,\n text: null,\n }\n }\n // TextMatchesQueryFilter and other non-QB filter types are not part of the\n // QB tree — they belong in the non-QB baseline.\n return null\n}\n\nfunction singleValueToCondition(\n filter: ColumnSingleValueQueryFilter,\n): QBCondition {\n const base = {\n kind: 'condition' as const,\n id: newId(),\n columnName: filter.columnName,\n columnType: null,\n values: [] as string[],\n rangeMin: null as string | null,\n rangeMax: null as string | null,\n text: null as string | null,\n }\n const [firstValue] = filter.values\n switch (filter.operator) {\n case ColumnSingleValueFilterOperator.IN:\n return { ...base, op: 'is_any_of', values: [...filter.values] }\n case ColumnSingleValueFilterOperator.EQUAL:\n return { ...base, op: 'equal', values: [...filter.values] }\n case ColumnSingleValueFilterOperator.NOT_EQUAL:\n return { ...base, op: 'not_equal', values: [...filter.values] }\n case ColumnSingleValueFilterOperator.GREATER_THAN:\n return { ...base, op: 'gt', rangeMin: firstValue ?? null }\n case ColumnSingleValueFilterOperator.GREATER_THAN_OR_EQUAL:\n return { ...base, op: 'gte', rangeMin: firstValue ?? null }\n case ColumnSingleValueFilterOperator.LESS_THAN:\n return { ...base, op: 'lt', rangeMax: firstValue ?? null }\n case ColumnSingleValueFilterOperator.LESS_THAN_OR_EQUAL:\n return { ...base, op: 'lte', rangeMax: firstValue ?? null }\n case ColumnSingleValueFilterOperator.BETWEEN:\n return {\n ...base,\n op: 'between',\n rangeMin: filter.values[0] ?? null,\n rangeMax: filter.values[1] ?? null,\n }\n case ColumnSingleValueFilterOperator.IS_NULL:\n return { ...base, op: 'no_value' }\n case ColumnSingleValueFilterOperator.IS_NOT_NULL:\n return { ...base, op: 'has_value' }\n case ColumnSingleValueFilterOperator.LIKE: {\n const classified = classifyLikePattern(firstValue ?? '')\n return { ...base, op: classified.op, text: classified.text }\n }\n default:\n // Compile-time exhaustiveness guard; the log fires only if a new operator\n // is added to ColumnSingleValueFilterOperator without a case here.\n filter.operator satisfies never\n console.warn(\n `singleValueToCondition: unrecognized filter operator, falling back to 'equal' for column \"${filter.columnName}\"`,\n { operator: filter.operator },\n )\n return { ...base, op: 'equal' }\n }\n}\n\n// -----------------------------------------------------------------------------\n// Facets → QB (mode switch)\n// -----------------------------------------------------------------------------\n\n/**\n * Translate `selectedFacets` into a QB group whose children mirror each facet\n * (as an AND-combined, non-negated group). The reverse direction is not\n * generally possible; a QB → facets switch clears the tree.\n */\nexport function selectedFacetsToQBGroup(\n selectedFacets: FacetColumnRequest[],\n): QBGroup {\n return {\n kind: 'group',\n id: newId(),\n combinator: 'AND',\n not: false,\n children: selectedFacets\n .map(facetToQBCondition)\n .filter((c): c is QBCondition => c !== null),\n }\n}\n\nfunction facetToQBCondition(facet: FacetColumnRequest): QBCondition | null {\n if (isFacetColumnValuesRequest(facet)) {\n if (!facet.facetValues || facet.facetValues.length === 0) return null\n return {\n kind: 'condition',\n id: newId(),\n columnName: facet.columnName,\n columnType: null,\n op: 'is_any_of',\n values: [...facet.facetValues],\n rangeMin: null,\n rangeMax: null,\n text: null,\n }\n }\n if (isFacetColumnRangeRequest(facet)) {\n const hasMin = facet.min != null && facet.min !== ''\n const hasMax = facet.max != null && facet.max !== ''\n if (!hasMin && !hasMax) return null\n const base = {\n kind: 'condition' as const,\n id: newId(),\n columnName: facet.columnName,\n columnType: null,\n values: [],\n text: null,\n }\n if (hasMin && hasMax) {\n return {\n ...base,\n op: 'between',\n rangeMin: facet.min!,\n rangeMax: facet.max!,\n }\n }\n if (hasMin) {\n return { ...base, op: 'gte', rangeMin: facet.min!, rangeMax: null }\n }\n return { ...base, op: 'lte', rangeMin: null, rangeMax: facet.max! }\n }\n return null\n}\n\n// -----------------------------------------------------------------------------\n// Utilities\n// -----------------------------------------------------------------------------\n\nlet idCounter = 0\nfunction newId(): string {\n if (\n typeof crypto !== 'undefined' &&\n typeof crypto.randomUUID === 'function'\n ) {\n return crypto.randomUUID()\n }\n // Monotonic counter is sufficient — QB ids are client-only React keys, not secrets.\n idCounter += 1\n return `qb-${idCounter}`\n}\n"],"mappings":";;;;AAmBA,IAAM,IACJ,qEACI,IACJ;AAOF,SAAgB,EAAa,GAAoC;CAC/D,OAAO,GAAY,SAAS,OAAO,KAAK;AAC1C;AAUA,SAAgB,EAAW,GAAuB;CAChD,OAAO,EAAM,QAAQ,YAAW,MAAM,OAAO,CAAE;AACjD;AAMA,SAAgB,EAAa,GAAuB;CAClD,OAAO,EAAM,QAAQ,eAAe,IAAI;AAC1C;AAOA,SAAgB,EAAoB,GAGlC;CACA,IAAM,IAAY,EAAQ,WAAW,GAAG,GAElC,IAAU,YAAY,KAAK,CAAO,GAElC,IAAO,EADA,EAAQ,MAAM,MAAmB,IAAU,KAAK,KAAA,CACnC,CAAI;CAI9B,OAHI,KAAa,IAAgB;EAAE,IAAI;EAAY;CAAK,IACpD,IAAgB;EAAE,IAAI;EAAe;CAAK,IAC1C,IAAkB;EAAE,IAAI;EAAa;CAAK,IACvC;EAAE,IAAI;EAAc;CAAK;AAClC;AAYA,SAAgB,EAAkB,GAAkC;CAClE,IAAI,EAAU,CAAI,GAAG;EACnB,IAAM,IAAW,EAAK,SACnB,IAAI,CAAiB,EACrB,QAAQ,MAAwB,MAAM,IAAI;EAQ7C,OAPI,EAAS,WAAW,IAAU,OAO3B;GALL,cAAc;GACd,UAAU,EAAK;GACf,KAAK,EAAK,OAAO,KAAA;GACjB;EAEK;CACT;CACA,OAAO,EAAqB,CAAI;AAClC;AAEA,SAAS,EACP,GAC2E;CAC3E,IAAM,EAAE,eAAY,eAAY,OAAI,WAAQ,aAAU,aAAU,YAAS;CACzE,IAAI,MAAe,MAAM,OAAO;CAEhC,QAAQ,GAAR;EACE,KAAK,aACH,OAAO,EAAY,GAAY,GAAY,CAAM;EACnD,KAAK,aACH,OAAO,EAAO,WAAW,IACrB,OACA,EAAqB,GAAY,CAAM;EAC7C,KAAK,WACH,OAAO,EAAc,GAAY,GAAU,CAAQ;EACrD,KAAK,MACH,OAAO,EACL,GACA,GACA,EAAgC,YAClC;EACF,KAAK,OACH,OAAO,EACL,GACA,GACA,EAAgC,qBAClC;EACF,KAAK,MACH,OAAO,EACL,GACA,GACA,EAAgC,SAClC;EACF,KAAK,OACH,OAAO,EACL,GACA,GACA,EAAgC,kBAClC;EACF,KAAK,SACH,OAAO,EACL,GACA,GACA,EAAgC,KAClC;EACF,KAAK,aACH,OAAO,EACL,GACA,GACA,EAAgC,SAClC;EACF,KAAK,aACH,OAAO,EACL,GACA,EAAgC,aAChC,CAAC,CACH;EACF,KAAK,YACH,OAAO,EACL,GACA,EAAgC,SAChC,CAAC,CACH;EACF,KAAK,YACH,OAAO,EAAW,GAAY,IAAM,MAAW,IAAI,EAAQ,EAAE;EAC/D,KAAK,eACH,OAAO,EAAW,GAAY,IAAM,MAAW,GAAG,EAAQ,EAAE;EAC9D,KAAK,aACH,OAAO,EAAW,GAAY,IAAM,MAAW,IAAI,GAAS;EAC9D,KAAK,cACH,OAAO,EAAQ,CAAI,IACf,OACA,EACE,GACA,EAAgC,OAChC,CAAC,CAAK,CACR;EACN,SAQE,OAJA,QAAQ,KACN,4EAA4E,EAAW,IACvF,EAAE,MAAG,CACP,GACO;CAEX;AACF;AAEA,SAAS,EAAQ,GAA2C;CAC1D,OAAO,KAAS,QAAQ,MAAU;AACpC;AAEA,SAAS,EACP,GACA,GACA,GAC2E;CAG3E,OAFI,EAAO,WAAW,IAAU,OAC5B,EAAa,CAAU,IAAU,EAAqB,GAAY,CAAM,IACrE,EACL,GACA,EAAgC,IAChC,CACF;AACF;AAEA,SAAS,EACP,GACA,GACA,GACqC;CAErC,OADI,EAAQ,CAAQ,KAAK,EAAQ,CAAQ,IAAU,OAC5C,EACL,GACA,EAAgC,SAChC,CAAC,GAAW,CAAS,CACvB;AACF;AAEA,SAAS,EACP,GACA,GACA,GACqC;CAErC,OADI,EAAO,WAAW,IAAU,OACzB,EAAsB,GAAY,GAAU,CAAC,EAAO,EAAE,CAAC;AAChE;AAEA,SAAS,EACP,GACA,GACA,GACqC;CAErC,OADI,EAAQ,CAAI,IAAU,OACnB,EACL,GACA,EAAgC,MAChC,CAAC,EAAK,EAAW,CAAK,CAAC,CAAC,CAC1B;AACF;AAEA,SAAS,EACP,GACA,GACA,GAC8B;CAC9B,OAAO;EACL,cAAc;EACd;EACA;EACA;CACF;AACF;AAEA,SAAS,EACP,GACA,GACqC;CACrC,OAAO;EACL,cAAc;EACd;EACA,UAAU,EAAyB;EACnC,WAAW,EAAyB;EACpC;CACF;AACF;AAEA,SAAS,EACP,GACA,GACA,GACqC;CAErC,OADI,KAAS,QAAQ,MAAU,KAAW,OACnC,EAAsB,GAAY,GAAU,CAAC,CAAK,CAAC;AAC5D;AAgBA,SAAgB,EAAkB,GAAoC;CACpE,IAAI,EAAc,CAAM,GAAG;EACzB,IAAM,KAAY,EAAO,YAAY,CAAC,GACnC,IAAI,CAAiB,EACrB,QAAQ,MAAmB,MAAM,IAAI;EACxC,OAAO;GACL,MAAM;GACN,IAAI,EAAM;GACV,YAAY,EAAO,YAAY;GAC/B,KAAK,EAAO,OAAO;GACnB;EACF;CACF;CAmBA,OAlBI,EAA+B,CAAM,IAChC,EAAuB,CAAM,IAElC,EAAsC,CAAM,IACvC;EACL,MAAM;EACN,IAAI,EAAM;EACV,YAAY,EAAO;EACnB,YAAY;EACZ,IAAI;EACJ,QAAQ,CAAC,GAAG,EAAO,MAAM;EACzB,UAAU;EACV,UAAU;EACV,MAAM;CACR,IAIK;AACT;AAEA,SAAS,EACP,GACa;CACb,IAAM,IAAO;EACX,MAAM;EACN,IAAI,EAAM;EACV,YAAY,EAAO;EACnB,YAAY;EACZ,QAAQ,CAAC;EACT,UAAU;EACV,UAAU;EACV,MAAM;CACR,GACM,CAAC,KAAc,EAAO;CAC5B,QAAQ,EAAO,UAAf;EACE,KAAK,EAAgC,IACnC,OAAO;GAAE,GAAG;GAAM,IAAI;GAAa,QAAQ,CAAC,GAAG,EAAO,MAAM;EAAE;EAChE,KAAK,EAAgC,OACnC,OAAO;GAAE,GAAG;GAAM,IAAI;GAAS,QAAQ,CAAC,GAAG,EAAO,MAAM;EAAE;EAC5D,KAAK,EAAgC,WACnC,OAAO;GAAE,GAAG;GAAM,IAAI;GAAa,QAAQ,CAAC,GAAG,EAAO,MAAM;EAAE;EAChE,KAAK,EAAgC,cACnC,OAAO;GAAE,GAAG;GAAM,IAAI;GAAM,UAAU,KAAc;EAAK;EAC3D,KAAK,EAAgC,uBACnC,OAAO;GAAE,GAAG;GAAM,IAAI;GAAO,UAAU,KAAc;EAAK;EAC5D,KAAK,EAAgC,WACnC,OAAO;GAAE,GAAG;GAAM,IAAI;GAAM,UAAU,KAAc;EAAK;EAC3D,KAAK,EAAgC,oBACnC,OAAO;GAAE,GAAG;GAAM,IAAI;GAAO,UAAU,KAAc;EAAK;EAC5D,KAAK,EAAgC,SACnC,OAAO;GACL,GAAG;GACH,IAAI;GACJ,UAAU,EAAO,OAAO,MAAM;GAC9B,UAAU,EAAO,OAAO,MAAM;EAChC;EACF,KAAK,EAAgC,SACnC,OAAO;GAAE,GAAG;GAAM,IAAI;EAAW;EACnC,KAAK,EAAgC,aACnC,OAAO;GAAE,GAAG;GAAM,IAAI;EAAY;EACpC,KAAK,EAAgC,MAAM;GACzC,IAAM,IAAa,EAAoB,KAAc,EAAE;GACvD,OAAO;IAAE,GAAG;IAAM,IAAI,EAAW;IAAI,MAAM,EAAW;GAAK;EAC7D;EACA,SAQE,OALA,EAAO,UACP,QAAQ,KACN,6FAA6F,EAAO,WAAW,IAC/G,EAAE,UAAU,EAAO,SAAS,CAC9B,GACO;GAAE,GAAG;GAAM,IAAI;EAAQ;CAClC;AACF;AAWA,SAAgB,EACd,GACS;CACT,OAAO;EACL,MAAM;EACN,IAAI,EAAM;EACV,YAAY;EACZ,KAAK;EACL,UAAU,EACP,IAAI,CAAkB,EACtB,QAAQ,MAAwB,MAAM,IAAI;CAC/C;AACF;AAEA,SAAS,EAAmB,GAA+C;CACzE,IAAI,EAA2B,CAAK,GAElC,OADI,CAAC,EAAM,eAAe,EAAM,YAAY,WAAW,IAAU,OAC1D;EACL,MAAM;EACN,IAAI,EAAM;EACV,YAAY,EAAM;EAClB,YAAY;EACZ,IAAI;EACJ,QAAQ,CAAC,GAAG,EAAM,WAAW;EAC7B,UAAU;EACV,UAAU;EACV,MAAM;CACR;CAEF,IAAI,EAA0B,CAAK,GAAG;EACpC,IAAM,IAAS,EAAM,OAAO,QAAQ,EAAM,QAAQ,IAC5C,IAAS,EAAM,OAAO,QAAQ,EAAM,QAAQ;EAClD,IAAI,CAAC,KAAU,CAAC,GAAQ,OAAO;EAC/B,IAAM,IAAO;GACX,MAAM;GACN,IAAI,EAAM;GACV,YAAY,EAAM;GAClB,YAAY;GACZ,QAAQ,CAAC;GACT,MAAM;EACR;EAYA,OAXI,KAAU,IACL;GACL,GAAG;GACH,IAAI;GACJ,UAAU,EAAM;GAChB,UAAU,EAAM;EAClB,IAEE,IACK;GAAE,GAAG;GAAM,IAAI;GAAO,UAAU,EAAM;GAAM,UAAU;EAAK,IAE7D;GAAE,GAAG;GAAM,IAAI;GAAO,UAAU;GAAM,UAAU,EAAM;EAAK;CACpE;CACA,OAAO;AACT;AAMA,IAAI,IAAY;AAChB,SAAS,IAAgB;CASvB,OAPE,OAAO,SAAW,OAClB,OAAO,OAAO,cAAe,aAEtB,OAAO,WAAW,KAG3B,KAAa,GACN,MAAM;AACf"}
|
|
1
|
+
{"version":3,"file":"queryBuilderTranslation.js","names":[],"sources":["../../../src/components/QueryBuilder/queryBuilderTranslation.ts"],"sourcesContent":["import {\n ColumnModel,\n ColumnMultiValueFunction,\n ColumnMultiValueFunctionQueryFilter,\n ColumnSingleValueFilterOperator,\n ColumnSingleValueQueryFilter,\n FacetColumnRequest,\n FILTER_GROUP_CONCRETE_TYPE_VALUE,\n FilterGroup,\n QueryFilter,\n} from '@sage-bionetworks/synapse-types'\nimport { ReadonlyDeep } from 'type-fest'\nimport {\n isColumnMultiValueFunctionQueryFilter,\n isColumnSingleValueQueryFilter,\n isFacetColumnRangeRequest,\n isFacetColumnValuesRequest,\n isFilterGroup,\n} from '../../utils/types/IsType'\nimport { isQBGroup, QBCondition, QBGroup, QBNode } from './QueryBuilderTypes'\nimport { newQBNodeId } from './queryBuilderId'\n\nconst COLUMN_SINGLE_VALUE_QUERY_FILTER =\n 'org.sagebionetworks.repo.model.table.ColumnSingleValueQueryFilter' as const\nconst COLUMN_MULTI_VALUE_FUNCTION_QUERY_FILTER =\n 'org.sagebionetworks.repo.model.table.ColumnMultiValueFunctionQueryFilter' as const\n\n// -----------------------------------------------------------------------------\n// Column-kind classification\n// -----------------------------------------------------------------------------\n\n/** A multi-value list column is one whose column type ends in `_LIST`. */\nexport function isListColumn(columnType: string | null): boolean {\n return columnType?.endsWith('_LIST') ?? false\n}\n\n// -----------------------------------------------------------------------------\n// LIKE escaping / classification\n// -----------------------------------------------------------------------------\n\n/**\n * Escape SQL LIKE metacharacters (`%` and `_`) plus the escape character itself\n * (`\\`) so a user's literal `50%` isn't treated as a wildcard match.\n */\nexport function escapeLike(input: string): string {\n return input.replace(/[\\\\%_]/g, ch => '\\\\' + ch)\n}\n\n/**\n * Inverse of {@link escapeLike}: strip the backslash escapes that\n * {@link escapeLike} added.\n */\nexport function unescapeLike(input: string): string {\n return input.replace(/\\\\([\\\\%_])/g, '$1')\n}\n\n/**\n * Classify a LIKE pattern string produced by {@link qbNodeToApiFilter} back\n * into a QB op + un-escaped text. Handles the four wildcard shapes\n * produced by that function (`%val%`, `val%`, `%val`, `val`).\n */\nexport function classifyLikePattern(pattern: string): {\n op: 'contains' | 'starts_with' | 'ends_with' | 'is_exactly'\n text: string\n} {\n const startsPct = pattern.startsWith('%')\n // Only treat a trailing '%' as a wildcard if it isn't itself escaped\n const endsPct = /(?<!\\\\)%$/.test(pattern)\n const core = pattern.slice(startsPct ? 1 : 0, endsPct ? -1 : undefined)\n const text = unescapeLike(core)\n if (startsPct && endsPct) return { op: 'contains', text }\n if (endsPct) return { op: 'starts_with', text }\n if (startsPct) return { op: 'ends_with', text }\n return { op: 'is_exactly', text }\n}\n\n// -----------------------------------------------------------------------------\n// QB → API\n// -----------------------------------------------------------------------------\n\n/**\n * Convert a QB tree node into a `QueryFilter`. Returns `null` when the node\n * (or an entire subtree) has no complete conditions — an incomplete leaf and\n * an empty group are both treated as \"no constraint\" so partial user input\n * never contributes to the outgoing query.\n */\nexport function qbNodeToApiFilter(node: QBNode): QueryFilter | null {\n if (isQBGroup(node)) {\n const children = node.children\n .map(qbNodeToApiFilter)\n .filter((f): f is QueryFilter => f !== null)\n if (children.length === 0) return null\n const filter: FilterGroup = {\n concreteType: FILTER_GROUP_CONCRETE_TYPE_VALUE,\n operator: node.combinator,\n not: node.not || undefined,\n children,\n }\n return filter\n }\n return conditionToApiFilter(node)\n}\n\nfunction conditionToApiFilter(\n node: QBCondition,\n): ColumnSingleValueQueryFilter | ColumnMultiValueFunctionQueryFilter | null {\n const { columnName, columnType, op, values, rangeMin, rangeMax, text } = node\n if (columnName === null) return null\n\n switch (op) {\n case 'is_any_of':\n return anyOfFilter(columnName, columnType, values)\n case 'is_all_of':\n return values.length === 0\n ? null\n : makeMultiValueFilter(columnName, values)\n case 'between':\n return betweenFilter(columnName, rangeMin, rangeMax)\n case 'gt':\n return rangeBoundFilter(\n columnName,\n rangeMin,\n ColumnSingleValueFilterOperator.GREATER_THAN,\n )\n case 'gte':\n return rangeBoundFilter(\n columnName,\n rangeMin,\n ColumnSingleValueFilterOperator.GREATER_THAN_OR_EQUAL,\n )\n case 'lt':\n return rangeBoundFilter(\n columnName,\n rangeMax,\n ColumnSingleValueFilterOperator.LESS_THAN,\n )\n case 'lte':\n return rangeBoundFilter(\n columnName,\n rangeMax,\n ColumnSingleValueFilterOperator.LESS_THAN_OR_EQUAL,\n )\n case 'equal':\n return equalityFilter(\n columnName,\n values,\n ColumnSingleValueFilterOperator.EQUAL,\n )\n case 'not_equal':\n return equalityFilter(\n columnName,\n values,\n ColumnSingleValueFilterOperator.NOT_EQUAL,\n )\n case 'has_value':\n return makeSingleValueFilter(\n columnName,\n ColumnSingleValueFilterOperator.IS_NOT_NULL,\n [],\n )\n case 'no_value':\n return makeSingleValueFilter(\n columnName,\n ColumnSingleValueFilterOperator.IS_NULL,\n [],\n )\n case 'contains':\n return likeFilter(columnName, text, escaped => `%${escaped}%`)\n case 'starts_with':\n return likeFilter(columnName, text, escaped => `${escaped}%`)\n case 'ends_with':\n return likeFilter(columnName, text, escaped => `%${escaped}`)\n case 'is_exactly':\n return isBlank(text)\n ? null\n : makeSingleValueFilter(\n columnName,\n ColumnSingleValueFilterOperator.EQUAL,\n [text!],\n )\n default: {\n // Compile-time exhaustiveness guard; the log fires only if a new op is\n // added to QBConditionOp without a case here.\n op satisfies never\n console.warn(\n `conditionToApiFilter: unrecognized QB op, skipping condition for column \"${columnName}\"`,\n { op },\n )\n return null\n }\n }\n}\n\nfunction isBlank(value: string | null | undefined): boolean {\n return value == null || value === ''\n}\n\nfunction anyOfFilter(\n columnName: string,\n columnType: string | null,\n values: string[],\n): ColumnSingleValueQueryFilter | ColumnMultiValueFunctionQueryFilter | null {\n if (values.length === 0) return null\n if (isListColumn(columnType)) return makeMultiValueFilter(columnName, values)\n return makeSingleValueFilter(\n columnName,\n ColumnSingleValueFilterOperator.IN,\n values,\n )\n}\n\nfunction betweenFilter(\n columnName: string,\n rangeMin: string | null,\n rangeMax: string | null,\n): ColumnSingleValueQueryFilter | null {\n if (isBlank(rangeMin) || isBlank(rangeMax)) return null\n return makeSingleValueFilter(\n columnName,\n ColumnSingleValueFilterOperator.BETWEEN,\n [rangeMin!, rangeMax!],\n )\n}\n\nfunction equalityFilter(\n columnName: string,\n values: string[],\n operator: ColumnSingleValueFilterOperator,\n): ColumnSingleValueQueryFilter | null {\n if (values.length === 0) return null\n return makeSingleValueFilter(columnName, operator, [values[0]])\n}\n\nfunction likeFilter(\n columnName: string,\n text: string | null,\n wrap: (escapedText: string) => string,\n): ColumnSingleValueQueryFilter | null {\n if (isBlank(text)) return null\n return makeSingleValueFilter(\n columnName,\n ColumnSingleValueFilterOperator.LIKE,\n [wrap(escapeLike(text!))],\n )\n}\n\nfunction makeSingleValueFilter(\n columnName: string,\n operator: ColumnSingleValueFilterOperator,\n values: string[],\n): ColumnSingleValueQueryFilter {\n return {\n concreteType: COLUMN_SINGLE_VALUE_QUERY_FILTER,\n columnName,\n operator,\n values,\n }\n}\n\nfunction makeMultiValueFilter(\n columnName: string,\n values: string[],\n): ColumnMultiValueFunctionQueryFilter {\n return {\n concreteType: COLUMN_MULTI_VALUE_FUNCTION_QUERY_FILTER,\n columnName,\n function: ColumnMultiValueFunction.HAS,\n _function: ColumnMultiValueFunction.HAS,\n values,\n }\n}\n\nfunction rangeBoundFilter(\n columnName: string,\n bound: string | null,\n operator: ColumnSingleValueFilterOperator,\n): ColumnSingleValueQueryFilter | null {\n if (bound == null || bound === '') return null\n return makeSingleValueFilter(columnName, operator, [bound])\n}\n\n// -----------------------------------------------------------------------------\n// API → QB (initial hydration)\n// -----------------------------------------------------------------------------\n\n/**\n * Convert an API `QueryFilter` back into a QB node. Used when the initial\n * query already contains a `FilterGroup` (see filterMode auto-detect) so the\n * QB tree can be reconstructed on mount.\n *\n * Some conversions are lossy — `HAS` always deserializes as `is_any_of` (we\n * can't distinguish it from an `is_all_of` at the API layer), and `EQUAL` on\n * text columns deserializes as `equal` (not `is_exactly`) because they share\n * the same wire representation. Users can adjust the operator picker.\n */\nexport function apiFilterToQBNode(filter: QueryFilter): QBNode | null {\n if (isFilterGroup(filter)) {\n const children = (filter.children ?? [])\n .map(apiFilterToQBNode)\n .filter((n): n is QBNode => n !== null)\n return {\n kind: 'group',\n id: newQBNodeId(),\n combinator: filter.operator ?? 'AND',\n not: filter.not ?? false,\n children,\n }\n }\n if (isColumnSingleValueQueryFilter(filter)) {\n return singleValueToCondition(filter)\n }\n if (isColumnMultiValueFunctionQueryFilter(filter)) {\n return {\n kind: 'condition',\n id: newQBNodeId(),\n columnName: filter.columnName,\n columnType: null,\n op: 'is_any_of',\n values: [...filter.values],\n rangeMin: null,\n rangeMax: null,\n text: null,\n }\n }\n // TextMatchesQueryFilter and other non-QB filter types are not part of the\n // QB tree — they belong in the non-QB baseline.\n return null\n}\n\nfunction singleValueToCondition(\n filter: ColumnSingleValueQueryFilter,\n): QBCondition {\n const base = {\n kind: 'condition' as const,\n id: newQBNodeId(),\n columnName: filter.columnName,\n columnType: null,\n values: [] as string[],\n rangeMin: null as string | null,\n rangeMax: null as string | null,\n text: null as string | null,\n }\n const [firstValue] = filter.values\n switch (filter.operator) {\n case ColumnSingleValueFilterOperator.IN:\n return { ...base, op: 'is_any_of', values: [...filter.values] }\n case ColumnSingleValueFilterOperator.EQUAL:\n return { ...base, op: 'equal', values: [...filter.values] }\n case ColumnSingleValueFilterOperator.NOT_EQUAL:\n return { ...base, op: 'not_equal', values: [...filter.values] }\n case ColumnSingleValueFilterOperator.GREATER_THAN:\n return { ...base, op: 'gt', rangeMin: firstValue ?? null }\n case ColumnSingleValueFilterOperator.GREATER_THAN_OR_EQUAL:\n return { ...base, op: 'gte', rangeMin: firstValue ?? null }\n case ColumnSingleValueFilterOperator.LESS_THAN:\n return { ...base, op: 'lt', rangeMax: firstValue ?? null }\n case ColumnSingleValueFilterOperator.LESS_THAN_OR_EQUAL:\n return { ...base, op: 'lte', rangeMax: firstValue ?? null }\n case ColumnSingleValueFilterOperator.BETWEEN:\n return {\n ...base,\n op: 'between',\n rangeMin: filter.values[0] ?? null,\n rangeMax: filter.values[1] ?? null,\n }\n case ColumnSingleValueFilterOperator.IS_NULL:\n return { ...base, op: 'no_value' }\n case ColumnSingleValueFilterOperator.IS_NOT_NULL:\n return { ...base, op: 'has_value' }\n case ColumnSingleValueFilterOperator.LIKE: {\n const classified = classifyLikePattern(firstValue ?? '')\n return { ...base, op: classified.op, text: classified.text }\n }\n default:\n // Compile-time exhaustiveness guard; the log fires only if a new operator\n // is added to ColumnSingleValueFilterOperator without a case here.\n filter.operator satisfies never\n console.warn(\n `singleValueToCondition: unrecognized filter operator, falling back to 'equal' for column \"${filter.columnName}\"`,\n { operator: filter.operator },\n )\n return { ...base, op: 'equal' }\n }\n}\n\n// -----------------------------------------------------------------------------\n// Facets → QB (mode switch)\n// -----------------------------------------------------------------------------\n\n/**\n * Translate `selectedFacets` into a QB group whose children mirror each facet\n * (as an AND-combined, non-negated group). The reverse direction is not\n * generally possible; a QB → facets switch clears the tree.\n */\nexport function selectedFacetsToQBGroup(\n selectedFacets: ReadonlyDeep<FacetColumnRequest[]>,\n columnModels?: ReadonlyDeep<ColumnModel[]>,\n): QBGroup {\n const columnTypeByName = new Map(\n (columnModels ?? []).map(cm => [cm.name, cm.columnType as string]),\n )\n return {\n kind: 'group',\n id: newQBNodeId(),\n combinator: 'AND',\n not: false,\n children: selectedFacets\n .map(facet =>\n facetToQBCondition(\n facet,\n columnTypeByName.get(facet.columnName) ?? null,\n ),\n )\n .filter((c): c is QBCondition => c !== null),\n }\n}\n\nfunction facetToQBCondition(\n facet: ReadonlyDeep<FacetColumnRequest>,\n columnType: string | null,\n): QBCondition | null {\n if (isFacetColumnValuesRequest(facet)) {\n if (!facet.facetValues || facet.facetValues.length === 0) return null\n return {\n kind: 'condition',\n id: newQBNodeId(),\n columnName: facet.columnName,\n columnType,\n op: 'is_any_of',\n values: [...facet.facetValues],\n rangeMin: null,\n rangeMax: null,\n text: null,\n }\n }\n if (isFacetColumnRangeRequest(facet)) {\n const hasMin = facet.min != null && facet.min !== ''\n const hasMax = facet.max != null && facet.max !== ''\n if (!hasMin && !hasMax) return null\n const base = {\n kind: 'condition' as const,\n id: newQBNodeId(),\n columnName: facet.columnName,\n columnType,\n values: [],\n text: null,\n }\n if (hasMin && hasMax) {\n return {\n ...base,\n op: 'between',\n rangeMin: facet.min!,\n rangeMax: facet.max!,\n }\n }\n if (hasMin) {\n return { ...base, op: 'gte', rangeMin: facet.min!, rangeMax: null }\n }\n return { ...base, op: 'lte', rangeMin: null, rangeMax: facet.max! }\n }\n return null\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import { QBGroup } from './QueryBuilderTypes';
|
|
3
|
+
/**
|
|
4
|
+
* Ask the backend to produce the effective SQL for a given QB tree by firing a
|
|
5
|
+
* `QueryBundleRequest` with `BUNDLE_MASK_COMBINED_SQL` and the tree translated
|
|
6
|
+
* into an `additionalFilters` `FilterGroup`. The QB does not otherwise drive
|
|
7
|
+
* the outgoing query in V1 — this hook exists purely to power the SQL preview
|
|
8
|
+
* tab in the summary bar.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useQBCombinedSql(tree: QBGroup | null): UseQueryResult<string | undefined>;
|
|
11
|
+
//# sourceMappingURL=useQBCombinedSql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useQBCombinedSql.d.ts","sourceRoot":"","sources":["../../../src/components/QueryBuilder/useQBCombinedSql.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAItD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAE7C;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,OAAO,GAAG,IAAI,GACnB,cAAc,CAAC,MAAM,GAAG,SAAS,CAAC,CA0BpC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import "../../utils/SynapseConstants.js";
|
|
2
|
+
import e from "../../synapse-queries/entity/useGetQueryResultBundle.js";
|
|
3
|
+
import { useQueryContext as t } from "../QueryContext/QueryContext.js";
|
|
4
|
+
import "../QueryContext/index.js";
|
|
5
|
+
import { qbNodeToApiFilter as n } from "./queryBuilderTranslation.js";
|
|
6
|
+
import { useMemo as r } from "react";
|
|
7
|
+
//#region src/components/QueryBuilder/useQBCombinedSql.ts
|
|
8
|
+
function i(i) {
|
|
9
|
+
let { currentQueryRequest: a } = t();
|
|
10
|
+
return e(r(() => {
|
|
11
|
+
let e = i ? n(i) : null;
|
|
12
|
+
return {
|
|
13
|
+
...a,
|
|
14
|
+
partMask: 256,
|
|
15
|
+
query: {
|
|
16
|
+
...a.query,
|
|
17
|
+
additionalFilters: e ? [e] : void 0,
|
|
18
|
+
offset: void 0,
|
|
19
|
+
limit: void 0,
|
|
20
|
+
sort: void 0,
|
|
21
|
+
selectedFacets: void 0
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}, [a, i]), { select: (e) => e.combinedSql });
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { i as useQBCombinedSql };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=useQBCombinedSql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useQBCombinedSql.js","names":[],"sources":["../../../src/components/QueryBuilder/useQBCombinedSql.ts"],"sourcesContent":["import useGetQueryResultBundle from '@/synapse-queries/entity/useGetQueryResultBundle'\nimport { BUNDLE_MASK_COMBINED_SQL } from '@/utils/SynapseConstants'\nimport { QueryBundleRequest } from '@sage-bionetworks/synapse-types'\nimport { UseQueryResult } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useQueryContext } from '../QueryContext'\nimport { qbNodeToApiFilter } from './queryBuilderTranslation'\nimport { QBGroup } from './QueryBuilderTypes'\n\n/**\n * Ask the backend to produce the effective SQL for a given QB tree by firing a\n * `QueryBundleRequest` with `BUNDLE_MASK_COMBINED_SQL` and the tree translated\n * into an `additionalFilters` `FilterGroup`. The QB does not otherwise drive\n * the outgoing query in V1 — this hook exists purely to power the SQL preview\n * tab in the summary bar.\n */\nexport function useQBCombinedSql(\n tree: QBGroup | null,\n): UseQueryResult<string | undefined> {\n const { currentQueryRequest } = useQueryContext()\n\n const request: QueryBundleRequest = useMemo(() => {\n const translated = tree ? qbNodeToApiFilter(tree) : null\n // Reuse the current query's SQL + entity so the backend combines the QB\n // filters against the same base view, but ask only for combinedSql.\n return {\n ...currentQueryRequest,\n partMask: BUNDLE_MASK_COMBINED_SQL,\n query: {\n ...currentQueryRequest.query,\n additionalFilters: translated ? [translated] : undefined,\n // combinedSql is unaffected by paging/sort, so drop them to keep the\n // cache key stable across scroll and re-sort.\n offset: undefined,\n limit: undefined,\n sort: undefined,\n selectedFacets: undefined,\n },\n }\n }, [currentQueryRequest, tree])\n\n return useGetQueryResultBundle(request, {\n select: bundle => bundle.combinedSql,\n })\n}\n"],"mappings":";;;;;;;AAgBA,SAAgB,EACd,GACoC;CACpC,IAAM,EAAE,2BAAwB,EAAgB;CAsBhD,OAAO,EApB6B,QAAc;EAChD,IAAM,IAAa,IAAO,EAAkB,CAAI,IAAI;EAGpD,OAAO;GACL,GAAG;GACH,UAAA;GACA,OAAO;IACL,GAAG,EAAoB;IACvB,mBAAmB,IAAa,CAAC,CAAU,IAAI,KAAA;IAG/C,QAAQ,KAAA;IACR,OAAO,KAAA;IACP,MAAM,KAAA;IACN,gBAAgB,KAAA;GAClB;EACF;CACF,GAAG,CAAC,GAAqB,CAAI,CAEE,GAAS,EACtC,SAAQ,MAAU,EAAO,YAC3B,CAAC;AACH"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Facet + column-model metadata for the QB property picker and pill values,
|
|
3
|
+
* fetched against the *base* query state with any QB-managed `FilterGroup`
|
|
4
|
+
* entries stripped out of `additionalFilters`.
|
|
5
|
+
*
|
|
6
|
+
* Rationale: Synapse's facet-values computation applies `additionalFilters`
|
|
7
|
+
* globally (unlike `selectedFacets`, which are self-excluded per facet). Once
|
|
8
|
+
* the QB commits a `FilterGroup`, the current query's facet results collapse
|
|
9
|
+
* to only the values that pass the QB filter — leaving the user unable to
|
|
10
|
+
* add or edit values that were filtered out. Firing a separate metadata
|
|
11
|
+
* query with the QB's own `FilterGroup` removed gives the QB stable
|
|
12
|
+
* dropdowns while still honoring any non-QB filters and `selectedFacets`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useQBFacetSourceMetadata(): {
|
|
15
|
+
columnModels: import("@sage-bionetworks/synapse-types").ColumnModel[];
|
|
16
|
+
facetResults: import("@sage-bionetworks/synapse-types").FacetColumnResult[];
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=useQBFacetSourceMetadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useQBFacetSourceMetadata.d.ts","sourceRoot":"","sources":["../../../src/components/QueryBuilder/useQBFacetSourceMetadata.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB;;;EA6BvC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useQueryContext as e } from "../QueryContext/QueryContext.js";
|
|
2
|
+
import "../QueryContext/index.js";
|
|
3
|
+
import { useTableQueryUseQueryOptions as t } from "../QueryWrapper/TableQueryUseQueryOptions.js";
|
|
4
|
+
import { useMemo as n } from "react";
|
|
5
|
+
import { FILTER_GROUP_CONCRETE_TYPE_VALUE as r } from "@sage-bionetworks/synapse-types";
|
|
6
|
+
import { useSuspenseQuery as i } from "@tanstack/react-query";
|
|
7
|
+
//#region src/components/QueryBuilder/useQBFacetSourceMetadata.ts
|
|
8
|
+
function a() {
|
|
9
|
+
let { currentQueryRequest: a } = e(), { queryMetadataQueryOptions: o } = t(n(() => {
|
|
10
|
+
let e = (a.query.additionalFilters ?? []).filter((e) => e.concreteType !== r);
|
|
11
|
+
return {
|
|
12
|
+
...a,
|
|
13
|
+
query: {
|
|
14
|
+
...a.query,
|
|
15
|
+
additionalFilters: e.length > 0 ? e : void 0
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}, [a])), { data: s } = i(o);
|
|
19
|
+
return n(() => ({
|
|
20
|
+
columnModels: s?.columnModels ?? [],
|
|
21
|
+
facetResults: s?.facets ?? []
|
|
22
|
+
}), [s]);
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { a as useQBFacetSourceMetadata };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=useQBFacetSourceMetadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useQBFacetSourceMetadata.js","names":[],"sources":["../../../src/components/QueryBuilder/useQBFacetSourceMetadata.ts"],"sourcesContent":["import {\n FILTER_GROUP_CONCRETE_TYPE_VALUE,\n QueryBundleRequest,\n} from '@sage-bionetworks/synapse-types'\nimport { useSuspenseQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useQueryContext } from '../QueryContext'\nimport { useTableQueryUseQueryOptions } from '../QueryWrapper/TableQueryUseQueryOptions'\n\n/**\n * Facet + column-model metadata for the QB property picker and pill values,\n * fetched against the *base* query state with any QB-managed `FilterGroup`\n * entries stripped out of `additionalFilters`.\n *\n * Rationale: Synapse's facet-values computation applies `additionalFilters`\n * globally (unlike `selectedFacets`, which are self-excluded per facet). Once\n * the QB commits a `FilterGroup`, the current query's facet results collapse\n * to only the values that pass the QB filter — leaving the user unable to\n * add or edit values that were filtered out. Firing a separate metadata\n * query with the QB's own `FilterGroup` removed gives the QB stable\n * dropdowns while still honoring any non-QB filters and `selectedFacets`.\n */\nexport function useQBFacetSourceMetadata() {\n const { currentQueryRequest } = useQueryContext()\n\n const strippedRequest: QueryBundleRequest = useMemo(() => {\n const existingFilters = currentQueryRequest.query.additionalFilters ?? []\n const nonQbFilters = existingFilters.filter(\n f => f.concreteType !== FILTER_GROUP_CONCRETE_TYPE_VALUE,\n )\n return {\n ...currentQueryRequest,\n query: {\n ...currentQueryRequest.query,\n additionalFilters: nonQbFilters.length > 0 ? nonQbFilters : undefined,\n },\n } as QueryBundleRequest\n }, [currentQueryRequest])\n\n const { queryMetadataQueryOptions } =\n useTableQueryUseQueryOptions(strippedRequest)\n\n const { data } = useSuspenseQuery(queryMetadataQueryOptions)\n\n return useMemo(\n () => ({\n columnModels: data?.columnModels ?? [],\n facetResults: data?.facets ?? [],\n }),\n [data],\n )\n}\n"],"mappings":";;;;;;;AAsBA,SAAgB,IAA2B;CACzC,IAAM,EAAE,2BAAwB,EAAgB,GAgB1C,EAAE,iCACN,EAf0C,QAAc;EAExD,IAAM,KADkB,EAAoB,MAAM,qBAAqB,CAAC,GACnC,QACnC,MAAK,EAAE,iBAAiB,CAC1B;EACA,OAAO;GACL,GAAG;GACH,OAAO;IACL,GAAG,EAAoB;IACvB,mBAAmB,EAAa,SAAS,IAAI,IAAe,KAAA;GAC9D;EACF;CACF,GAAG,CAAC,CAAmB,CAGQ,CAAe,GAExC,EAAE,YAAS,EAAiB,CAAyB;CAE3D,OAAO,SACE;EACL,cAAc,GAAM,gBAAgB,CAAC;EACrC,cAAc,GAAM,UAAU,CAAC;CACjC,IACA,CAAC,CAAI,CACP;AACF"}
|
|
@@ -37,9 +37,22 @@ type QueryWrapperPlotNavOwnProps = {
|
|
|
37
37
|
lockedColumn?: QueryWrapperProps['lockedColumn'];
|
|
38
38
|
initialLimit?: number;
|
|
39
39
|
hideTopLevelControls?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* When true, shows a `Show / Hide Query Builder` toggle in `TopLevelControls`.
|
|
42
|
+
* The QB and the facet nav are mutually exclusive — turning the QB on hides
|
|
43
|
+
* the facet nav entirely.
|
|
44
|
+
*/
|
|
45
|
+
showQueryBuilderControl?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* When true, the QB is shown by default. When `showQueryBuilderControl` is
|
|
48
|
+
* also true, the user can toggle it back off from `TopLevelControls`. When
|
|
49
|
+
* `showQueryBuilderControl` is false the QB is permanently displayed with
|
|
50
|
+
* no toggle button.
|
|
51
|
+
*/
|
|
52
|
+
defaultShowQueryBuilder?: boolean;
|
|
40
53
|
} & Omit<TopLevelControlsProps, 'entityId'> & Pick<QueryWrapperPlotNavCustomPlotParams, 'onCustomPlotClick'> & Pick<QueryWrapperProps, 'isRowSelectionVisible' | 'rowSelectionPrimaryKey' | 'isRowSelectionUIFloating' | 'fileIdColumnName' | 'fileNameColumnName' | 'fileVersionColumnName'> & Pick<QueryVisualizationWrapperProps, 'defaultShowPlots' | 'visibleColumnCount' | 'hiddenColumns' | 'columnAliases' | 'renderFacetValue' | 'rgbIndex' | 'showLastUpdatedOn' | 'noContentPlaceholderType' | 'unitDescription' | 'additionalFiltersSessionStorageKey' | 'helpConfiguration' | 'hideCopyToClipboard' | 'hideSearchBarControl' | 'hideVisualizationsControl' | 'enabledExternalAnalysisPlatforms' | 'lockTextMatchesQueryFilterPill'> & Pick<QueryContextType, 'combineRangeFacetConfig'>;
|
|
41
54
|
export type QueryWrapperPlotNavProps = QueryOrDeprecatedSearchParams & PlotsContainerProps & QueryWrapperPlotNavOwnProps;
|
|
42
|
-
export type QueryWrapperPlotNavContentsProps = Pick<QueryWrapperPlotNavProps, 'tableConfiguration' | 'name' | 'cardConfiguration' | 'facetsToPlot' | 'availableFacets' | 'initialExpandedFacetControls' | 'hideDownload' | 'hideAddToDownloadListMenuItem' | 'hideProgrammaticOptionsMenuItem' | 'hideQueryCount' | 'hideSqlEditorControl' | 'hideVisualizationsControl' | 'searchConfiguration' | 'enabledExternalAnalysisPlatforms' | 'cavaticaConnectAccountURL' | 'customControls' | 'customPlots' | 'fileIdColumnName' | 'fileNameColumnName' | 'fileVersionColumnName' | 'initialLimit' | 'initialPlotTypeByFacetColumnName' | 'hideTopLevelControls'> & {
|
|
55
|
+
export type QueryWrapperPlotNavContentsProps = Pick<QueryWrapperPlotNavProps, 'tableConfiguration' | 'name' | 'cardConfiguration' | 'facetsToPlot' | 'availableFacets' | 'initialExpandedFacetControls' | 'hideDownload' | 'hideAddToDownloadListMenuItem' | 'hideProgrammaticOptionsMenuItem' | 'hideQueryCount' | 'hideSqlEditorControl' | 'hideVisualizationsControl' | 'searchConfiguration' | 'enabledExternalAnalysisPlatforms' | 'cavaticaConnectAccountURL' | 'customControls' | 'customPlots' | 'fileIdColumnName' | 'fileNameColumnName' | 'fileVersionColumnName' | 'initialLimit' | 'initialPlotTypeByFacetColumnName' | 'hideTopLevelControls' | 'showQueryBuilderControl' | 'defaultShowQueryBuilder'> & {
|
|
43
56
|
isFullTextSearchEnabled: boolean;
|
|
44
57
|
remount?: () => void;
|
|
45
58
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryWrapperPlotNav.d.ts","sourceRoot":"","sources":["../../../src/components/QueryWrapperPlotNav/QueryWrapperPlotNav.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAA;AAiBlG,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AAItE,OAAO,EAAE,mCAAmC,EAAE,MAAM,qBAAqB,CAAA;AACzE,OAAO,EAAE,gBAAgB,EAAmB,MAAM,iBAAiB,CAAA;AACnE,OAAO,EAGL,8BAA8B,EAC/B,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAgB,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAGjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAiB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAElE,OAAyB,EACvB,qBAAqB,EACrB,aAAa,EACd,MAAM,mDAAmD,CAAA;AAG1D,OAAuB,EACrB,mBAAmB,EACpB,MAAM,qCAAqC,CAAA;AAC5C,OAA4B,EAC1B,wBAAwB,EACzB,MAAM,6CAA6C,CAAA;
|
|
1
|
+
{"version":3,"file":"QueryWrapperPlotNav.d.ts","sourceRoot":"","sources":["../../../src/components/QueryWrapperPlotNav/QueryWrapperPlotNav.tsx"],"names":[],"mappings":"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"}
|