@finos/legend-query-builder 4.14.45 → 4.14.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/lib/__lib__/QueryBuilderTesting.d.ts +1 -0
  2. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderTesting.js +1 -0
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.d.ts.map +1 -1
  6. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.js.map +1 -1
  7. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  8. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +93 -2
  9. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  10. package/lib/graph/QueryBuilderMetaModelConst.d.ts +1 -0
  11. package/lib/graph/QueryBuilderMetaModelConst.d.ts.map +1 -1
  12. package/lib/graph/QueryBuilderMetaModelConst.js +1 -0
  13. package/lib/graph/QueryBuilderMetaModelConst.js.map +1 -1
  14. package/lib/index.css +2 -2
  15. package/lib/index.css.map +1 -1
  16. package/lib/package.json +1 -1
  17. package/lib/stores/QueryBuilderStateHashUtils.d.ts +1 -0
  18. package/lib/stores/QueryBuilderStateHashUtils.d.ts.map +1 -1
  19. package/lib/stores/QueryBuilderStateHashUtils.js +1 -0
  20. package/lib/stores/QueryBuilderStateHashUtils.js.map +1 -1
  21. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts.map +1 -1
  22. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +2 -0
  23. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
  24. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperator.d.ts +2 -0
  25. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperator.d.ts.map +1 -1
  26. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperator.js +8 -0
  27. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperator.js.map +1 -1
  28. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperatorLoader.d.ts.map +1 -1
  29. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperatorLoader.js +2 -0
  30. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperatorLoader.js.map +1 -1
  31. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.d.ts +1 -0
  32. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.d.ts.map +1 -1
  33. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.js +7 -3
  34. package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.js.map +1 -1
  35. package/lib/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperatorValueSpecificationBuilder.d.ts.map +1 -1
  36. package/lib/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperatorValueSpecificationBuilder.js.map +1 -1
  37. package/lib/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_Percentile.d.ts +37 -0
  38. package/lib/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_Percentile.d.ts.map +1 -0
  39. package/lib/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_Percentile.js +123 -0
  40. package/lib/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_Percentile.js.map +1 -0
  41. package/package.json +3 -3
  42. package/src/__lib__/QueryBuilderTesting.ts +1 -0
  43. package/src/components/fetch-structure/QueryBuilderFetchStructurePanel.tsx +0 -1
  44. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +208 -4
  45. package/src/graph/QueryBuilderMetaModelConst.ts +1 -0
  46. package/src/stores/QueryBuilderStateHashUtils.ts +1 -0
  47. package/src/stores/fetch-structure/tds/QueryBuilderTDSState.ts +5 -0
  48. package/src/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperator.ts +10 -0
  49. package/src/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperatorLoader.ts +2 -0
  50. package/src/stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.ts +9 -3
  51. package/src/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperatorValueSpecificationBuilder.ts +0 -1
  52. package/src/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_Percentile.ts +241 -0
  53. package/tsconfig.json +1 -0
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { matchFunctionName, PRIMITIVE_TYPE, SimpleFunctionExpression, VariableExpression, GenericType, GenericTypeExplicitReference, Multiplicity, PrimitiveInstanceValue, PrimitiveType, extractElementNameFromPath, } from '@finos/legend-graph';
17
+ import { QueryBuilderAggregateColumnState } from '../QueryBuilderAggregationState.js';
18
+ import { QueryBuilderAggregateOperator } from '../QueryBuilderAggregateOperator.js';
19
+ import { QueryBuilderSimpleProjectionColumnState, } from '../../projection/QueryBuilderProjectionColumnState.js';
20
+ import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../../../../graph/QueryBuilderMetaModelConst.js';
21
+ import { hashArray, assertTrue, guaranteeType, } from '@finos/legend-shared';
22
+ import { QUERY_BUILDER_STATE_HASH_STRUCTURE } from '../../../../QueryBuilderStateHashUtils.js';
23
+ import { action, makeObservable, observable } from 'mobx';
24
+ export class QueryBuilderAggregateOperator_Percentile extends QueryBuilderAggregateOperator {
25
+ percentile;
26
+ acending;
27
+ continuous;
28
+ constructor() {
29
+ super();
30
+ makeObservable(this, {
31
+ percentile: observable,
32
+ acending: observable,
33
+ continuous: observable,
34
+ setPercentile: action,
35
+ setAcending: action,
36
+ setContinuous: action,
37
+ });
38
+ }
39
+ setPercentile(val) {
40
+ this.percentile = val;
41
+ }
42
+ setAcending(val) {
43
+ this.acending = val;
44
+ }
45
+ setContinuous(val) {
46
+ this.continuous = val;
47
+ }
48
+ getLabel(projectionColumnState) {
49
+ return 'percentile';
50
+ }
51
+ isCompatibleWithColumn(projectionColumnState) {
52
+ if (projectionColumnState instanceof QueryBuilderSimpleProjectionColumnState) {
53
+ const propertyType = projectionColumnState.propertyExpressionState.propertyExpression.func
54
+ .value.genericType.value.rawType;
55
+ return [
56
+ PRIMITIVE_TYPE.NUMBER,
57
+ PRIMITIVE_TYPE.INTEGER,
58
+ PRIMITIVE_TYPE.DECIMAL,
59
+ PRIMITIVE_TYPE.FLOAT,
60
+ ].includes(propertyType.path);
61
+ }
62
+ return true;
63
+ }
64
+ buildAggregateExpression(propertyExpression, variableName, graph) {
65
+ const percentileValue = this.percentile ?? 0;
66
+ const expression = new SimpleFunctionExpression(extractElementNameFromPath(QUERY_BUILDER_SUPPORTED_FUNCTIONS.PERCENTILE));
67
+ const percentile = new PrimitiveInstanceValue(GenericTypeExplicitReference.create(new GenericType(PrimitiveType.NUMBER)));
68
+ percentile.values = [percentileValue];
69
+ if (this.acending === undefined ||
70
+ this.continuous === undefined ||
71
+ (this.acending && this.continuous)) {
72
+ expression.parametersValues.push(new VariableExpression(variableName, Multiplicity.ONE), percentile);
73
+ }
74
+ else {
75
+ const acending = new PrimitiveInstanceValue(GenericTypeExplicitReference.create(new GenericType(PrimitiveType.BOOLEAN)));
76
+ acending.values = [this.acending];
77
+ const continuous = new PrimitiveInstanceValue(GenericTypeExplicitReference.create(new GenericType(PrimitiveType.BOOLEAN)));
78
+ continuous.values = [this.continuous];
79
+ expression.parametersValues.push(new VariableExpression(variableName, Multiplicity.ONE), percentile, acending, continuous);
80
+ }
81
+ return expression;
82
+ }
83
+ buildAggregateColumnState(expression, lambdaParam, projectionColumnState) {
84
+ if (matchFunctionName(expression.functionName, QUERY_BUILDER_SUPPORTED_FUNCTIONS.PERCENTILE)) {
85
+ const aggregateColumnState = new QueryBuilderAggregateColumnState(projectionColumnState.tdsState.aggregationState, projectionColumnState, new QueryBuilderAggregateOperator_Percentile());
86
+ const currentOperator = guaranteeType(aggregateColumnState.operator, QueryBuilderAggregateOperator_Percentile);
87
+ aggregateColumnState.setLambdaParameterName(lambdaParam.name);
88
+ assertTrue([2, 4].includes(expression.parametersValues.length), `Can't process percentile() expression: percentile() expects 2 or 4 argument`);
89
+ // variable
90
+ const variableExpression = guaranteeType(expression.parametersValues[0], VariableExpression, `Can't process percentile() expression: only support percentile() immediately following a variable expression`);
91
+ assertTrue(aggregateColumnState.lambdaParameterName === variableExpression.name, `Can't process percentile() expression: expects variable used in lambda body '${variableExpression.name}' to match lambda parameter '${aggregateColumnState.lambdaParameterName}'`);
92
+ const percentile = guaranteeType(expression.parametersValues[1], PrimitiveInstanceValue, `Can't process percentile() expression: percentile() expects arugment #2 to be a primitive instance value`);
93
+ currentOperator.percentile = percentile.values[0];
94
+ if (expression.parametersValues.length === 4) {
95
+ const acending = guaranteeType(expression.parametersValues[2], PrimitiveInstanceValue, `Can't process percentile() expression: percentile() expects arugment #3 to be a primitive instance value`);
96
+ currentOperator.acending = acending.values[0];
97
+ const continuous = guaranteeType(expression.parametersValues[3], PrimitiveInstanceValue, `Can't process percentile() expression: percentile() expects arugment #4 to be a primitive instance value`);
98
+ currentOperator.continuous = continuous.values[0];
99
+ }
100
+ // operator
101
+ assertTrue(this.isCompatibleWithColumn(aggregateColumnState.projectionColumnState), `Can't process percentile() expression: property is not compatible with operator`);
102
+ aggregateColumnState.setOperator(currentOperator);
103
+ return aggregateColumnState;
104
+ }
105
+ return undefined;
106
+ }
107
+ get getOperator() {
108
+ return new QueryBuilderAggregateOperator_Percentile();
109
+ }
110
+ get allValidationIssues() {
111
+ const validationIssues = [];
112
+ if (this.percentile === undefined || this.percentile > 100) {
113
+ validationIssues.push('Invalid Aggregation Argument for Percentile');
114
+ }
115
+ return validationIssues;
116
+ }
117
+ get hashCode() {
118
+ return hashArray([
119
+ QUERY_BUILDER_STATE_HASH_STRUCTURE.AGGREGATE_OPERATOR_PERCENTILE,
120
+ ]);
121
+ }
122
+ }
123
+ //# sourceMappingURL=QueryBuilderAggregateOperator_Percentile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBuilderAggregateOperator_Percentile.js","sourceRoot":"","sources":["../../../../../../src/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_Percentile.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finos/legend-query-builder",
3
- "version": "4.14.45",
3
+ "version": "4.14.46",
4
4
  "description": "Legend query builder core",
5
5
  "keywords": [
6
6
  "legend",
@@ -42,10 +42,10 @@
42
42
  "test:watch": "jest --watch"
43
43
  },
44
44
  "dependencies": {
45
- "@finos/legend-application": "15.1.6",
45
+ "@finos/legend-application": "15.1.7",
46
46
  "@finos/legend-art": "7.1.35",
47
47
  "@finos/legend-graph": "31.10.3",
48
- "@finos/legend-lego": "1.2.36",
48
+ "@finos/legend-lego": "1.2.37",
49
49
  "@finos/legend-server-depot": "6.0.44",
50
50
  "@finos/legend-shared": "10.0.39",
51
51
  "@finos/legend-storage": "3.0.89",
@@ -40,6 +40,7 @@ export enum QUERY_BUILDER_TEST_ID {
40
40
  QUERY_BUILDER_WINDOW_GROUPBY = 'query__builder__window',
41
41
  QUERY_BUILDER_EXPLORER = 'query__builder__explorer',
42
42
  QUERY_BUILDER_PROPERTY_SEARCH_PANEL = 'query__builder__property__search__panel',
43
+ QUERY_BUILDER_PERCENTILE_PANEL = 'query__builder__percentile__panel',
43
44
  QUERY_BUILDER_PARAMETERS = 'query-builder__parameters',
44
45
  QUERY_BUILDER_CONSTANTS = 'query-builder__constants',
45
46
  QUERY_BUILDER_TOOLTIP_ICON = 'query-builder__tooltip__icon',
@@ -73,7 +73,6 @@ export const QueryBuilderFetchStructurePanel = observer(
73
73
  queryBuilderState.workflowState.getFetchStructureLayoutConfig(
74
74
  queryBuilderState,
75
75
  );
76
-
77
76
  return (
78
77
  <Panel data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FETCH_STRUCTURE}>
79
78
  <PanelHeader>
@@ -41,6 +41,8 @@ import {
41
41
  FunctionIcon,
42
42
  CogIcon,
43
43
  InfoCircleIcon,
44
+ BasePopover,
45
+ InputWithInlineValidation,
44
46
  } from '@finos/legend-art';
45
47
  import {
46
48
  type QueryBuilderExplorerTreeDragSource,
@@ -116,6 +118,7 @@ import {
116
118
  QueryBuilderPropertyInfoTooltip,
117
119
  } from '../shared/QueryBuilderPropertyInfoTooltip.js';
118
120
  import { getNameOfValueSpecification } from '../shared/QueryBuilderVariableSelector.js';
121
+ import { QueryBuilderAggregateOperator_Percentile } from '../../stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_Percentile.js';
119
122
 
120
123
  const QueryBuilderProjectionColumnContextMenu = observer(
121
124
  forwardRef<
@@ -689,6 +692,52 @@ const QueryBuilderProjectionColumnEditor = observer(
689
692
  }),
690
693
  [handleDrop],
691
694
  );
695
+ const percentileButtonRef = useRef<HTMLButtonElement>(null);
696
+ const percentileInputRef = useRef<HTMLInputElement>(null);
697
+ const [isPercentileOpen, setIsPercentileOpen] = useState(false);
698
+ const [percentileValue, setPercentileValue] = useState(
699
+ aggregateColumnState &&
700
+ aggregateColumnState.operator instanceof
701
+ QueryBuilderAggregateOperator_Percentile &&
702
+ aggregateColumnState.operator.percentile !== undefined
703
+ ? (aggregateColumnState.operator.percentile * 100).toString()
704
+ : '',
705
+ );
706
+ const [acending, setAcending] = useState(
707
+ aggregateColumnState &&
708
+ aggregateColumnState.operator instanceof
709
+ QueryBuilderAggregateOperator_Percentile
710
+ ? aggregateColumnState.operator.acending
711
+ : undefined,
712
+ );
713
+ const [continuous, setContinuous] = useState(
714
+ aggregateColumnState &&
715
+ aggregateColumnState.operator instanceof
716
+ QueryBuilderAggregateOperator_Percentile
717
+ ? aggregateColumnState.operator.continuous
718
+ : undefined,
719
+ );
720
+ const percentileOptions = ['true', 'false'].map((op) => ({
721
+ label: op,
722
+ value: op,
723
+ }));
724
+ const getPercentileDisplayValue = (): string => {
725
+ if (percentileValue === '') {
726
+ return '...';
727
+ }
728
+ if (acending === undefined || continuous === undefined) {
729
+ return `${Number(percentileValue)}`;
730
+ }
731
+ return `${Number(percentileValue)}, ${acending}, ${continuous}`;
732
+ };
733
+ const setPercentileArguments = (): void => {
734
+ setIsPercentileOpen(!isPercentileOpen);
735
+ };
736
+ const onPercentileValueChange: React.ChangeEventHandler<
737
+ HTMLInputElement
738
+ > = (event) => {
739
+ setPercentileValue(event.target.value);
740
+ };
692
741
 
693
742
  return (
694
743
  <PanelDnDEntry
@@ -817,12 +866,167 @@ const QueryBuilderProjectionColumnEditor = observer(
817
866
  <div className="query-builder__projection__column__aggregate">
818
867
  <div className="query-builder__projection__column__aggregate__operator">
819
868
  {aggregateColumnState && (
820
- <div className="query-builder__projection__column__aggregate__operator__label">
821
- {aggregateColumnState.operator.getLabel(
822
- projectionColumnState,
823
- )}
869
+ <div className="query-builder__projection__column__aggregate__operator">
870
+ <div className="query-builder__projection__column__aggregate__operator__label">
871
+ {aggregateColumnState.operator.getLabel(
872
+ projectionColumnState,
873
+ )}
874
+ {aggregateColumnState.operator instanceof
875
+ QueryBuilderAggregateOperator_Percentile && (
876
+ <button
877
+ className="query-builder__projection__column__aggregate__operator__percentile__badge"
878
+ ref={percentileButtonRef}
879
+ onClick={setPercentileArguments}
880
+ title="Set Percentile Argument(s)..."
881
+ >
882
+ {getPercentileDisplayValue()}
883
+ </button>
884
+ )}
885
+ </div>
824
886
  </div>
825
887
  )}
888
+ {aggregateColumnState && isPercentileOpen && (
889
+ <BasePopover
890
+ open={isPercentileOpen}
891
+ PaperProps={{
892
+ classes: {
893
+ root: 'query-builder__projection__column__aggregate__operator__percentile__container__root',
894
+ },
895
+ }}
896
+ className={clsx(
897
+ 'query-builder__projection__column__aggregate__operator__percentile__container',
898
+ )}
899
+ anchorEl={percentileButtonRef.current}
900
+ onClose={() => {
901
+ const percentileOperator =
902
+ aggregateColumnState.operator as QueryBuilderAggregateOperator_Percentile;
903
+ if (percentileValue === '') {
904
+ percentileOperator.setPercentile(undefined);
905
+ } else {
906
+ percentileOperator.setPercentile(
907
+ Number(percentileValue) / 100,
908
+ );
909
+ }
910
+ if (acending !== undefined && continuous !== undefined) {
911
+ percentileOperator.setAcending(acending);
912
+ percentileOperator.setContinuous(continuous);
913
+ }
914
+ setIsPercentileOpen(false);
915
+ }}
916
+ anchorOrigin={{
917
+ vertical: 'bottom',
918
+ horizontal: 'left',
919
+ }}
920
+ transformOrigin={{
921
+ vertical: 'top',
922
+ horizontal: 'center',
923
+ }}
924
+ >
925
+ <div
926
+ data-testid={
927
+ QUERY_BUILDER_TEST_ID.QUERY_BUILDER_PERCENTILE_PANEL
928
+ }
929
+ className=""
930
+ >
931
+ <div className="query-builder__projection__column__aggregate__operator__percentile__argument-combo">
932
+ <div className="query-builder__projection__column__aggregate__operator__percentile__argument-combo__label">
933
+ Percentile
934
+ <br />
935
+ (0-100)
936
+ </div>
937
+ <div
938
+ className={clsx(
939
+ 'query-builder__projection__column__aggregate__operator__percentile__argument-combo__value',
940
+ )}
941
+ >
942
+ <InputWithInlineValidation
943
+ ref={percentileInputRef}
944
+ className={clsx(
945
+ 'query-builder__projection__column__aggregate__operator__percentile__input input--dark',
946
+ )}
947
+ type="text"
948
+ inputMode="numeric"
949
+ onChange={onPercentileValueChange}
950
+ value={percentileValue}
951
+ error={
952
+ percentileValue && Number(percentileValue) > 100
953
+ ? `Invalid aggregation agruement for ${aggregateColumnState.columnName}`
954
+ : undefined
955
+ }
956
+ />
957
+ </div>
958
+ </div>
959
+ <div className="query-builder__projection__column__aggregate__operator__percentile__argument-combo">
960
+ <div className="query-builder__projection__column__aggregate__operator__percentile__argument-combo__label">
961
+ Acending
962
+ </div>
963
+ <CustomSelectorInput
964
+ className="query-loader__results__sort-by__selector query-builder__projection__column__aggregate__operator__percentile__argument-combo__value"
965
+ options={percentileOptions}
966
+ onChange={(option: {
967
+ label: string;
968
+ value: string;
969
+ }) => {
970
+ setAcending(option.value === 'true' ? true : false);
971
+ }}
972
+ value={{
973
+ label:
974
+ acending === undefined
975
+ ? ''
976
+ : acending
977
+ ? 'true'
978
+ : 'false',
979
+ value:
980
+ acending === undefined
981
+ ? ''
982
+ : acending
983
+ ? 'true'
984
+ : 'false',
985
+ }}
986
+ darkMode={
987
+ !applicationStore.layoutService
988
+ .TEMPORARY__isLightColorThemeEnabled
989
+ }
990
+ />
991
+ </div>
992
+ <div className="query-builder__projection__column__aggregate__operator__percentile__argument-combo">
993
+ <div className="query-builder__projection__column__aggregate__operator__percentile__argument-combo__label">
994
+ Continous
995
+ </div>
996
+ <CustomSelectorInput
997
+ className="query-loader__results__sort-by__selector query-builder__projection__column__aggregate__operator__percentile__argument-combo__value"
998
+ options={percentileOptions}
999
+ onChange={(option: {
1000
+ label: string;
1001
+ value: string;
1002
+ }) =>
1003
+ setContinuous(
1004
+ option.value === 'true' ? true : false,
1005
+ )
1006
+ }
1007
+ value={{
1008
+ label:
1009
+ continuous === undefined
1010
+ ? ''
1011
+ : continuous
1012
+ ? 'true'
1013
+ : 'false',
1014
+ value:
1015
+ continuous === undefined
1016
+ ? ''
1017
+ : continuous
1018
+ ? 'true'
1019
+ : 'false',
1020
+ }}
1021
+ darkMode={
1022
+ !applicationStore.layoutService
1023
+ .TEMPORARY__isLightColorThemeEnabled
1024
+ }
1025
+ />
1026
+ </div>
1027
+ </div>
1028
+ </BasePopover>
1029
+ )}
826
1030
  {isCalendarEnabled &&
827
1031
  aggregateColumnState &&
828
1032
  aggregateCalendarFunctions.length > 0 && (
@@ -163,6 +163,7 @@ export enum QUERY_BUILDER_SUPPORTED_FUNCTIONS {
163
163
  FROM = 'meta::pure::mapping::from',
164
164
  CHECKED = 'meta::pure::dataQuality::checked',
165
165
  MERGERUNTIMES = 'meta::pure::runtime::mergeRuntimes',
166
+ PERCENTILE = 'meta::pure::functions::math::percentile',
166
167
 
167
168
  // TOTDS
168
169
  TABLE_TO_TDS = 'meta::pure::tds::tableToTDS',
@@ -32,6 +32,7 @@ export enum QUERY_BUILDER_STATE_HASH_STRUCTURE {
32
32
  AGGREGATE_OPERATOR_STD_DEV_SAMPLE = 'AGGREGATE_OPERATOR_STD_DEV_SAMPLE',
33
33
  AGGREGATE_OPERATOR_SUM = 'AGGREGATE_OPERATOR_SUM',
34
34
  AGGREGATE_COLUMN_STATE = 'AGGREGATE_COLUMN_STATE',
35
+ AGGREGATE_OPERATOR_PERCENTILE = 'AGGREGATE_OPERATOR_PERCENTILE',
35
36
  AGGREGATION_STATE = 'AGGREGATION_STATE',
36
37
  SIMPLE_PROJECTION_COLUMN_STATE = 'SIMPLE_PROJECTION_COLUMN_STATE',
37
38
  PROPERTY_EXPRESSION_STATE = 'PROPERTY_EXPRESSION_STATE',
@@ -139,6 +139,7 @@ export class QueryBuilderTDSState
139
139
  super(queryBuilderState, fetchStructureState);
140
140
 
141
141
  makeObservable(this, {
142
+ aggregationState: observable,
142
143
  projectionColumns: observable,
143
144
  isConvertDerivationProjectionObjects: observable,
144
145
  showPostFilterPanel: observable,
@@ -343,6 +344,10 @@ export class QueryBuilderTDSState
343
344
  }
344
345
  });
345
346
 
347
+ this.aggregationState.allValidationIssues.forEach((issue) =>
348
+ validationIssues.push(issue),
349
+ );
350
+
346
351
  return validationIssues;
347
352
  }
348
353
 
@@ -35,6 +35,8 @@ export abstract class QueryBuilderAggregateOperator implements Hashable {
35
35
 
36
36
  constructor() {
37
37
  makeObservable(this, {
38
+ getOperator: computed,
39
+ allValidationIssues: computed,
38
40
  hashCode: computed,
39
41
  });
40
42
  }
@@ -84,5 +86,13 @@ export abstract class QueryBuilderAggregateOperator implements Hashable {
84
86
  return aggregateColumnState.projectionColumnState.getColumnType();
85
87
  }
86
88
 
89
+ get getOperator(): QueryBuilderAggregateOperator {
90
+ return this;
91
+ }
92
+
93
+ get allValidationIssues(): string[] {
94
+ return [];
95
+ }
96
+
87
97
  abstract get hashCode(): string;
88
98
  }
@@ -25,6 +25,7 @@ import { QueryBuilderAggregateOperator_Min } from './operators/QueryBuilderAggre
25
25
  import { QueryBuilderAggregateOperator_Max } from './operators/QueryBuilderAggregateOperator_Max.js';
26
26
  import { QueryBuilderAggregateOperator_JoinString } from './operators/QueryBuilderAggregateOperator_JoinString.js';
27
27
  import type { QueryBuilderAggregateOperator } from './QueryBuilderAggregateOperator.js';
28
+ import { QueryBuilderAggregateOperator_Percentile } from './operators/QueryBuilderAggregateOperator_Percentile.js';
28
29
 
29
30
  export const getQueryBuilderCoreAggregrationOperators =
30
31
  (): QueryBuilderAggregateOperator[] => [
@@ -35,6 +36,7 @@ export const getQueryBuilderCoreAggregrationOperators =
35
36
  new QueryBuilderAggregateOperator_Average(),
36
37
  new QueryBuilderAggregateOperator_Min(),
37
38
  new QueryBuilderAggregateOperator_Max(),
39
+ new QueryBuilderAggregateOperator_Percentile(),
38
40
  new QueryBuilderAggregateOperator_StdDev_Population(),
39
41
  new QueryBuilderAggregateOperator_StdDev_Sample(),
40
42
  new QueryBuilderAggregateOperator_JoinString(),
@@ -136,6 +136,8 @@ export class QueryBuilderAggregationState implements Hashable {
136
136
  addColumn: action,
137
137
  changeColumnAggregateOperator: action,
138
138
  disableCalendar: action,
139
+
140
+ allValidationIssues: computed,
139
141
  hashCode: computed,
140
142
  });
141
143
 
@@ -179,7 +181,7 @@ export class QueryBuilderAggregationState implements Hashable {
179
181
  `${colName} (${val.getLabel(projectionColumnState)})`,
180
182
  );
181
183
  }
182
- aggregateColumnState.setOperator(val);
184
+ aggregateColumnState.setOperator(val.getOperator);
183
185
  } else {
184
186
  if (!hideOperatorInColumnName) {
185
187
  projectionColumnState.setColumnName(
@@ -189,9 +191,9 @@ export class QueryBuilderAggregationState implements Hashable {
189
191
  const newAggregateColumnState = new QueryBuilderAggregateColumnState(
190
192
  this,
191
193
  projectionColumnState,
192
- val,
194
+ val.getOperator,
193
195
  );
194
- newAggregateColumnState.setOperator(val);
196
+ newAggregateColumnState.setOperator(val.getOperator);
195
197
  this.addColumn(newAggregateColumnState);
196
198
 
197
199
  // automatically move the column to the end
@@ -233,6 +235,10 @@ export class QueryBuilderAggregationState implements Hashable {
233
235
  });
234
236
  }
235
237
 
238
+ get allValidationIssues(): string[] {
239
+ return this.columns.map((col) => col.operator.allValidationIssues).flat();
240
+ }
241
+
236
242
  get hashCode(): string {
237
243
  return hashArray([
238
244
  QUERY_BUILDER_STATE_HASH_STRUCTURE.AGGREGATION_STATE,
@@ -97,7 +97,6 @@ export const buildAggregateColumnState = (
97
97
  )}() expression: property is not compatible with operator`,
98
98
  );
99
99
  aggregateColumnState.setOperator(operator);
100
-
101
100
  return aggregateColumnState;
102
101
  }
103
102