@finos/legend-application 8.0.2 → 9.0.1

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 (123) hide show
  1. package/lib/components/LegendApplicationComponentFrameworkProvider.d.ts +4 -2
  2. package/lib/components/LegendApplicationComponentFrameworkProvider.d.ts.map +1 -1
  3. package/lib/components/LegendApplicationComponentFrameworkProvider.js +7 -4
  4. package/lib/components/LegendApplicationComponentFrameworkProvider.js.map +1 -1
  5. package/lib/components/NotificationManager.js +1 -1
  6. package/lib/components/NotificationManager.js.map +1 -1
  7. package/lib/components/WebApplicationNavigatorProvider.d.ts.map +1 -1
  8. package/lib/components/WebApplicationNavigatorProvider.js +1 -1
  9. package/lib/components/WebApplicationNavigatorProvider.js.map +1 -1
  10. package/lib/components/{shared/execution-plan-viewer → execution-plan-viewer}/ExecutionPlanViewer.d.ts +1 -1
  11. package/lib/components/execution-plan-viewer/ExecutionPlanViewer.d.ts.map +1 -0
  12. package/lib/components/{shared/execution-plan-viewer → execution-plan-viewer}/ExecutionPlanViewer.js +3 -3
  13. package/lib/components/execution-plan-viewer/ExecutionPlanViewer.js.map +1 -0
  14. package/lib/components/{shared/execution-plan-viewer → execution-plan-viewer}/SQLExecutionNodeViewer.d.ts +1 -1
  15. package/lib/components/execution-plan-viewer/SQLExecutionNodeViewer.d.ts.map +1 -0
  16. package/lib/components/{shared/execution-plan-viewer → execution-plan-viewer}/SQLExecutionNodeViewer.js +2 -2
  17. package/lib/components/execution-plan-viewer/SQLExecutionNodeViewer.js.map +1 -0
  18. package/lib/components/shared/DocumentationLink.d.ts +5 -0
  19. package/lib/components/shared/DocumentationLink.d.ts.map +1 -1
  20. package/lib/components/shared/DocumentationLink.js +12 -2
  21. package/lib/components/shared/DocumentationLink.js.map +1 -1
  22. package/lib/components/shared/{PackageableElementOptionRenderer.d.ts → PackageableElementOptionLabel.d.ts} +1 -1
  23. package/lib/components/shared/PackageableElementOptionLabel.d.ts.map +1 -0
  24. package/lib/components/shared/{PackageableElementOptionRenderer.js → PackageableElementOptionLabel.js} +5 -5
  25. package/lib/components/shared/PackageableElementOptionLabel.js.map +1 -0
  26. package/lib/components/shared/TextInputEditor.d.ts.map +1 -1
  27. package/lib/components/shared/TextInputEditor.js +1 -2
  28. package/lib/components/shared/TextInputEditor.js.map +1 -1
  29. package/lib/index.css +2 -2
  30. package/lib/index.css.map +1 -1
  31. package/lib/index.d.ts +8 -9
  32. package/lib/index.d.ts.map +1 -1
  33. package/lib/index.js +8 -9
  34. package/lib/index.js.map +1 -1
  35. package/lib/stores/ApplicationStore.d.ts +2 -0
  36. package/lib/stores/ApplicationStore.d.ts.map +1 -1
  37. package/lib/stores/ApplicationStore.js +13 -10
  38. package/lib/stores/ApplicationStore.js.map +1 -1
  39. package/lib/stores/AssistantService.js +1 -1
  40. package/lib/stores/AssistantService.js.map +1 -1
  41. package/lib/stores/{shared/ExecutionPlanState.d.ts → ExecutionPlanState.d.ts} +1 -1
  42. package/lib/stores/ExecutionPlanState.d.ts.map +1 -0
  43. package/lib/stores/{shared/ExecutionPlanState.js → ExecutionPlanState.js} +0 -0
  44. package/lib/stores/ExecutionPlanState.js.map +1 -0
  45. package/lib/stores/LegendApplicationDocumentation.d.ts +2 -1
  46. package/lib/stores/LegendApplicationDocumentation.d.ts.map +1 -1
  47. package/lib/stores/LegendApplicationDocumentation.js +1 -0
  48. package/lib/stores/LegendApplicationDocumentation.js.map +1 -1
  49. package/lib/stores/WebApplicationNavigator.d.ts +62 -30
  50. package/lib/stores/WebApplicationNavigator.d.ts.map +1 -1
  51. package/lib/stores/WebApplicationNavigator.js +80 -15
  52. package/lib/stores/WebApplicationNavigator.js.map +1 -1
  53. package/lib/{components/ApplicationTestID.js → stores/WebApplicationRouter.d.ts} +4 -5
  54. package/lib/stores/WebApplicationRouter.d.ts.map +1 -0
  55. package/{src/components/ApplicationTestID.ts → lib/stores/WebApplicationRouter.js} +4 -4
  56. package/lib/stores/WebApplicationRouter.js.map +1 -0
  57. package/package.json +9 -11
  58. package/src/components/LegendApplicationComponentFrameworkProvider.tsx +18 -14
  59. package/src/components/NotificationManager.tsx +1 -1
  60. package/src/components/WebApplicationNavigatorProvider.tsx +1 -1
  61. package/src/components/{shared/execution-plan-viewer → execution-plan-viewer}/ExecutionPlanViewer.tsx +3 -3
  62. package/src/components/{shared/execution-plan-viewer → execution-plan-viewer}/SQLExecutionNodeViewer.tsx +3 -3
  63. package/src/components/shared/DocumentationLink.tsx +25 -1
  64. package/src/components/shared/{PackageableElementOptionRenderer.tsx → PackageableElementOptionLabel.tsx} +4 -4
  65. package/src/components/shared/TextInputEditor.tsx +1 -2
  66. package/src/index.ts +9 -9
  67. package/src/stores/ApplicationStore.ts +15 -12
  68. package/src/stores/AssistantService.ts +1 -1
  69. package/src/stores/{shared/ExecutionPlanState.ts → ExecutionPlanState.ts} +1 -1
  70. package/src/stores/LegendApplicationDocumentation.ts +1 -0
  71. package/src/stores/WebApplicationNavigator.ts +149 -39
  72. package/{lib/components/ApplicationTestID.d.ts → src/stores/WebApplicationRouter.ts} +12 -4
  73. package/tsconfig.json +7 -16
  74. package/lib/components/ApplicationTestID.d.ts.map +0 -1
  75. package/lib/components/ApplicationTestID.js.map +0 -1
  76. package/lib/components/shared/BasicValueSpecificationEditor.d.ts +0 -52
  77. package/lib/components/shared/BasicValueSpecificationEditor.d.ts.map +0 -1
  78. package/lib/components/shared/BasicValueSpecificationEditor.js +0 -323
  79. package/lib/components/shared/BasicValueSpecificationEditor.js.map +0 -1
  80. package/lib/components/shared/CustomDatePicker.d.ts +0 -38
  81. package/lib/components/shared/CustomDatePicker.d.ts.map +0 -1
  82. package/lib/components/shared/CustomDatePicker.js +0 -616
  83. package/lib/components/shared/CustomDatePicker.js.map +0 -1
  84. package/lib/components/shared/LambdaEditor.d.ts +0 -92
  85. package/lib/components/shared/LambdaEditor.d.ts.map +0 -1
  86. package/lib/components/shared/LambdaEditor.js +0 -434
  87. package/lib/components/shared/LambdaEditor.js.map +0 -1
  88. package/lib/components/shared/LambdaParameterValuesEditor.d.ts +0 -25
  89. package/lib/components/shared/LambdaParameterValuesEditor.d.ts.map +0 -1
  90. package/lib/components/shared/LambdaParameterValuesEditor.js +0 -52
  91. package/lib/components/shared/LambdaParameterValuesEditor.js.map +0 -1
  92. package/lib/components/shared/PackageableElementOptionRenderer.d.ts.map +0 -1
  93. package/lib/components/shared/PackageableElementOptionRenderer.js.map +0 -1
  94. package/lib/components/shared/execution-plan-viewer/ExecutionPlanViewer.d.ts.map +0 -1
  95. package/lib/components/shared/execution-plan-viewer/ExecutionPlanViewer.js.map +0 -1
  96. package/lib/components/shared/execution-plan-viewer/SQLExecutionNodeViewer.d.ts.map +0 -1
  97. package/lib/components/shared/execution-plan-viewer/SQLExecutionNodeViewer.js.map +0 -1
  98. package/lib/stores/CJS__Fuse.cjs +0 -35
  99. package/lib/stores/CJS__Fuse.cjs.map +0 -1
  100. package/lib/stores/CJS__Fuse.d.cts +0 -28
  101. package/lib/stores/CJS__Fuse.d.cts.map +0 -1
  102. package/lib/stores/shared/ExecutionPlanState.d.ts.map +0 -1
  103. package/lib/stores/shared/ExecutionPlanState.js.map +0 -1
  104. package/lib/stores/shared/LambdaEditorState.d.ts +0 -40
  105. package/lib/stores/shared/LambdaEditorState.d.ts.map +0 -1
  106. package/lib/stores/shared/LambdaEditorState.js +0 -81
  107. package/lib/stores/shared/LambdaEditorState.js.map +0 -1
  108. package/lib/stores/shared/LambdaParameterState.d.ts +0 -62
  109. package/lib/stores/shared/LambdaParameterState.d.ts.map +0 -1
  110. package/lib/stores/shared/LambdaParameterState.js +0 -160
  111. package/lib/stores/shared/LambdaParameterState.js.map +0 -1
  112. package/lib/stores/shared/ValueSpecificationModifierHelper.d.ts +0 -27
  113. package/lib/stores/shared/ValueSpecificationModifierHelper.d.ts.map +0 -1
  114. package/lib/stores/shared/ValueSpecificationModifierHelper.js +0 -49
  115. package/lib/stores/shared/ValueSpecificationModifierHelper.js.map +0 -1
  116. package/src/components/shared/BasicValueSpecificationEditor.tsx +0 -828
  117. package/src/components/shared/CustomDatePicker.tsx +0 -1292
  118. package/src/components/shared/LambdaEditor.tsx +0 -854
  119. package/src/components/shared/LambdaParameterValuesEditor.tsx +0 -118
  120. package/src/stores/CJS__Fuse.cts +0 -28
  121. package/src/stores/shared/LambdaEditorState.ts +0 -118
  122. package/src/stores/shared/LambdaParameterState.ts +0 -253
  123. package/src/stores/shared/ValueSpecificationModifierHelper.ts +0 -104
@@ -1,828 +0,0 @@
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
-
17
- import {
18
- type TooltipPlacement,
19
- type InputActionMeta,
20
- Tooltip,
21
- DollarIcon,
22
- clsx,
23
- InfoCircleIcon,
24
- RefreshIcon,
25
- CheckSquareIcon,
26
- SquareIcon,
27
- CustomSelectorInput,
28
- SaveIcon,
29
- PencilIcon,
30
- } from '@finos/legend-art';
31
- import {
32
- type Enum,
33
- type Type,
34
- type ValueSpecification,
35
- type PureModel,
36
- PrimitiveInstanceValue,
37
- CollectionInstanceValue,
38
- EnumValueInstanceValue,
39
- INTERNAL__PropagatedValue,
40
- SimpleFunctionExpression,
41
- VariableExpression,
42
- EnumValueExplicitReference,
43
- TYPICAL_MULTIPLICITY_TYPE,
44
- PrimitiveType,
45
- PRIMITIVE_TYPE,
46
- GenericTypeExplicitReference,
47
- GenericType,
48
- Enumeration,
49
- getEnumValue,
50
- getMultiplicityDescription,
51
- } from '@finos/legend-graph';
52
- import {
53
- type DebouncedFunc,
54
- type GeneratorFn,
55
- guaranteeNonNullable,
56
- isNonNullable,
57
- returnUndefOnError,
58
- uniq,
59
- } from '@finos/legend-shared';
60
- import { flowResult } from 'mobx';
61
- import { observer } from 'mobx-react-lite';
62
- import CSVParser from 'papaparse';
63
- import { useEffect, useRef, useState } from 'react';
64
- import {
65
- instanceValue_changeValue,
66
- instanceValue_changeValues,
67
- } from '../../stores/shared/ValueSpecificationModifierHelper.js';
68
- import { useApplicationStore } from '../ApplicationStoreProvider.js';
69
- import { CustomDatePicker } from './CustomDatePicker.js';
70
-
71
- type TypeCheckOption = {
72
- expectedType: Type;
73
- /**
74
- * Indicates if a strict type-matching will happen.
75
- * Sometimes, auto-boxing allow some rooms to wiggle,
76
- * for example we can assign a Float to an Integer, a
77
- * Date to a DateTime. With this flag set to `true`
78
- * we will not allow this.
79
- */
80
- match?: boolean;
81
- };
82
-
83
- const ParameterInfoTooltip: React.FC<{
84
- variable: VariableExpression;
85
- children: React.ReactElement;
86
- placement?: TooltipPlacement | undefined;
87
- }> = (props) => {
88
- const { variable, children, placement } = props;
89
- const type = variable.genericType?.value.rawType;
90
- return (
91
- <Tooltip
92
- arrow={true}
93
- {...(placement !== undefined ? { placement } : {})}
94
- classes={{
95
- tooltip: 'value-spec-paramater__tooltip',
96
- arrow: 'value-spec-paramater__tooltip__arrow',
97
- tooltipPlacementRight: 'value-spec-paramater__tooltip--right',
98
- }}
99
- TransitionProps={{
100
- // disable transition
101
- // NOTE: somehow, this is the only workaround we have, if for example
102
- // we set `appear = true`, the tooltip will jump out of position
103
- timeout: 0,
104
- }}
105
- title={
106
- <div className="value-spec-paramater__tooltip__content">
107
- <div className="value-spec-paramater__tooltip__item">
108
- <div className="value-spec-paramater__tooltip__item__label">
109
- Type
110
- </div>
111
- <div className="value-spec-paramater__tooltip__item__value">
112
- {type?.name ?? ''}
113
- </div>
114
- </div>
115
- <div className="value-spec-paramater__tooltip__item">
116
- <div className="value-spec-paramater__tooltip__item__label">
117
- Var Name
118
- </div>
119
- <div className="value-spec-paramater__tooltip__item__value">
120
- {variable.name}
121
- </div>
122
- </div>
123
- <div className="value-spec-paramater__tooltip__item">
124
- <div className="value-spec-paramater__tooltip__item__label">
125
- Multiplicity
126
- </div>
127
- <div className="value-spec-paramater__tooltip__item__value">
128
- {getMultiplicityDescription(variable.multiplicity)}
129
- </div>
130
- </div>
131
- </div>
132
- }
133
- >
134
- {children}
135
- </Tooltip>
136
- );
137
- };
138
-
139
- const VariableExpressionParameterEditor = observer(
140
- (props: {
141
- valueSpecification: VariableExpression;
142
- className?: string | undefined;
143
- resetValue: () => void;
144
- }) => {
145
- const { valueSpecification, className, resetValue } = props;
146
- const varName = valueSpecification.name;
147
- return (
148
- <div className={clsx('value-spec-editor__parameter', className)}>
149
- <div className="value-spec-editor__parameter__icon">
150
- <DollarIcon />
151
- </div>
152
- <div className="value-spec-editor__parameter__label">
153
- <div className="value-spec-editor__parameter__text">{varName}</div>
154
- <ParameterInfoTooltip variable={valueSpecification}>
155
- <div className="value-spec-editor__parameter__info">
156
- <InfoCircleIcon />
157
- </div>
158
- </ParameterInfoTooltip>
159
- <button
160
- className="value-spec-editor__parameter__reset-btn"
161
- title="Reset"
162
- onClick={resetValue}
163
- >
164
- <RefreshIcon />
165
- </button>
166
- </div>
167
- </div>
168
- );
169
- },
170
- );
171
-
172
- const StringPrimitiveInstanceValueEditor = observer(
173
- (props: {
174
- valueSpecification: PrimitiveInstanceValue;
175
- className?: string | undefined;
176
- setValueSpecification: (val: ValueSpecification) => void;
177
- resetValue: () => void;
178
- selectorConfig?:
179
- | {
180
- values: string[] | undefined;
181
- isLoading: boolean;
182
- reloadValues:
183
- | DebouncedFunc<(inputValue: string) => GeneratorFn<void>>
184
- | undefined;
185
- cleanUpReloadValues?: () => void;
186
- }
187
- | undefined;
188
- }) => {
189
- const {
190
- valueSpecification,
191
- className,
192
- resetValue,
193
- setValueSpecification,
194
- selectorConfig,
195
- } = props;
196
- const useSelector = Boolean(selectorConfig);
197
- const applicationStore = useApplicationStore();
198
- const value = valueSpecification.values[0] as string;
199
- const updateValueSpec = (val: string): void => {
200
- instanceValue_changeValue(valueSpecification, val, 0);
201
- setValueSpecification(valueSpecification);
202
- };
203
- const changeInputValue: React.ChangeEventHandler<HTMLInputElement> = (
204
- event,
205
- ) => {
206
- updateValueSpec(event.target.value);
207
- };
208
- // custom select
209
- const selectedValue = { value: value, label: value };
210
- const reloadValuesFunc = selectorConfig?.reloadValues;
211
- const changeValue = (
212
- val: null | { value: number | string; label: string },
213
- ): void => {
214
- const newValue = val === null ? '' : val.value.toString();
215
- updateValueSpec(newValue);
216
- };
217
- const handleInputChange = (
218
- inputValue: string,
219
- actionChange: InputActionMeta,
220
- ): void => {
221
- if (actionChange.action === 'input-change') {
222
- updateValueSpec(inputValue);
223
- reloadValuesFunc?.cancel();
224
- const reloadValuesFuncTransformation = reloadValuesFunc?.(inputValue);
225
- if (reloadValuesFuncTransformation) {
226
- flowResult(reloadValuesFuncTransformation).catch(
227
- applicationStore.alertUnhandledError,
228
- );
229
- }
230
- }
231
- if (actionChange.action === 'input-blur') {
232
- reloadValuesFunc?.cancel();
233
- selectorConfig?.cleanUpReloadValues?.();
234
- }
235
- };
236
- const isLoading = selectorConfig?.isLoading;
237
- const queryOptions = selectorConfig?.values?.length
238
- ? selectorConfig.values.map((e) => ({
239
- value: e,
240
- label: e.toString(),
241
- }))
242
- : undefined;
243
- const noOptionsMessage =
244
- selectorConfig?.values === undefined ? (): null => null : undefined;
245
-
246
- return (
247
- <div className={clsx('value-spec-editor', className)}>
248
- {useSelector ? (
249
- <CustomSelectorInput
250
- className="value-spec-editor__enum-selector"
251
- options={queryOptions}
252
- onChange={changeValue}
253
- value={selectedValue}
254
- onInputChange={handleInputChange}
255
- darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
256
- isLoading={isLoading}
257
- allowCreateWhileLoading={true}
258
- noOptionsMessage={noOptionsMessage}
259
- components={{
260
- DropdownIndicator: null,
261
- }}
262
- />
263
- ) : (
264
- <input
265
- className="panel__content__form__section__input value-spec-editor__input"
266
- spellCheck={false}
267
- value={value}
268
- placeholder={value === '' ? '(empty)' : undefined}
269
- onChange={changeInputValue}
270
- />
271
- )}
272
- <button
273
- className="value-spec-editor__reset-btn"
274
- title="Reset"
275
- onClick={resetValue}
276
- >
277
- <RefreshIcon />
278
- </button>
279
- </div>
280
- );
281
- },
282
- );
283
-
284
- const BooleanPrimitiveInstanceValueEditor = observer(
285
- (props: {
286
- valueSpecification: PrimitiveInstanceValue;
287
- className?: string | undefined;
288
- resetValue: () => void;
289
- setValueSpecification: (val: ValueSpecification) => void;
290
- }) => {
291
- const { valueSpecification, className, resetValue, setValueSpecification } =
292
- props;
293
- const value = valueSpecification.values[0] as boolean;
294
- const toggleValue = (): void => {
295
- instanceValue_changeValue(valueSpecification, !value, 0);
296
- setValueSpecification(valueSpecification);
297
- };
298
-
299
- return (
300
- <div className={clsx('value-spec-editor', className)}>
301
- <button
302
- className={clsx('value-spec-editor__toggler__btn', {
303
- 'value-spec-editor__toggler__btn--toggled': value,
304
- })}
305
- onClick={toggleValue}
306
- >
307
- {value ? <CheckSquareIcon /> : <SquareIcon />}
308
- </button>
309
- <button
310
- className="value-spec-editor__reset-btn"
311
- title="Reset"
312
- onClick={resetValue}
313
- >
314
- <RefreshIcon />
315
- </button>
316
- </div>
317
- );
318
- },
319
- );
320
-
321
- const NumberPrimitiveInstanceValueEditor = observer(
322
- (props: {
323
- valueSpecification: PrimitiveInstanceValue;
324
- isInteger: boolean;
325
- className?: string | undefined;
326
- resetValue: () => void;
327
- setValueSpecification: (val: ValueSpecification) => void;
328
- }) => {
329
- const {
330
- valueSpecification,
331
- isInteger,
332
- className,
333
- resetValue,
334
- setValueSpecification,
335
- } = props;
336
- const value = valueSpecification.values[0] as number;
337
- const changeValue: React.ChangeEventHandler<HTMLInputElement> = (event) => {
338
- let inputVal = isInteger
339
- ? parseInt(event.target.value, 10)
340
- : parseFloat(event.target.value);
341
- inputVal = isNaN(inputVal) ? 0 : inputVal;
342
- instanceValue_changeValue(valueSpecification, inputVal, 0);
343
- setValueSpecification(valueSpecification);
344
- };
345
-
346
- return (
347
- <div className={clsx('value-spec-editor', className)}>
348
- <input
349
- className="panel__content__form__section__input value-spec-editor__input"
350
- spellCheck={false}
351
- type="number"
352
- value={value}
353
- onChange={changeValue}
354
- />
355
- <button
356
- className="value-spec-editor__reset-btn"
357
- title="Reset"
358
- onClick={resetValue}
359
- >
360
- <RefreshIcon />
361
- </button>
362
- </div>
363
- );
364
- },
365
- );
366
-
367
- const EnumValueInstanceValueEditor = observer(
368
- (props: {
369
- valueSpecification: EnumValueInstanceValue;
370
- className?: string | undefined;
371
- setValueSpecification: (val: ValueSpecification) => void;
372
- resetValue: () => void;
373
- }) => {
374
- const { valueSpecification, className, resetValue, setValueSpecification } =
375
- props;
376
- const enumValueRef = guaranteeNonNullable(valueSpecification.values[0]);
377
- const enumValue = enumValueRef.value;
378
- const options = enumValue._OWNER.values.map((value) => ({
379
- label: value.name,
380
- value: value,
381
- }));
382
- const changeValue = (val: { value: Enum; label: string }): void => {
383
- instanceValue_changeValue(
384
- valueSpecification,
385
- EnumValueExplicitReference.create(val.value),
386
- 0,
387
- );
388
- setValueSpecification(valueSpecification);
389
- };
390
-
391
- return (
392
- <div className={clsx('value-spec-editor', className)}>
393
- <CustomSelectorInput
394
- className="value-spec-editor__enum-selector"
395
- options={options}
396
- onChange={changeValue}
397
- value={{ value: enumValue, label: enumValue.name }}
398
- darkMode={true}
399
- />
400
- <button
401
- className="value-spec-editor__reset-btn"
402
- title="Reset"
403
- onClick={resetValue}
404
- >
405
- <RefreshIcon />
406
- </button>
407
- </div>
408
- );
409
- },
410
- );
411
-
412
- const stringifyValue = (values: ValueSpecification[]): string => {
413
- if (values.length === 0) {
414
- return '';
415
- }
416
- return CSVParser.unparse([
417
- values
418
- .map((val) => {
419
- if (val instanceof PrimitiveInstanceValue) {
420
- return val.values[0];
421
- } else if (val instanceof EnumValueInstanceValue) {
422
- return guaranteeNonNullable(val.values[0]).value.name;
423
- }
424
- return undefined;
425
- })
426
- .filter(isNonNullable),
427
- ]).trim();
428
- };
429
-
430
- /**
431
- * NOTE: We attempt to be less disruptive here by not throwing errors left and right, instead
432
- * we silently remove values which are not valid or parsable. But perhaps, we can consider
433
- * passing in logger or notifier to show give the users some idea of what went wrong instead
434
- * of silently swallow parts of their inputs like this.
435
- */
436
- const setCollectionValue = (
437
- valueSpecification: CollectionInstanceValue,
438
- graph: PureModel,
439
- expectedType: Type,
440
- value: string,
441
- ): void => {
442
- if (value.trim().length === 0) {
443
- instanceValue_changeValues(valueSpecification, []);
444
- return;
445
- }
446
- const multiplicityOne = graph.getTypicalMultiplicity(
447
- TYPICAL_MULTIPLICITY_TYPE.ONE,
448
- );
449
- let result: unknown[] = [];
450
- const parseResult = CSVParser.parse<string[]>(value.trim(), {
451
- delimiter: ',',
452
- });
453
- const parseData = parseResult.data[0] as string[]; // only take the first line
454
- if (parseResult.errors.length) {
455
- if (
456
- parseResult.errors[0] &&
457
- parseResult.errors[0].code === 'UndetectableDelimiter' &&
458
- parseResult.errors[0].type === 'Delimiter' &&
459
- parseResult.data.length === 1
460
- ) {
461
- // NOTE: this happens when the user only put one item in the value input
462
- // we can go the other way by ensure the input has a comma but this is arguably neater
463
- // as it tinkers with the parser
464
- } else {
465
- // there were some parsing error, escape
466
- // NOTE: ideally, we could show a warning here
467
- return;
468
- }
469
- } else if (expectedType instanceof PrimitiveType) {
470
- switch (expectedType.path) {
471
- case PRIMITIVE_TYPE.STRING: {
472
- result = uniq(parseData)
473
- .map((item): PrimitiveInstanceValue | undefined => {
474
- const primitiveInstanceValue = new PrimitiveInstanceValue(
475
- GenericTypeExplicitReference.create(
476
- new GenericType(expectedType),
477
- ),
478
- multiplicityOne,
479
- );
480
- primitiveInstanceValue.values = [item.toString()];
481
- return primitiveInstanceValue;
482
- })
483
- .filter(isNonNullable);
484
- break;
485
- }
486
- case PRIMITIVE_TYPE.NUMBER:
487
- case PRIMITIVE_TYPE.FLOAT:
488
- case PRIMITIVE_TYPE.DECIMAL:
489
- case PRIMITIVE_TYPE.INTEGER: {
490
- result = uniq(
491
- parseData
492
- .filter((val) => !isNaN(Number(val)))
493
- .map((val) => Number(val)),
494
- )
495
- .map((item): PrimitiveInstanceValue | undefined => {
496
- const primitiveInstanceValue = new PrimitiveInstanceValue(
497
- GenericTypeExplicitReference.create(
498
- new GenericType(expectedType),
499
- ),
500
- multiplicityOne,
501
- );
502
- primitiveInstanceValue.values = [item];
503
- return primitiveInstanceValue;
504
- })
505
- .filter(isNonNullable);
506
- break;
507
- }
508
- default:
509
- // unsupported expected type, just escape
510
- return;
511
- }
512
- } else if (expectedType instanceof Enumeration) {
513
- result = uniq(parseData.map((item) => item.trim()))
514
- .map((item): EnumValueInstanceValue | undefined => {
515
- const _enum = returnUndefOnError(() =>
516
- getEnumValue(expectedType, item),
517
- );
518
- if (!_enum) {
519
- return undefined;
520
- }
521
- const enumValueInstanceValue = new EnumValueInstanceValue(
522
- GenericTypeExplicitReference.create(new GenericType(expectedType)),
523
- multiplicityOne,
524
- );
525
- enumValueInstanceValue.values = [
526
- EnumValueExplicitReference.create(_enum),
527
- ];
528
- return enumValueInstanceValue;
529
- })
530
- .filter(isNonNullable);
531
- }
532
- instanceValue_changeValues(valueSpecification, result);
533
- };
534
-
535
- const COLLECTION_PREVIEW_CHAR_LIMIT = 50;
536
-
537
- const CollectionValueInstanceValueEditor = observer(
538
- (props: {
539
- valueSpecification: CollectionInstanceValue;
540
- graph: PureModel;
541
- expectedType: Type;
542
- className?: string | undefined;
543
- resetValue: () => void;
544
- setValueSpecification: (val: ValueSpecification) => void;
545
- }) => {
546
- const {
547
- valueSpecification,
548
- graph,
549
- expectedType,
550
- className,
551
- resetValue,
552
- setValueSpecification,
553
- } = props;
554
- const inputRef = useRef<HTMLInputElement>(null);
555
- const [text, setText] = useState(stringifyValue(valueSpecification.values));
556
- const [editable, setEditable] = useState(false);
557
- const valueText = stringifyValue(valueSpecification.values);
558
- const previewText = `List(${
559
- valueSpecification.values.length === 0
560
- ? 'empty'
561
- : valueSpecification.values.length
562
- })${
563
- valueSpecification.values.length === 0
564
- ? ''
565
- : `: ${
566
- valueText.length > COLLECTION_PREVIEW_CHAR_LIMIT
567
- ? `${valueText.substring(0, COLLECTION_PREVIEW_CHAR_LIMIT)}...`
568
- : valueText
569
- }`
570
- }`;
571
- const enableEdit = (): void => setEditable(true);
572
- const saveEdit = (): void => {
573
- setEditable(false);
574
- setCollectionValue(valueSpecification, graph, expectedType, text);
575
- setText(stringifyValue(valueSpecification.values));
576
- setValueSpecification(valueSpecification);
577
- };
578
- const changeValue: React.ChangeEventHandler<HTMLInputElement> = (event) =>
579
- setText(event.target.value);
580
-
581
- // focus the input box when edit is enabled
582
- useEffect(() => {
583
- if (editable) {
584
- inputRef.current?.focus();
585
- }
586
- }, [editable]);
587
-
588
- if (editable) {
589
- return (
590
- <div className={clsx('value-spec-editor', className)}>
591
- <input
592
- ref={inputRef}
593
- className="panel__content__form__section__input value-spec-editor__input"
594
- spellCheck={false}
595
- value={text}
596
- placeholder={text === '' ? '(empty)' : undefined}
597
- onChange={changeValue}
598
- />
599
- <button
600
- className="value-spec-editor__list-editor__save-button btn--dark"
601
- onClick={saveEdit}
602
- >
603
- <SaveIcon />
604
- </button>
605
- <button
606
- className="value-spec-editor__reset-btn"
607
- title="Reset"
608
- onClick={resetValue}
609
- >
610
- <RefreshIcon />
611
- </button>
612
- </div>
613
- );
614
- }
615
- return (
616
- <div
617
- className={clsx('value-spec-editor', className)}
618
- onClick={enableEdit}
619
- title="Click to edit"
620
- >
621
- <input
622
- className="value-spec-editor__list-editor__preview"
623
- spellCheck={false}
624
- value={previewText}
625
- disabled={true}
626
- />
627
- <button className="value-spec-editor__list-editor__edit-icon">
628
- <PencilIcon />
629
- </button>
630
- </div>
631
- );
632
- },
633
- );
634
-
635
- const UnsupportedValueSpecificationEditor: React.FC = () => (
636
- <div className="value-spec-editor--unsupported">unsupported</div>
637
- );
638
-
639
- const DateInstanceValueEditor = observer(
640
- (props: {
641
- valueSpecification: PrimitiveInstanceValue | SimpleFunctionExpression;
642
- graph: PureModel;
643
- typeCheckOption: TypeCheckOption;
644
- className?: string | undefined;
645
- setValueSpecification: (val: ValueSpecification) => void;
646
- resetValue: () => void;
647
- }) => {
648
- const {
649
- valueSpecification,
650
- setValueSpecification,
651
- graph,
652
- typeCheckOption,
653
- resetValue,
654
- } = props;
655
-
656
- return (
657
- <div className="value-spec-editor">
658
- <CustomDatePicker
659
- valueSpecification={valueSpecification}
660
- graph={graph}
661
- typeCheckOption={typeCheckOption}
662
- setValueSpecification={setValueSpecification}
663
- />
664
- <button
665
- className="value-spec-editor__reset-btn"
666
- title="Reset"
667
- onClick={resetValue}
668
- >
669
- <RefreshIcon />
670
- </button>
671
- </div>
672
- );
673
- },
674
- );
675
-
676
- /**
677
- * TODO we should pass in the props `resetValueSpecification`. Reset
678
- * should be part of this editor. Also through here we can call `observe_` accordingly.
679
- *
680
- * See https://github.com/finos/legend-studio/pull/1021
681
- */
682
- export const BasicValueSpecificationEditor: React.FC<{
683
- valueSpecification: ValueSpecification;
684
- graph: PureModel;
685
- typeCheckOption: TypeCheckOption;
686
- className?: string | undefined;
687
- setValueSpecification: (val: ValueSpecification) => void;
688
- resetValue: () => void;
689
- selectorConfig?:
690
- | {
691
- values: string[] | undefined;
692
- isLoading: boolean;
693
- reloadValues:
694
- | DebouncedFunc<(inputValue: string) => GeneratorFn<void>>
695
- | undefined;
696
- cleanUpReloadValues?: () => void;
697
- }
698
- | undefined;
699
- }> = (props) => {
700
- const {
701
- className,
702
- valueSpecification,
703
- graph,
704
- typeCheckOption,
705
- setValueSpecification,
706
- resetValue,
707
- selectorConfig,
708
- } = props;
709
- if (valueSpecification instanceof PrimitiveInstanceValue) {
710
- const _type = valueSpecification.genericType.value.rawType;
711
- switch (_type.path) {
712
- case PRIMITIVE_TYPE.STRING:
713
- return (
714
- <StringPrimitiveInstanceValueEditor
715
- valueSpecification={valueSpecification}
716
- setValueSpecification={setValueSpecification}
717
- className={className}
718
- resetValue={resetValue}
719
- selectorConfig={selectorConfig}
720
- />
721
- );
722
- case PRIMITIVE_TYPE.BOOLEAN:
723
- return (
724
- <BooleanPrimitiveInstanceValueEditor
725
- valueSpecification={valueSpecification}
726
- setValueSpecification={setValueSpecification}
727
- className={className}
728
- resetValue={resetValue}
729
- />
730
- );
731
- case PRIMITIVE_TYPE.NUMBER:
732
- case PRIMITIVE_TYPE.FLOAT:
733
- case PRIMITIVE_TYPE.DECIMAL:
734
- case PRIMITIVE_TYPE.INTEGER:
735
- return (
736
- <NumberPrimitiveInstanceValueEditor
737
- valueSpecification={valueSpecification}
738
- isInteger={_type.path === PRIMITIVE_TYPE.INTEGER}
739
- setValueSpecification={setValueSpecification}
740
- className={className}
741
- resetValue={resetValue}
742
- />
743
- );
744
- case PRIMITIVE_TYPE.DATE:
745
- case PRIMITIVE_TYPE.STRICTDATE:
746
- case PRIMITIVE_TYPE.DATETIME:
747
- case PRIMITIVE_TYPE.LATESTDATE:
748
- return (
749
- <DateInstanceValueEditor
750
- valueSpecification={valueSpecification}
751
- graph={graph}
752
- typeCheckOption={typeCheckOption}
753
- className={className}
754
- setValueSpecification={setValueSpecification}
755
- resetValue={resetValue}
756
- />
757
- );
758
- default:
759
- return <UnsupportedValueSpecificationEditor />;
760
- }
761
- } else if (valueSpecification instanceof EnumValueInstanceValue) {
762
- return (
763
- <EnumValueInstanceValueEditor
764
- valueSpecification={valueSpecification}
765
- className={className}
766
- resetValue={resetValue}
767
- setValueSpecification={setValueSpecification}
768
- />
769
- );
770
- } else if (
771
- valueSpecification instanceof CollectionInstanceValue &&
772
- valueSpecification.genericType
773
- ) {
774
- // NOTE: since when we fill in the arguments, `[]` (or `nullish` value in Pure)
775
- // is used for parameters we don't handle, we should not attempt to support empty collection
776
- // without generic type here as that is equivalent to `[]`
777
- return (
778
- <CollectionValueInstanceValueEditor
779
- valueSpecification={valueSpecification}
780
- graph={graph}
781
- expectedType={typeCheckOption.expectedType}
782
- className={className}
783
- resetValue={resetValue}
784
- setValueSpecification={setValueSpecification}
785
- />
786
- );
787
- }
788
- // property expression
789
- else if (valueSpecification instanceof VariableExpression) {
790
- return (
791
- <VariableExpressionParameterEditor
792
- valueSpecification={valueSpecification}
793
- className={className}
794
- resetValue={resetValue}
795
- />
796
- );
797
- } else if (valueSpecification instanceof INTERNAL__PropagatedValue) {
798
- return (
799
- <BasicValueSpecificationEditor
800
- valueSpecification={valueSpecification.getValue()}
801
- graph={graph}
802
- typeCheckOption={typeCheckOption}
803
- setValueSpecification={setValueSpecification}
804
- resetValue={resetValue}
805
- />
806
- );
807
- } else if (
808
- valueSpecification instanceof SimpleFunctionExpression &&
809
- [
810
- PRIMITIVE_TYPE.DATE.toString(),
811
- PRIMITIVE_TYPE.STRICTDATE.toString(),
812
- PRIMITIVE_TYPE.DATETIME.toString(),
813
- PRIMITIVE_TYPE.LATESTDATE.toString(),
814
- ].includes(typeCheckOption.expectedType.path)
815
- ) {
816
- return (
817
- <DateInstanceValueEditor
818
- valueSpecification={valueSpecification}
819
- graph={graph}
820
- typeCheckOption={typeCheckOption}
821
- className={className}
822
- setValueSpecification={setValueSpecification}
823
- resetValue={resetValue}
824
- />
825
- );
826
- }
827
- return <UnsupportedValueSpecificationEditor />;
828
- };