@finos/legend-application 7.0.3 → 7.1.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 (47) hide show
  1. package/lib/components/shared/BasicValueSpecificationEditor.d.ts +8 -0
  2. package/lib/components/shared/BasicValueSpecificationEditor.d.ts.map +1 -1
  3. package/lib/components/shared/BasicValueSpecificationEditor.js +44 -6
  4. package/lib/components/shared/BasicValueSpecificationEditor.js.map +1 -1
  5. package/lib/components/shared/LambdaEditor.d.ts +1 -0
  6. package/lib/components/shared/LambdaEditor.d.ts.map +1 -1
  7. package/lib/components/shared/LambdaEditor.js +12 -5
  8. package/lib/components/shared/LambdaEditor.js.map +1 -1
  9. package/lib/components/shared/LambdaParameterValuesEditor.d.ts.map +1 -1
  10. package/lib/components/shared/LambdaParameterValuesEditor.js +2 -2
  11. package/lib/components/shared/LambdaParameterValuesEditor.js.map +1 -1
  12. package/lib/components/shared/PackageableElementOptionRenderer.d.ts +2 -2
  13. package/lib/components/shared/PackageableElementOptionRenderer.d.ts.map +1 -1
  14. package/lib/components/shared/PackageableElementOptionRenderer.js +36 -3
  15. package/lib/components/shared/PackageableElementOptionRenderer.js.map +1 -1
  16. package/lib/components/shared/TextInputEditor.d.ts.map +1 -1
  17. package/lib/components/shared/TextInputEditor.js +3 -1
  18. package/lib/components/shared/TextInputEditor.js.map +1 -1
  19. package/lib/const.d.ts +2 -1
  20. package/lib/const.d.ts.map +1 -1
  21. package/lib/const.js +1 -0
  22. package/lib/const.js.map +1 -1
  23. package/lib/index.css +2 -2
  24. package/lib/index.css.map +1 -1
  25. package/lib/index.d.ts +1 -0
  26. package/lib/index.d.ts.map +1 -1
  27. package/lib/index.js +1 -0
  28. package/lib/index.js.map +1 -1
  29. package/lib/stores/ApplicationStore.d.ts +7 -0
  30. package/lib/stores/ApplicationStore.d.ts.map +1 -1
  31. package/lib/stores/ApplicationStore.js +11 -0
  32. package/lib/stores/ApplicationStore.js.map +1 -1
  33. package/lib/stores/LegendApplicationSDLCSetupState.d.ts +30 -0
  34. package/lib/stores/LegendApplicationSDLCSetupState.d.ts.map +1 -0
  35. package/lib/stores/LegendApplicationSDLCSetupState.js +128 -0
  36. package/lib/stores/LegendApplicationSDLCSetupState.js.map +1 -0
  37. package/package.json +11 -10
  38. package/src/components/shared/BasicValueSpecificationEditor.tsx +105 -11
  39. package/src/components/shared/LambdaEditor.tsx +19 -2
  40. package/src/components/shared/LambdaParameterValuesEditor.tsx +7 -5
  41. package/src/components/shared/PackageableElementOptionRenderer.tsx +37 -3
  42. package/src/components/shared/TextInputEditor.tsx +3 -1
  43. package/src/const.ts +1 -0
  44. package/src/index.ts +1 -0
  45. package/src/stores/ApplicationStore.ts +13 -0
  46. package/src/stores/LegendApplicationSDLCSetupState.ts +175 -0
  47. package/tsconfig.json +1 -0
@@ -16,6 +16,7 @@
16
16
 
17
17
  import {
18
18
  type TooltipPlacement,
19
+ type InputActionMeta,
19
20
  Tooltip,
20
21
  DollarIcon,
21
22
  clsx,
@@ -49,11 +50,14 @@ import {
49
50
  getMultiplicityDescription,
50
51
  } from '@finos/legend-graph';
51
52
  import {
53
+ type DebouncedFunc,
54
+ type GeneratorFn,
52
55
  guaranteeNonNullable,
53
56
  isNonNullable,
54
57
  returnUndefOnError,
55
58
  uniq,
56
59
  } from '@finos/legend-shared';
60
+ import { flowResult } from 'mobx';
57
61
  import { observer } from 'mobx-react-lite';
58
62
  import CSVParser from 'papaparse';
59
63
  import { useEffect, useRef, useState } from 'react';
@@ -61,6 +65,7 @@ import {
61
65
  instanceValue_changeValue,
62
66
  instanceValue_changeValues,
63
67
  } from '../../stores/shared/ValueSpecificationModifierHelper.js';
68
+ import { useApplicationStore } from '../ApplicationStoreProvider.js';
64
69
  import { CustomDatePicker } from './CustomDatePicker.js';
65
70
 
66
71
  type TypeCheckOption = {
@@ -170,23 +175,100 @@ const StringPrimitiveInstanceValueEditor = observer(
170
175
  className?: string | undefined;
171
176
  setValueSpecification: (val: ValueSpecification) => void;
172
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;
173
188
  }) => {
174
- const { valueSpecification, className, resetValue, setValueSpecification } =
175
- props;
189
+ const {
190
+ valueSpecification,
191
+ className,
192
+ resetValue,
193
+ setValueSpecification,
194
+ selectorConfig,
195
+ } = props;
196
+ const useSelector = Boolean(selectorConfig);
197
+ const applicationStore = useApplicationStore();
176
198
  const value = valueSpecification.values[0] as string;
177
- const changeValue: React.ChangeEventHandler<HTMLInputElement> = (event) => {
178
- instanceValue_changeValue(valueSpecification, event.target.value, 0);
199
+ const updateValueSpec = (val: string): void => {
200
+ instanceValue_changeValue(valueSpecification, val, 0);
179
201
  setValueSpecification(valueSpecification);
180
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
+
181
246
  return (
182
247
  <div className={clsx('value-spec-editor', className)}>
183
- <input
184
- className="panel__content__form__section__input value-spec-editor__input"
185
- spellCheck={false}
186
- value={value}
187
- placeholder={value === '' ? '(empty)' : undefined}
188
- onChange={changeValue}
189
- />
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
+ )}
190
272
  <button
191
273
  className="value-spec-editor__reset-btn"
192
274
  title="Reset"
@@ -604,6 +686,16 @@ export const BasicValueSpecificationEditor: React.FC<{
604
686
  className?: string | undefined;
605
687
  setValueSpecification: (val: ValueSpecification) => void;
606
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;
607
699
  }> = (props) => {
608
700
  const {
609
701
  className,
@@ -612,6 +704,7 @@ export const BasicValueSpecificationEditor: React.FC<{
612
704
  typeCheckOption,
613
705
  setValueSpecification,
614
706
  resetValue,
707
+ selectorConfig,
615
708
  } = props;
616
709
  if (valueSpecification instanceof PrimitiveInstanceValue) {
617
710
  const _type = valueSpecification.genericType.value.rawType;
@@ -623,6 +716,7 @@ export const BasicValueSpecificationEditor: React.FC<{
623
716
  setValueSpecification={setValueSpecification}
624
717
  className={className}
625
718
  resetValue={resetValue}
719
+ selectorConfig={selectorConfig}
626
720
  />
627
721
  );
628
722
  case PRIMITIVE_TYPE.BOOLEAN:
@@ -100,6 +100,7 @@ const LambdaEditorInline = observer(
100
100
  backdropSetter?: ((val: boolean) => void) | undefined;
101
101
  onKeyDownEventHandlers: LambdaEditorOnKeyDownEventHandler[];
102
102
  openInPopUp: () => void;
103
+ onEditorFocusEventHandler?: (() => void) | undefined;
103
104
  }) => {
104
105
  const {
105
106
  className,
@@ -118,12 +119,16 @@ const LambdaEditorInline = observer(
118
119
  hideErrorBar,
119
120
  onKeyDownEventHandlers,
120
121
  openInPopUp,
122
+ onEditorFocusEventHandler,
121
123
  } = props;
122
124
  const applicationStore = useApplicationStore();
123
125
  const onDidChangeModelContentEventDisposer = useRef<
124
126
  IDisposable | undefined
125
127
  >(undefined);
126
128
  const onKeyDownEventDisposer = useRef<IDisposable | undefined>(undefined);
129
+ const onDidFocusEditorWidgetDisposer = useRef<IDisposable | undefined>(
130
+ undefined,
131
+ );
127
132
  const value = normalizeLineEnding(lambdaEditorState.lambdaString);
128
133
  const parserError = lambdaEditorState.parserError;
129
134
  const compilationError = lambdaEditorState.compilationError;
@@ -183,13 +188,15 @@ const LambdaEditorInline = observer(
183
188
  const _editor = monacoEditorAPI.create(element, {
184
189
  ...baseTextEditorSettings,
185
190
  language: EDITOR_LANGUAGE.PURE,
186
- theme: EDITOR_THEME.LEGEND,
191
+ theme: applicationStore.TEMPORARY__isLightThemeEnabled
192
+ ? EDITOR_THEME.TEMPORARY__VSCODE_LIGHT
193
+ : EDITOR_THEME.LEGEND,
187
194
  ...lambdaEditorOptions,
188
195
  });
189
196
  disableEditorHotKeys(_editor);
190
197
  setEditor(_editor);
191
198
  }
192
- }, [editor, useBaseTextEditorSettings]);
199
+ }, [editor, applicationStore, useBaseTextEditorSettings]);
193
200
 
194
201
  // set styling for expanded mode
195
202
  useEffect(() => {
@@ -305,6 +312,13 @@ const LambdaEditorInline = observer(
305
312
  });
306
313
  });
307
314
 
315
+ onDidFocusEditorWidgetDisposer.current?.dispose();
316
+ onDidFocusEditorWidgetDisposer.current = editor.onDidFocusEditorWidget(
317
+ () => {
318
+ onEditorFocusEventHandler?.();
319
+ },
320
+ );
321
+
308
322
  // Set the text value
309
323
  const currentValue = getEditorValue(editor);
310
324
  const editorModel = editor.getModel();
@@ -738,6 +752,7 @@ export const LambdaEditor = observer(
738
752
  * to allow activating global hotkeys while typing in the editor
739
753
  */
740
754
  onKeyDownEventHandlers?: LambdaEditorOnKeyDownEventHandler[];
755
+ onEditorFocusEventHandler?: (() => void) | undefined;
741
756
  }) => {
742
757
  const {
743
758
  className,
@@ -754,6 +769,7 @@ export const LambdaEditor = observer(
754
769
  useBaseTextEditorSettings,
755
770
  hideErrorBar,
756
771
  onKeyDownEventHandlers,
772
+ onEditorFocusEventHandler,
757
773
  } = props;
758
774
  const [showPopUp, setShowPopUp] = useState(false);
759
775
  const openInPopUp = (): void => setShowPopUp(true);
@@ -831,6 +847,7 @@ export const LambdaEditor = observer(
831
847
  hideErrorBar={hideErrorBar}
832
848
  onKeyDownEventHandlers={onKeyDownEventHandlers ?? []}
833
849
  openInPopUp={openInPopUp}
850
+ onEditorFocusEventHandler={onEditorFocusEventHandler}
834
851
  />
835
852
  );
836
853
  },
@@ -53,11 +53,11 @@ export const LambdaParameterValuesEditor = observer(
53
53
  paper: 'editor-modal__content',
54
54
  }}
55
55
  >
56
- <div className="modal modal--dark editor-modal lambda__parameters__editor__modal">
56
+ <div className="modal modal--dark editor-modal lambda-parameter-values__modal">
57
57
  <div className="modal__header">
58
58
  <div className="modal__title">Set Parameter Values</div>
59
59
  </div>
60
- <div className="modal__body lambda__parameters__editor__modal__body">
60
+ <div className="modal__body lambda-parameter-values__modal__body">
61
61
  {lambdaParametersState.parameterStates.map((paramState) => {
62
62
  const stringType = graph.getPrimitiveType(PRIMITIVE_TYPE.STRING);
63
63
  const variableType = paramState.variableType ?? stringType;
@@ -66,9 +66,11 @@ export const LambdaParameterValuesEditor = observer(
66
66
  key={paramState.uuid}
67
67
  className="panel__content__form__section"
68
68
  >
69
- <div className="lambda__parameters__editor__value__label">
70
- <div>{paramState.parameter.name}</div>
71
- <div className="lambda__parameters__editor__value__name">
69
+ <div className="lambda-parameter-values__value__label">
70
+ <div className="lambda-parameter-values__value__label__name">
71
+ {paramState.parameter.name}
72
+ </div>
73
+ <div className="lambda-parameter-values__value__label__type">
72
74
  {variableType.name}
73
75
  </div>
74
76
  </div>
@@ -14,10 +14,35 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import type { PackageableElement } from '@finos/legend-graph';
17
+ import {
18
+ type PackageableElement,
19
+ isSystemElement,
20
+ isGeneratedElement,
21
+ isDependencyElement,
22
+ } from '@finos/legend-graph';
18
23
  import type { PackageableElementOption } from '../../stores/shared/PackageableElementOption.js';
19
24
 
20
- export const getPackageableElementOptionalFormatter = (props?: {
25
+ const getElementColorCode = (element: PackageableElement): string =>
26
+ isSystemElement(element)
27
+ ? 'system'
28
+ : isGeneratedElement(element)
29
+ ? 'generated'
30
+ : isDependencyElement(element)
31
+ ? 'dependency'
32
+ : '';
33
+
34
+ const generateOptionTooltipText = (
35
+ element: PackageableElement,
36
+ ): string | undefined =>
37
+ isSystemElement(element)
38
+ ? 'system element'
39
+ : isGeneratedElement(element)
40
+ ? 'generated element'
41
+ : isDependencyElement(element)
42
+ ? 'dependency element'
43
+ : undefined;
44
+
45
+ export const getPackageableElementOptionFormatter = (props: {
21
46
  darkMode?: boolean;
22
47
  }): ((
23
48
  option: PackageableElementOption<PackageableElement>,
@@ -25,12 +50,21 @@ export const getPackageableElementOptionalFormatter = (props?: {
25
50
  function PackageableElementOptionLabel(
26
51
  option: PackageableElementOption<PackageableElement>,
27
52
  ): React.ReactNode {
28
- const className = props?.darkMode
53
+ const className = props.darkMode
29
54
  ? 'packageable-element-format-option-label--dark'
30
55
  : 'packageable-element-format-option-label';
56
+ const colorCode = getElementColorCode(option.value);
31
57
 
32
58
  return (
33
59
  <div className={className}>
60
+ <div
61
+ title={generateOptionTooltipText(option.value)}
62
+ className={`packageable-element-format-option-label-type ${
63
+ colorCode
64
+ ? `packageable-element-format-option-label-type--${colorCode}`
65
+ : ''
66
+ } `}
67
+ ></div>
34
68
  <div className={`${className}__name`}>{option.label}</div>
35
69
  {option.value.package && (
36
70
  <div className={`${className}__tag`}>{option.value.path}</div>
@@ -92,7 +92,9 @@ export const TextInputEditor: React.FC<{
92
92
  const element = textInputRef.current;
93
93
  const _editor = monacoEditorAPI.create(element, {
94
94
  ...baseTextEditorSettings,
95
- theme: EDITOR_THEME.LEGEND,
95
+ theme: applicationStore.TEMPORARY__isLightThemeEnabled
96
+ ? EDITOR_THEME.TEMPORARY__VSCODE_LIGHT
97
+ : EDITOR_THEME.LEGEND,
96
98
  formatOnType: true,
97
99
  formatOnPaste: true,
98
100
  });
package/src/const.ts CHANGED
@@ -20,6 +20,7 @@ export const MONOSPACED_FONT_FAMILY = 'Roboto Mono';
20
20
 
21
21
  export enum EDITOR_THEME {
22
22
  LEGEND = 'LEGEND',
23
+ TEMPORARY__VSCODE_LIGHT = 'vs',
23
24
  }
24
25
 
25
26
  export enum EDITOR_LANGUAGE {
package/src/index.ts CHANGED
@@ -40,6 +40,7 @@ export * from './stores/ApplicationNavigationContextService.js';
40
40
  export * from './stores/LegendApplicationPlugin.js';
41
41
 
42
42
  export * from './stores/ApplicationStoreTestUtils.js';
43
+ export * from './stores/LegendApplicationSDLCSetupState.js';
43
44
 
44
45
  // ------------------------------------------- Shared components -------------------------------------------
45
46
 
@@ -136,6 +136,14 @@ export class ApplicationStore<
136
136
  telemetryService = new TelemetryService();
137
137
  tracerService = new TracerService();
138
138
 
139
+ // theme
140
+ /**
141
+ * NOTE: this is the poor man way of doing theming
142
+ * we would need to revise this flag later
143
+ * See https://github.com/finos/legend-studio/issues/264
144
+ */
145
+ TEMPORARY__isLightThemeEnabled = false;
146
+
139
147
  constructor(
140
148
  config: T,
141
149
  navigator: WebApplicationNavigator,
@@ -151,6 +159,7 @@ export class ApplicationStore<
151
159
  notifyWarning: action,
152
160
  notifyIllegalState: action,
153
161
  notifyError: action,
162
+ TEMPORARY__setIsLightThemeEnabled: action,
154
163
  });
155
164
 
156
165
  this.config = config;
@@ -173,6 +182,10 @@ export class ApplicationStore<
173
182
  );
174
183
  }
175
184
 
185
+ TEMPORARY__setIsLightThemeEnabled(val: boolean): void {
186
+ this.TEMPORARY__isLightThemeEnabled = val;
187
+ }
188
+
176
189
  setBlockingAlert(alertInfo: BlockingAlertInfo | undefined): void {
177
190
  this.blockingAlertInfo = alertInfo;
178
191
  }
@@ -0,0 +1,175 @@
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 { SDLCServerClient, User } from '@finos/legend-server-sdlc';
18
+ import {
19
+ type GeneratorFn,
20
+ assertErrorThrown,
21
+ HttpStatus,
22
+ LogEvent,
23
+ NetworkClientError,
24
+ type PlainObject,
25
+ } from '@finos/legend-shared';
26
+ import {
27
+ action,
28
+ computed,
29
+ flow,
30
+ flowResult,
31
+ makeObservable,
32
+ observable,
33
+ } from 'mobx';
34
+ import { APPLICATION_EVENT } from './ApplicationEvent.js';
35
+ import {
36
+ type GenericLegendApplicationStore,
37
+ ActionAlertActionType,
38
+ ActionAlertType,
39
+ } from './ApplicationStore.js';
40
+
41
+ export class LegendApplicationSDLCSetupState {
42
+ applicationStore: GenericLegendApplicationStore;
43
+ sdlcServerClient: SDLCServerClient;
44
+ isSDLCAuthorized = false;
45
+ SDLCServerTermsOfServicesUrlsToView: string[] = [];
46
+
47
+ constructor(
48
+ applicationStore: GenericLegendApplicationStore,
49
+ sdlcServerClient: SDLCServerClient,
50
+ ) {
51
+ makeObservable(this, {
52
+ isSDLCAuthorized: observable,
53
+ SDLCServerTermsOfServicesUrlsToView: observable,
54
+ dismissSDLCServerTermsOfServicesAlert: action,
55
+ needsToAcceptSDLCServerTermsOfServices: computed,
56
+ initializeSDLCServerClient: flow,
57
+ fetchCurrentUser: flow,
58
+ });
59
+ this.applicationStore = applicationStore;
60
+ this.sdlcServerClient = sdlcServerClient;
61
+ }
62
+
63
+ *initializeSDLCServerClient(): GeneratorFn<void> {
64
+ try {
65
+ this.isSDLCAuthorized =
66
+ (yield this.sdlcServerClient.isAuthorized()) as boolean;
67
+ if (!this.isSDLCAuthorized) {
68
+ this.applicationStore.navigator.jumpTo(
69
+ SDLCServerClient.authorizeCallbackUrl(
70
+ this.sdlcServerClient.baseUrl ?? '',
71
+ this.applicationStore.navigator.getCurrentLocation(),
72
+ ),
73
+ );
74
+ } else {
75
+ // Only proceed intialization after passing authorization check
76
+
77
+ // check terms of service agreement status
78
+ this.SDLCServerTermsOfServicesUrlsToView =
79
+ (yield this.sdlcServerClient.hasAcceptedTermsOfService()) as string[];
80
+ if (this.SDLCServerTermsOfServicesUrlsToView.length) {
81
+ this.applicationStore.setActionAlertInfo({
82
+ message: `Please read and accept the SDLC servers' terms of service`,
83
+ prompt: `Click 'Done' when you have accepted all the terms`,
84
+ type: ActionAlertType.CAUTION,
85
+ actions: [
86
+ {
87
+ label: 'See terms of services',
88
+ default: true,
89
+ handler: (): void =>
90
+ this.SDLCServerTermsOfServicesUrlsToView.forEach((url) =>
91
+ this.applicationStore.navigator.openNewWindow(url),
92
+ ),
93
+ type: ActionAlertActionType.PROCEED,
94
+ },
95
+ {
96
+ label: 'Done',
97
+ type: ActionAlertActionType.PROCEED_WITH_CAUTION,
98
+ handler: (): void => {
99
+ this.dismissSDLCServerTermsOfServicesAlert();
100
+ this.applicationStore.navigator.reload();
101
+ },
102
+ },
103
+ ],
104
+ });
105
+ }
106
+
107
+ // fetch server features config + current user
108
+ yield this.sdlcServerClient.fetchServerFeaturesConfiguration();
109
+ yield flowResult(this.fetchCurrentUser());
110
+ }
111
+ } catch (error) {
112
+ assertErrorThrown(error);
113
+ if (
114
+ // eslint-disable-next-line no-process-env
115
+ process.env.NODE_ENV === 'development' &&
116
+ error instanceof NetworkClientError &&
117
+ error.response.status === HttpStatus.UNAUTHORIZED
118
+ ) {
119
+ this.applicationStore.setActionAlertInfo({
120
+ message:
121
+ 'The first time the application starts in development mode, the developer would need to authenticate using SDLC server. Please do so then manually reload the app',
122
+ type: ActionAlertType.STANDARD,
123
+ actions: [
124
+ {
125
+ label: 'Authenticate using SDLC',
126
+ type: ActionAlertActionType.PROCEED,
127
+ default: true,
128
+ handler: (): void => {
129
+ this.applicationStore.navigator.openNewWindow(
130
+ this.sdlcServerClient.currentUserUrl,
131
+ );
132
+ this.applicationStore.setBlockingAlert({
133
+ message:
134
+ 'Waiting for the developer to authenticate using SDLC server',
135
+ prompt:
136
+ 'Please manually reload the application after authentication',
137
+ });
138
+ },
139
+ },
140
+ ],
141
+ });
142
+ } else {
143
+ this.applicationStore.log.error(
144
+ LogEvent.create(APPLICATION_EVENT.APPLICATION_SETUP_FAILURE),
145
+ error,
146
+ );
147
+ this.applicationStore.notifyError(error);
148
+ }
149
+ }
150
+ }
151
+
152
+ *fetchCurrentUser(): GeneratorFn<void> {
153
+ try {
154
+ const currentUser = User.serialization.fromJson(
155
+ (yield this.sdlcServerClient.getCurrentUser()) as PlainObject<User>,
156
+ );
157
+ this.sdlcServerClient.setCurrentUser(currentUser);
158
+ } catch (error) {
159
+ assertErrorThrown(error);
160
+ this.applicationStore.log.error(
161
+ LogEvent.create(APPLICATION_EVENT.APPLICATION_SETUP_FAILURE),
162
+ error,
163
+ );
164
+ this.applicationStore.notifyWarning(error.message);
165
+ }
166
+ }
167
+
168
+ get needsToAcceptSDLCServerTermsOfServices(): boolean {
169
+ return Boolean(this.SDLCServerTermsOfServicesUrlsToView.length);
170
+ }
171
+
172
+ dismissSDLCServerTermsOfServicesAlert(): void {
173
+ this.SDLCServerTermsOfServicesUrlsToView = [];
174
+ }
175
+ }
package/tsconfig.json CHANGED
@@ -41,6 +41,7 @@
41
41
  "./src/stores/DocumentationService.ts",
42
42
  "./src/stores/EventService.ts",
43
43
  "./src/stores/LegendApplicationPlugin.ts",
44
+ "./src/stores/LegendApplicationSDLCSetupState.ts",
44
45
  "./src/stores/PureLanguageSupport.ts",
45
46
  "./src/stores/WebApplicationNavigator.ts",
46
47
  "./src/stores/shared/ExecutionPlanState.ts",