@finos/legend-extension-dsl-data-space
Version:
Legend extension for Data Space DSL
153 lines • 14.3 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
/**
* Copyright (c) 2020-present, Goldman Sachs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { observer } from 'mobx-react-lite';
import { CaretDownIcon, CaretUpIcon, ControlledDropdownMenu, MenuContent, MenuContentDivider, MenuContentItem, MoreVerticalIcon, PlayIcon, VerifiedIcon, SparkleStarsIcon, clsx, } from '@finos/legend-art';
import {} from '../stores/DataSpaceViewerState.js';
import { DataSpaceExecutionContextViewer } from './DataSpaceExecutionContextViewer.js';
import { DataSpaceInfoPanel } from './DataSpaceInfoPanel.js';
import { DataSpaceSupportPanel } from './DataSpaceSupportPanel.js';
import { DataSpaceWiki } from './DataSpaceWiki.js';
import { DataSpaceViewerActivityBar } from './DataSpaceViewerActivityBar.js';
import { useCallback, useEffect, useRef, useState } from 'react';
import { DATA_SPACE_WIKI_PAGE_SECTIONS } from '../stores/DataSpaceLayoutState.js';
import { DATA_SPACE_VIEWER_ACTIVITY_MODE, generateAnchorForActivity, } from '../stores/DataSpaceViewerNavigation.js';
import { DataSpacePlaceholderPanel } from './DataSpacePlaceholder.js';
import { useApplicationStore } from '@finos/legend-application';
import { DataSpaceLegendAIIntegration } from './DataSpaceLegendAIIntegration.js';
const DataSpaceHeader = observer((props) => {
const { dataSpaceViewerState, showFullHeader } = props;
const applicationStore = useApplicationStore();
const headerRef = useRef(null);
const analysisResult = dataSpaceViewerState.dataSpaceAnalysisResult;
useEffect(() => {
if (headerRef.current) {
dataSpaceViewerState.layoutState.header = headerRef.current;
}
}, [dataSpaceViewerState]);
return (_jsx("div", { ref: headerRef, className: clsx('data-space__viewer__header', {
'data-space__viewer__header--floating': showFullHeader,
}), children: _jsxs("div", { className: clsx('data-space__viewer__header__content', {
'data-space__viewer__header__content--expanded': dataSpaceViewerState.layoutState.isExpandedModeEnabled,
}), children: [_jsxs("div", { className: "data-space__viewer__header__title", title: `${analysisResult.displayName} - ${analysisResult.path}`, children: [_jsx("div", { className: "data-space__viewer__header__title__label", children: analysisResult.displayName }), dataSpaceViewerState.isVerified && (_jsx("div", { className: "data-space__viewer__header__title__verified-badge", title: "Verified Data Product", children: _jsx(VerifiedIcon, {}) }))] }), _jsxs("div", { className: "data-space__viewer__header__actions", children: [_jsx(ControlledDropdownMenu, { className: "data-space__viewer__header__execution-context-selector", menuProps: {
anchorOrigin: { vertical: 'bottom', horizontal: 'center' },
transformOrigin: { vertical: 'top', horizontal: 'center' },
elevation: 7,
}, title: `Current Execution Context: ${dataSpaceViewerState.currentExecutionContext.name}\nClick to switch`, content: _jsx(MenuContent, { children: Array.from(dataSpaceViewerState.dataSpaceAnalysisResult.executionContextsIndex.values()).map((context) => (_jsx(MenuContentItem, { className: clsx('data-space__viewer__header__execution-context-selector__option', {
'data-space__viewer__header__execution-context-selector__option--active': context ===
dataSpaceViewerState.currentExecutionContext,
}), onClick: () => dataSpaceViewerState.setCurrentExecutionContext(context), children: context.name }, context.name))) }), children: _jsxs("div", { className: "data-space__viewer__header__execution-context-selector__trigger", children: [_jsx("div", { className: "data-space__viewer__header__execution-context-selector__trigger__icon", children: _jsx(PlayIcon, {}) }), _jsx("div", { className: "data-space__viewer__header__execution-context-selector__trigger__label", children: dataSpaceViewerState.currentExecutionContext.name }), _jsx("div", { className: "data-space__viewer__header__execution-context-selector__trigger__dropdown-icon", children: _jsx(CaretDownIcon, {}) })] }) }), _jsx(ControlledDropdownMenu, { className: "data-space__viewer__header__actions-selector", menuProps: {
anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
transformOrigin: { vertical: 'top', horizontal: 'right' },
elevation: 7,
}, title: "More Actions...", content: _jsxs(MenuContent, { children: [_jsx(MenuContentItem, { onClick: () => dataSpaceViewerState.queryDataSpace(dataSpaceViewerState.currentExecutionContext.name), children: "Query Data Product" }), _jsx(MenuContentDivider, {}), _jsx(MenuContentItem, { onClick: () => dataSpaceViewerState.viewProject(analysisResult.path), children: "View Project" }), _jsx(MenuContentItem, { onClick: () => {
dataSpaceViewerState
.viewSDLCProject(analysisResult.path)
.catch(applicationStore.alertUnhandledError);
}, children: "View SDLC Project" }), _jsx(MenuContentDivider, {}), _jsx(MenuContentItem, { onClick: () => {
const documentationUrl = analysisResult.supportInfo?.documentationUrl;
if (documentationUrl) {
applicationStore.navigationService.navigator.visitAddress(documentationUrl);
}
}, children: "Read Documentation" }), _jsx(MenuContentItem, { onClick: () => dataSpaceViewerState.changeZone(generateAnchorForActivity(DATA_SPACE_VIEWER_ACTIVITY_MODE.SUPPORT)), children: "Get Help" })] }), children: _jsx(MoreVerticalIcon, {}) })] })] }) }));
});
export const DataSpaceViewer = observer((props) => {
const { dataSpaceViewerState } = props;
const frame = useRef(null);
const [showFullHeader, setShowFullHeader] = useState(false);
const [scrollPercentage, setScrollPercentage] = useState(0);
const [isAIChatOpen, setIsAIChatOpen] = useState(false);
const [panelWidth, setPanelWidth] = useState(500);
const isResizing = useRef(false);
const handleResizeMouseDown = useCallback((e) => {
e.preventDefault();
isResizing.current = true;
const onMouseMove = (ev) => {
if (!isResizing.current) {
return;
}
const newWidth = window.innerWidth - ev.clientX;
setPanelWidth(Math.max(320, Math.min(newWidth, window.innerWidth * 0.6)));
};
const onMouseUp = () => {
isResizing.current = false;
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
document.body.style.cursor = '';
document.body.style.userSelect = '';
};
document.body.style.cursor = 'col-resize';
document.body.style.userSelect = 'none';
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
}, []);
const onScroll = (event) => {
const scrollTop = event.currentTarget.scrollTop;
setShowFullHeader(scrollTop > 0);
dataSpaceViewerState.layoutState.setTopScrollerVisible(scrollTop > 0);
setScrollPercentage(event.currentTarget.scrollHeight <= 0
? 100
: Math.round(((event.currentTarget.scrollTop +
event.currentTarget.clientHeight) /
event.currentTarget.scrollHeight) *
100));
};
const scrollToTop = () => {
if (dataSpaceViewerState.layoutState.frame) {
dataSpaceViewerState.layoutState.frame.scrollTo({
top: 0,
behavior: 'smooth',
});
}
};
const isShowingWiki = DATA_SPACE_WIKI_PAGE_SECTIONS.includes(dataSpaceViewerState.currentActivity);
const isAIEnabled = dataSpaceViewerState.legendAIConfig.enabled && isShowingWiki;
const dsTitle = dataSpaceViewerState.dataSpaceAnalysisResult.title ??
dataSpaceViewerState.dataSpaceAnalysisResult.name;
useEffect(() => {
if (frame.current) {
dataSpaceViewerState.layoutState.setFrame(frame.current);
}
}, [dataSpaceViewerState]);
return (_jsxs("div", { className: clsx('data-space__viewer', {
'data-space__viewer--chat-open': isAIChatOpen,
}), style: isAIChatOpen
? { '--ai-panel-width': `${panelWidth}px` }
: undefined, children: [_jsx(DataSpaceViewerActivityBar, { dataSpaceViewerState: dataSpaceViewerState }), _jsxs("div", { ref: frame, className: "data-space__viewer__body", onScroll: onScroll, children: [_jsx(DataSpaceHeader, { dataSpaceViewerState: dataSpaceViewerState, showFullHeader: showFullHeader }), dataSpaceViewerState.layoutState.isTopScrollerVisible && (_jsxs("div", { className: "data-space__viewer__scroller", children: [_jsx("button", { className: "data-space__viewer__scroller__btn btn--dark", tabIndex: -1, title: "Scroll to top", disabled: !dataSpaceViewerState.layoutState.frame, onClick: scrollToTop, children: _jsx(CaretUpIcon, {}) }), _jsxs("div", { className: "data-space__viewer__scroller__percentage", children: [scrollPercentage, "%"] })] })), _jsx("div", { className: clsx('data-space__viewer__frame', {
'data-space__viewer__frame--boundless': isShowingWiki,
'data-space__viewer__frame--expanded': dataSpaceViewerState.layoutState.isExpandedModeEnabled,
}), children: _jsxs("div", { className: "data-space__viewer__content", children: [isShowingWiki && (_jsx(DataSpaceWiki, { dataSpaceViewerState: dataSpaceViewerState })), dataSpaceViewerState.currentActivity ===
DATA_SPACE_VIEWER_ACTIVITY_MODE.EXECUTION_CONTEXT && (_jsx(DataSpaceExecutionContextViewer, { dataSpaceViewerState: dataSpaceViewerState })), dataSpaceViewerState.currentActivity ===
DATA_SPACE_VIEWER_ACTIVITY_MODE.DATA_STORES && (_jsx(DataSpacePlaceholderPanel, { header: "Data Stores", message: "This panel will provide details about the available datasets' schema and test data" })), dataSpaceViewerState.currentActivity ===
DATA_SPACE_VIEWER_ACTIVITY_MODE.DATA_AVAILABILITY && (_jsx(DataSpacePlaceholderPanel, { header: "Data Availability", message: "This panel will provide details about the status of data being made available to end-users and applications" })), dataSpaceViewerState.currentActivity ===
DATA_SPACE_VIEWER_ACTIVITY_MODE.DATA_READINESS && (_jsx(DataSpacePlaceholderPanel, { header: "Data Readiness", message: "This will provide details about the status of data being prepared to collect, process, and analyze" })), dataSpaceViewerState.currentActivity ===
DATA_SPACE_VIEWER_ACTIVITY_MODE.DATA_COST && (_jsx(DataSpacePlaceholderPanel, { header: "Data Cost", message: "This will provide details about the cost of data usage" })), dataSpaceViewerState.currentActivity ===
DATA_SPACE_VIEWER_ACTIVITY_MODE.DATA_GOVERNANCE && (_jsx(DataSpacePlaceholderPanel, { header: "Data Governance", message: "This will provide details about data policy, data contract, and dataset lineage information" })), dataSpaceViewerState.currentActivity ===
DATA_SPACE_VIEWER_ACTIVITY_MODE.INFO && (_jsx(DataSpaceInfoPanel, { dataSpaceViewerState: dataSpaceViewerState })), dataSpaceViewerState.currentActivity ===
DATA_SPACE_VIEWER_ACTIVITY_MODE.SUPPORT && (_jsx(DataSpaceSupportPanel, { dataSpaceViewerState: dataSpaceViewerState }))] }) })] }), isAIEnabled && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "data-space__viewer__ai-panel", style: {
width: panelWidth,
display: isAIChatOpen ? undefined : 'none',
}, children: [_jsx("button", { type: "button", className: "data-space__viewer__ai-panel__resize-handle", "aria-label": "Resize AI panel", onMouseDown: handleResizeMouseDown, onKeyDown: (e) => {
const step = 20;
if (e.key === 'ArrowLeft') {
setPanelWidth((w) => Math.min(w + step, window.innerWidth * 0.6));
}
else if (e.key === 'ArrowRight') {
setPanelWidth((w) => Math.max(w - step, 320));
}
} }), _jsx(DataSpaceLegendAIIntegration, { dataSpaceViewerState: dataSpaceViewerState, config: dataSpaceViewerState.legendAIConfig, onClose: () => setIsAIChatOpen(false), onMinimize: () => setIsAIChatOpen(false) })] }), !isAIChatOpen && (_jsxs("button", { className: "legend-ai-chat-toggle", onClick: () => setIsAIChatOpen(true), title: `Ask ${dsTitle}`, children: [_jsx("span", { className: "legend-ai-chat-toggle__icon", children: _jsx(SparkleStarsIcon, {}) }), _jsxs("span", { className: "legend-ai-chat-toggle__label", children: ["Ask ", dsTitle] })] }))] }))] }));
});
//# sourceMappingURL=DataSpaceViewer.js.map