@finos/legend-query-builder 4.14.40 → 4.14.41
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/lib/components/QueryBuilderParametersPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderParametersPanel.js +20 -2
- package/lib/components/QueryBuilderParametersPanel.js.map +1 -1
- package/lib/components/QueryBuilderSideBar.d.ts.map +1 -1
- package/lib/components/QueryBuilderSideBar.js +5 -14
- package/lib/components/QueryBuilderSideBar.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +12 -4
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.js +6 -2
- package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
- package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/result/QueryBuilderResultPanel.js +2 -1
- package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/shared/BasicValueSpecificationEditor.d.ts +11 -9
- package/lib/components/shared/BasicValueSpecificationEditor.d.ts.map +1 -1
- package/lib/components/shared/BasicValueSpecificationEditor.js +158 -143
- package/lib/components/shared/BasicValueSpecificationEditor.js.map +1 -1
- package/lib/components/shared/QueryBuilderVariableSelector.d.ts.map +1 -1
- package/lib/components/shared/QueryBuilderVariableSelector.js +8 -1
- package/lib/components/shared/QueryBuilderVariableSelector.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderPropertyEditorState.d.ts +1 -0
- package/lib/stores/QueryBuilderPropertyEditorState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderPropertyEditorState.js +2 -1
- package/lib/stores/QueryBuilderPropertyEditorState.js.map +1 -1
- package/lib/stores/QueryBuilderState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderState.js +12 -0
- package/lib/stores/QueryBuilderState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.js +2 -2
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.d.ts +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.js +4 -3
- package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.js.map +1 -1
- package/lib/stores/milestoning/QueryBuilderMilestoningHelper.d.ts +1 -0
- package/lib/stores/milestoning/QueryBuilderMilestoningHelper.d.ts.map +1 -1
- package/lib/stores/milestoning/QueryBuilderMilestoningHelper.js +16 -0
- package/lib/stores/milestoning/QueryBuilderMilestoningHelper.js.map +1 -1
- package/lib/stores/milestoning/QueryBuilderMilestoningState.d.ts +3 -0
- package/lib/stores/milestoning/QueryBuilderMilestoningState.d.ts.map +1 -1
- package/lib/stores/milestoning/QueryBuilderMilestoningState.js +40 -0
- package/lib/stores/milestoning/QueryBuilderMilestoningState.js.map +1 -1
- package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts +1 -0
- package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts.map +1 -1
- package/lib/stores/shared/ValueSpecificationEditorHelper.js +48 -0
- package/lib/stores/shared/ValueSpecificationEditorHelper.js.map +1 -1
- package/package.json +8 -8
- package/src/components/QueryBuilderParametersPanel.tsx +55 -0
- package/src/components/QueryBuilderSideBar.tsx +0 -35
- package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +22 -6
- package/src/components/filter/QueryBuilderFilterPanel.tsx +13 -5
- package/src/components/result/QueryBuilderResultPanel.tsx +9 -1
- package/src/components/shared/BasicValueSpecificationEditor.tsx +288 -285
- package/src/components/shared/QueryBuilderVariableSelector.tsx +22 -0
- package/src/stores/QueryBuilderPropertyEditorState.ts +2 -1
- package/src/stores/QueryBuilderState.ts +14 -0
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.ts +2 -2
- package/src/stores/filter/QueryBuilderFilterState.ts +6 -3
- package/src/stores/filter/operators/QueryBuilderFilterOperator_In.ts +2 -2
- package/src/stores/milestoning/QueryBuilderMilestoningHelper.ts +24 -0
- package/src/stores/milestoning/QueryBuilderMilestoningState.ts +54 -0
- package/src/stores/shared/ValueSpecificationEditorHelper.ts +63 -0
@@ -14,10 +14,14 @@
|
|
14
14
|
* limitations under the License.
|
15
15
|
*/
|
16
16
|
|
17
|
-
import {
|
17
|
+
import {
|
18
|
+
DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH,
|
19
|
+
useApplicationStore,
|
20
|
+
} from '@finos/legend-application';
|
18
21
|
import {
|
19
22
|
type TooltipPlacement,
|
20
23
|
type InputActionData,
|
24
|
+
type SelectActionData,
|
21
25
|
Tooltip,
|
22
26
|
DollarIcon,
|
23
27
|
clsx,
|
@@ -29,9 +33,6 @@ import {
|
|
29
33
|
SaveIcon,
|
30
34
|
PencilIcon,
|
31
35
|
DragPreviewLayer,
|
32
|
-
FilledWindowMaximizeIcon,
|
33
|
-
BasePopover,
|
34
|
-
PanelFormSection,
|
35
36
|
CalculateIcon,
|
36
37
|
InputWithInlineValidation,
|
37
38
|
} from '@finos/legend-art';
|
@@ -52,7 +53,6 @@ import {
|
|
52
53
|
GenericTypeExplicitReference,
|
53
54
|
GenericType,
|
54
55
|
Enumeration,
|
55
|
-
getEnumValue,
|
56
56
|
getMultiplicityDescription,
|
57
57
|
type ObserverContext,
|
58
58
|
matchFunctionName,
|
@@ -63,16 +63,16 @@ import {
|
|
63
63
|
type GeneratorFn,
|
64
64
|
guaranteeNonNullable,
|
65
65
|
isNonNullable,
|
66
|
-
returnUndefOnError,
|
67
|
-
uniq,
|
68
|
-
parseCSVString,
|
69
66
|
guaranteeIsNumber,
|
70
67
|
csvStringify,
|
71
68
|
guaranteeType,
|
69
|
+
isNonEmptyString,
|
70
|
+
parseCSVString,
|
71
|
+
uniq,
|
72
72
|
} from '@finos/legend-shared';
|
73
73
|
import { flowResult } from 'mobx';
|
74
74
|
import { observer } from 'mobx-react-lite';
|
75
|
-
import {
|
75
|
+
import React, {
|
76
76
|
forwardRef,
|
77
77
|
useEffect,
|
78
78
|
useImperativeHandle,
|
@@ -91,6 +91,10 @@ import {
|
|
91
91
|
} from '../../stores/QueryBuilderValueSpecificationHelper.js';
|
92
92
|
import { evaluate } from 'mathjs';
|
93
93
|
import { isUsedDateFunctionSupportedInFormMode } from '../../stores/QueryBuilderStateBuilder.js';
|
94
|
+
import {
|
95
|
+
convertTextToPrimitiveInstanceValue,
|
96
|
+
getValueSpecificationStringValue,
|
97
|
+
} from '../../stores/shared/ValueSpecificationEditorHelper.js';
|
94
98
|
|
95
99
|
type TypeCheckOption = {
|
96
100
|
expectedType: Type;
|
@@ -222,16 +226,7 @@ const StringPrimitiveInstanceValueEditor = observer(
|
|
222
226
|
className?: string | undefined;
|
223
227
|
setValueSpecification: (val: ValueSpecification) => void;
|
224
228
|
resetValue: () => void;
|
225
|
-
selectorConfig?:
|
226
|
-
| {
|
227
|
-
values: string[] | undefined;
|
228
|
-
isLoading: boolean;
|
229
|
-
reloadValues:
|
230
|
-
| DebouncedFunc<(inputValue: string) => GeneratorFn<void>>
|
231
|
-
| undefined;
|
232
|
-
cleanUpReloadValues?: () => void;
|
233
|
-
}
|
234
|
-
| undefined;
|
229
|
+
selectorConfig?: BasicValueSpecificationEditorSelectorConfig | undefined;
|
235
230
|
obseverContext: ObserverContext;
|
236
231
|
}
|
237
232
|
>(function StringPrimitiveInstanceValueEditor(props, ref) {
|
@@ -628,153 +623,276 @@ const stringifyValue = (values: ValueSpecification[]): string => {
|
|
628
623
|
]).trim();
|
629
624
|
};
|
630
625
|
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
): void => {
|
643
|
-
if (value.trim().length === 0) {
|
644
|
-
instanceValue_setValues(valueSpecification, [], obseverContext);
|
645
|
-
return;
|
626
|
+
const getPlaceHolder = (expectedType: Type): string => {
|
627
|
+
if (expectedType instanceof PrimitiveType) {
|
628
|
+
switch (expectedType.path) {
|
629
|
+
case PRIMITIVE_TYPE.DATE:
|
630
|
+
case PRIMITIVE_TYPE.STRICTDATE:
|
631
|
+
return 'yyyy-mm-dd';
|
632
|
+
case PRIMITIVE_TYPE.DATETIME:
|
633
|
+
return 'yyyy-mm-ddThh:mm:ss';
|
634
|
+
default:
|
635
|
+
return 'Add';
|
636
|
+
}
|
646
637
|
}
|
647
|
-
|
638
|
+
return 'Add';
|
639
|
+
};
|
648
640
|
|
649
|
-
|
641
|
+
interface BasicValueSpecificationEditorSelectorConfig {
|
642
|
+
values: string[] | undefined;
|
643
|
+
isLoading: boolean;
|
644
|
+
reloadValues:
|
645
|
+
| DebouncedFunc<(inputValue: string) => GeneratorFn<void>>
|
646
|
+
| undefined;
|
647
|
+
cleanUpReloadValues?: () => void;
|
648
|
+
}
|
650
649
|
|
651
|
-
|
652
|
-
|
653
|
-
|
650
|
+
const PrimitiveCollectionInstanceValueEditor = observer(
|
651
|
+
(props: {
|
652
|
+
valueSpecification: CollectionInstanceValue;
|
653
|
+
expectedType: Type;
|
654
|
+
saveEdit: () => void;
|
655
|
+
selectorConfig?: BasicValueSpecificationEditorSelectorConfig | undefined;
|
656
|
+
observerContext: ObserverContext;
|
657
|
+
}) => {
|
658
|
+
const {
|
659
|
+
valueSpecification,
|
660
|
+
expectedType,
|
661
|
+
saveEdit,
|
662
|
+
selectorConfig,
|
663
|
+
observerContext,
|
664
|
+
} = props;
|
654
665
|
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
666
|
+
// local state and variables
|
667
|
+
const applicationStore = useApplicationStore();
|
668
|
+
const inputRef = useRef(null);
|
669
|
+
const [inputValue, setInputValue] = useState('');
|
670
|
+
const [inputValueIsError, setInputValueIsError] = useState(false);
|
671
|
+
const [selectedOptions, setSelectedOptions] = useState<
|
672
|
+
{ label: string; value: string }[]
|
673
|
+
>(
|
674
|
+
valueSpecification.values
|
675
|
+
.map((valueSpec) => getValueSpecificationStringValue(valueSpec))
|
676
|
+
.filter(isNonEmptyString)
|
677
|
+
.map((value) => ({
|
678
|
+
label: value,
|
679
|
+
value,
|
680
|
+
})),
|
681
|
+
);
|
682
|
+
|
683
|
+
// typehead search setup
|
684
|
+
const isTypeaheadSearchEnabled =
|
685
|
+
expectedType === PrimitiveType.STRING && Boolean(selectorConfig);
|
686
|
+
const reloadValuesFunc = isTypeaheadSearchEnabled
|
687
|
+
? selectorConfig?.reloadValues
|
688
|
+
: undefined;
|
689
|
+
const cleanUpReloadValuesFunc = isTypeaheadSearchEnabled
|
690
|
+
? selectorConfig?.cleanUpReloadValues
|
691
|
+
: undefined;
|
692
|
+
const isLoading = isTypeaheadSearchEnabled
|
693
|
+
? selectorConfig?.isLoading
|
694
|
+
: undefined;
|
695
|
+
const queryOptions =
|
696
|
+
isTypeaheadSearchEnabled && selectorConfig?.values?.length
|
697
|
+
? selectorConfig.values.map((e) => ({
|
698
|
+
value: e,
|
699
|
+
label: e.toString(),
|
700
|
+
}))
|
701
|
+
: undefined;
|
702
|
+
const noMatchMessage =
|
703
|
+
isTypeaheadSearchEnabled && isLoading ? 'Loading...' : undefined;
|
704
|
+
|
705
|
+
// helper functions
|
706
|
+
const buildOptionForValueSpec = (
|
707
|
+
value: ValueSpecification,
|
708
|
+
): { label: string; value: string } => {
|
709
|
+
const stringValue = guaranteeNonNullable(
|
710
|
+
getValueSpecificationStringValue(value),
|
711
|
+
);
|
712
|
+
return {
|
713
|
+
label: stringValue,
|
714
|
+
value: stringValue,
|
715
|
+
};
|
716
|
+
};
|
717
|
+
|
718
|
+
const isValueAlreadySelected = (value: string): boolean =>
|
719
|
+
selectedOptions.map((option) => option.value).includes(value);
|
720
|
+
|
721
|
+
/**
|
722
|
+
* NOTE: We attempt to be less disruptive here by not throwing errors left and right, instead
|
723
|
+
* we simply return null for values which are not valid or parsable. But perhaps, we can consider
|
724
|
+
* passing in logger or notifier to give the users some idea of what went wrong instead of ignoring
|
725
|
+
* their input.
|
726
|
+
*/
|
727
|
+
const convertInputValueToValueSpec = (): ValueSpecification | null => {
|
728
|
+
const trimmedInputValue = inputValue.trim();
|
729
|
+
|
730
|
+
if (isValueAlreadySelected(trimmedInputValue)) {
|
731
|
+
return null;
|
674
732
|
}
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
.map((val) => Number(val)),
|
683
|
-
)
|
684
|
-
.map((item): PrimitiveInstanceValue | undefined => {
|
685
|
-
const primitiveInstanceValue = new PrimitiveInstanceValue(
|
686
|
-
GenericTypeExplicitReference.create(
|
687
|
-
new GenericType(expectedType),
|
688
|
-
),
|
689
|
-
);
|
690
|
-
instanceValue_setValues(
|
691
|
-
primitiveInstanceValue,
|
692
|
-
[item],
|
693
|
-
obseverContext,
|
694
|
-
);
|
695
|
-
return primitiveInstanceValue;
|
696
|
-
})
|
697
|
-
.filter(isNonNullable);
|
698
|
-
break;
|
733
|
+
|
734
|
+
if (trimmedInputValue.length) {
|
735
|
+
return convertTextToPrimitiveInstanceValue(
|
736
|
+
expectedType,
|
737
|
+
trimmedInputValue,
|
738
|
+
observerContext,
|
739
|
+
);
|
699
740
|
}
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
[item],
|
716
|
-
obseverContext,
|
717
|
-
);
|
718
|
-
return primitiveInstanceValue;
|
719
|
-
})
|
720
|
-
.filter(isNonNullable);
|
721
|
-
break;
|
741
|
+
return null;
|
742
|
+
};
|
743
|
+
|
744
|
+
const addInputValueToSelectedOptions = (): void => {
|
745
|
+
const newValueSpec = convertInputValueToValueSpec();
|
746
|
+
|
747
|
+
if (newValueSpec !== null) {
|
748
|
+
setSelectedOptions([
|
749
|
+
...selectedOptions,
|
750
|
+
buildOptionForValueSpec(newValueSpec),
|
751
|
+
]);
|
752
|
+
setInputValue('');
|
753
|
+
reloadValuesFunc?.cancel();
|
754
|
+
} else if (inputValue.trim().length) {
|
755
|
+
setInputValueIsError(true);
|
722
756
|
}
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
new GenericType(expectedType),
|
739
|
-
),
|
740
|
-
);
|
741
|
-
instanceValue_setValues(
|
742
|
-
primitiveInstanceValue,
|
743
|
-
[item],
|
744
|
-
obseverContext,
|
745
|
-
);
|
746
|
-
return primitiveInstanceValue;
|
747
|
-
})
|
748
|
-
.filter(isNonNullable);
|
749
|
-
break;
|
757
|
+
};
|
758
|
+
|
759
|
+
// event handlers
|
760
|
+
const changeValue = (
|
761
|
+
newSelectedOptions: { value: string; label: string }[],
|
762
|
+
actionChange: SelectActionData<{ value: string; label: string }>,
|
763
|
+
): void => {
|
764
|
+
setSelectedOptions(newSelectedOptions);
|
765
|
+
if (actionChange.action === 'select-option') {
|
766
|
+
setInputValue('');
|
767
|
+
} else if (
|
768
|
+
actionChange.action === 'remove-value' &&
|
769
|
+
actionChange.removedValue.value === inputValue
|
770
|
+
) {
|
771
|
+
setInputValueIsError(false);
|
750
772
|
}
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
.
|
758
|
-
|
759
|
-
|
760
|
-
);
|
761
|
-
|
762
|
-
|
773
|
+
};
|
774
|
+
|
775
|
+
const handleInputChange = (
|
776
|
+
newInputValue: string,
|
777
|
+
actionChange: InputActionData,
|
778
|
+
): void => {
|
779
|
+
if (actionChange.action === 'input-change') {
|
780
|
+
setInputValue(newInputValue);
|
781
|
+
setInputValueIsError(false);
|
782
|
+
reloadValuesFunc?.cancel();
|
783
|
+
const reloadValuesFuncTransformation =
|
784
|
+
reloadValuesFunc?.(newInputValue);
|
785
|
+
if (reloadValuesFuncTransformation) {
|
786
|
+
flowResult(reloadValuesFuncTransformation).catch(
|
787
|
+
applicationStore.alertUnhandledError,
|
788
|
+
);
|
763
789
|
}
|
764
|
-
|
765
|
-
|
766
|
-
);
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
790
|
+
}
|
791
|
+
if (actionChange.action === 'input-blur') {
|
792
|
+
reloadValuesFunc?.cancel();
|
793
|
+
cleanUpReloadValuesFunc?.();
|
794
|
+
}
|
795
|
+
};
|
796
|
+
|
797
|
+
const updateValueSpecAndSaveEdit = (): void => {
|
798
|
+
const newValueSpec = convertInputValueToValueSpec();
|
799
|
+
const finalSelectedOptions =
|
800
|
+
newValueSpec !== null
|
801
|
+
? [...selectedOptions, buildOptionForValueSpec(newValueSpec)]
|
802
|
+
: selectedOptions;
|
803
|
+
instanceValue_setValues(
|
804
|
+
valueSpecification,
|
805
|
+
finalSelectedOptions
|
806
|
+
.map((option) => option.value)
|
807
|
+
.map((value) =>
|
808
|
+
convertTextToPrimitiveInstanceValue(
|
809
|
+
expectedType,
|
810
|
+
value,
|
811
|
+
observerContext,
|
812
|
+
),
|
813
|
+
)
|
814
|
+
.filter(isNonNullable),
|
815
|
+
observerContext,
|
816
|
+
);
|
817
|
+
saveEdit();
|
818
|
+
};
|
819
|
+
|
820
|
+
const handleKeyDown = (event: KeyboardEvent): void => {
|
821
|
+
if ((event.key === 'Enter' || event.key === ',') && !event.shiftKey) {
|
822
|
+
addInputValueToSelectedOptions();
|
823
|
+
event.preventDefault();
|
824
|
+
}
|
825
|
+
};
|
826
|
+
|
827
|
+
const handlePaste = (event: React.ClipboardEvent<string>): void => {
|
828
|
+
const pastedText = event.clipboardData.getData('text');
|
829
|
+
const parsedData = parseCSVString(pastedText);
|
830
|
+
if (!parsedData) {
|
831
|
+
return;
|
832
|
+
}
|
833
|
+
const newValues = uniq(parsedData)
|
834
|
+
.map((value) => {
|
835
|
+
const newValueSpec = convertTextToPrimitiveInstanceValue(
|
836
|
+
expectedType,
|
837
|
+
value,
|
838
|
+
observerContext,
|
839
|
+
);
|
840
|
+
return newValueSpec
|
841
|
+
? getValueSpecificationStringValue(newValueSpec)
|
842
|
+
: null;
|
843
|
+
})
|
844
|
+
.filter(isNonNullable)
|
845
|
+
.filter((value) => !isValueAlreadySelected(value));
|
846
|
+
setSelectedOptions([
|
847
|
+
...selectedOptions,
|
848
|
+
...newValues.map((value) => ({ label: value, value })),
|
849
|
+
]);
|
850
|
+
event.preventDefault();
|
851
|
+
};
|
852
|
+
|
853
|
+
return (
|
854
|
+
<>
|
855
|
+
<CustomSelectorInput
|
856
|
+
className={clsx('value-spec-editor__primitive-collection-selector', {
|
857
|
+
'value-spec-editor__primitive-collection-selector--error':
|
858
|
+
inputValueIsError,
|
859
|
+
})}
|
860
|
+
options={queryOptions}
|
861
|
+
inputValue={inputValue}
|
862
|
+
isMulti={true}
|
863
|
+
menuIsOpen={
|
864
|
+
isTypeaheadSearchEnabled &&
|
865
|
+
inputValue.length >= DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH
|
866
|
+
}
|
867
|
+
autoFocus={true}
|
868
|
+
inputRef={inputRef}
|
869
|
+
onChange={changeValue}
|
870
|
+
onInputChange={handleInputChange}
|
871
|
+
onBlur={() => updateValueSpecAndSaveEdit()}
|
872
|
+
onKeyDown={handleKeyDown}
|
873
|
+
onPaste={handlePaste}
|
874
|
+
value={selectedOptions}
|
875
|
+
darkMode={
|
876
|
+
!applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
|
877
|
+
}
|
878
|
+
isLoading={isLoading}
|
879
|
+
noMatchMessage={noMatchMessage}
|
880
|
+
placeholder={null}
|
881
|
+
inputPlaceholder={getPlaceHolder(expectedType)}
|
882
|
+
components={{
|
883
|
+
DropdownIndicator: null,
|
884
|
+
}}
|
885
|
+
/>
|
886
|
+
<button
|
887
|
+
className="value-spec-editor__list-editor__save-button btn--dark"
|
888
|
+
onClick={updateValueSpecAndSaveEdit}
|
889
|
+
>
|
890
|
+
<SaveIcon />
|
891
|
+
</button>
|
892
|
+
</>
|
893
|
+
);
|
894
|
+
},
|
895
|
+
);
|
778
896
|
|
779
897
|
const EnumCollectionInstanceValueEditor = observer(
|
780
898
|
(props: {
|
@@ -853,7 +971,8 @@ const EnumCollectionInstanceValueEditor = observer(
|
|
853
971
|
darkMode={
|
854
972
|
!applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
|
855
973
|
}
|
856
|
-
placeholder=
|
974
|
+
placeholder={null}
|
975
|
+
inputPlaceholder="Add"
|
857
976
|
autoFocus={true}
|
858
977
|
menuIsOpen={true}
|
859
978
|
/>
|
@@ -870,21 +989,6 @@ const EnumCollectionInstanceValueEditor = observer(
|
|
870
989
|
|
871
990
|
const COLLECTION_PREVIEW_CHAR_LIMIT = 50;
|
872
991
|
|
873
|
-
const getPlaceHolder = (expectedType: Type): string => {
|
874
|
-
if (expectedType instanceof PrimitiveType) {
|
875
|
-
switch (expectedType.path) {
|
876
|
-
case PRIMITIVE_TYPE.DATE:
|
877
|
-
case PRIMITIVE_TYPE.STRICTDATE:
|
878
|
-
return 'yyyy-mm-dd';
|
879
|
-
case PRIMITIVE_TYPE.DATETIME:
|
880
|
-
return 'yyyy-mm-ddThh:mm:ss';
|
881
|
-
default:
|
882
|
-
return '(empty)';
|
883
|
-
}
|
884
|
-
}
|
885
|
-
return '(empty)';
|
886
|
-
};
|
887
|
-
|
888
992
|
const CollectionValueInstanceValueEditor = observer(
|
889
993
|
(props: {
|
890
994
|
valueSpecification: CollectionInstanceValue;
|
@@ -893,6 +997,7 @@ const CollectionValueInstanceValueEditor = observer(
|
|
893
997
|
className?: string | undefined;
|
894
998
|
resetValue: () => void;
|
895
999
|
setValueSpecification: (val: ValueSpecification) => void;
|
1000
|
+
selectorConfig?: BasicValueSpecificationEditorSelectorConfig | undefined;
|
896
1001
|
obseverContext: ObserverContext;
|
897
1002
|
}) => {
|
898
1003
|
const {
|
@@ -901,14 +1006,11 @@ const CollectionValueInstanceValueEditor = observer(
|
|
901
1006
|
className,
|
902
1007
|
resetValue,
|
903
1008
|
setValueSpecification,
|
1009
|
+
selectorConfig,
|
904
1010
|
obseverContext,
|
905
1011
|
} = props;
|
906
|
-
const inputRef = useRef<HTMLTextAreaElement>(null);
|
907
1012
|
|
908
|
-
const [text, setText] = useState(stringifyValue(valueSpecification.values));
|
909
1013
|
const [editable, setEditable] = useState(false);
|
910
|
-
const [showAdvancedEditorPopover, setShowAdvancedEditorPopover] =
|
911
|
-
useState(false);
|
912
1014
|
const valueText = stringifyValue(valueSpecification.values);
|
913
1015
|
const previewText = `List(${
|
914
1016
|
valueSpecification.values.length === 0
|
@@ -927,78 +1029,13 @@ const CollectionValueInstanceValueEditor = observer(
|
|
927
1029
|
const saveEdit = (): void => {
|
928
1030
|
if (editable) {
|
929
1031
|
setEditable(false);
|
930
|
-
setShowAdvancedEditorPopover(false);
|
931
1032
|
setValueSpecification(valueSpecification);
|
932
1033
|
}
|
933
1034
|
};
|
934
|
-
const updateValueSpecAndSaveEdit = (): void => {
|
935
|
-
if (editable) {
|
936
|
-
setCollectionValue(
|
937
|
-
valueSpecification,
|
938
|
-
expectedType,
|
939
|
-
text,
|
940
|
-
obseverContext,
|
941
|
-
);
|
942
|
-
setText(stringifyValue(valueSpecification.values));
|
943
|
-
saveEdit();
|
944
|
-
}
|
945
|
-
};
|
946
|
-
|
947
|
-
const changeValueTextArea: React.ChangeEventHandler<HTMLTextAreaElement> = (
|
948
|
-
event,
|
949
|
-
) => {
|
950
|
-
setText(event.target.value);
|
951
|
-
};
|
952
|
-
const expandButtonName = `${valueSpecification.hashCode}ExpandButton`;
|
953
|
-
const handleOnBlur: React.FocusEventHandler<HTMLTextAreaElement> = (
|
954
|
-
event,
|
955
|
-
) => {
|
956
|
-
// disable save if target is expand button
|
957
|
-
if (
|
958
|
-
(event.relatedTarget as HTMLButtonElement | undefined)?.name !==
|
959
|
-
expandButtonName
|
960
|
-
) {
|
961
|
-
updateValueSpecAndSaveEdit();
|
962
|
-
}
|
963
|
-
};
|
964
|
-
|
965
|
-
const placeholder = text === '' ? getPlaceHolder(expectedType) : undefined;
|
966
|
-
|
967
|
-
// focus the input box when edit is enabled
|
968
|
-
useEffect(() => {
|
969
|
-
if (editable) {
|
970
|
-
inputRef.current?.focus();
|
971
|
-
}
|
972
|
-
}, [editable]);
|
973
1035
|
|
974
1036
|
if (editable) {
|
975
1037
|
return (
|
976
1038
|
<>
|
977
|
-
{showAdvancedEditorPopover && (
|
978
|
-
<BasePopover
|
979
|
-
onClose={() => setShowAdvancedEditorPopover(false)}
|
980
|
-
open={showAdvancedEditorPopover}
|
981
|
-
anchorEl={inputRef.current}
|
982
|
-
>
|
983
|
-
<textarea
|
984
|
-
className="panel__content__form__section__input value-spec-editor__list-editor__textarea"
|
985
|
-
spellCheck={false}
|
986
|
-
value={text}
|
987
|
-
placeholder={placeholder}
|
988
|
-
onChange={changeValueTextArea}
|
989
|
-
onKeyDown={(event): void => {
|
990
|
-
if (event.key === 'Enter' && !event.shiftKey) {
|
991
|
-
updateValueSpecAndSaveEdit();
|
992
|
-
}
|
993
|
-
}}
|
994
|
-
/>
|
995
|
-
<PanelFormSection>
|
996
|
-
<div className="value-spec-editor__list-editor__textarea__description">
|
997
|
-
Hit Enter to Apply Change
|
998
|
-
</div>
|
999
|
-
</PanelFormSection>
|
1000
|
-
</BasePopover>
|
1001
|
-
)}
|
1002
1039
|
<div className={clsx('value-spec-editor', className)}>
|
1003
1040
|
{expectedType instanceof Enumeration ? (
|
1004
1041
|
<EnumCollectionInstanceValueEditor
|
@@ -1007,39 +1044,13 @@ const CollectionValueInstanceValueEditor = observer(
|
|
1007
1044
|
saveEdit={saveEdit}
|
1008
1045
|
/>
|
1009
1046
|
) : (
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
value={text}
|
1018
|
-
placeholder={placeholder}
|
1019
|
-
onChange={changeValueTextArea}
|
1020
|
-
onKeyDown={(event): void => {
|
1021
|
-
if (event.key === 'Enter' && !event.shiftKey) {
|
1022
|
-
updateValueSpecAndSaveEdit();
|
1023
|
-
}
|
1024
|
-
}}
|
1025
|
-
onBlur={handleOnBlur}
|
1026
|
-
/>
|
1027
|
-
<button
|
1028
|
-
className="value-spec-editor__list-editor__expand-button btn--dark"
|
1029
|
-
onClick={() => setShowAdvancedEditorPopover(true)}
|
1030
|
-
tabIndex={-1}
|
1031
|
-
name={expandButtonName}
|
1032
|
-
title="Expand window..."
|
1033
|
-
>
|
1034
|
-
<FilledWindowMaximizeIcon />
|
1035
|
-
</button>
|
1036
|
-
<button
|
1037
|
-
className="value-spec-editor__list-editor__save-button btn--dark"
|
1038
|
-
onClick={saveEdit}
|
1039
|
-
>
|
1040
|
-
<SaveIcon />
|
1041
|
-
</button>
|
1042
|
-
</>
|
1047
|
+
<PrimitiveCollectionInstanceValueEditor
|
1048
|
+
valueSpecification={valueSpecification}
|
1049
|
+
expectedType={expectedType}
|
1050
|
+
saveEdit={saveEdit}
|
1051
|
+
selectorConfig={selectorConfig}
|
1052
|
+
observerContext={obseverContext}
|
1053
|
+
/>
|
1043
1054
|
)}
|
1044
1055
|
<button
|
1045
1056
|
className="value-spec-editor__reset-btn"
|
@@ -1141,16 +1152,7 @@ export const BasicValueSpecificationEditor = forwardRef<
|
|
1141
1152
|
setValueSpecification: (val: ValueSpecification) => void;
|
1142
1153
|
resetValue: () => void;
|
1143
1154
|
isConstant?: boolean;
|
1144
|
-
selectorConfig?:
|
1145
|
-
| {
|
1146
|
-
values: string[] | undefined;
|
1147
|
-
isLoading: boolean;
|
1148
|
-
reloadValues:
|
1149
|
-
| DebouncedFunc<(inputValue: string) => GeneratorFn<void>>
|
1150
|
-
| undefined;
|
1151
|
-
cleanUpReloadValues?: () => void;
|
1152
|
-
}
|
1153
|
-
| undefined;
|
1155
|
+
selectorConfig?: BasicValueSpecificationEditorSelectorConfig | undefined;
|
1154
1156
|
}
|
1155
1157
|
>(function BasicValueSpecificationEditor(props, ref) {
|
1156
1158
|
const {
|
@@ -1249,6 +1251,7 @@ export const BasicValueSpecificationEditor = forwardRef<
|
|
1249
1251
|
className={className}
|
1250
1252
|
resetValue={resetValue}
|
1251
1253
|
setValueSpecification={setValueSpecification}
|
1254
|
+
selectorConfig={selectorConfig}
|
1252
1255
|
obseverContext={obseverContext}
|
1253
1256
|
/>
|
1254
1257
|
);
|