@finos/legend-query-builder 4.14.45 → 4.14.46

Sign up to get free protection for your applications and to get access to all the features.
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