@finos/legend-extension-dsl-data-space 10.4.170 → 10.4.172

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 (28) hide show
  1. package/lib/components/DataSpaceWiki.d.ts.map +1 -1
  2. package/lib/components/DataSpaceWiki.js +2 -2
  3. package/lib/components/DataSpaceWiki.js.map +1 -1
  4. package/lib/graph-manager/action/analytics/DataSpaceAnalysis.d.ts +3 -44
  5. package/lib/graph-manager/action/analytics/DataSpaceAnalysis.d.ts.map +1 -1
  6. package/lib/graph-manager/action/analytics/DataSpaceAnalysis.js +0 -51
  7. package/lib/graph-manager/action/analytics/DataSpaceAnalysis.js.map +1 -1
  8. package/lib/graph-manager/protocol/pure/v1/V1_DSL_DataSpace_PureGraphManagerExtension.d.ts.map +1 -1
  9. package/lib/graph-manager/protocol/pure/v1/V1_DSL_DataSpace_PureGraphManagerExtension.js +14 -13
  10. package/lib/graph-manager/protocol/pure/v1/V1_DSL_DataSpace_PureGraphManagerExtension.js.map +1 -1
  11. package/lib/index.css +2 -2
  12. package/lib/index.css.map +1 -1
  13. package/lib/package.json +1 -1
  14. package/lib/stores/DataSpaceModelsDocumentationState.d.ts +2 -78
  15. package/lib/stores/DataSpaceModelsDocumentationState.d.ts.map +1 -1
  16. package/lib/stores/DataSpaceModelsDocumentationState.js +3 -400
  17. package/lib/stores/DataSpaceModelsDocumentationState.js.map +1 -1
  18. package/package.json +6 -6
  19. package/src/components/DataSpaceWiki.tsx +6 -3
  20. package/src/graph-manager/action/analytics/DataSpaceAnalysis.ts +2 -68
  21. package/src/graph-manager/protocol/pure/v1/V1_DSL_DataSpace_PureGraphManagerExtension.ts +21 -19
  22. package/src/stores/DataSpaceModelsDocumentationState.ts +3 -597
  23. package/tsconfig.json +0 -1
  24. package/lib/components/DataSpaceModelsDocumentation.d.ts +0 -22
  25. package/lib/components/DataSpaceModelsDocumentation.d.ts.map +0 -1
  26. package/lib/components/DataSpaceModelsDocumentation.js +0 -389
  27. package/lib/components/DataSpaceModelsDocumentation.js.map +0 -1
  28. package/src/components/DataSpaceModelsDocumentation.tsx +0 -1151
@@ -1,1151 +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 { observer } from 'mobx-react-lite';
18
- import {
19
- AnchorLinkIcon,
20
- BasePopover,
21
- ChevronDownIcon,
22
- ChevronRightIcon,
23
- ClockIcon,
24
- CogIcon,
25
- ControlledDropdownMenu,
26
- FilterIcon,
27
- InfoCircleIcon,
28
- MenuContent,
29
- MenuContentItem,
30
- MoreVerticalIcon,
31
- SearchIcon,
32
- TimesIcon,
33
- Tooltip,
34
- clsx,
35
- type TreeNodeContainerProps,
36
- TreeView,
37
- PackageIcon,
38
- CheckSquareIcon,
39
- MinusSquareIcon,
40
- EmptySquareIcon,
41
- CaretRightIcon,
42
- CaretLeftIcon,
43
- } from '@finos/legend-art';
44
- import { type DataSpaceViewerState } from '../stores/DataSpaceViewerState.js';
45
- import { DataSpaceWikiPlaceholder } from './DataSpacePlaceholder.js';
46
- import {
47
- DataSpaceAssociationDocumentationEntry,
48
- DataSpaceBasicDocumentationEntry,
49
- DataSpaceClassDocumentationEntry,
50
- DataSpaceEnumerationDocumentationEntry,
51
- DataSpaceModelDocumentationEntry,
52
- DataSpacePropertyDocumentationEntry,
53
- type NormalizedDataSpaceDocumentationEntry,
54
- } from '../graph-manager/action/analytics/DataSpaceAnalysis.js';
55
- import { debounce, isNonNullable, prettyCONSTName } from '@finos/legend-shared';
56
- import { useApplicationStore, useCommands } from '@finos/legend-application';
57
- import {
58
- CORE_PURE_PATH,
59
- ELEMENT_PATH_DELIMITER,
60
- MILESTONING_STEREOTYPE,
61
- PROPERTY_ACCESSOR,
62
- getMultiplicityDescription,
63
- } from '@finos/legend-graph';
64
- import { useEffect, useMemo, useRef } from 'react';
65
- import {
66
- type ModelsDocumentationFilterTreeNodeData,
67
- type DataSpaceViewerModelsDocumentationState,
68
- ModelsDocumentationFilterTreeTypeNodeData,
69
- ModelsDocumentationFilterTreeElementNodeData,
70
- ModelsDocumentationFilterTreePackageNodeData,
71
- ModelsDocumentationFilterTreeNodeCheckType,
72
- uncheckFilterTreeNode,
73
- checkFilterTreeNode,
74
- uncheckAllFilterTree,
75
- ModelsDocumentationFilterTreeRootNodeData,
76
- } from '../stores/DataSpaceModelsDocumentationState.js';
77
- import {
78
- DataGrid,
79
- type DataGridCellRendererParams,
80
- } from '@finos/legend-lego/data-grid';
81
- import { FuzzySearchAdvancedConfigMenu } from '@finos/legend-lego/application';
82
- import {
83
- DATA_SPACE_VIEWER_ACTIVITY_MODE,
84
- generateAnchorForActivity,
85
- } from '../stores/DataSpaceViewerNavigation.js';
86
-
87
- const getMilestoningLabel = (val: string | undefined): string | undefined => {
88
- switch (val) {
89
- case MILESTONING_STEREOTYPE.BITEMPORAL:
90
- return 'Bi-temporal';
91
- case MILESTONING_STEREOTYPE.BUSINESS_TEMPORAL:
92
- return 'Business Temporal';
93
- case MILESTONING_STEREOTYPE.PROCESSING_TEMPORAL:
94
- return 'Processing Temporal';
95
- default:
96
- return undefined;
97
- }
98
- };
99
-
100
- const ElementInfoTooltip: React.FC<{
101
- entry: DataSpaceModelDocumentationEntry;
102
- children: React.ReactElement;
103
- }> = (props) => {
104
- const { entry, children } = props;
105
-
106
- return (
107
- <Tooltip
108
- arrow={false}
109
- placement="bottom-end"
110
- disableInteractive={true}
111
- classes={{
112
- tooltip: 'data-space__viewer__tooltip',
113
- tooltipPlacementRight: 'data-space__viewer__tooltip--right',
114
- }}
115
- slotProps={{
116
- transition: {
117
- // disable transition
118
- // NOTE: somehow, this is the only workaround we have, if for example
119
- // we set `appear = true`, the tooltip will jump out of position
120
- timeout: 0,
121
- },
122
- }}
123
- title={
124
- <div className="data-space__viewer__tooltip__content">
125
- <div className="data-space__viewer__tooltip__item">
126
- <div className="data-space__viewer__tooltip__item__label">Name</div>
127
- <div className="data-space__viewer__tooltip__item__value">
128
- {entry.name}
129
- </div>
130
- </div>
131
- <div className="data-space__viewer__tooltip__item">
132
- <div className="data-space__viewer__tooltip__item__label">Path</div>
133
- <div className="data-space__viewer__tooltip__item__value">
134
- {entry.path}
135
- </div>
136
- </div>
137
- {entry instanceof DataSpaceClassDocumentationEntry &&
138
- entry.milestoning !== undefined && (
139
- <div className="data-space__viewer__tooltip__item">
140
- <div className="data-space__viewer__tooltip__item__label">
141
- Milestoning
142
- </div>
143
- <div className="data-space__viewer__tooltip__item__value">
144
- {getMilestoningLabel(entry.milestoning)}
145
- </div>
146
- </div>
147
- )}
148
- </div>
149
- }
150
- >
151
- {children}
152
- </Tooltip>
153
- );
154
- };
155
-
156
- const PropertyInfoTooltip: React.FC<{
157
- entry: DataSpacePropertyDocumentationEntry;
158
- elementEntry: DataSpaceModelDocumentationEntry;
159
- children: React.ReactElement;
160
- }> = (props) => {
161
- const { entry, elementEntry, children } = props;
162
-
163
- return (
164
- <Tooltip
165
- arrow={false}
166
- placement="bottom-end"
167
- disableInteractive={true}
168
- classes={{
169
- tooltip: 'data-space__viewer__tooltip',
170
- tooltipPlacementRight: 'data-space__viewer__tooltip--right',
171
- }}
172
- slotProps={{
173
- transition: {
174
- // disable transition
175
- // NOTE: somehow, this is the only workaround we have, if for example
176
- // we set `appear = true`, the tooltip will jump out of position
177
- timeout: 0,
178
- },
179
- }}
180
- title={
181
- <div className="data-space__viewer__tooltip__content">
182
- <div className="data-space__viewer__tooltip__item">
183
- <div className="data-space__viewer__tooltip__item__label">Name</div>
184
- <div className="data-space__viewer__tooltip__item__value">
185
- {entry.name}
186
- </div>
187
- </div>
188
- <div className="data-space__viewer__tooltip__item">
189
- <div className="data-space__viewer__tooltip__item__label">
190
- Owner
191
- </div>
192
- <div className="data-space__viewer__tooltip__item__value">
193
- {elementEntry.path}
194
- </div>
195
- </div>
196
- {entry.type && (
197
- <div className="data-space__viewer__tooltip__item">
198
- <div className="data-space__viewer__tooltip__item__label">
199
- Type
200
- </div>
201
- <div className="data-space__viewer__tooltip__item__value">
202
- {entry.type}
203
- </div>
204
- </div>
205
- )}
206
- {entry.multiplicity && (
207
- <div className="data-space__viewer__tooltip__item">
208
- <div className="data-space__viewer__tooltip__item__label">
209
- Multiplicity
210
- </div>
211
- <div className="data-space__viewer__tooltip__item__value">
212
- {getMultiplicityDescription(entry.multiplicity)}
213
- </div>
214
- </div>
215
- )}
216
- {entry.milestoning && (
217
- <div className="data-space__viewer__tooltip__item">
218
- <div className="data-space__viewer__tooltip__item__label">
219
- Milestoning
220
- </div>
221
- <div className="data-space__viewer__tooltip__item__value">
222
- {getMilestoningLabel(entry.milestoning)}
223
- </div>
224
- </div>
225
- )}
226
- </div>
227
- }
228
- >
229
- {children}
230
- </Tooltip>
231
- );
232
- };
233
-
234
- const ElementContentCellRenderer = observer(
235
- (
236
- params: DataGridCellRendererParams<NormalizedDataSpaceDocumentationEntry> & {
237
- dataSpaceViewerState: DataSpaceViewerState;
238
- },
239
- ) => {
240
- const { data, dataSpaceViewerState } = params;
241
- const applicationStore = useApplicationStore();
242
- const showHumanizedForm =
243
- dataSpaceViewerState.modelsDocumentationState.showHumanizedForm;
244
-
245
- if (!data) {
246
- return null;
247
- }
248
-
249
- const copyPath = (): void => {
250
- applicationStore.clipboardService
251
- .copyTextToClipboard(data.elementEntry.path)
252
- .catch(applicationStore.alertUnhandledError);
253
- };
254
- const label = showHumanizedForm
255
- ? prettyCONSTName(data.elementEntry.name)
256
- : data.elementEntry.name;
257
-
258
- if (data.elementEntry instanceof DataSpaceClassDocumentationEntry) {
259
- return (
260
- <div
261
- className="data-space__viewer__models-documentation__grid__cell"
262
- title={`Class: ${data.elementEntry.path}`}
263
- >
264
- <div className="data-space__viewer__models-documentation__grid__cell__label">
265
- <div className="data-space__viewer__models-documentation__grid__cell__label__icon data-space__viewer__models-documentation__grid__cell__label__icon--class">
266
- C
267
- </div>
268
- <div className="data-space__viewer__models-documentation__grid__cell__label__text">
269
- {label}
270
- </div>
271
- {data.elementEntry.milestoning && (
272
- <div
273
- className="data-space__viewer__models-documentation__grid__cell__label__milestoning-badge"
274
- title={`Milestoning: ${getMilestoningLabel(
275
- data.elementEntry.milestoning,
276
- )}`}
277
- >
278
- <ClockIcon />
279
- </div>
280
- )}
281
- </div>
282
- <div className="data-space__viewer__models-documentation__grid__cell__actions">
283
- <ElementInfoTooltip entry={data.elementEntry}>
284
- <div className="data-space__viewer__models-documentation__grid__cell__action">
285
- <InfoCircleIcon className="data-space__viewer__models-documentation__grid__cell__action__info" />
286
- </div>
287
- </ElementInfoTooltip>
288
- <ControlledDropdownMenu
289
- className="data-space__viewer__models-documentation__grid__cell__action"
290
- menuProps={{
291
- anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
292
- transformOrigin: { vertical: 'top', horizontal: 'right' },
293
- elevation: 7,
294
- }}
295
- content={
296
- <MenuContent>
297
- <MenuContentItem onClick={copyPath}>
298
- Copy Path
299
- </MenuContentItem>
300
- <MenuContentItem disabled={true}>
301
- Preview Data
302
- </MenuContentItem>
303
- </MenuContent>
304
- }
305
- >
306
- <MoreVerticalIcon />
307
- </ControlledDropdownMenu>
308
- </div>
309
- </div>
310
- );
311
- } else if (
312
- data.elementEntry instanceof DataSpaceEnumerationDocumentationEntry
313
- ) {
314
- return (
315
- <div
316
- className="data-space__viewer__models-documentation__grid__cell"
317
- title={`Enumeration: ${data.elementEntry.path}`}
318
- >
319
- <div className="data-space__viewer__models-documentation__grid__cell__label">
320
- <div className="data-space__viewer__models-documentation__grid__cell__label__icon data-space__viewer__models-documentation__grid__cell__label__icon--enumeration">
321
- E
322
- </div>
323
- <div className="data-space__viewer__models-documentation__grid__cell__label__text">
324
- {label}
325
- </div>
326
- </div>
327
- <div className="data-space__viewer__models-documentation__grid__cell__actions">
328
- <ElementInfoTooltip entry={data.elementEntry}>
329
- <div className="data-space__viewer__models-documentation__grid__cell__action">
330
- <InfoCircleIcon className="data-space__viewer__models-documentation__grid__cell__action__info" />
331
- </div>
332
- </ElementInfoTooltip>
333
- <ControlledDropdownMenu
334
- className="data-space__viewer__models-documentation__grid__cell__action"
335
- menuProps={{
336
- anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
337
- transformOrigin: { vertical: 'top', horizontal: 'right' },
338
- elevation: 7,
339
- }}
340
- content={
341
- <MenuContent>
342
- <MenuContentItem onClick={copyPath}>
343
- Copy Path
344
- </MenuContentItem>
345
- </MenuContent>
346
- }
347
- >
348
- <MoreVerticalIcon />
349
- </ControlledDropdownMenu>
350
- </div>
351
- </div>
352
- );
353
- } else if (
354
- data.elementEntry instanceof DataSpaceAssociationDocumentationEntry
355
- ) {
356
- return (
357
- <div
358
- className="data-space__viewer__models-documentation__grid__cell"
359
- title={`Association: ${data.elementEntry.path}`}
360
- >
361
- <div className="data-space__viewer__models-documentation__grid__cell__label">
362
- <div className="data-space__viewer__models-documentation__grid__cell__label__icon data-space__viewer__models-documentation__grid__cell__label__icon--association">
363
- A
364
- </div>
365
- <div className="data-space__viewer__models-documentation__grid__cell__label__text">
366
- {label}
367
- </div>
368
- </div>
369
- <div className="data-space__viewer__models-documentation__grid__cell__actions">
370
- <ElementInfoTooltip entry={data.elementEntry}>
371
- <div className="data-space__viewer__models-documentation__grid__cell__action">
372
- <InfoCircleIcon className="data-space__viewer__models-documentation__grid__cell__action__info" />
373
- </div>
374
- </ElementInfoTooltip>
375
- <ControlledDropdownMenu
376
- className="data-space__viewer__models-documentation__grid__cell__action"
377
- menuProps={{
378
- anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
379
- transformOrigin: { vertical: 'top', horizontal: 'right' },
380
- elevation: 7,
381
- }}
382
- content={
383
- <MenuContent>
384
- <MenuContentItem onClick={copyPath}>
385
- Copy Path
386
- </MenuContentItem>
387
- </MenuContent>
388
- }
389
- >
390
- <MoreVerticalIcon />
391
- </ControlledDropdownMenu>
392
- </div>
393
- </div>
394
- );
395
- }
396
- return null;
397
- },
398
- );
399
-
400
- const SubElementDocContentCellRenderer = observer(
401
- (
402
- params: DataGridCellRendererParams<NormalizedDataSpaceDocumentationEntry> & {
403
- dataSpaceViewerState: DataSpaceViewerState;
404
- },
405
- ) => {
406
- const { data, dataSpaceViewerState } = params;
407
- const applicationStore = useApplicationStore();
408
- const showHumanizedForm =
409
- dataSpaceViewerState.modelsDocumentationState.showHumanizedForm;
410
-
411
- if (!data) {
412
- return null;
413
- }
414
-
415
- let label = showHumanizedForm ? prettyCONSTName(data.text) : data.text;
416
- const isDerivedProperty = label.endsWith('()');
417
- label = isDerivedProperty ? label.slice(0, -2) : label;
418
-
419
- if (data.entry instanceof DataSpaceModelDocumentationEntry) {
420
- return null;
421
- } else if (data.entry instanceof DataSpacePropertyDocumentationEntry) {
422
- return (
423
- <div
424
- className="data-space__viewer__models-documentation__grid__cell"
425
- title={`${isDerivedProperty ? 'Derived property' : 'Property'}: ${
426
- data.elementEntry.path
427
- }${PROPERTY_ACCESSOR}${data.entry.name}`}
428
- >
429
- <div className="data-space__viewer__models-documentation__grid__cell__label">
430
- <div className="data-space__viewer__models-documentation__grid__cell__label__icon data-space__viewer__models-documentation__grid__cell__label__icon--property">
431
- P
432
- </div>
433
- <div className="data-space__viewer__models-documentation__grid__cell__label__text">
434
- {label}
435
- </div>
436
- {isDerivedProperty && (
437
- <div className="data-space__viewer__models-documentation__grid__cell__label__derived-property-badge">
438
- ()
439
- </div>
440
- )}
441
- {data.entry.milestoning && (
442
- <div
443
- className="data-space__viewer__models-documentation__grid__cell__label__milestoning-badge"
444
- title={`Milestoning: ${getMilestoningLabel(
445
- data.entry.milestoning,
446
- )}`}
447
- >
448
- <ClockIcon />
449
- </div>
450
- )}
451
- </div>
452
- <div className="data-space__viewer__models-documentation__grid__cell__actions">
453
- <PropertyInfoTooltip
454
- entry={data.entry}
455
- elementEntry={data.elementEntry}
456
- >
457
- <div className="data-space__viewer__models-documentation__grid__cell__action">
458
- <InfoCircleIcon className="data-space__viewer__models-documentation__grid__cell__action__info" />
459
- </div>
460
- </PropertyInfoTooltip>
461
- <ControlledDropdownMenu
462
- className="data-space__viewer__models-documentation__grid__cell__action"
463
- menuProps={{
464
- anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
465
- transformOrigin: { vertical: 'top', horizontal: 'right' },
466
- elevation: 7,
467
- }}
468
- content={
469
- <MenuContent>
470
- <MenuContentItem disabled={true}>
471
- Preview Data
472
- </MenuContentItem>
473
- </MenuContent>
474
- }
475
- >
476
- <MoreVerticalIcon />
477
- </ControlledDropdownMenu>
478
- </div>
479
- </div>
480
- );
481
- } else if (data.entry instanceof DataSpaceBasicDocumentationEntry) {
482
- const copyValue = (): void => {
483
- applicationStore.clipboardService
484
- .copyTextToClipboard(
485
- data.elementEntry.path + PROPERTY_ACCESSOR + data.entry.name,
486
- )
487
- .catch(applicationStore.alertUnhandledError);
488
- };
489
- return (
490
- <div
491
- className="data-space__viewer__models-documentation__grid__cell"
492
- title={`Enum: ${data.elementEntry.path}${PROPERTY_ACCESSOR}${data.entry.name}`}
493
- >
494
- <div className="data-space__viewer__models-documentation__grid__cell__label">
495
- <div className="data-space__viewer__models-documentation__grid__cell__label__icon data-space__viewer__models-documentation__grid__cell__label__icon--enum">
496
- e
497
- </div>
498
- <div className="data-space__viewer__models-documentation__grid__cell__label__text">
499
- {label}
500
- </div>
501
- </div>
502
- <div className="data-space__viewer__models-documentation__grid__cell__actions">
503
- <ControlledDropdownMenu
504
- className="data-space__viewer__models-documentation__grid__cell__action"
505
- menuProps={{
506
- anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
507
- transformOrigin: { vertical: 'top', horizontal: 'right' },
508
- elevation: 7,
509
- }}
510
- content={
511
- <MenuContent>
512
- <MenuContentItem onClick={copyValue}>
513
- Copy Value
514
- </MenuContentItem>
515
- </MenuContent>
516
- }
517
- >
518
- <MoreVerticalIcon />
519
- </ControlledDropdownMenu>
520
- </div>
521
- </div>
522
- );
523
- }
524
- return null;
525
- },
526
- );
527
-
528
- const ElementDocumentationCellRenderer = (
529
- params: DataGridCellRendererParams<NormalizedDataSpaceDocumentationEntry> & {
530
- dataSpaceViewerState: DataSpaceViewerState;
531
- },
532
- ): React.ReactNode => {
533
- const data = params.data;
534
- if (!data) {
535
- return null;
536
- }
537
- return data.documentation.trim() ? (
538
- data.documentation
539
- ) : (
540
- <div className="data-space__viewer__grid__empty-cell">
541
- No documentation provided
542
- </div>
543
- );
544
- };
545
-
546
- const DataSpaceModelsDocumentationGridPanel = observer(
547
- (props: { dataSpaceViewerState: DataSpaceViewerState }) => {
548
- const { dataSpaceViewerState } = props;
549
- const documentationState = dataSpaceViewerState.modelsDocumentationState;
550
- const darkMode =
551
- !dataSpaceViewerState.applicationStore.layoutService
552
- .TEMPORARY__isLightColorThemeEnabled;
553
-
554
- return (
555
- <div
556
- className={clsx(
557
- 'data-space__viewer__models-documentation__grid',
558
- 'data-space__viewer__grid',
559
- {
560
- 'data-space__viewer__models-documentation__grid--shrink':
561
- documentationState.showFilterPanel,
562
- 'ag-theme-balham': !darkMode,
563
- 'ag-theme-balham-dark': darkMode,
564
- },
565
- )}
566
- >
567
- <DataGrid
568
- rowData={documentationState.filteredSearchResults}
569
- overlayNoRowsTemplate={`<div class="data-space__viewer__grid--empty">No documentation found</div>`}
570
- // highlight element row
571
- getRowClass={(params) =>
572
- params.data?.entry instanceof DataSpaceModelDocumentationEntry
573
- ? 'data-space__viewer__models-documentation__grid__element-row'
574
- : undefined
575
- }
576
- alwaysShowVerticalScroll={true}
577
- gridOptions={{
578
- suppressScrollOnNewData: true,
579
- getRowId: (rowData) => rowData.data.uuid,
580
- }}
581
- suppressFieldDotNotation={true}
582
- columnDefs={[
583
- {
584
- minWidth: 50,
585
- sortable: true,
586
- resizable: true,
587
- cellRendererParams: {
588
- dataSpaceViewerState,
589
- },
590
- cellRenderer: ElementContentCellRenderer,
591
- headerName: 'Model',
592
- flex: 1,
593
- },
594
- {
595
- minWidth: 50,
596
- sortable: false,
597
- resizable: true,
598
- cellRendererParams: {
599
- dataSpaceViewerState,
600
- },
601
- cellRenderer: SubElementDocContentCellRenderer,
602
- headerName: '',
603
- flex: 1,
604
- },
605
- {
606
- minWidth: 50,
607
- sortable: false,
608
- resizable: false,
609
- headerClass: 'data-space__viewer__grid__last-column-header',
610
- cellRenderer: ElementDocumentationCellRenderer,
611
- headerName: 'Documentation',
612
- flex: 1,
613
- wrapText: true,
614
- autoHeight: true,
615
- },
616
- ]}
617
- />
618
- </div>
619
- );
620
- },
621
- );
622
-
623
- const getFilterTreeNodeIcon = (
624
- node: ModelsDocumentationFilterTreeNodeData,
625
- ): React.ReactNode | undefined => {
626
- if (node instanceof ModelsDocumentationFilterTreeElementNodeData) {
627
- if (node.typePath === CORE_PURE_PATH.CLASS) {
628
- return (
629
- <div className="data-space__viewer__models-documentation__filter__tree__node__type-icon data-space__viewer__models-documentation__filter__tree__node__type-icon--class">
630
- C
631
- </div>
632
- );
633
- } else if (node.typePath === CORE_PURE_PATH.ENUMERATION) {
634
- return (
635
- <div className="data-space__viewer__models-documentation__filter__tree__node__type-icon data-space__viewer__models-documentation__filter__tree__node__type-icon--enumeration">
636
- E
637
- </div>
638
- );
639
- } else if (node.typePath === CORE_PURE_PATH.ASSOCIATION) {
640
- return (
641
- <div className="data-space__viewer__models-documentation__filter__tree__node__type-icon data-space__viewer__models-documentation__filter__tree__node__type-icon--association">
642
- A
643
- </div>
644
- );
645
- }
646
- } else if (node instanceof ModelsDocumentationFilterTreePackageNodeData) {
647
- return (
648
- <div className="data-space__viewer__models-documentation__filter__tree__node__type-icon data-space__viewer__models-documentation__filter__tree__node__type-icon--package">
649
- <PackageIcon />
650
- </div>
651
- );
652
- } else if (node instanceof ModelsDocumentationFilterTreeTypeNodeData) {
653
- switch (node.typePath) {
654
- case CORE_PURE_PATH.CLASS:
655
- return (
656
- <div className="data-space__viewer__models-documentation__filter__tree__node__type-icon data-space__viewer__models-documentation__filter__tree__node__type-icon--class">
657
- C
658
- </div>
659
- );
660
- case CORE_PURE_PATH.ENUMERATION:
661
- return (
662
- <div className="data-space__viewer__models-documentation__filter__tree__node__type-icon data-space__viewer__models-documentation__filter__tree__node__type-icon--enumeration">
663
- E
664
- </div>
665
- );
666
- case CORE_PURE_PATH.ASSOCIATION:
667
- return (
668
- <div className="data-space__viewer__models-documentation__filter__tree__node__type-icon data-space__viewer__models-documentation__filter__tree__node__type-icon--association">
669
- A
670
- </div>
671
- );
672
- default:
673
- return undefined;
674
- }
675
- }
676
- return undefined;
677
- };
678
-
679
- const getFilterNodeCount = (
680
- node: ModelsDocumentationFilterTreeNodeData,
681
- documentationState: DataSpaceViewerModelsDocumentationState,
682
- ): number | undefined => {
683
- if (node instanceof ModelsDocumentationFilterTreeElementNodeData) {
684
- return documentationState.searchResults.filter(
685
- (result) => node.elementPath === result.elementEntry.path,
686
- ).length;
687
- } else if (node instanceof ModelsDocumentationFilterTreePackageNodeData) {
688
- return documentationState.searchResults.filter(
689
- (result) =>
690
- node.packagePath === result.elementEntry.path ||
691
- result.elementEntry.path.startsWith(
692
- `${node.packagePath}${ELEMENT_PATH_DELIMITER}`,
693
- ),
694
- ).length;
695
- } else if (node instanceof ModelsDocumentationFilterTreeTypeNodeData) {
696
- return node.typePath === CORE_PURE_PATH.CLASS
697
- ? documentationState.searchResults.filter(
698
- (entry) =>
699
- entry.elementEntry instanceof DataSpaceClassDocumentationEntry,
700
- ).length
701
- : node.typePath === CORE_PURE_PATH.ENUMERATION
702
- ? documentationState.searchResults.filter(
703
- (entry) =>
704
- entry.elementEntry instanceof
705
- DataSpaceEnumerationDocumentationEntry,
706
- ).length
707
- : node.typePath === CORE_PURE_PATH.ASSOCIATION
708
- ? documentationState.searchResults.filter(
709
- (entry) =>
710
- entry.elementEntry instanceof
711
- DataSpaceAssociationDocumentationEntry,
712
- ).length
713
- : undefined;
714
- } else if (node instanceof ModelsDocumentationFilterTreeRootNodeData) {
715
- return documentationState.searchResults.length;
716
- }
717
- return undefined;
718
- };
719
-
720
- const DataSpaceModelsDocumentationFilterTreeNodeContainer = observer(
721
- (
722
- props: TreeNodeContainerProps<
723
- ModelsDocumentationFilterTreeNodeData,
724
- {
725
- documentationState: DataSpaceViewerModelsDocumentationState;
726
- refreshTreeData: () => void;
727
- uncheckTree: () => void;
728
- updateFilter: () => void;
729
- }
730
- >,
731
- ) => {
732
- const { node, level, innerProps } = props;
733
- const { documentationState, refreshTreeData, uncheckTree, updateFilter } =
734
- innerProps;
735
- const isExpandable = Boolean(node.childrenIds.length);
736
- const expandIcon = isExpandable ? (
737
- node.isOpen ? (
738
- <ChevronDownIcon />
739
- ) : (
740
- <ChevronRightIcon />
741
- )
742
- ) : (
743
- <div />
744
- );
745
- const checkerIcon =
746
- node.checkType === ModelsDocumentationFilterTreeNodeCheckType.CHECKED ? (
747
- <CheckSquareIcon />
748
- ) : node.checkType ===
749
- ModelsDocumentationFilterTreeNodeCheckType.PARTIALLY_CHECKED ? (
750
- <MinusSquareIcon />
751
- ) : (
752
- <EmptySquareIcon />
753
- );
754
- const nodeCount = getFilterNodeCount(node, documentationState);
755
- const toggleChecker: React.MouseEventHandler = (event) => {
756
- event.stopPropagation();
757
-
758
- if (
759
- node.checkType === ModelsDocumentationFilterTreeNodeCheckType.CHECKED
760
- ) {
761
- uncheckFilterTreeNode(node);
762
- } else {
763
- checkFilterTreeNode(node);
764
- }
765
-
766
- refreshTreeData();
767
- updateFilter();
768
- };
769
- const toggleExpandNode: React.MouseEventHandler = (event) => {
770
- event.stopPropagation();
771
-
772
- if (isExpandable) {
773
- node.setIsOpen(!node.isOpen);
774
- refreshTreeData();
775
- }
776
- };
777
- const onNodeClick = (): void => {
778
- uncheckTree();
779
- checkFilterTreeNode(node);
780
-
781
- if (isExpandable && !node.isOpen) {
782
- node.setIsOpen(true);
783
- }
784
- refreshTreeData();
785
- updateFilter();
786
- };
787
-
788
- return (
789
- <div
790
- className="tree-view__node__container data-space__viewer__models-documentation__filter__tree__node__container"
791
- style={{
792
- paddingLeft: `${(level - 1) * 1.4}rem`,
793
- display: 'flex',
794
- }}
795
- onClick={onNodeClick}
796
- >
797
- <div
798
- className="data-space__viewer__models-documentation__filter__tree__node__expand-icon"
799
- onClick={toggleExpandNode}
800
- >
801
- {expandIcon}
802
- </div>
803
- <div
804
- className="data-space__viewer__models-documentation__filter__tree__node__checker"
805
- onClick={toggleChecker}
806
- >
807
- {checkerIcon}
808
- </div>
809
- {getFilterTreeNodeIcon(node)}
810
- <div className="tree-view__node__label data-space__viewer__models-documentation__filter__tree__node__label">
811
- {node.label}
812
- </div>
813
- {nodeCount !== undefined && (
814
- <div className="tree-view__node__label data-space__viewer__models-documentation__filter__tree__node__count">
815
- {nodeCount}
816
- </div>
817
- )}
818
- </div>
819
- );
820
- },
821
- );
822
-
823
- const DataSpaceModelsDocumentationFilterPanel = observer(
824
- (props: { dataSpaceViewerState: DataSpaceViewerState }) => {
825
- const { dataSpaceViewerState } = props;
826
- const documentationState = dataSpaceViewerState.modelsDocumentationState;
827
- const resetAll = (): void => documentationState.resetAllFilters();
828
- const resetTypeFilter = (): void => documentationState.resetTypeFilter();
829
- const resetPackageFilter = (): void =>
830
- documentationState.resetPackageFilter();
831
-
832
- return (
833
- <div className="data-space__viewer__models-documentation__filter__panel">
834
- <div className="data-space__viewer__models-documentation__filter__group">
835
- <div className="data-space__viewer__models-documentation__filter__group__header">
836
- <div className="data-space__viewer__models-documentation__filter__group__header__label">
837
- Filter
838
- </div>
839
- <div className="data-space__viewer__models-documentation__filter__group__header__actions">
840
- <button
841
- className="data-space__viewer__models-documentation__filter__group__header__reset"
842
- tabIndex={-1}
843
- disabled={!documentationState.isFilterCustomized}
844
- onClick={resetAll}
845
- >
846
- Reset All
847
- </button>
848
- </div>
849
- </div>
850
- </div>
851
- <div className="data-space__viewer__models-documentation__filter__group data-space__viewer__models-documentation__filter__group--by-type">
852
- <div className="data-space__viewer__models-documentation__filter__group__header">
853
- <div className="data-space__viewer__models-documentation__filter__group__header__label">
854
- Filter by Type
855
- </div>
856
- <div className="data-space__viewer__models-documentation__filter__group__header__actions">
857
- <button
858
- className="data-space__viewer__models-documentation__filter__group__header__reset"
859
- tabIndex={-1}
860
- disabled={!documentationState.isTypeFilterCustomized}
861
- onClick={resetTypeFilter}
862
- >
863
- Reset
864
- </button>
865
- </div>
866
- </div>
867
- <div className="data-space__viewer__models-documentation__filter__group__content">
868
- <TreeView
869
- components={{
870
- TreeNodeContainer:
871
- DataSpaceModelsDocumentationFilterTreeNodeContainer,
872
- }}
873
- treeData={documentationState.typeFilterTreeData}
874
- getChildNodes={(node) =>
875
- node.childrenIds
876
- .map((id) =>
877
- documentationState.typeFilterTreeData.nodes.get(id),
878
- )
879
- .filter(isNonNullable)
880
- .sort((a, b) => a.label.localeCompare(b.label))
881
- }
882
- innerProps={{
883
- documentationState,
884
- refreshTreeData: (): void =>
885
- documentationState.resetTypeFilterTreeData(),
886
- uncheckTree: (): void =>
887
- uncheckAllFilterTree(documentationState.typeFilterTreeData),
888
- updateFilter: (): void => documentationState.updateTypeFilter(),
889
- }}
890
- />
891
- </div>
892
- </div>
893
- <div className="data-space__viewer__models-documentation__filter__group data-space__viewer__models-documentation__filter__group--by-package">
894
- <div className="data-space__viewer__models-documentation__filter__group__header">
895
- <div className="data-space__viewer__models-documentation__filter__group__header__label">
896
- Filter by Package
897
- </div>
898
- <div className="data-space__viewer__models-documentation__filter__group__header__actions">
899
- <button
900
- className="data-space__viewer__models-documentation__filter__group__header__reset"
901
- tabIndex={-1}
902
- disabled={!documentationState.isPackageFilterCustomized}
903
- onClick={resetPackageFilter}
904
- >
905
- Reset
906
- </button>
907
- </div>
908
- </div>
909
- <div className="data-space__viewer__models-documentation__filter__group__content">
910
- <TreeView
911
- components={{
912
- TreeNodeContainer:
913
- DataSpaceModelsDocumentationFilterTreeNodeContainer,
914
- }}
915
- treeData={documentationState.packageFilterTreeData}
916
- getChildNodes={(node) =>
917
- node.childrenIds
918
- .map((id) =>
919
- documentationState.packageFilterTreeData.nodes.get(id),
920
- )
921
- .filter(isNonNullable)
922
- .sort((a, b) => a.label.localeCompare(b.label))
923
- }
924
- innerProps={{
925
- documentationState,
926
- refreshTreeData: (): void =>
927
- documentationState.resetPackageFilterTreeData(),
928
- uncheckTree: (): void =>
929
- uncheckAllFilterTree(
930
- documentationState.packageFilterTreeData,
931
- ),
932
- updateFilter: (): void =>
933
- documentationState.updatePackageFilter(),
934
- }}
935
- />
936
- </div>
937
- </div>
938
- </div>
939
- );
940
- },
941
- );
942
-
943
- const DataSpaceModelsDocumentationSearchBar = observer(
944
- (props: { dataSpaceViewerState: DataSpaceViewerState }) => {
945
- const { dataSpaceViewerState } = props;
946
- const searchInputRef = useRef<HTMLInputElement>(null);
947
- const searchConfigTriggerRef = useRef<HTMLButtonElement>(null);
948
- const documentationState = dataSpaceViewerState.modelsDocumentationState;
949
- const searchText = documentationState.searchText;
950
- const debouncedSearch = useMemo(
951
- () => debounce(() => documentationState.search(), 100),
952
- [documentationState],
953
- );
954
- const onSearchTextChange: React.ChangeEventHandler<HTMLInputElement> = (
955
- event,
956
- ) => {
957
- documentationState.setSearchText(event.target.value);
958
- debouncedSearch.cancel();
959
- debouncedSearch();
960
- };
961
-
962
- // actions
963
- const clearSearchText = (): void => {
964
- documentationState.resetSearch();
965
- documentationState.focusSearchInput();
966
- };
967
- const toggleSearchConfigMenu = (): void =>
968
- documentationState.setShowSearchConfigurationMenu(
969
- !documentationState.showSearchConfigurationMenu,
970
- );
971
- const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {
972
- if (event.code === 'Escape') {
973
- documentationState.selectSearchInput();
974
- }
975
- };
976
-
977
- // search config menu
978
- const closeSearchConfigMenu = (): void =>
979
- documentationState.setShowSearchConfigurationMenu(false);
980
- const onSearchConfigMenuOpen = (): void =>
981
- documentationState.focusSearchInput();
982
-
983
- useEffect(() => {
984
- if (searchInputRef.current) {
985
- documentationState.setSearchInput(searchInputRef.current);
986
- }
987
- return () => documentationState.setSearchInput(undefined);
988
- }, [documentationState]);
989
-
990
- return (
991
- <div className="data-space__viewer__models-documentation__search">
992
- <input
993
- ref={searchInputRef}
994
- onKeyDown={onKeyDown}
995
- className="data-space__viewer__models-documentation__search__input input--dark"
996
- spellCheck={false}
997
- onChange={onSearchTextChange}
998
- value={searchText}
999
- placeholder="Search (Ctrl + Shift + F)"
1000
- />
1001
- <button
1002
- ref={searchConfigTriggerRef}
1003
- className={clsx(
1004
- 'data-space__viewer__models-documentation__search__input__config__trigger',
1005
- {
1006
- 'data-space__viewer__models-documentation__search__input__config__trigger--toggled':
1007
- documentationState.showSearchConfigurationMenu,
1008
- 'data-space__viewer__models-documentation__search__input__config__trigger--active':
1009
- documentationState.searchConfigurationState
1010
- .isAdvancedSearchActive,
1011
- },
1012
- )}
1013
- tabIndex={-1}
1014
- onClick={toggleSearchConfigMenu}
1015
- title={`${
1016
- documentationState.searchConfigurationState.isAdvancedSearchActive
1017
- ? 'Advanced search is currently active\n'
1018
- : ''
1019
- }Click to toggle search config menu`}
1020
- >
1021
- <CogIcon />
1022
- </button>
1023
- <BasePopover
1024
- open={Boolean(documentationState.showSearchConfigurationMenu)}
1025
- slotProps={{
1026
- transition: {
1027
- onEnter: onSearchConfigMenuOpen,
1028
- },
1029
- }}
1030
- anchorEl={searchConfigTriggerRef.current}
1031
- onClose={closeSearchConfigMenu}
1032
- anchorOrigin={{
1033
- vertical: 'bottom',
1034
- horizontal: 'center',
1035
- }}
1036
- transformOrigin={{
1037
- vertical: 'top',
1038
- horizontal: 'center',
1039
- }}
1040
- >
1041
- <FuzzySearchAdvancedConfigMenu
1042
- configState={documentationState.searchConfigurationState}
1043
- />
1044
- </BasePopover>
1045
- {!searchText ? (
1046
- <div className="data-space__viewer__models-documentation__search__input__search__icon">
1047
- <SearchIcon />
1048
- </div>
1049
- ) : (
1050
- <button
1051
- className="data-space__viewer__models-documentation__search__input__clear-btn"
1052
- tabIndex={-1}
1053
- onClick={clearSearchText}
1054
- title="Clear"
1055
- >
1056
- <TimesIcon />
1057
- </button>
1058
- )}
1059
- </div>
1060
- );
1061
- },
1062
- );
1063
-
1064
- export const DataSpaceModelsDocumentation = observer(
1065
- (props: { dataSpaceViewerState: DataSpaceViewerState }) => {
1066
- const { dataSpaceViewerState } = props;
1067
- const sectionRef = useRef<HTMLDivElement>(null);
1068
- const anchor = generateAnchorForActivity(
1069
- DATA_SPACE_VIEWER_ACTIVITY_MODE.MODELS_DOCUMENTATION,
1070
- );
1071
-
1072
- useCommands(dataSpaceViewerState.modelsDocumentationState);
1073
-
1074
- useEffect(() => {
1075
- if (sectionRef.current) {
1076
- dataSpaceViewerState.layoutState.setWikiPageAnchor(
1077
- anchor,
1078
- sectionRef.current,
1079
- );
1080
- }
1081
- return () => dataSpaceViewerState.layoutState.unsetWikiPageAnchor(anchor);
1082
- }, [dataSpaceViewerState, anchor]);
1083
-
1084
- const documentationEntries =
1085
- dataSpaceViewerState.dataSpaceAnalysisResult.elementDocs;
1086
- const documentationState = dataSpaceViewerState.modelsDocumentationState;
1087
-
1088
- const toggleFilterPanel = (): void =>
1089
- documentationState.setShowFilterPanel(
1090
- !documentationState.showFilterPanel,
1091
- );
1092
-
1093
- return (
1094
- <div ref={sectionRef} className="data-space__viewer__wiki__section">
1095
- <div className="data-space__viewer__wiki__section__header">
1096
- <div className="data-space__viewer__wiki__section__header__label">
1097
- Models Documentation
1098
- <button
1099
- className="data-space__viewer__wiki__section__header__anchor"
1100
- tabIndex={-1}
1101
- onClick={() => dataSpaceViewerState.changeZone(anchor, true)}
1102
- >
1103
- <AnchorLinkIcon />
1104
- </button>
1105
- </div>
1106
- </div>
1107
- <div className="data-space__viewer__wiki__section__content">
1108
- {documentationEntries.length > 0 && (
1109
- <div className="data-space__viewer__models-documentation">
1110
- <div className="data-space__viewer__models-documentation__header">
1111
- <button
1112
- className="data-space__viewer__models-documentation__filter__toggler"
1113
- title="Toggle Filter Panel"
1114
- tabIndex={-1}
1115
- onClick={toggleFilterPanel}
1116
- >
1117
- <div className="data-space__viewer__models-documentation__filter__toggler__arrow">
1118
- {documentationState.showFilterPanel ? (
1119
- <CaretLeftIcon />
1120
- ) : (
1121
- <CaretRightIcon />
1122
- )}
1123
- </div>
1124
- <div className="data-space__viewer__models-documentation__filter__toggler__icon">
1125
- <FilterIcon />
1126
- </div>
1127
- </button>
1128
- <DataSpaceModelsDocumentationSearchBar
1129
- dataSpaceViewerState={dataSpaceViewerState}
1130
- />
1131
- </div>
1132
- <div className="data-space__viewer__models-documentation__content">
1133
- {documentationState.showFilterPanel && (
1134
- <DataSpaceModelsDocumentationFilterPanel
1135
- dataSpaceViewerState={dataSpaceViewerState}
1136
- />
1137
- )}
1138
- <DataSpaceModelsDocumentationGridPanel
1139
- dataSpaceViewerState={dataSpaceViewerState}
1140
- />
1141
- </div>
1142
- </div>
1143
- )}
1144
- {documentationEntries.length === 0 && (
1145
- <DataSpaceWikiPlaceholder message="(not specified)" />
1146
- )}
1147
- </div>
1148
- </div>
1149
- );
1150
- },
1151
- );