@finos/legend-application-studio 15.1.0 → 15.2.0

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 (144) hide show
  1. package/lib/components/EditorComponentTestUtils.d.ts.map +1 -1
  2. package/lib/components/EditorComponentTestUtils.js +6 -6
  3. package/lib/components/EditorComponentTestUtils.js.map +1 -1
  4. package/lib/components/editor/edit-panel/FunctionEditor.d.ts.map +1 -1
  5. package/lib/components/editor/edit-panel/FunctionEditor.js +3 -3
  6. package/lib/components/editor/edit-panel/FunctionEditor.js.map +1 -1
  7. package/lib/components/editor/edit-panel/UnsupportedElementEditor.js +1 -1
  8. package/lib/components/editor/edit-panel/UnsupportedElementEditor.js.map +1 -1
  9. package/lib/components/editor/edit-panel/connection-editor/ConnectionEditor.d.ts.map +1 -1
  10. package/lib/components/editor/edit-panel/connection-editor/ConnectionEditor.js +2 -2
  11. package/lib/components/editor/edit-panel/connection-editor/ConnectionEditor.js.map +1 -1
  12. package/lib/components/editor/edit-panel/connection-editor/DatabaseBuilder.js +1 -1
  13. package/lib/components/editor/edit-panel/connection-editor/DatabaseBuilder.js.map +1 -1
  14. package/lib/{stores/editor-state/element-editor-state/mapping/relational → components/editor/edit-panel/connection-editor}/DatabaseEditorHelper.d.ts +0 -0
  15. package/lib/components/editor/edit-panel/connection-editor/DatabaseEditorHelper.d.ts.map +1 -0
  16. package/lib/{stores/editor-state/element-editor-state/mapping/relational → components/editor/edit-panel/connection-editor}/DatabaseEditorHelper.js +0 -0
  17. package/lib/components/editor/edit-panel/connection-editor/DatabaseEditorHelper.js.map +1 -0
  18. package/lib/components/editor/edit-panel/connection-editor/RelationalDatabaseConnectionEditor.d.ts +3 -12
  19. package/lib/components/editor/edit-panel/connection-editor/RelationalDatabaseConnectionEditor.d.ts.map +1 -1
  20. package/lib/components/editor/edit-panel/connection-editor/RelationalDatabaseConnectionEditor.js +103 -41
  21. package/lib/components/editor/edit-panel/connection-editor/RelationalDatabaseConnectionEditor.js.map +1 -1
  22. package/lib/components/editor/edit-panel/connection-editor/post-processor-editor/MapperPostProcessorEditor.d.ts +26 -0
  23. package/lib/components/editor/edit-panel/connection-editor/post-processor-editor/MapperPostProcessorEditor.d.ts.map +1 -0
  24. package/lib/components/editor/edit-panel/connection-editor/post-processor-editor/MapperPostProcessorEditor.js +77 -0
  25. package/lib/components/editor/edit-panel/connection-editor/post-processor-editor/MapperPostProcessorEditor.js.map +1 -0
  26. package/lib/components/editor/edit-panel/data-editor/EmbeddedDataEditor.d.ts.map +1 -1
  27. package/lib/components/editor/edit-panel/data-editor/EmbeddedDataEditor.js +1 -1
  28. package/lib/components/editor/edit-panel/data-editor/EmbeddedDataEditor.js.map +1 -1
  29. package/lib/components/editor/edit-panel/mapping-editor/EnumerationMappingEditor.d.ts.map +1 -1
  30. package/lib/components/editor/edit-panel/mapping-editor/EnumerationMappingEditor.js +1 -1
  31. package/lib/components/editor/edit-panel/mapping-editor/EnumerationMappingEditor.js.map +1 -1
  32. package/lib/components/editor/edit-panel/mapping-editor/InstanceSetImplementationEditor.js +2 -2
  33. package/lib/components/editor/edit-panel/mapping-editor/InstanceSetImplementationEditor.js.map +1 -1
  34. package/lib/components/editor/edit-panel/mapping-editor/InstanceSetImplementationSourceSelectorModal.d.ts.map +1 -1
  35. package/lib/components/editor/edit-panel/mapping-editor/InstanceSetImplementationSourceSelectorModal.js +2 -5
  36. package/lib/components/editor/edit-panel/mapping-editor/InstanceSetImplementationSourceSelectorModal.js.map +1 -1
  37. package/lib/components/editor/edit-panel/mapping-editor/NewMappingElementModal.d.ts.map +1 -1
  38. package/lib/components/editor/edit-panel/mapping-editor/NewMappingElementModal.js +4 -4
  39. package/lib/components/editor/edit-panel/mapping-editor/NewMappingElementModal.js.map +1 -1
  40. package/lib/components/editor/edit-panel/mapping-editor/relational/TableOrViewSourceTree.js +1 -1
  41. package/lib/components/editor/edit-panel/mapping-editor/relational/TableOrViewSourceTree.js.map +1 -1
  42. package/lib/components/editor/edit-panel/service-editor/ServiceExecutionEditor.d.ts.map +1 -1
  43. package/lib/components/editor/edit-panel/service-editor/ServiceExecutionEditor.js +2 -1
  44. package/lib/components/editor/edit-panel/service-editor/ServiceExecutionEditor.js.map +1 -1
  45. package/lib/components/editor/edit-panel/service-editor/testable/ServiceTestDataEditor.d.ts.map +1 -1
  46. package/lib/components/editor/edit-panel/service-editor/testable/ServiceTestDataEditor.js +7 -5
  47. package/lib/components/editor/edit-panel/service-editor/testable/ServiceTestDataEditor.js.map +1 -1
  48. package/lib/components/editor/edit-panel/uml-editor/AssociationEditor.d.ts.map +1 -1
  49. package/lib/components/editor/edit-panel/uml-editor/AssociationEditor.js +2 -2
  50. package/lib/components/editor/edit-panel/uml-editor/AssociationEditor.js.map +1 -1
  51. package/lib/components/editor/edit-panel/uml-editor/ClassEditor.d.ts.map +1 -1
  52. package/lib/components/editor/edit-panel/uml-editor/ClassEditor.js +9 -7
  53. package/lib/components/editor/edit-panel/uml-editor/ClassEditor.js.map +1 -1
  54. package/lib/components/editor/edit-panel/uml-editor/StereotypeSelector.d.ts.map +1 -1
  55. package/lib/components/editor/edit-panel/uml-editor/StereotypeSelector.js +4 -1
  56. package/lib/components/editor/edit-panel/uml-editor/StereotypeSelector.js.map +1 -1
  57. package/lib/components/editor/edit-panel/uml-editor/TaggedValueEditor.d.ts.map +1 -1
  58. package/lib/components/editor/edit-panel/uml-editor/TaggedValueEditor.js +4 -1
  59. package/lib/components/editor/edit-panel/uml-editor/TaggedValueEditor.js.map +1 -1
  60. package/lib/components/editor/side-bar/CreateNewElementModal.d.ts.map +1 -1
  61. package/lib/components/editor/side-bar/CreateNewElementModal.js +7 -4
  62. package/lib/components/editor/side-bar/CreateNewElementModal.js.map +1 -1
  63. package/lib/components/editor/side-bar/testable/GlobalTestRunner.d.ts.map +1 -1
  64. package/lib/components/editor/side-bar/testable/GlobalTestRunner.js +8 -2
  65. package/lib/components/editor/side-bar/testable/GlobalTestRunner.js.map +1 -1
  66. package/lib/index.css +1 -1
  67. package/lib/index.d.ts +3 -2
  68. package/lib/index.d.ts.map +1 -1
  69. package/lib/index.js +3 -2
  70. package/lib/index.js.map +1 -1
  71. package/lib/package.json +6 -6
  72. package/lib/stores/EditorStore.d.ts +1 -9
  73. package/lib/stores/EditorStore.d.ts.map +1 -1
  74. package/lib/stores/EditorStore.js +3 -54
  75. package/lib/stores/EditorStore.js.map +1 -1
  76. package/lib/stores/StoreRelational_LegendStudioApplicationPlugin_Extension.d.ts +28 -1
  77. package/lib/stores/StoreRelational_LegendStudioApplicationPlugin_Extension.d.ts.map +1 -1
  78. package/lib/stores/editor/NewElementState.d.ts +1 -1
  79. package/lib/stores/editor/NewElementState.d.ts.map +1 -1
  80. package/lib/stores/editor/NewElementState.js +5 -3
  81. package/lib/stores/editor/NewElementState.js.map +1 -1
  82. package/lib/stores/editor-state/ModelImporterState.d.ts.map +1 -1
  83. package/lib/stores/editor-state/ModelImporterState.js +10 -6
  84. package/lib/stores/editor-state/ModelImporterState.js.map +1 -1
  85. package/lib/stores/editor-state/element-editor-state/connection/ConnectionEditorState.d.ts +9 -2
  86. package/lib/stores/editor-state/element-editor-state/connection/ConnectionEditorState.d.ts.map +1 -1
  87. package/lib/stores/editor-state/element-editor-state/connection/ConnectionEditorState.js +32 -2
  88. package/lib/stores/editor-state/element-editor-state/connection/ConnectionEditorState.js.map +1 -1
  89. package/lib/stores/editor-state/element-editor-state/connection/PostProcessorEditorState.d.ts +30 -0
  90. package/lib/stores/editor-state/element-editor-state/connection/PostProcessorEditorState.d.ts.map +1 -0
  91. package/lib/stores/editor-state/element-editor-state/connection/PostProcessorEditorState.js +49 -0
  92. package/lib/stores/editor-state/element-editor-state/connection/PostProcessorEditorState.js.map +1 -0
  93. package/lib/stores/editor-state/element-editor-state/service/ServiceExecutionState.js +1 -1
  94. package/lib/stores/editor-state/element-editor-state/service/ServiceExecutionState.js.map +1 -1
  95. package/lib/stores/editor-state/element-editor-state/service/testable/ServiceTestDataState.d.ts +2 -1
  96. package/lib/stores/editor-state/element-editor-state/service/testable/ServiceTestDataState.d.ts.map +1 -1
  97. package/lib/stores/editor-state/element-editor-state/service/testable/ServiceTestDataState.js +6 -4
  98. package/lib/stores/editor-state/element-editor-state/service/testable/ServiceTestDataState.js.map +1 -1
  99. package/lib/stores/graphModifier/StoreRelational_GraphModifierHelper.d.ts +10 -1
  100. package/lib/stores/graphModifier/StoreRelational_GraphModifierHelper.d.ts.map +1 -1
  101. package/lib/stores/graphModifier/StoreRelational_GraphModifierHelper.js +27 -1
  102. package/lib/stores/graphModifier/StoreRelational_GraphModifierHelper.js.map +1 -1
  103. package/lib/stores/sidebar-state/testable/GlobalTestRunnerState.d.ts +1 -3
  104. package/lib/stores/sidebar-state/testable/GlobalTestRunnerState.d.ts.map +1 -1
  105. package/lib/stores/sidebar-state/testable/GlobalTestRunnerState.js +1 -4
  106. package/lib/stores/sidebar-state/testable/GlobalTestRunnerState.js.map +1 -1
  107. package/package.json +14 -14
  108. package/src/components/EditorComponentTestUtils.tsx +6 -12
  109. package/src/components/editor/edit-panel/FunctionEditor.tsx +9 -2
  110. package/src/components/editor/edit-panel/UnsupportedElementEditor.tsx +1 -1
  111. package/src/components/editor/edit-panel/connection-editor/ConnectionEditor.tsx +6 -2
  112. package/src/components/editor/edit-panel/connection-editor/DatabaseBuilder.tsx +1 -1
  113. package/src/{stores/editor-state/element-editor-state/mapping/relational → components/editor/edit-panel/connection-editor}/DatabaseEditorHelper.tsx +0 -0
  114. package/src/components/editor/edit-panel/connection-editor/RelationalDatabaseConnectionEditor.tsx +371 -172
  115. package/src/components/editor/edit-panel/connection-editor/post-processor-editor/MapperPostProcessorEditor.tsx +278 -0
  116. package/src/components/editor/edit-panel/data-editor/EmbeddedDataEditor.tsx +2 -1
  117. package/src/components/editor/edit-panel/mapping-editor/EnumerationMappingEditor.tsx +5 -1
  118. package/src/components/editor/edit-panel/mapping-editor/InstanceSetImplementationEditor.tsx +2 -2
  119. package/src/components/editor/edit-panel/mapping-editor/InstanceSetImplementationSourceSelectorModal.tsx +2 -9
  120. package/src/components/editor/edit-panel/mapping-editor/NewMappingElementModal.tsx +4 -3
  121. package/src/components/editor/edit-panel/mapping-editor/relational/TableOrViewSourceTree.tsx +1 -1
  122. package/src/components/editor/edit-panel/service-editor/ServiceExecutionEditor.tsx +6 -2
  123. package/src/components/editor/edit-panel/service-editor/testable/ServiceTestDataEditor.tsx +12 -5
  124. package/src/components/editor/edit-panel/uml-editor/AssociationEditor.tsx +3 -1
  125. package/src/components/editor/edit-panel/uml-editor/ClassEditor.tsx +21 -12
  126. package/src/components/editor/edit-panel/uml-editor/StereotypeSelector.tsx +7 -4
  127. package/src/components/editor/edit-panel/uml-editor/TaggedValueEditor.tsx +7 -4
  128. package/src/components/editor/side-bar/CreateNewElementModal.tsx +9 -3
  129. package/src/components/editor/side-bar/testable/GlobalTestRunner.tsx +13 -1
  130. package/src/index.ts +6 -2
  131. package/src/stores/EditorStore.ts +2 -81
  132. package/src/stores/StoreRelational_LegendStudioApplicationPlugin_Extension.ts +55 -0
  133. package/src/stores/editor/NewElementState.ts +8 -7
  134. package/src/stores/editor-state/ModelImporterState.ts +15 -11
  135. package/src/stores/editor-state/element-editor-state/connection/ConnectionEditorState.ts +47 -1
  136. package/src/stores/editor-state/element-editor-state/connection/PostProcessorEditorState.ts +73 -0
  137. package/src/stores/editor-state/element-editor-state/service/ServiceExecutionState.ts +1 -1
  138. package/src/stores/editor-state/element-editor-state/service/testable/ServiceTestDataState.ts +14 -4
  139. package/src/stores/graphModifier/StoreRelational_GraphModifierHelper.ts +64 -0
  140. package/src/stores/sidebar-state/testable/GlobalTestRunnerState.ts +2 -9
  141. package/tsconfig.json +5 -3
  142. package/tsconfig.package.json +38 -0
  143. package/lib/stores/editor-state/element-editor-state/mapping/relational/DatabaseEditorHelper.d.ts.map +0 -1
  144. package/lib/stores/editor-state/element-editor-state/mapping/relational/DatabaseEditorHelper.js.map +0 -1
@@ -20,6 +20,7 @@ import {
20
20
  CORE_AUTHENTICATION_STRATEGY_TYPE,
21
21
  CORE_DATASOURCE_SPEC_TYPE,
22
22
  RELATIONAL_DATABASE_TAB_TYPE,
23
+ POST_PROCESSOR_TYPE,
23
24
  } from '../../../../stores/editor-state/element-editor-state/connection/ConnectionEditorState.js';
24
25
  import { useState } from 'react';
25
26
  import {
@@ -33,11 +34,27 @@ import {
33
34
  TimesIcon,
34
35
  ErrorIcon,
35
36
  PencilIcon,
37
+ PanelHeader,
38
+ PanelHeaderActionItem,
39
+ PlusIcon,
40
+ PanelTextEditor,
41
+ ContextMenu,
42
+ MenuContent,
43
+ MenuContentItem,
44
+ PanelListSelectorItem,
45
+ DropdownMenu,
46
+ PanelTabs,
47
+ BlankPanelContent,
48
+ ResizablePanelSplitterLine,
49
+ PanelContent,
50
+ Panel,
36
51
  } from '@finos/legend-art';
37
52
  import { capitalize, prettyCONSTName } from '@finos/legend-shared';
53
+
38
54
  import {
39
55
  type RelationalDatabaseConnection,
40
56
  type Store,
57
+ type PostProcessor,
41
58
  DatabaseType,
42
59
  DelegatedKerberosAuthenticationStrategy,
43
60
  OAuthAuthenticationStrategy,
@@ -54,6 +71,7 @@ import {
54
71
  BigQueryDatasourceSpecification,
55
72
  RedshiftDatasourceSpecification,
56
73
  PackageableElementExplicitReference,
74
+ MapperPostProcessor,
57
75
  } from '@finos/legend-graph';
58
76
  import { runInAction } from 'mobx';
59
77
  import type { LegendStudioApplicationPlugin } from '../../../../stores/LegendStudioApplicationPlugin.js';
@@ -116,7 +134,12 @@ import {
116
134
  gcpWorkloadIdentityFederationAuthenticationStrategy_setServiceAccountEmail,
117
135
  gcpWorkloadIdentityFederationAuthenticationStrategy_setAdditionalGcpScopes,
118
136
  middleTierUsernamePasswordAuthenticationStrategy_setVaultReference,
137
+ relationalDatabaseConnection_addPostProcessor,
138
+ relationalDatabaseConnection_deletePostProcessor,
119
139
  } from '../../../../stores/graphModifier/StoreRelational_GraphModifierHelper.js';
140
+ import { MapperPostProcessorEditor } from './post-processor-editor/MapperPostProcessorEditor.js';
141
+ import { UnsupportedEditorPanel } from '../UnsupportedElementEditor.js';
142
+ import type { MapperPostProcessorEditorState } from '../../../../stores/editor-state/element-editor-state/connection/PostProcessorEditorState.js';
120
143
 
121
144
  /**
122
145
  * NOTE: this is a WIP we did to quickly assemble a modular UI for relational database connection editor
@@ -126,13 +149,13 @@ import {
126
149
  // TODO: consider to move this to shared
127
150
  export const ConnectionEditor_BooleanEditor = observer(
128
151
  (props: {
129
- propertyName: string;
152
+ name: string;
130
153
  description?: string;
131
154
  value: boolean | undefined;
132
155
  isReadOnly: boolean;
133
156
  update: (value: boolean | undefined) => void;
134
157
  }) => {
135
- const { value, propertyName, description, isReadOnly, update } = props;
158
+ const { value, name, description, isReadOnly, update } = props;
136
159
  const toggle = (): void => {
137
160
  if (!isReadOnly) {
138
161
  update(!value);
@@ -142,7 +165,7 @@ export const ConnectionEditor_BooleanEditor = observer(
142
165
  return (
143
166
  <div className="panel__content__form__section">
144
167
  <div className="panel__content__form__section__header__label">
145
- {capitalize(propertyName)}
168
+ {capitalize(name)}
146
169
  </div>
147
170
  <div
148
171
  className={clsx('panel__content__form__section__toggler', {
@@ -168,60 +191,22 @@ export const ConnectionEditor_BooleanEditor = observer(
168
191
  },
169
192
  );
170
193
 
171
- // TODO: consider to move this to shared
172
- export const ConnectionEditor_StringEditor = observer(
173
- (props: {
174
- propertyName: string;
175
- description?: string;
176
- value: string | undefined;
177
- isReadOnly: boolean;
178
- update: (value: string | undefined) => void;
179
- }) => {
180
- const { value, propertyName, description, isReadOnly, update } = props;
181
- const displayValue = value ?? '';
182
- const changeValue: React.ChangeEventHandler<HTMLInputElement> = (event) => {
183
- const stringValue = event.target.value;
184
- const updatedValue = stringValue ? stringValue : undefined;
185
- update(updatedValue);
186
- };
187
-
188
- return (
189
- <div className="panel__content__form__section">
190
- <div className="panel__content__form__section__header__label">
191
- {capitalize(propertyName)}
192
- </div>
193
- <div className="panel__content__form__section__header__prompt">
194
- {description}
195
- </div>
196
- <input
197
- className="panel__content__form__section__input"
198
- spellCheck={false}
199
- disabled={isReadOnly}
200
- value={displayValue}
201
- onChange={changeValue}
202
- />
203
- </div>
204
- );
205
- },
206
- );
207
-
208
194
  // TODO: consider to move this to shared
209
195
  export const ConnectionEditor_TextEditor = observer(
210
196
  (props: {
211
- propertyName: string;
197
+ name: string;
212
198
  description?: string;
213
199
  value: string | undefined;
214
200
  isReadOnly: boolean;
215
201
  language: EDITOR_LANGUAGE;
216
202
  update: (value: string | undefined) => void;
217
203
  }) => {
218
- const { value, propertyName, description, isReadOnly, language, update } =
219
- props;
204
+ const { value, name, description, isReadOnly, language, update } = props;
220
205
 
221
206
  return (
222
207
  <div className="panel__content__form__section">
223
208
  <div className="panel__content__form__section__header__label">
224
- {capitalize(propertyName)}
209
+ {capitalize(name)}
225
210
  </div>
226
211
  <div className="panel__content__form__section__header__prompt">
227
212
  {description}
@@ -242,13 +227,13 @@ export const ConnectionEditor_TextEditor = observer(
242
227
  // TODO: consider to move this to shared
243
228
  export const ConnectionEditor_ArrayEditor = observer(
244
229
  (props: {
245
- propertyName: string;
230
+ name: string;
246
231
  description?: string;
247
232
  values: string[];
248
233
  isReadOnly: boolean;
249
234
  update: (updatedValues: string[]) => void;
250
235
  }) => {
251
- const { propertyName, description, values, isReadOnly, update } = props;
236
+ const { name, description, values, isReadOnly, update } = props;
252
237
  const arrayValues = values;
253
238
  // NOTE: `showEditInput` is either boolean (to hide/show the add value button) or a number (index of the item being edited)
254
239
  const [showEditInput, setShowEditInput] = useState<boolean | number>(false);
@@ -300,7 +285,7 @@ export const ConnectionEditor_ArrayEditor = observer(
300
285
  return (
301
286
  <div className="panel__content__form__section">
302
287
  <div className="panel__content__form__section__header__label">
303
- {capitalize(propertyName)}
288
+ {capitalize(name)}
304
289
  </div>
305
290
  <div className="panel__content__form__section__header__prompt">
306
291
  {description}
@@ -434,7 +419,7 @@ const LocalH2DatasourceSpecificationEditor = observer(
434
419
  <ConnectionEditor_TextEditor
435
420
  isReadOnly={isReadOnly}
436
421
  value={SQLValue}
437
- propertyName={'test data setup SQL'}
422
+ name={'test data setup SQL'}
438
423
  language={EDITOR_LANGUAGE.SQL}
439
424
  update={(value: string | undefined): void =>
440
425
  localH2DatasourceSpecification_setTestDataSetupSqls(
@@ -448,7 +433,7 @@ const LocalH2DatasourceSpecificationEditor = observer(
448
433
  },
449
434
  );
450
435
 
451
- // data source
436
+ //data source
452
437
  const StaticDatasourceSpecificationEditor = observer(
453
438
  (props: {
454
439
  sourceSpec: StaticDatasourceSpecification;
@@ -462,10 +447,10 @@ const StaticDatasourceSpecificationEditor = observer(
462
447
 
463
448
  return (
464
449
  <>
465
- <ConnectionEditor_StringEditor
450
+ <PanelTextEditor
466
451
  isReadOnly={isReadOnly}
467
452
  value={sourceSpec.host}
468
- propertyName={'host'}
453
+ name={'host'}
469
454
  update={(value: string | undefined): void =>
470
455
  staticDatasourceSpecification_setHost(sourceSpec, value ?? '')
471
456
  }
@@ -483,10 +468,10 @@ const StaticDatasourceSpecificationEditor = observer(
483
468
  onChange={changePort}
484
469
  />
485
470
  </div>
486
- <ConnectionEditor_StringEditor
471
+ <PanelTextEditor
487
472
  isReadOnly={isReadOnly}
488
473
  value={sourceSpec.databaseName}
489
- propertyName={'database'}
474
+ name={'database'}
490
475
  update={(value: string | undefined): void =>
491
476
  staticDatasourceSpecification_setDatabaseName(
492
477
  sourceSpec,
@@ -507,10 +492,10 @@ const EmbeddedH2DatasourceSpecificationEditor = observer(
507
492
  const { sourceSpec, isReadOnly } = props;
508
493
  return (
509
494
  <>
510
- <ConnectionEditor_StringEditor
495
+ <PanelTextEditor
511
496
  isReadOnly={isReadOnly}
512
497
  value={sourceSpec.databaseName}
513
- propertyName={'database'}
498
+ name={'database'}
514
499
  update={(value: string | undefined): void =>
515
500
  embeddedH2DatasourceSpecification_setDatabaseName(
516
501
  sourceSpec,
@@ -518,10 +503,10 @@ const EmbeddedH2DatasourceSpecificationEditor = observer(
518
503
  )
519
504
  }
520
505
  />
521
- <ConnectionEditor_StringEditor
506
+ <PanelTextEditor
522
507
  isReadOnly={isReadOnly}
523
508
  value={sourceSpec.directory}
524
- propertyName={'directory'}
509
+ name={'directory'}
525
510
  update={(value: string | undefined): void =>
526
511
  embeddedH2DatasourceSpecification_setDirectory(
527
512
  sourceSpec,
@@ -532,7 +517,7 @@ const EmbeddedH2DatasourceSpecificationEditor = observer(
532
517
  <ConnectionEditor_BooleanEditor
533
518
  isReadOnly={isReadOnly}
534
519
  value={sourceSpec.autoServerMode}
535
- propertyName={'auto server mode'}
520
+ name={'auto server mode'}
536
521
  update={(value?: boolean): void =>
537
522
  embeddedH2DatasourceSpecification_setAutoServerMode(
538
523
  sourceSpec,
@@ -553,10 +538,10 @@ const DatabricksDatasourceSpecificationEditor = observer(
553
538
  const { sourceSpec, isReadOnly } = props;
554
539
  return (
555
540
  <>
556
- <ConnectionEditor_StringEditor
541
+ <PanelTextEditor
557
542
  isReadOnly={isReadOnly}
558
543
  value={sourceSpec.hostname}
559
- propertyName="hostname"
544
+ name="hostname"
560
545
  update={(value: string | undefined): void =>
561
546
  databricksDatasourceSpecification_setHostName(
562
547
  sourceSpec,
@@ -564,18 +549,18 @@ const DatabricksDatasourceSpecificationEditor = observer(
564
549
  )
565
550
  }
566
551
  />
567
- <ConnectionEditor_StringEditor
552
+ <PanelTextEditor
568
553
  isReadOnly={isReadOnly}
569
554
  value={sourceSpec.port}
570
- propertyName="port"
555
+ name="port"
571
556
  update={(value: string | undefined): void =>
572
557
  databricksDatasourceSpecification_setPort(sourceSpec, value ?? '')
573
558
  }
574
559
  />
575
- <ConnectionEditor_StringEditor
560
+ <PanelTextEditor
576
561
  isReadOnly={isReadOnly}
577
562
  value={sourceSpec.protocol}
578
- propertyName="protocol"
563
+ name="protocol"
579
564
  update={(value: string | undefined): void =>
580
565
  databricksDatasourceSpecification_setProtocol(
581
566
  sourceSpec,
@@ -583,10 +568,10 @@ const DatabricksDatasourceSpecificationEditor = observer(
583
568
  )
584
569
  }
585
570
  />
586
- <ConnectionEditor_StringEditor
571
+ <PanelTextEditor
587
572
  isReadOnly={isReadOnly}
588
573
  value={sourceSpec.httpPath}
589
- propertyName="httpPath"
574
+ name="httpPath"
590
575
  update={(value: string | undefined): void =>
591
576
  databricksDatasourceSpecification_setHttpPath(
592
577
  sourceSpec,
@@ -607,90 +592,90 @@ const SnowflakeDatasourceSpecificationEditor = observer(
607
592
  const { sourceSpec, isReadOnly } = props;
608
593
  return (
609
594
  <>
610
- <ConnectionEditor_StringEditor
595
+ <PanelTextEditor
611
596
  isReadOnly={isReadOnly}
612
597
  value={sourceSpec.accountName}
613
- propertyName="account"
598
+ name="account"
614
599
  update={(value: string | undefined): void =>
615
600
  snowflakeDatasourceSpec_setAccountName(sourceSpec, value ?? '')
616
601
  }
617
602
  />
618
- <ConnectionEditor_StringEditor
603
+ <PanelTextEditor
619
604
  isReadOnly={isReadOnly}
620
605
  value={sourceSpec.region}
621
- propertyName="region"
606
+ name="region"
622
607
  update={(value: string | undefined): void =>
623
608
  snowflakeDatasourceSpec_setRegion(sourceSpec, value ?? '')
624
609
  }
625
610
  />
626
- <ConnectionEditor_StringEditor
611
+ <PanelTextEditor
627
612
  isReadOnly={isReadOnly}
628
613
  value={sourceSpec.warehouseName}
629
- propertyName="warehouse"
614
+ name="warehouse"
630
615
  update={(value: string | undefined): void =>
631
616
  snowflakeDatasourceSpec_setWarehouseName(sourceSpec, value ?? '')
632
617
  }
633
618
  />
634
- <ConnectionEditor_StringEditor
619
+ <PanelTextEditor
635
620
  isReadOnly={isReadOnly}
636
621
  value={sourceSpec.databaseName}
637
- propertyName="database"
622
+ name="database"
638
623
  update={(value: string | undefined): void =>
639
624
  snowflakeDatasourceSpec_setDatabaseName(sourceSpec, value ?? '')
640
625
  }
641
626
  />
642
- <ConnectionEditor_StringEditor
627
+ <PanelTextEditor
643
628
  isReadOnly={isReadOnly}
644
629
  value={sourceSpec.cloudType}
645
- propertyName="cloud type"
630
+ name="cloud type"
646
631
  update={(value: string | undefined): void =>
647
632
  snowflakeDatasourceSpec_setCloudType(sourceSpec, value)
648
633
  }
649
634
  />
650
- <ConnectionEditor_StringEditor
635
+ <PanelTextEditor
651
636
  isReadOnly={isReadOnly}
652
637
  value={sourceSpec.proxyHost}
653
- propertyName="proxy host"
638
+ name="proxy host"
654
639
  update={(value: string | undefined): void =>
655
640
  snowflakeDatasourceSpec_setProxyHost(sourceSpec, value)
656
641
  }
657
642
  />
658
- <ConnectionEditor_StringEditor
643
+ <PanelTextEditor
659
644
  isReadOnly={isReadOnly}
660
645
  value={sourceSpec.proxyPort}
661
- propertyName="proxy port"
646
+ name="proxy port"
662
647
  update={(value: string | undefined): void =>
663
648
  snowflakeDatasourceSpec_setProxyPort(sourceSpec, value)
664
649
  }
665
650
  />
666
- <ConnectionEditor_StringEditor
651
+ <PanelTextEditor
667
652
  isReadOnly={isReadOnly}
668
653
  value={sourceSpec.nonProxyHosts}
669
- propertyName="non proxy hosts"
654
+ name="non proxy hosts"
670
655
  update={(value: string | undefined): void =>
671
656
  snowflakeDatasourceSpec_setNonProxyHosts(sourceSpec, value)
672
657
  }
673
658
  />
674
- <ConnectionEditor_StringEditor
659
+ <PanelTextEditor
675
660
  isReadOnly={isReadOnly}
676
661
  value={sourceSpec.organization}
677
- propertyName="organization"
662
+ name="organization"
678
663
  update={(value: string | undefined): void =>
679
664
  snowflakeDatasourceSpec_setOrganization(sourceSpec, value)
680
665
  }
681
666
  />
682
- <ConnectionEditor_StringEditor
667
+ <PanelTextEditor
683
668
  isReadOnly={isReadOnly}
684
669
  value={sourceSpec.accountType}
685
- propertyName="account type"
670
+ name="account type"
686
671
  update={(value: string | undefined): void =>
687
672
  snowflakeDatasourceSpec_setAccountType(sourceSpec, value)
688
673
  }
689
674
  />
690
- <ConnectionEditor_StringEditor
675
+ <PanelTextEditor
691
676
  isReadOnly={isReadOnly}
692
677
  value={sourceSpec.role}
693
- propertyName="role"
678
+ name="role"
694
679
  update={(value: string | undefined): void =>
695
680
  snowflakeDatasourceSpec_setRole(sourceSpec, value)
696
681
  }
@@ -699,7 +684,7 @@ const SnowflakeDatasourceSpecificationEditor = observer(
699
684
  <ConnectionEditor_BooleanEditor
700
685
  isReadOnly={isReadOnly}
701
686
  value={sourceSpec.quotedIdentifiersIgnoreCase}
702
- propertyName="quoted identifiers ignore case"
687
+ name="quoted identifiers ignore case"
703
688
  description="Controls whether Snowflake will treat alphabetic characters in double-quoted identifiers as uppercase"
704
689
  update={(value: boolean | undefined): void =>
705
690
  snowflakeDatasourceSpec_setQuotedIdentifiersIgnoreCase(
@@ -725,10 +710,10 @@ const RedshiftDatasourceSpecificationEditor = observer(
725
710
  };
726
711
  return (
727
712
  <>
728
- <ConnectionEditor_StringEditor
713
+ <PanelTextEditor
729
714
  isReadOnly={isReadOnly}
730
715
  value={sourceSpec.host}
731
- propertyName="host"
716
+ name="host"
732
717
  update={(value: string | undefined): void =>
733
718
  redshiftDatasourceSpecification_setHost(sourceSpec, value ?? '')
734
719
  }
@@ -746,10 +731,10 @@ const RedshiftDatasourceSpecificationEditor = observer(
746
731
  onChange={changePort}
747
732
  />
748
733
  </div>
749
- <ConnectionEditor_StringEditor
734
+ <PanelTextEditor
750
735
  isReadOnly={isReadOnly}
751
736
  value={sourceSpec.databaseName}
752
- propertyName="database"
737
+ name="database"
753
738
  update={(value: string | undefined): void =>
754
739
  redshiftDatasourceSpecification_setDatabaseName(
755
740
  sourceSpec,
@@ -758,18 +743,18 @@ const RedshiftDatasourceSpecificationEditor = observer(
758
743
  }
759
744
  />
760
745
 
761
- <ConnectionEditor_StringEditor
746
+ <PanelTextEditor
762
747
  isReadOnly={isReadOnly}
763
748
  value={sourceSpec.region}
764
- propertyName="region"
749
+ name="region"
765
750
  update={(value: string | undefined): void =>
766
751
  redshiftDatasourceSpecification_setRegion(sourceSpec, value ?? '')
767
752
  }
768
753
  />
769
- <ConnectionEditor_StringEditor
754
+ <PanelTextEditor
770
755
  isReadOnly={isReadOnly}
771
756
  value={sourceSpec.clusterID}
772
- propertyName="cluster"
757
+ name="cluster"
773
758
  update={(value: string | undefined): void =>
774
759
  redshiftDatasourceSpecification_setClusterID(
775
760
  sourceSpec,
@@ -777,10 +762,10 @@ const RedshiftDatasourceSpecificationEditor = observer(
777
762
  )
778
763
  }
779
764
  />
780
- <ConnectionEditor_StringEditor
765
+ <PanelTextEditor
781
766
  isReadOnly={isReadOnly}
782
767
  value={sourceSpec.endpointURL}
783
- propertyName="endpointURL"
768
+ name="endpointURL"
784
769
  update={(value: string | undefined): void =>
785
770
  redshiftDatasourceSpecification_setEndpointURL(
786
771
  sourceSpec,
@@ -801,10 +786,10 @@ const BigQueryDatasourceSpecificationEditor = observer(
801
786
  const { sourceSpec, isReadOnly } = props;
802
787
  return (
803
788
  <>
804
- <ConnectionEditor_StringEditor
789
+ <PanelTextEditor
805
790
  isReadOnly={isReadOnly}
806
791
  value={sourceSpec.projectId}
807
- propertyName={'project id'}
792
+ name={'project id'}
808
793
  update={(value: string | undefined): void =>
809
794
  bigQueryDatasourceSpecification_setProjectId(
810
795
  sourceSpec,
@@ -812,10 +797,10 @@ const BigQueryDatasourceSpecificationEditor = observer(
812
797
  )
813
798
  }
814
799
  />
815
- <ConnectionEditor_StringEditor
800
+ <PanelTextEditor
816
801
  isReadOnly={isReadOnly}
817
802
  value={sourceSpec.defaultDataset}
818
- propertyName={'default dataset'}
803
+ name={'default dataset'}
819
804
  update={(value: string | undefined): void =>
820
805
  bigQueryDatasourceSpecification_setDefaultDataset(
821
806
  sourceSpec,
@@ -823,10 +808,10 @@ const BigQueryDatasourceSpecificationEditor = observer(
823
808
  )
824
809
  }
825
810
  />
826
- <ConnectionEditor_StringEditor
811
+ <PanelTextEditor
827
812
  isReadOnly={isReadOnly}
828
813
  value={sourceSpec.proxyHost}
829
- propertyName="proxy host"
814
+ name="proxy host"
830
815
  description="Specifies proxy host for connection to GCP BigQuery"
831
816
  update={(value: string | undefined): void =>
832
817
  bigQueryDatasourceSpecification_setProxyHost(
@@ -835,10 +820,10 @@ const BigQueryDatasourceSpecificationEditor = observer(
835
820
  )
836
821
  }
837
822
  />
838
- <ConnectionEditor_StringEditor
823
+ <PanelTextEditor
839
824
  isReadOnly={isReadOnly}
840
825
  value={sourceSpec.proxyPort}
841
- propertyName="proxy port"
826
+ name="proxy port"
842
827
  description="Specifies proxy port for connection to GCP BigQuery"
843
828
  update={(value: string | undefined): void =>
844
829
  bigQueryDatasourceSpecification_setProxyPort(
@@ -862,10 +847,10 @@ const DelegatedKerberosAuthenticationStrategyEditor = observer(
862
847
  const { authSpec, isReadOnly } = props;
863
848
  return (
864
849
  <>
865
- <ConnectionEditor_StringEditor
850
+ <PanelTextEditor
866
851
  isReadOnly={isReadOnly}
867
852
  value={authSpec.serverPrincipal}
868
- propertyName={'server principal'}
853
+ name={'server principal'}
869
854
  update={(value: string | undefined): void =>
870
855
  delegatedKerberosAuthenticationStrategy_setServerPrincipal(
871
856
  authSpec,
@@ -886,10 +871,10 @@ const ApiTokenAuthenticationStrategyEditor = observer(
886
871
  const { authSpec, isReadOnly } = props;
887
872
  return (
888
873
  <>
889
- <ConnectionEditor_StringEditor
874
+ <PanelTextEditor
890
875
  isReadOnly={isReadOnly}
891
876
  value={authSpec.apiToken}
892
- propertyName={'apiTokenRef'}
877
+ name={'apiTokenRef'}
893
878
  update={(value: string | undefined): void =>
894
879
  apiTokenAuthenticationStrategy_setApiToken(authSpec, value ?? '')
895
880
  }
@@ -907,10 +892,10 @@ const SnowflakePublicAuthenticationStrategyEditor = observer(
907
892
  const { authSpec, isReadOnly } = props;
908
893
  return (
909
894
  <>
910
- <ConnectionEditor_StringEditor
895
+ <PanelTextEditor
911
896
  isReadOnly={isReadOnly}
912
897
  value={authSpec.privateKeyVaultReference}
913
- propertyName={'private key vault reference'}
898
+ name={'private key vault reference'}
914
899
  update={(value: string | undefined): void =>
915
900
  snowflakePublicAuthenticationStrategy_setPrivateKeyVaultReference(
916
901
  authSpec,
@@ -918,10 +903,10 @@ const SnowflakePublicAuthenticationStrategyEditor = observer(
918
903
  )
919
904
  }
920
905
  />
921
- <ConnectionEditor_StringEditor
906
+ <PanelTextEditor
922
907
  isReadOnly={isReadOnly}
923
908
  value={authSpec.passPhraseVaultReference}
924
- propertyName={'pass phrase vault reference'}
909
+ name={'pass phrase vault reference'}
925
910
  update={(value: string | undefined): void =>
926
911
  snowflakePublicAuthenticationStrategy_setPassPhraseVaultReference(
927
912
  authSpec,
@@ -929,10 +914,10 @@ const SnowflakePublicAuthenticationStrategyEditor = observer(
929
914
  )
930
915
  }
931
916
  />
932
- <ConnectionEditor_StringEditor
917
+ <PanelTextEditor
933
918
  isReadOnly={isReadOnly}
934
919
  value={authSpec.publicUserName}
935
- propertyName={'public user name'}
920
+ name={'public user name'}
936
921
  update={(value: string | undefined): void =>
937
922
  snowflakePublicAuthenticationStrategy_setPublicUserName(
938
923
  authSpec,
@@ -950,18 +935,18 @@ const OAuthAuthenticationStrategyEditor = observer(
950
935
  const { authSpec, isReadOnly } = props;
951
936
  return (
952
937
  <>
953
- <ConnectionEditor_StringEditor
938
+ <PanelTextEditor
954
939
  isReadOnly={isReadOnly}
955
940
  value={authSpec.oauthKey}
956
- propertyName={'oauth key'}
941
+ name={'oauth key'}
957
942
  update={(value: string | undefined): void =>
958
943
  oAuthAuthenticationStrategy_setOauthKey(authSpec, value ?? '')
959
944
  }
960
945
  />
961
- <ConnectionEditor_StringEditor
946
+ <PanelTextEditor
962
947
  isReadOnly={isReadOnly}
963
948
  value={authSpec.scopeName}
964
- propertyName={'scope name'}
949
+ name={'scope name'}
965
950
  update={(value: string | undefined): void =>
966
951
  oAuthAuthenticationStrategy_setScopeName(authSpec, value ?? '')
967
952
  }
@@ -979,10 +964,10 @@ const UsernamePasswordAuthenticationStrategyEditor = observer(
979
964
  const { authSpec, isReadOnly } = props;
980
965
  return (
981
966
  <>
982
- <ConnectionEditor_StringEditor
967
+ <PanelTextEditor
983
968
  isReadOnly={isReadOnly}
984
969
  value={authSpec.baseVaultReference}
985
- propertyName={'base vault reference'}
970
+ name={'base vault reference'}
986
971
  update={(value: string | undefined): void =>
987
972
  usernamePasswordAuthenticationStrategy_setBaseVaultReference(
988
973
  authSpec,
@@ -990,10 +975,10 @@ const UsernamePasswordAuthenticationStrategyEditor = observer(
990
975
  )
991
976
  }
992
977
  />
993
- <ConnectionEditor_StringEditor
978
+ <PanelTextEditor
994
979
  isReadOnly={isReadOnly}
995
980
  value={authSpec.userNameVaultReference}
996
- propertyName={'user name vault reference'}
981
+ name={'user name vault reference'}
997
982
  update={(value: string | undefined): void =>
998
983
  usernamePasswordAuthenticationStrategy_setUserNameVaultReference(
999
984
  authSpec,
@@ -1001,10 +986,10 @@ const UsernamePasswordAuthenticationStrategyEditor = observer(
1001
986
  )
1002
987
  }
1003
988
  />
1004
- <ConnectionEditor_StringEditor
989
+ <PanelTextEditor
1005
990
  isReadOnly={isReadOnly}
1006
991
  value={authSpec.passwordVaultReference}
1007
- propertyName={'password vault reference'}
992
+ name={'password vault reference'}
1008
993
  update={(value: string | undefined): void =>
1009
994
  usernamePasswordAuthenticationStrategy_setPasswordVaultReference(
1010
995
  authSpec,
@@ -1025,10 +1010,10 @@ const MiddleTierUsernamePasswordAuthenticationStrategyEditor = observer(
1025
1010
  const { authSpec, isReadOnly } = props;
1026
1011
  return (
1027
1012
  <>
1028
- <ConnectionEditor_StringEditor
1013
+ <PanelTextEditor
1029
1014
  isReadOnly={isReadOnly}
1030
1015
  value={authSpec.vaultReference}
1031
- propertyName={'vault reference'}
1016
+ name={'vault reference'}
1032
1017
  description="Specifies the cred vault reference containing connection credentials"
1033
1018
  update={(value: string | undefined): void =>
1034
1019
  middleTierUsernamePasswordAuthenticationStrategy_setVaultReference(
@@ -1051,10 +1036,10 @@ const GCPWorkloadIdentityFederationAuthenticationStrategyEditor = observer(
1051
1036
  const GCPScopes = authSpec.additionalGcpScopes.join('\n');
1052
1037
  return (
1053
1038
  <>
1054
- <ConnectionEditor_StringEditor
1039
+ <PanelTextEditor
1055
1040
  isReadOnly={isReadOnly}
1056
1041
  value={authSpec.serviceAccountEmail}
1057
- propertyName={'Service Account Email'}
1042
+ name={'Service Account Email'}
1058
1043
  update={(value: string | undefined): void =>
1059
1044
  gcpWorkloadIdentityFederationAuthenticationStrategy_setServiceAccountEmail(
1060
1045
  authSpec,
@@ -1062,10 +1047,10 @@ const GCPWorkloadIdentityFederationAuthenticationStrategyEditor = observer(
1062
1047
  )
1063
1048
  }
1064
1049
  />
1065
- <ConnectionEditor_StringEditor
1050
+ <PanelTextEditor
1066
1051
  isReadOnly={isReadOnly}
1067
1052
  value={GCPScopes}
1068
- propertyName={'Additional GCP Scopes'}
1053
+ name={'Additional GCP Scopes'}
1069
1054
  update={(value: string | undefined): void =>
1070
1055
  gcpWorkloadIdentityFederationAuthenticationStrategy_setAdditionalGcpScopes(
1071
1056
  authSpec,
@@ -1103,6 +1088,7 @@ const RelationalConnectionStoreEditor = observer(
1103
1088
  connectionValueState.editorStore.graphManagerState.graph.ownStores;
1104
1089
  const options = stores.map(buildElementOption);
1105
1090
  const store = connection.store.value;
1091
+
1106
1092
  const selectedStore = {
1107
1093
  value: store,
1108
1094
  label: isStoreEmpty ? noStoreLabel : store.path,
@@ -1151,6 +1137,232 @@ const RelationalConnectionStoreEditor = observer(
1151
1137
  },
1152
1138
  );
1153
1139
 
1140
+ const renderEditorPostProcessor = (
1141
+ connectionValueState: RelationalDatabaseConnectionValueState,
1142
+ postProcessor: PostProcessor,
1143
+ isReadOnly: boolean,
1144
+ plugins: LegendStudioApplicationPlugin[],
1145
+ ): React.ReactNode => {
1146
+ if (postProcessor instanceof MapperPostProcessor) {
1147
+ return (
1148
+ <MapperPostProcessorEditor
1149
+ postProcessorState={
1150
+ connectionValueState.postProcessorState as MapperPostProcessorEditorState
1151
+ }
1152
+ isReadOnly={isReadOnly}
1153
+ postProcessor={postProcessor}
1154
+ />
1155
+ );
1156
+ } else {
1157
+ const extraPostProcessorEditorRenderers = plugins.flatMap(
1158
+ (plugin) =>
1159
+ (
1160
+ plugin as StoreRelational_LegendStudioApplicationPlugin_Extension
1161
+ ).getExtraPostProcessorEditorRenderers?.() ?? [],
1162
+ );
1163
+ for (const editorRenderer of extraPostProcessorEditorRenderers) {
1164
+ const editor = editorRenderer(postProcessor, connectionValueState, false);
1165
+ if (editor) {
1166
+ return editor;
1167
+ }
1168
+ }
1169
+ return (
1170
+ <UnsupportedEditorPanel
1171
+ isReadOnly={true}
1172
+ text="Can't display post-processor in form mode"
1173
+ ></UnsupportedEditorPanel>
1174
+ );
1175
+ }
1176
+ };
1177
+
1178
+ const PostProcessorRelationalConnectionEditor = observer(
1179
+ (props: {
1180
+ connectionValueState: RelationalDatabaseConnectionValueState;
1181
+ isReadOnly: boolean;
1182
+ }) => {
1183
+ const { connectionValueState, isReadOnly } = props;
1184
+
1185
+ const connection = connectionValueState.connection;
1186
+
1187
+ const postProcessors = connection.postProcessors;
1188
+
1189
+ const editorStore = useEditorStore();
1190
+ const observerContext = editorStore.changeDetectionState.observerContext;
1191
+ const plugins = editorStore.pluginManager.getApplicationPlugins();
1192
+
1193
+ const postProcessorState = connectionValueState.postProcessorState;
1194
+
1195
+ const deletePostProcessor =
1196
+ (postProcessor: PostProcessor): (() => void) =>
1197
+ (): void => {
1198
+ relationalDatabaseConnection_deletePostProcessor(
1199
+ connectionValueState,
1200
+ postProcessor,
1201
+ );
1202
+ if (
1203
+ postProcessor ===
1204
+ connectionValueState.postProcessorState?.postProcessor
1205
+ ) {
1206
+ connectionValueState.postProcessorState.setPostProcessorState(
1207
+ undefined,
1208
+ );
1209
+ }
1210
+ };
1211
+ const postProcessorOptions = (
1212
+ Object.values(POST_PROCESSOR_TYPE) as string[]
1213
+ )
1214
+ .concat(
1215
+ plugins.flatMap(
1216
+ (plugin) =>
1217
+ (
1218
+ plugin as StoreRelational_LegendStudioApplicationPlugin_Extension
1219
+ ).getExtraPostProcessorClassifiers?.() ?? [],
1220
+ ),
1221
+ )
1222
+ .map((e) => ({
1223
+ value: e,
1224
+ label: prettyCONSTName(e),
1225
+ }));
1226
+
1227
+ const addPostProcessor =
1228
+ (postProcessorType: string): (() => void) =>
1229
+ (): void => {
1230
+ switch (postProcessorType) {
1231
+ case POST_PROCESSOR_TYPE.MAPPER: {
1232
+ relationalDatabaseConnection_addPostProcessor(
1233
+ connectionValueState,
1234
+ new MapperPostProcessor(),
1235
+ observerContext,
1236
+ );
1237
+ break;
1238
+ }
1239
+ default: {
1240
+ const extraPostProcessorCreators = plugins.flatMap(
1241
+ (plugin) =>
1242
+ (
1243
+ plugin as StoreRelational_LegendStudioApplicationPlugin_Extension
1244
+ ).getExtraPostProcessorCreators?.() ?? [],
1245
+ );
1246
+ for (const creator of extraPostProcessorCreators) {
1247
+ creator(postProcessorType, connectionValueState, observerContext);
1248
+ }
1249
+ }
1250
+ }
1251
+
1252
+ connectionValueState.postProcessorState?.setPostProcessorState(
1253
+ connectionValueState.connection.postProcessors[
1254
+ connectionValueState.connection.postProcessors.length - 1
1255
+ ],
1256
+ );
1257
+ };
1258
+
1259
+ const selectPostProcessor = (postProcessor: PostProcessor): void => {
1260
+ connectionValueState.selectPostProcessor(postProcessor);
1261
+ };
1262
+
1263
+ return (
1264
+ <div className="relational-connection-editor">
1265
+ <ResizablePanelGroup orientation="horizontal">
1266
+ <ResizablePanelSplitter>
1267
+ <ResizablePanelSplitterLine color="var(--color-dark-grey-200)" />
1268
+ </ResizablePanelSplitter>
1269
+ <ResizablePanel>
1270
+ <div className="relational-connection-editor__content">
1271
+ <ResizablePanelGroup orientation="vertical">
1272
+ <ResizablePanel size={150} minSize={70}>
1273
+ <Panel>
1274
+ <PanelHeader title="post-processor">
1275
+ <DropdownMenu
1276
+ disabled={isReadOnly}
1277
+ content={postProcessorOptions.map(
1278
+ (postProcessorType) => (
1279
+ <MenuContentItem
1280
+ key={postProcessorType.value}
1281
+ onClick={addPostProcessor(
1282
+ postProcessorType.value,
1283
+ )}
1284
+ >
1285
+ New {postProcessorType.label} Post-Processor
1286
+ </MenuContentItem>
1287
+ ),
1288
+ )}
1289
+ menuProps={{
1290
+ anchorOrigin: {
1291
+ vertical: 'bottom',
1292
+ horizontal: 'right',
1293
+ },
1294
+ transformOrigin: {
1295
+ vertical: 'top',
1296
+ horizontal: 'right',
1297
+ },
1298
+ elevation: 7,
1299
+ }}
1300
+ >
1301
+ <PanelHeaderActionItem
1302
+ disabled={isReadOnly}
1303
+ title="Create Post-Processor"
1304
+ >
1305
+ <PlusIcon />
1306
+ </PanelHeaderActionItem>
1307
+ </DropdownMenu>
1308
+ </PanelHeader>
1309
+ <PanelContent>
1310
+ {postProcessors.map((postProcessor, idx) => (
1311
+ <ContextMenu
1312
+ key={postProcessor._UUID}
1313
+ disabled={isReadOnly}
1314
+ content={
1315
+ <MenuContent>
1316
+ <MenuContentItem
1317
+ onClick={deletePostProcessor(postProcessor)}
1318
+ >
1319
+ Delete
1320
+ </MenuContentItem>
1321
+ </MenuContent>
1322
+ }
1323
+ menuProps={{ elevation: 7 }}
1324
+ >
1325
+ <PanelListSelectorItem
1326
+ title={`Post-Processor ${idx + 1}`}
1327
+ onSelect={() => selectPostProcessor(postProcessor)}
1328
+ isSelected={
1329
+ postProcessor ===
1330
+ postProcessorState?.postProcessor
1331
+ }
1332
+ />
1333
+ </ContextMenu>
1334
+ ))}
1335
+ </PanelContent>
1336
+ </Panel>
1337
+ </ResizablePanel>
1338
+ <ResizablePanelSplitter>
1339
+ <ResizablePanelSplitterLine color="var(--color-dark-grey-200)" />
1340
+ </ResizablePanelSplitter>
1341
+ <ResizablePanel>
1342
+ {postProcessorState?.postProcessor &&
1343
+ renderEditorPostProcessor(
1344
+ connectionValueState,
1345
+ postProcessorState.postProcessor,
1346
+ true,
1347
+ plugins,
1348
+ )}
1349
+ {!postProcessorState && (
1350
+ <BlankPanelContent>
1351
+ {!postProcessors.length
1352
+ ? 'Addddd a post-processor'
1353
+ : 'Select a post-processor to view'}
1354
+ </BlankPanelContent>
1355
+ )}
1356
+ </ResizablePanel>
1357
+ </ResizablePanelGroup>
1358
+ </div>
1359
+ </ResizablePanel>
1360
+ </ResizablePanelGroup>
1361
+ </div>
1362
+ );
1363
+ },
1364
+ );
1365
+
1154
1366
  const renderDatasourceSpecificationEditor = (
1155
1367
  connection: RelationalDatabaseConnection,
1156
1368
  isReadOnly: boolean,
@@ -1310,6 +1522,7 @@ const RelationalConnectionGeneralEditor = observer(
1310
1522
  const connection = connectionValueState.connection;
1311
1523
  const editorStore = useEditorStore();
1312
1524
  const plugins = editorStore.pluginManager.getApplicationPlugins();
1525
+
1313
1526
  // database type
1314
1527
  const typeOptions = Object.values(DatabaseType).map((e) => ({
1315
1528
  value: e,
@@ -1386,11 +1599,8 @@ const RelationalConnectionGeneralEditor = observer(
1386
1599
  <ResizablePanelGroup orientation="horizontal">
1387
1600
  <ResizablePanel size={200} minSize={15}>
1388
1601
  <div className="panel">
1389
- <div className="panel__header">
1390
- <div className="panel__header__title">
1391
- <div className="panel__header__title__label">general</div>
1392
- </div>
1393
- </div>
1602
+ <PanelHeader title="general"></PanelHeader>
1603
+
1394
1604
  <div className="panel__content relational-connection-editor__general">
1395
1605
  <div className="panel__content__form__section">
1396
1606
  <div className="panel__content__form__section__header__label">
@@ -1406,7 +1616,7 @@ const RelationalConnectionGeneralEditor = observer(
1406
1616
  <ConnectionEditor_BooleanEditor
1407
1617
  isReadOnly={isReadOnly}
1408
1618
  value={connection.quoteIdentifiers}
1409
- propertyName="Quote identifiers"
1619
+ name="Quote identifiers"
1410
1620
  description="Specifies whether to use double-quotes for SQL identifiers"
1411
1621
  update={(value?: boolean): void =>
1412
1622
  dBConnection_setQuoteIdentifiers(connection, Boolean(value))
@@ -1421,13 +1631,7 @@ const RelationalConnectionGeneralEditor = observer(
1421
1631
  <ResizablePanelGroup orientation="vertical">
1422
1632
  <ResizablePanel size={450} minSize={50}>
1423
1633
  <div className="relational-connection-editor__auth">
1424
- <div className="panel__header">
1425
- <div className="panel__header__title">
1426
- <div className="panel__header__title__label">
1427
- datasource spec
1428
- </div>
1429
- </div>
1430
- </div>
1634
+ <PanelHeader title="datasource spec"></PanelHeader>
1431
1635
  <div className="panel__content relational-connection-editor__auth__content">
1432
1636
  <div className="panel__content__form__section">
1433
1637
  <div className="panel__content__form__section__header__label">
@@ -1453,13 +1657,7 @@ const RelationalConnectionGeneralEditor = observer(
1453
1657
  <ResizablePanelSplitter />
1454
1658
  <ResizablePanel>
1455
1659
  <div className="relational-connection-editor__source">
1456
- <div className="panel__header">
1457
- <div className="panel__header__title">
1458
- <div className="panel__header__title__label">
1459
- authentication spec
1460
- </div>
1461
- </div>
1462
- </div>
1660
+ <PanelHeader title="authentication spec"></PanelHeader>
1463
1661
  <div className="panel__content relational-connection-editor__source__content">
1464
1662
  <div className="panel__content__form__section">
1465
1663
  <div className="panel__content__form__section__header__label">
@@ -1499,27 +1697,22 @@ export const RelationalDatabaseConnectionEditor = observer(
1499
1697
  const { connectionValueState, isReadOnly } = props;
1500
1698
  const selectedTab = connectionValueState.selectedTab;
1501
1699
  const changeTab =
1502
- (tab: RELATIONAL_DATABASE_TAB_TYPE): (() => void) =>
1503
- (): void =>
1504
- connectionValueState.setSelectedTab(tab);
1700
+ <T,>( // eslint-disable-line
1701
+ tab: T,
1702
+ ) =>
1703
+ (): void => {
1704
+ connectionValueState.setSelectedTab(
1705
+ tab as unknown as RELATIONAL_DATABASE_TAB_TYPE,
1706
+ );
1707
+ };
1505
1708
  return (
1506
1709
  <>
1507
- <div className="panel__header">
1508
- <div className="uml-element-editor__tabs">
1509
- {Object.values(RELATIONAL_DATABASE_TAB_TYPE).map((tab) => (
1510
- <div
1511
- key={tab}
1512
- onClick={changeTab(tab)}
1513
- className={clsx('relational-connection-editor__tab', {
1514
- 'relational-connection-editor__tab--active':
1515
- tab === selectedTab,
1516
- })}
1517
- >
1518
- {prettyCONSTName(tab)}
1519
- </div>
1520
- ))}
1521
- </div>
1522
- </div>
1710
+ <PanelTabs
1711
+ tabTitles={Object.values(RELATIONAL_DATABASE_TAB_TYPE)}
1712
+ changeTheTab={changeTab}
1713
+ selectedTab={selectedTab}
1714
+ tabClassName="relational-connection-editor__tab"
1715
+ />
1523
1716
  <div className="panel__content">
1524
1717
  {selectedTab === RELATIONAL_DATABASE_TAB_TYPE.GENERAL && (
1525
1718
  <RelationalConnectionGeneralEditor
@@ -1533,6 +1726,12 @@ export const RelationalDatabaseConnectionEditor = observer(
1533
1726
  isReadOnly={isReadOnly}
1534
1727
  />
1535
1728
  )}
1729
+ {selectedTab === RELATIONAL_DATABASE_TAB_TYPE.POST_PROCESSORS && (
1730
+ <PostProcessorRelationalConnectionEditor
1731
+ connectionValueState={connectionValueState}
1732
+ isReadOnly={isReadOnly}
1733
+ />
1734
+ )}
1536
1735
  </div>
1537
1736
  </>
1538
1737
  );