@finos/legend-extension-dsl-data-space 10.4.256 → 10.4.258
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/DataSpaceDataAccess.d.ts +1 -1
- package/lib/components/DataSpaceDataAccess.d.ts.map +1 -1
- package/lib/components/DataSpaceDataAccess.js +7 -16
- package/lib/components/DataSpaceDataAccess.js.map +1 -1
- package/lib/components/DataSpaceDescription.d.ts.map +1 -1
- package/lib/components/DataSpaceDescription.js +2 -6
- package/lib/components/DataSpaceDescription.js.map +1 -1
- package/lib/components/DataSpaceExecutionContextViewer.d.ts +14 -0
- package/lib/components/DataSpaceExecutionContextViewer.d.ts.map +1 -1
- package/lib/components/DataSpaceExecutionContextViewer.js +23 -23
- package/lib/components/DataSpaceExecutionContextViewer.js.map +1 -1
- package/lib/components/DataSpaceQualityEmote.d.ts.map +1 -1
- package/lib/components/DataSpaceQualityEmote.js +6 -4
- package/lib/components/DataSpaceQualityEmote.js.map +1 -1
- package/lib/components/DataSpaceQuickStart.d.ts.map +1 -1
- package/lib/components/DataSpaceQuickStart.js +90 -22
- package/lib/components/DataSpaceQuickStart.js.map +1 -1
- package/lib/components/DataSpaceViewer.d.ts.map +1 -1
- package/lib/components/DataSpaceViewer.js +27 -9
- package/lib/components/DataSpaceViewer.js.map +1 -1
- package/lib/components/DataSpaceViewerActivityBar.d.ts.map +1 -1
- package/lib/components/DataSpaceViewerActivityBar.js +9 -5
- package/lib/components/DataSpaceViewerActivityBar.js.map +1 -1
- package/lib/components/__test-utils__/DataSpaceViewerTestUtils.d.ts +1 -1
- package/lib/components/__test-utils__/DataSpaceViewerTestUtils.d.ts.map +1 -1
- package/lib/components/__test-utils__/DataSpaceViewerTestUtils.js.map +1 -1
- package/lib/components/query-builder/DataSpaceQueryBuilder.d.ts.map +1 -1
- package/lib/components/query-builder/DataSpaceQueryBuilder.js +24 -15
- package/lib/components/query-builder/DataSpaceQueryBuilder.js.map +1 -1
- package/lib/graph-manager/action/analytics/DataSpaceAnalysis.d.ts +16 -0
- package/lib/graph-manager/action/analytics/DataSpaceAnalysis.d.ts.map +1 -1
- package/lib/graph-manager/action/analytics/DataSpaceAnalysis.js +16 -0
- package/lib/graph-manager/action/analytics/DataSpaceAnalysis.js.map +1 -1
- package/lib/graph-manager/protocol/pure/v1/V1_DSL_DataSpace_PureGraphManagerExtension.d.ts.map +1 -1
- package/lib/graph-manager/protocol/pure/v1/V1_DSL_DataSpace_PureGraphManagerExtension.js +31 -2
- package/lib/graph-manager/protocol/pure/v1/V1_DSL_DataSpace_PureGraphManagerExtension.js.map +1 -1
- package/lib/graph-manager/protocol/pure/v1/engine/analytics/V1_DataSpaceAnalysis.d.ts +18 -0
- package/lib/graph-manager/protocol/pure/v1/engine/analytics/V1_DataSpaceAnalysis.d.ts.map +1 -1
- package/lib/graph-manager/protocol/pure/v1/engine/analytics/V1_DataSpaceAnalysis.js +48 -0
- package/lib/graph-manager/protocol/pure/v1/engine/analytics/V1_DataSpaceAnalysis.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/{DataSpaceMappingProviderAccessState.d.ts → DataSpaceDataProductAccessState.d.ts} +16 -10
- package/lib/stores/DataSpaceDataProductAccessState.d.ts.map +1 -0
- package/lib/stores/{DataSpaceMappingProviderAccessState.js → DataSpaceDataProductAccessState.js} +27 -16
- package/lib/stores/DataSpaceDataProductAccessState.js.map +1 -0
- package/lib/stores/DataSpaceLayoutState.d.ts +7 -34
- package/lib/stores/DataSpaceLayoutState.d.ts.map +1 -1
- package/lib/stores/DataSpaceLayoutState.js +22 -159
- package/lib/stores/DataSpaceLayoutState.js.map +1 -1
- package/lib/stores/DataSpaceViewerDiagramViewerState.js +1 -2
- package/lib/stores/DataSpaceViewerDiagramViewerState.js.map +1 -1
- package/lib/stores/DataSpaceViewerState.d.ts +54 -24
- package/lib/stores/DataSpaceViewerState.d.ts.map +1 -1
- package/lib/stores/DataSpaceViewerState.js +139 -55
- package/lib/stores/DataSpaceViewerState.js.map +1 -1
- package/lib/stores/query/DataSpaceAdvancedSearchState.d.ts.map +1 -1
- package/lib/stores/query/DataSpaceAdvancedSearchState.js +7 -1
- package/lib/stores/query/DataSpaceAdvancedSearchState.js.map +1 -1
- package/lib/stores/query-builder/DataSpaceQueryBuilderState.d.ts +2 -0
- package/lib/stores/query-builder/DataSpaceQueryBuilderState.d.ts.map +1 -1
- package/lib/stores/query-builder/DataSpaceQueryBuilderState.js +36 -9
- package/lib/stores/query-builder/DataSpaceQueryBuilderState.js.map +1 -1
- package/package.json +14 -14
- package/src/components/DataSpaceDataAccess.tsx +26 -68
- package/src/components/DataSpaceDescription.tsx +8 -41
- package/src/components/DataSpaceExecutionContextViewer.tsx +68 -69
- package/src/components/DataSpaceQualityEmote.tsx +6 -4
- package/src/components/DataSpaceQuickStart.tsx +284 -114
- package/src/components/DataSpaceViewer.tsx +83 -45
- package/src/components/DataSpaceViewerActivityBar.tsx +11 -7
- package/src/components/__test-utils__/DataSpaceViewerTestUtils.ts +1 -6
- package/src/components/query-builder/DataSpaceQueryBuilder.tsx +117 -101
- package/src/graph-manager/action/analytics/DataSpaceAnalysis.ts +19 -0
- package/src/graph-manager/protocol/pure/v1/V1_DSL_DataSpace_PureGraphManagerExtension.ts +37 -0
- package/src/graph-manager/protocol/pure/v1/engine/analytics/V1_DataSpaceAnalysis.ts +85 -0
- package/src/stores/{DataSpaceMappingProviderAccessState.ts → DataSpaceDataProductAccessState.ts} +40 -18
- package/src/stores/DataSpaceLayoutState.ts +25 -209
- package/src/stores/DataSpaceViewerDiagramViewerState.ts +1 -1
- package/src/stores/DataSpaceViewerState.ts +188 -88
- package/src/stores/query/DataSpaceAdvancedSearchState.ts +9 -2
- package/src/stores/query-builder/DataSpaceQueryBuilderState.ts +48 -12
- package/tsconfig.json +1 -1
- package/lib/stores/DataSpaceMappingProviderAccessState.d.ts.map +0 -1
- package/lib/stores/DataSpaceMappingProviderAccessState.js.map +0 -1
|
@@ -24,18 +24,29 @@ import {
|
|
|
24
24
|
ExpandMoreIcon,
|
|
25
25
|
LegendLogo,
|
|
26
26
|
MoreVerticalIcon,
|
|
27
|
-
|
|
27
|
+
RefreshIcon,
|
|
28
28
|
StatisticsIcon,
|
|
29
29
|
clsx,
|
|
30
30
|
} from '@finos/legend-art';
|
|
31
|
+
import { IconButton } from '@mui/material';
|
|
32
|
+
import {
|
|
33
|
+
CollapsibleChevron,
|
|
34
|
+
CollapsibleWikiSection,
|
|
35
|
+
DataProductAPGAccessRequestControl,
|
|
36
|
+
} from '@finos/legend-extension-dsl-data-product';
|
|
31
37
|
import { type DataSpaceViewerState } from '../stores/DataSpaceViewerState.js';
|
|
32
38
|
import { useApplicationStore } from '@finos/legend-application';
|
|
39
|
+
import { extractElementNameFromPath } from '@finos/legend-graph';
|
|
33
40
|
import {
|
|
41
|
+
type DataSpaceExecutableAnalysisResult,
|
|
42
|
+
type DataSpaceExecutionContextAnalysisResult,
|
|
34
43
|
DataSpaceExecutableTDSResult,
|
|
35
44
|
DataSpaceServiceExecutableInfo,
|
|
36
45
|
DataSpaceMultiExecutionServiceExecutableInfo,
|
|
46
|
+
LakehouseDataProductExecutableAccessorInfo,
|
|
37
47
|
} from '../graph-manager/action/analytics/DataSpaceAnalysis.js';
|
|
38
48
|
import { DataSpaceMarkdownTextViewer } from './DataSpaceMarkdownTextViewer.js';
|
|
49
|
+
import { DataSpaceOpenDataProductButton } from './DataSpaceExecutionContextViewer.js';
|
|
39
50
|
import type { DSL_DataSpace_LegendApplicationPlugin_Extension } from '../stores/DSL_DataSpace_LegendApplicationPlugin_Extension.js';
|
|
40
51
|
import { useEffect, useRef, useState } from 'react';
|
|
41
52
|
import { DataSpaceWikiPlaceholder } from './DataSpacePlaceholder.js';
|
|
@@ -118,6 +129,219 @@ const TDSColumnTypeCellRenderer = (
|
|
|
118
129
|
);
|
|
119
130
|
};
|
|
120
131
|
|
|
132
|
+
const DATA_PRODUCT_GROUP_AUTO_COLLAPSE_THRESHOLD = 3;
|
|
133
|
+
|
|
134
|
+
type DataSpaceDataProductAccessGroup = {
|
|
135
|
+
dataProductPath: string;
|
|
136
|
+
accessPointGroupIds: string[];
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Resolves the `(dataProductPath, accessPointGroupId)` pairs an executable
|
|
141
|
+
* needs access to: either the Lakehouse Data Products its accessors reference,
|
|
142
|
+
* or — for an executable served by a mappingProvider execution context — the
|
|
143
|
+
* Data Product and access point groups that context resolves through.
|
|
144
|
+
*/
|
|
145
|
+
const resolveDataProductAccessGroups = (
|
|
146
|
+
executableAnalysisResult: DataSpaceExecutableAnalysisResult,
|
|
147
|
+
executionContext: DataSpaceExecutionContextAnalysisResult | undefined,
|
|
148
|
+
): DataSpaceDataProductAccessGroup[] => {
|
|
149
|
+
const groupsByDataProduct = new Map<string, string[]>();
|
|
150
|
+
const addGroup = (
|
|
151
|
+
dataProductPath: string,
|
|
152
|
+
accessPointGroupId: string,
|
|
153
|
+
): void => {
|
|
154
|
+
const accessPointGroupIds = groupsByDataProduct.get(dataProductPath) ?? [];
|
|
155
|
+
if (!accessPointGroupIds.includes(accessPointGroupId)) {
|
|
156
|
+
accessPointGroupIds.push(accessPointGroupId);
|
|
157
|
+
}
|
|
158
|
+
groupsByDataProduct.set(dataProductPath, accessPointGroupIds);
|
|
159
|
+
};
|
|
160
|
+
for (const accessor of executableAnalysisResult.executableAccessorInfo) {
|
|
161
|
+
if (accessor instanceof LakehouseDataProductExecutableAccessorInfo) {
|
|
162
|
+
addGroup(accessor.dataProductPath, accessor.accessPointGroupId);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (groupsByDataProduct.size === 0) {
|
|
166
|
+
const mappingProvider = executionContext?.mappingProvider;
|
|
167
|
+
mappingProvider?.keys.forEach((key) =>
|
|
168
|
+
addGroup(mappingProvider.element, key),
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
return Array.from(groupsByDataProduct.entries()).map(
|
|
172
|
+
([dataProductPath, accessPointGroupIds]) => ({
|
|
173
|
+
dataProductPath,
|
|
174
|
+
accessPointGroupIds,
|
|
175
|
+
}),
|
|
176
|
+
);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Renders the "Request Access" button + status for each
|
|
181
|
+
* `(dataProductPath, accessPointGroupId)` pair, grouped by Data Product path.
|
|
182
|
+
* Access states are shared across executables + APGs of the same DP via
|
|
183
|
+
* `DataSpaceViewerState.dataProductAccessStates`.
|
|
184
|
+
*/
|
|
185
|
+
const DataSpaceDataProductAccessPanel = observer(
|
|
186
|
+
(props: {
|
|
187
|
+
viewerState: DataSpaceViewerState;
|
|
188
|
+
groups: DataSpaceDataProductAccessGroup[];
|
|
189
|
+
}) => {
|
|
190
|
+
const { viewerState, groups } = props;
|
|
191
|
+
const tokenProvider =
|
|
192
|
+
viewerState.mappingProviderAccessConfig?.tokenProvider ??
|
|
193
|
+
((): undefined => undefined);
|
|
194
|
+
const [collapsedDataProducts, setCollapsedDataProducts] = useState<
|
|
195
|
+
Set<string>
|
|
196
|
+
>(
|
|
197
|
+
() =>
|
|
198
|
+
new Set(
|
|
199
|
+
groups.length >= DATA_PRODUCT_GROUP_AUTO_COLLAPSE_THRESHOLD
|
|
200
|
+
? groups.map((group) => group.dataProductPath)
|
|
201
|
+
: [],
|
|
202
|
+
),
|
|
203
|
+
);
|
|
204
|
+
if (groups.length === 0) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
const toggleGroupCollapse = (dataProductPath: string): void => {
|
|
208
|
+
setCollapsedDataProducts((prev) => {
|
|
209
|
+
const next = new Set(prev);
|
|
210
|
+
if (next.has(dataProductPath)) {
|
|
211
|
+
next.delete(dataProductPath);
|
|
212
|
+
} else {
|
|
213
|
+
next.add(dataProductPath);
|
|
214
|
+
}
|
|
215
|
+
return next;
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
return (
|
|
219
|
+
<div className="data-space__viewer__quickstart__tds__apg-access">
|
|
220
|
+
<div className="data-space__viewer__quickstart__tds__apg-access__header">
|
|
221
|
+
Data Product Access
|
|
222
|
+
</div>
|
|
223
|
+
{groups.map((group) => {
|
|
224
|
+
const isGroupCollapsed = collapsedDataProducts.has(
|
|
225
|
+
group.dataProductPath,
|
|
226
|
+
);
|
|
227
|
+
const accessState = viewerState.getDataProductAccessState(
|
|
228
|
+
group.dataProductPath,
|
|
229
|
+
);
|
|
230
|
+
return (
|
|
231
|
+
<div
|
|
232
|
+
key={group.dataProductPath}
|
|
233
|
+
className="data-space__viewer__quickstart__tds__apg-access__group"
|
|
234
|
+
>
|
|
235
|
+
<div className="data-space__viewer__quickstart__tds__apg-access__group__header-row">
|
|
236
|
+
<button
|
|
237
|
+
className="data-space__viewer__quickstart__tds__apg-access__group__caret-btn"
|
|
238
|
+
tabIndex={-1}
|
|
239
|
+
onClick={() => toggleGroupCollapse(group.dataProductPath)}
|
|
240
|
+
title={isGroupCollapsed ? 'Expand' : 'Collapse'}
|
|
241
|
+
>
|
|
242
|
+
<ExpandMoreIcon
|
|
243
|
+
className={clsx(
|
|
244
|
+
'data-space__viewer__quickstart__tds__apg-access__group__caret',
|
|
245
|
+
{
|
|
246
|
+
'data-space__viewer__quickstart__tds__apg-access__group__caret--collapsed':
|
|
247
|
+
isGroupCollapsed,
|
|
248
|
+
},
|
|
249
|
+
)}
|
|
250
|
+
/>
|
|
251
|
+
</button>
|
|
252
|
+
<div className="data-space__viewer__quickstart__tds__apg-access__group__header">
|
|
253
|
+
<span
|
|
254
|
+
className="data-space__viewer__quickstart__tds__apg-access__group__label"
|
|
255
|
+
title={group.dataProductPath}
|
|
256
|
+
>
|
|
257
|
+
{extractElementNameFromPath(group.dataProductPath)}
|
|
258
|
+
</span>
|
|
259
|
+
<span className="data-space__viewer__quickstart__tds__apg-access__group__count">
|
|
260
|
+
{group.accessPointGroupIds.length}
|
|
261
|
+
</span>
|
|
262
|
+
</div>
|
|
263
|
+
<div className="data-space__viewer__quickstart__tds__apg-access__group__actions">
|
|
264
|
+
<DataSpaceOpenDataProductButton
|
|
265
|
+
dataSpaceViewerState={viewerState}
|
|
266
|
+
dataProductPath={group.dataProductPath}
|
|
267
|
+
/>
|
|
268
|
+
{accessState && (
|
|
269
|
+
<IconButton
|
|
270
|
+
className="data-space__viewer__quickstart__tds__apg-access__group__refresh-btn"
|
|
271
|
+
size="small"
|
|
272
|
+
color="primary"
|
|
273
|
+
title="Refresh Data Product access"
|
|
274
|
+
disabled={accessState.initializingState.isInProgress}
|
|
275
|
+
onClick={(): void =>
|
|
276
|
+
viewerState.refreshDataProductAccessState(
|
|
277
|
+
group.dataProductPath,
|
|
278
|
+
)
|
|
279
|
+
}
|
|
280
|
+
>
|
|
281
|
+
<RefreshIcon />
|
|
282
|
+
</IconButton>
|
|
283
|
+
)}
|
|
284
|
+
</div>
|
|
285
|
+
</div>
|
|
286
|
+
{!isGroupCollapsed && (
|
|
287
|
+
<div className="data-space__viewer__quickstart__tds__apg-access__group__rows">
|
|
288
|
+
{group.accessPointGroupIds.map((accessPointGroupId) => {
|
|
289
|
+
const apgState =
|
|
290
|
+
accessState?.dataProductViewerState?.apgStates.find(
|
|
291
|
+
(state) => state.apg.id === accessPointGroupId,
|
|
292
|
+
);
|
|
293
|
+
return (
|
|
294
|
+
<div
|
|
295
|
+
key={accessPointGroupId}
|
|
296
|
+
className="data-space__viewer__quickstart__tds__apg-access__row"
|
|
297
|
+
>
|
|
298
|
+
<span
|
|
299
|
+
className="data-space__viewer__quickstart__tds__apg-access__row__apg"
|
|
300
|
+
title={accessPointGroupId}
|
|
301
|
+
>
|
|
302
|
+
{accessPointGroupId}
|
|
303
|
+
</span>
|
|
304
|
+
<div className="data-space__viewer__quickstart__tds__apg-access__row__actions">
|
|
305
|
+
{apgState && accessState?.dataAccessState ? (
|
|
306
|
+
<DataProductAPGAccessRequestControl
|
|
307
|
+
apgState={apgState}
|
|
308
|
+
dataAccessState={accessState.dataAccessState}
|
|
309
|
+
tokenProvider={tokenProvider}
|
|
310
|
+
/>
|
|
311
|
+
) : accessState?.errorMessage ? (
|
|
312
|
+
<span title={accessState.errorMessage}>
|
|
313
|
+
Unavailable
|
|
314
|
+
</span>
|
|
315
|
+
) : accessState?.initializingState.isInProgress ? (
|
|
316
|
+
<span>Loading...</span>
|
|
317
|
+
) : null}
|
|
318
|
+
</div>
|
|
319
|
+
</div>
|
|
320
|
+
);
|
|
321
|
+
})}
|
|
322
|
+
</div>
|
|
323
|
+
)}
|
|
324
|
+
</div>
|
|
325
|
+
);
|
|
326
|
+
})}
|
|
327
|
+
</div>
|
|
328
|
+
);
|
|
329
|
+
},
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
const resolveExecutionContextForExecutable = (
|
|
333
|
+
dataSpaceViewerState: DataSpaceViewerState,
|
|
334
|
+
executableAnalysisResult: DataSpaceExecutableAnalysisResult,
|
|
335
|
+
): DataSpaceExecutionContextAnalysisResult | undefined => {
|
|
336
|
+
const analysisResult = dataSpaceViewerState.dataSpaceAnalysisResult;
|
|
337
|
+
const executionContextKey =
|
|
338
|
+
executableAnalysisResult.info?.executionContextKey;
|
|
339
|
+
return executionContextKey
|
|
340
|
+
? (analysisResult.executionContextsIndex.get(executionContextKey) ??
|
|
341
|
+
analysisResult.defaultExecutionContext)
|
|
342
|
+
: analysisResult.defaultExecutionContext;
|
|
343
|
+
};
|
|
344
|
+
|
|
121
345
|
const DataSpaceExecutableResultView = observer(
|
|
122
346
|
(props: {
|
|
123
347
|
executableState: DataSpaceViewerExecutableState;
|
|
@@ -137,6 +361,13 @@ const DataSpaceExecutableResultView = observer(
|
|
|
137
361
|
dataSpaceViewerState.quickStartState.dataAccessStateIndex.get(
|
|
138
362
|
executableAnalysisResult,
|
|
139
363
|
);
|
|
364
|
+
const dataProductAccessGroups = resolveDataProductAccessGroups(
|
|
365
|
+
executableAnalysisResult,
|
|
366
|
+
resolveExecutionContextForExecutable(
|
|
367
|
+
dataSpaceViewerState,
|
|
368
|
+
executableAnalysisResult,
|
|
369
|
+
),
|
|
370
|
+
);
|
|
140
371
|
const isTDSResult =
|
|
141
372
|
resultState instanceof DataSpaceExecutableTDSResultState;
|
|
142
373
|
|
|
@@ -397,19 +628,26 @@ const DataSpaceExecutableResultView = observer(
|
|
|
397
628
|
</div>
|
|
398
629
|
</div>
|
|
399
630
|
)}
|
|
400
|
-
{selectedTab === EXECUTABLE_ACTION_TAB.DATA_ACCESS &&
|
|
401
|
-
|
|
402
|
-
<
|
|
403
|
-
|
|
404
|
-
|
|
631
|
+
{selectedTab === EXECUTABLE_ACTION_TAB.DATA_ACCESS && (
|
|
632
|
+
<>
|
|
633
|
+
<DataSpaceDataProductAccessPanel
|
|
634
|
+
viewerState={dataSpaceViewerState}
|
|
635
|
+
groups={dataProductAccessGroups}
|
|
405
636
|
/>
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
637
|
+
{dataAccessState ? (
|
|
638
|
+
<DataAccessOverview
|
|
639
|
+
dataAccessState={dataAccessState}
|
|
640
|
+
compact={true}
|
|
641
|
+
/>
|
|
642
|
+
) : dataProductAccessGroups.length === 0 ? (
|
|
643
|
+
<div className="data-space__viewer__quickstart__tds__placeholder-panel">
|
|
644
|
+
<BlankPanelContent>
|
|
645
|
+
No data access information available
|
|
646
|
+
</BlankPanelContent>
|
|
647
|
+
</div>
|
|
648
|
+
) : null}
|
|
649
|
+
</>
|
|
650
|
+
)}
|
|
413
651
|
{selectedTab === EXECUTABLE_ACTION_TAB.USAGE_STATS && (
|
|
414
652
|
<div className="data-space__viewer__quickstart__tds__placeholder-panel">
|
|
415
653
|
<BlankPanelContent>
|
|
@@ -471,14 +709,6 @@ const DataSpaceExecutableAnalysisResultView = observer(
|
|
|
471
709
|
const executableAnalysisResult = executableState.value;
|
|
472
710
|
const quickStartRef = useRef<HTMLDivElement>(null);
|
|
473
711
|
const anchor = generateAnchorForQuickStart(executableAnalysisResult);
|
|
474
|
-
const isCollapsed =
|
|
475
|
-
dataSpaceViewerState.layoutState.sectionCollapseState.isSectionCollapsed(
|
|
476
|
-
anchor,
|
|
477
|
-
);
|
|
478
|
-
const toggleCollapse = (): void =>
|
|
479
|
-
dataSpaceViewerState.layoutState.sectionCollapseState.toggleSectionCollapse(
|
|
480
|
-
anchor,
|
|
481
|
-
);
|
|
482
712
|
|
|
483
713
|
useEffect(() => {
|
|
484
714
|
if (quickStartRef.current) {
|
|
@@ -510,37 +740,30 @@ const DataSpaceExecutableAnalysisResultView = observer(
|
|
|
510
740
|
return (
|
|
511
741
|
<div ref={quickStartRef} className="data-space__viewer__quickstart__item">
|
|
512
742
|
<div className="data-space__viewer__quickstart__item__header">
|
|
513
|
-
<button
|
|
514
|
-
className="data-space__viewer__quickstart__item__header__caret-btn"
|
|
515
|
-
tabIndex={-1}
|
|
516
|
-
onClick={toggleCollapse}
|
|
517
|
-
title={isCollapsed ? 'Expand' : 'Collapse'}
|
|
518
|
-
>
|
|
519
|
-
<ExpandMoreIcon
|
|
520
|
-
className={clsx(
|
|
521
|
-
'data-space__viewer__quickstart__item__header__caret',
|
|
522
|
-
{
|
|
523
|
-
'data-space__viewer__quickstart__item__header__caret--collapsed':
|
|
524
|
-
isCollapsed,
|
|
525
|
-
},
|
|
526
|
-
)}
|
|
527
|
-
/>
|
|
528
|
-
</button>
|
|
529
743
|
<div className="data-space__viewer__quickstart__item__header__title">
|
|
530
744
|
{executableAnalysisResult.title}
|
|
531
745
|
</div>
|
|
532
746
|
<div className="data-space__viewer__quickstart__item__header__type">
|
|
533
747
|
{executableTypeLabel}
|
|
534
748
|
</div>
|
|
749
|
+
<CollapsibleChevron
|
|
750
|
+
viewerState={dataSpaceViewerState}
|
|
751
|
+
anchor={anchor}
|
|
752
|
+
/>
|
|
535
753
|
<button
|
|
536
754
|
className="data-space__viewer__quickstart__item__header__anchor"
|
|
537
755
|
tabIndex={-1}
|
|
538
|
-
onClick={() =>
|
|
756
|
+
onClick={() => {
|
|
757
|
+
dataSpaceViewerState.changeZone(anchor, true);
|
|
758
|
+
dataSpaceViewerState.copyLinkToClipboard(anchor);
|
|
759
|
+
}}
|
|
539
760
|
>
|
|
540
761
|
<AnchorLinkIcon />
|
|
541
762
|
</button>
|
|
542
763
|
</div>
|
|
543
|
-
{!
|
|
764
|
+
{!dataSpaceViewerState.layoutState.sectionCollapseState.isSectionCollapsed(
|
|
765
|
+
anchor,
|
|
766
|
+
) && (
|
|
544
767
|
<>
|
|
545
768
|
{executableAnalysisResult.description !== undefined && (
|
|
546
769
|
<div className="data-space__viewer__quickstart__item__description">
|
|
@@ -568,24 +791,11 @@ const DataSpaceExecutableAnalysisResultView = observer(
|
|
|
568
791
|
export const DataSpaceQuickStart = observer(
|
|
569
792
|
(props: { dataSpaceViewerState: DataSpaceViewerState }) => {
|
|
570
793
|
const { dataSpaceViewerState } = props;
|
|
571
|
-
const applicationStore = useApplicationStore();
|
|
572
794
|
const analysisResult = dataSpaceViewerState.dataSpaceAnalysisResult;
|
|
573
|
-
const documentationUrl = analysisResult.supportInfo?.documentationUrl;
|
|
574
795
|
const sectionRef = useRef<HTMLDivElement>(null);
|
|
575
796
|
const anchor = generateAnchorForActivity(
|
|
576
797
|
DATA_SPACE_VIEWER_ACTIVITY_MODE.QUICK_START,
|
|
577
798
|
);
|
|
578
|
-
const executableAnchors = dataSpaceViewerState.executableStates.map(
|
|
579
|
-
(executableState) => generateAnchorForQuickStart(executableState.value),
|
|
580
|
-
);
|
|
581
|
-
const isCollapsed =
|
|
582
|
-
dataSpaceViewerState.layoutState.sectionCollapseState.areAllSectionsCollapsed(
|
|
583
|
-
executableAnchors,
|
|
584
|
-
);
|
|
585
|
-
const toggleCollapse = (): void =>
|
|
586
|
-
dataSpaceViewerState.layoutState.sectionCollapseState.toggleAllSectionsCollapse(
|
|
587
|
-
executableAnchors,
|
|
588
|
-
);
|
|
589
799
|
|
|
590
800
|
useEffect(() => {
|
|
591
801
|
if (sectionRef.current) {
|
|
@@ -597,71 +807,31 @@ export const DataSpaceQuickStart = observer(
|
|
|
597
807
|
return () => dataSpaceViewerState.layoutState.unsetWikiPageAnchor(anchor);
|
|
598
808
|
}, [dataSpaceViewerState, anchor]);
|
|
599
809
|
|
|
600
|
-
const seeDocumentation = (): void => {
|
|
601
|
-
if (documentationUrl) {
|
|
602
|
-
applicationStore.navigationService.navigator.visitAddress(
|
|
603
|
-
documentationUrl,
|
|
604
|
-
);
|
|
605
|
-
}
|
|
606
|
-
};
|
|
607
|
-
|
|
608
810
|
return (
|
|
609
|
-
<div ref={sectionRef} className="
|
|
610
|
-
<
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
811
|
+
<div ref={sectionRef} className="viewer__wiki__section">
|
|
812
|
+
<CollapsibleWikiSection
|
|
813
|
+
viewerState={dataSpaceViewerState}
|
|
814
|
+
section={DATA_SPACE_VIEWER_ACTIVITY_MODE.QUICK_START}
|
|
815
|
+
showDocumentation={true}
|
|
816
|
+
>
|
|
817
|
+
<div className="viewer__wiki__section__content">
|
|
818
|
+
{dataSpaceViewerState.executableStates.length !== 0 && (
|
|
819
|
+
<div className="data-space__viewer__quickstart">
|
|
820
|
+
{dataSpaceViewerState.executableStates.map(
|
|
821
|
+
(executableState) => (
|
|
822
|
+
<DataSpaceExecutableAnalysisResultView
|
|
823
|
+
key={executableState.uuid}
|
|
824
|
+
executableState={executableState}
|
|
825
|
+
/>
|
|
826
|
+
),
|
|
827
|
+
)}
|
|
828
|
+
</div>
|
|
829
|
+
)}
|
|
830
|
+
{analysisResult.executables.length === 0 && (
|
|
831
|
+
<DataSpaceWikiPlaceholder message="(not specified)" />
|
|
629
832
|
)}
|
|
630
|
-
Quick Start
|
|
631
|
-
<button
|
|
632
|
-
className="data-space__viewer__wiki__section__header__anchor"
|
|
633
|
-
tabIndex={-1}
|
|
634
|
-
onClick={() => dataSpaceViewerState.changeZone(anchor, true)}
|
|
635
|
-
>
|
|
636
|
-
<AnchorLinkIcon />
|
|
637
|
-
</button>
|
|
638
833
|
</div>
|
|
639
|
-
|
|
640
|
-
<button
|
|
641
|
-
className="data-space__viewer__wiki__section__header__documentation"
|
|
642
|
-
tabIndex={-1}
|
|
643
|
-
onClick={seeDocumentation}
|
|
644
|
-
title="See Documentation"
|
|
645
|
-
>
|
|
646
|
-
<QuestionCircleIcon />
|
|
647
|
-
</button>
|
|
648
|
-
)}
|
|
649
|
-
</div>
|
|
650
|
-
<div className="data-space__viewer__wiki__section__content">
|
|
651
|
-
{dataSpaceViewerState.executableStates.length !== 0 && (
|
|
652
|
-
<div className="data-space__viewer__quickstart">
|
|
653
|
-
{dataSpaceViewerState.executableStates.map((executableState) => (
|
|
654
|
-
<DataSpaceExecutableAnalysisResultView
|
|
655
|
-
key={executableState.uuid}
|
|
656
|
-
executableState={executableState}
|
|
657
|
-
/>
|
|
658
|
-
))}
|
|
659
|
-
</div>
|
|
660
|
-
)}
|
|
661
|
-
{analysisResult.executables.length === 0 && (
|
|
662
|
-
<DataSpaceWikiPlaceholder message="(not specified)" />
|
|
663
|
-
)}
|
|
664
|
-
</div>
|
|
834
|
+
</CollapsibleWikiSection>
|
|
665
835
|
</div>
|
|
666
836
|
);
|
|
667
837
|
},
|
|
@@ -56,6 +56,11 @@ const DataSpaceHeader = observer(
|
|
|
56
56
|
const applicationStore = useApplicationStore();
|
|
57
57
|
const headerRef = useRef<HTMLDivElement>(null);
|
|
58
58
|
const analysisResult = dataSpaceViewerState.dataSpaceAnalysisResult;
|
|
59
|
+
const hasMultipleExecutionContexts =
|
|
60
|
+
analysisResult.executionContextsIndex.size > 1;
|
|
61
|
+
const runQueryContext =
|
|
62
|
+
analysisResult.defaultExecutionContext ??
|
|
63
|
+
Array.from(analysisResult.executionContextsIndex.values())[0];
|
|
59
64
|
|
|
60
65
|
useEffect(() => {
|
|
61
66
|
if (headerRef.current) {
|
|
@@ -97,61 +102,94 @@ const DataSpaceHeader = observer(
|
|
|
97
102
|
qualityState={dataSpaceViewerState.qualityState}
|
|
98
103
|
/>
|
|
99
104
|
<div className="data-space__viewer__header__actions">
|
|
100
|
-
{
|
|
101
|
-
<
|
|
102
|
-
className="data-space__viewer__header__execution-context-selector"
|
|
103
|
-
menuProps={{
|
|
104
|
-
anchorOrigin: { vertical: 'bottom', horizontal: 'center' },
|
|
105
|
-
transformOrigin: { vertical: 'top', horizontal: 'center' },
|
|
106
|
-
elevation: 7,
|
|
107
|
-
}}
|
|
108
|
-
title={`Current Execution Context: ${dataSpaceViewerState.currentExecutionContext.name}\nClick to switch`}
|
|
109
|
-
content={
|
|
110
|
-
<MenuContent>
|
|
111
|
-
{Array.from(
|
|
112
|
-
dataSpaceViewerState.dataSpaceAnalysisResult.executionContextsIndex.values(),
|
|
113
|
-
).map((context) => (
|
|
114
|
-
<MenuContentItem
|
|
115
|
-
key={context.name}
|
|
116
|
-
className={clsx(
|
|
117
|
-
'data-space__viewer__header__execution-context-selector__option',
|
|
118
|
-
{
|
|
119
|
-
'data-space__viewer__header__execution-context-selector__option--active':
|
|
120
|
-
context ===
|
|
121
|
-
dataSpaceViewerState.currentExecutionContext,
|
|
122
|
-
},
|
|
123
|
-
)}
|
|
124
|
-
onClick={() =>
|
|
125
|
-
dataSpaceViewerState.setCurrentExecutionContext(
|
|
126
|
-
context,
|
|
127
|
-
)
|
|
128
|
-
}
|
|
129
|
-
>
|
|
130
|
-
{context.name}
|
|
131
|
-
</MenuContentItem>
|
|
132
|
-
))}
|
|
133
|
-
</MenuContent>
|
|
134
|
-
}
|
|
135
|
-
>
|
|
105
|
+
{runQueryContext && (
|
|
106
|
+
<div className="data-space__viewer__header__execution-context-selector">
|
|
136
107
|
<div className="data-space__viewer__header__execution-context-selector__trigger">
|
|
137
|
-
<div
|
|
108
|
+
<div
|
|
109
|
+
className="data-space__viewer__header__execution-context-selector__trigger__icon"
|
|
110
|
+
title="Run Query"
|
|
111
|
+
onClick={() =>
|
|
112
|
+
dataSpaceViewerState.queryDataSpace(
|
|
113
|
+
runQueryContext.name,
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
>
|
|
138
117
|
<PlayIcon />
|
|
139
118
|
</div>
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
119
|
+
{hasMultipleExecutionContexts ? (
|
|
120
|
+
<ControlledDropdownMenu
|
|
121
|
+
className="data-space__viewer__header__execution-context-selector__trigger__switcher"
|
|
122
|
+
menuProps={{
|
|
123
|
+
anchorOrigin: {
|
|
124
|
+
vertical: 'bottom',
|
|
125
|
+
horizontal: 'center',
|
|
126
|
+
},
|
|
127
|
+
transformOrigin: {
|
|
128
|
+
vertical: 'top',
|
|
129
|
+
horizontal: 'center',
|
|
130
|
+
},
|
|
131
|
+
elevation: 0,
|
|
132
|
+
MenuListProps: {
|
|
133
|
+
className:
|
|
134
|
+
'data-space__viewer__header__execution-context-selector__menu',
|
|
135
|
+
},
|
|
136
|
+
}}
|
|
137
|
+
title={`Run Query in another execution context\nDefault: ${runQueryContext.name}`}
|
|
138
|
+
content={
|
|
139
|
+
<MenuContent>
|
|
140
|
+
{Array.from(
|
|
141
|
+
dataSpaceViewerState.dataSpaceAnalysisResult.executionContextsIndex.values(),
|
|
142
|
+
).map((context) => (
|
|
143
|
+
<MenuContentItem
|
|
144
|
+
key={context.name}
|
|
145
|
+
className={clsx(
|
|
146
|
+
'data-space__viewer__header__execution-context-selector__option',
|
|
147
|
+
{
|
|
148
|
+
'data-space__viewer__header__execution-context-selector__option--active':
|
|
149
|
+
context ===
|
|
150
|
+
dataSpaceViewerState.currentExecutionContext,
|
|
151
|
+
},
|
|
152
|
+
)}
|
|
153
|
+
onClick={() => {
|
|
154
|
+
dataSpaceViewerState.setCurrentExecutionContext(
|
|
155
|
+
context,
|
|
156
|
+
);
|
|
157
|
+
dataSpaceViewerState.queryDataSpace(
|
|
158
|
+
context.name,
|
|
159
|
+
);
|
|
160
|
+
}}
|
|
161
|
+
>
|
|
162
|
+
{context.name}
|
|
163
|
+
</MenuContentItem>
|
|
164
|
+
))}
|
|
165
|
+
</MenuContent>
|
|
166
|
+
}
|
|
167
|
+
>
|
|
168
|
+
<div className="data-space__viewer__header__execution-context-selector__trigger__label">
|
|
169
|
+
Run Query
|
|
170
|
+
</div>
|
|
171
|
+
<div className="data-space__viewer__header__execution-context-selector__trigger__dropdown-icon">
|
|
172
|
+
<CaretDownIcon />
|
|
173
|
+
</div>
|
|
174
|
+
</ControlledDropdownMenu>
|
|
175
|
+
) : (
|
|
176
|
+
<div className="data-space__viewer__header__execution-context-selector__trigger__label">
|
|
177
|
+
Run Query
|
|
178
|
+
</div>
|
|
179
|
+
)}
|
|
146
180
|
</div>
|
|
147
|
-
</
|
|
181
|
+
</div>
|
|
148
182
|
)}
|
|
149
183
|
<ControlledDropdownMenu
|
|
150
184
|
className="data-space__viewer__header__actions-selector"
|
|
151
185
|
menuProps={{
|
|
152
186
|
anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
|
|
153
187
|
transformOrigin: { vertical: 'top', horizontal: 'right' },
|
|
154
|
-
elevation:
|
|
188
|
+
elevation: 0,
|
|
189
|
+
MenuListProps: {
|
|
190
|
+
className:
|
|
191
|
+
'data-space__viewer__header__actions-selector__menu',
|
|
192
|
+
},
|
|
155
193
|
}}
|
|
156
194
|
title="More Actions..."
|
|
157
195
|
content={
|
|
@@ -126,13 +126,17 @@ export const DataSpaceViewerActivityBar = observer(
|
|
|
126
126
|
<LaunchIcon className="data-space__viewer__activity-bar__icon--launch" />
|
|
127
127
|
),
|
|
128
128
|
},
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
129
|
+
...(dataSpaceViewerState.isDataAccessAvailable
|
|
130
|
+
? [
|
|
131
|
+
{
|
|
132
|
+
mode: DATA_SPACE_VIEWER_ACTIVITY_MODE.DATA_ACCESS,
|
|
133
|
+
title: 'Data Access',
|
|
134
|
+
icon: (
|
|
135
|
+
<DataAccessIcon className="data-space__viewer__activity-bar__icon--access" />
|
|
136
|
+
),
|
|
137
|
+
},
|
|
138
|
+
]
|
|
139
|
+
: []),
|
|
136
140
|
];
|
|
137
141
|
|
|
138
142
|
const activities: ActivityBarItemConfig[] = [
|
|
@@ -107,12 +107,7 @@ export const TEST_DATA_SPACE_VERSION_ID = '0.0.0';
|
|
|
107
107
|
|
|
108
108
|
export type TEST__DataSpaceViewerActionOverrides = {
|
|
109
109
|
viewDataProduct?:
|
|
110
|
-
| ((
|
|
111
|
-
groupId: string,
|
|
112
|
-
artifactId: string,
|
|
113
|
-
versionId: string,
|
|
114
|
-
dataProductPath: string,
|
|
115
|
-
) => void)
|
|
110
|
+
| ((dataProductPath: string, deploymentId: number) => void)
|
|
116
111
|
| undefined;
|
|
117
112
|
fetchDataSpaceQuality?: (() => Promise<DataSpaceQualityResult>) | undefined;
|
|
118
113
|
};
|