UNPKG

@finos/legend-application-studio

Version:
251 lines 22.5 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } 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 { createContext, useContext, useEffect, useMemo, useState, useRef, } from 'react'; import { observer, useLocalObservable } from 'mobx-react-lite'; import { clsx, AssistantIcon, compareLabelFn, GitBranchIcon, CustomSelectorInput, LongArrowRightIcon, DividerWithText, SearchIcon, BaseCard, OpenIcon, Dialog, MarkdownTextViewer, Modal, } from '@finos/legend-art'; import { LEGEND_STUDIO_TEST_ID } from '../../__lib__/LegendStudioTesting.js'; import { generateEditorRoute, LEGEND_STUDIO_ROUTE_PATTERN_TOKEN, } from '../../__lib__/LegendStudioNavigation.js'; import { flowResult } from 'mobx'; import { useApplicationNavigationContext } from '@finos/legend-application'; import { useParams } from '@finos/legend-application/browser'; import { LEGEND_STUDIO_DOCUMENTATION_KEY } from '../../__lib__/LegendStudioDocumentation.js'; import { CreateProjectModal } from './CreateProjectModal.js'; import { ActivityBarMenu } from '../editor/ActivityBar.js'; import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../__lib__/LegendStudioApplicationNavigationContext.js'; import { CreateWorkspaceModal } from './CreateWorkspaceModal.js'; import { useLegendStudioApplicationStore, useLegendStudioBaseStore, } from '../LegendStudioFrameworkProvider.js'; import { buildProjectOption, getProjectOptionLabelFormatter, } from './ProjectSelectorUtils.js'; import { buildWorkspaceOption, formatWorkspaceOptionLabel, } from './WorkspaceSelectorUtils.js'; import { debounce, guaranteeNonNullable } from '@finos/legend-shared'; import { WorkspaceSetupStore } from '../../stores/workspace-setup/WorkspaceSetupStore.js'; import { openShowcaseManager } from '../../stores/ShowcaseManagerState.js'; const WorkspaceSetupStoreContext = createContext(undefined); export const DEFAULT_WORKSPACE_SOURCE = 'HEAD'; export const ShowcaseCard = (props) => { const applicationStore = useLegendStudioApplicationStore(); const appDocUrl = applicationStore.documentationService.url; return (_jsx(BaseCard, { className: "workspace-setup__content__card", cardMedia: undefined, cardName: "Showcase Projects", cardContent: _jsxs("div", { className: "workspace-setup__content__card__content", children: ["Review showcase projects with sample project code and re-use existing code snippets to quickly build your model.", ' ', !props.hideDocumentation && (_jsxs(_Fragment, { children: ["Review Studio", ' ', _jsx("a", { href: appDocUrl, target: "_blank", rel: "noreferrer", className: "workspace-setup__content__link", children: "documentation" }), "."] }))] }), cardActions: [ { title: 'Showcase explorer', content: (_jsx("div", { className: "workspace-setup__content__card__action__icon", children: _jsx(OpenIcon, {}) })), action: () => openShowcaseManager(applicationStore), }, ], isStable: true })); }; export const DocumentationCard = () => { const applicationStore = useLegendStudioApplicationStore(); const appDocUrl = applicationStore.documentationService.url; return (_jsx(BaseCard, { className: "workspace-setup__content__card", cardName: "Documentation", cardContent: _jsxs("div", { className: "workspace-setup__content__card__content", children: ["Review Studio", ' ', _jsx("a", { href: appDocUrl, target: "_blank", rel: "noreferrer", className: "workspace-setup__content__link", children: "documentation" }), "."] }), cardActions: [ { title: 'Review documentation', content: (_jsx("div", { className: "workspace-setup__content__card__action__icon", children: _jsx(OpenIcon, {}) })), action: () => { if (appDocUrl) { applicationStore.navigationService.navigator.visitAddress(appDocUrl); } }, }, ], isStable: true })); }; export const ProductionCard = () => { const applicationStore = useLegendStudioApplicationStore(); const productionDocument = applicationStore.documentationService.getDocEntry(LEGEND_STUDIO_DOCUMENTATION_KEY.APPLICATION_PRODUCTION); return (productionDocument?.title && productionDocument.markdownText && productionDocument.text && (_jsx(BaseCard, { className: "workspace-setup__content__card", cardName: productionDocument.title, cardContent: productionDocument.markdownText.value, cardActions: [ { title: productionDocument.text, content: (_jsx("div", { className: "workspace-setup__content__card__action__icon", children: _jsx(OpenIcon, {}) })), action: () => { if (productionDocument.url) { applicationStore.navigationService.navigator.visitAddress(productionDocument.url); } }, }, ], isStable: true }))); }; export const SandboxCard = () => { const applicationStore = useLegendStudioApplicationStore(); const sandboxDocument = applicationStore.documentationService.getDocEntry(LEGEND_STUDIO_DOCUMENTATION_KEY.APPLICATION_SANDBOX); return (sandboxDocument?.title && sandboxDocument.markdownText && sandboxDocument.text && (_jsx(BaseCard, { className: "workspace-setup__content__card", cardName: sandboxDocument.title, cardContent: sandboxDocument.markdownText.value, cardActions: [ { title: sandboxDocument.text, content: (_jsx("div", { className: "workspace-setup__content__card__action__icon", children: _jsx(OpenIcon, {}) })), action: () => { if (sandboxDocument.url) { applicationStore.navigationService.navigator.visitAddress(sandboxDocument.url); } }, }, ], isStable: true }))); }; export const RuleEngagementCard = () => { const applicationStore = useLegendStudioApplicationStore(); const ruleEngagementDocument = applicationStore.documentationService.getDocEntry(LEGEND_STUDIO_DOCUMENTATION_KEY.APPLICATION_RULE_ENGAGEMENT); return (ruleEngagementDocument?.title && ruleEngagementDocument.markdownText && ruleEngagementDocument.text && (_jsx(BaseCard, { className: "workspace-setup__content__card", cardMedia: undefined, cardName: ruleEngagementDocument.title, cardContent: ruleEngagementDocument.markdownText.value, cardActions: [ { title: ruleEngagementDocument.text, content: (_jsx("div", { className: "workspace-setup__content__card__action__icon", children: _jsx(OpenIcon, {}) })), action: () => { if (ruleEngagementDocument.url) { applicationStore.navigationService.navigator.visitAddress(ruleEngagementDocument.url); } }, }, ], isStable: true }))); }; const WorkspaceSetupStoreProvider = ({ children }) => { const applicationStore = useLegendStudioApplicationStore(); const baseStore = useLegendStudioBaseStore(); const store = useLocalObservable(() => new WorkspaceSetupStore(applicationStore, baseStore.sdlcServerClient)); return (_jsx(WorkspaceSetupStoreContext.Provider, { value: store, children: children })); }; export const useWorkspaceSetupStore = () => guaranteeNonNullable(useContext(WorkspaceSetupStoreContext), `Can't find workspace setup store in context`); const withWorkspaceSetupStore = (WrappedComponent) => function WithWorkspaceSetupStore() { return (_jsx(WorkspaceSetupStoreProvider, { children: _jsx(WrappedComponent, {}) })); }; const SandboxAccessModal = observer(() => { const setupStore = useWorkspaceSetupStore(); const closeModal = () => setupStore.setSandboxModal(false); const applicationStore = setupStore.applicationStore; const documentation = applicationStore.documentationService.getDocEntry(LEGEND_STUDIO_DOCUMENTATION_KEY.SETUP_CREATE_SANDBOX_UNAUTHORIZED); return (_jsx(Dialog, { open: true, onClose: closeModal, children: _jsxs(Modal, { darkMode: !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, className: "sandbox-project-modal", children: [_jsx("div", { className: "sandbox-project-modal__header", children: _jsx("div", { className: "sandbox-project-modal__header__label", children: "Create Sandbox Project" }) }), _jsx("div", { className: "sandbox-project-modal__form panel__content__form", children: _jsx("div", { className: "panel__content__form__section sandbox-project-modal__form__unsupported", children: "You do not have access to create a Sandbox Project" }) }), _jsx("div", { className: "sandbox-project-modal__content", children: documentation?.markdownText && (_jsx("div", { className: "panel__content__form__section", children: _jsx(MarkdownTextViewer, { value: documentation.markdownText }) })) })] }) })); }); export const WorkspaceSetup = withWorkspaceSetupStore(observer(() => { const params = useParams(); const projectId = params[LEGEND_STUDIO_ROUTE_PATTERN_TOKEN.PROJECT_ID]; const workspaceId = params[LEGEND_STUDIO_ROUTE_PATTERN_TOKEN.WORKSPACE_ID]; const groupWorkspaceId = params[LEGEND_STUDIO_ROUTE_PATTERN_TOKEN.GROUP_WORKSPACE_ID]; const setupStore = useWorkspaceSetupStore(); const applicationStore = useLegendStudioApplicationStore(); const [projectSearchText, setProjectSearchText] = useState(''); const goButtonRef = useRef(null); //TODO: fix logo loading issue for localhost const logoPath = `${applicationStore.config.baseAddress}favicon.ico`; const toggleAssistant = () => applicationStore.assistantService.toggleAssistant(); // projects const projectOptions = setupStore.projects .map(buildProjectOption) .sort(compareLabelFn); const selectedProjectOption = setupStore.currentProject ? buildProjectOption(setupStore.currentProject) : null; const onProjectChange = (val) => { if (val) { flowResult(setupStore.changeProject(val.value)).catch(applicationStore.alertUnhandledError); } else { setupStore.resetProject(); } }; const showCreateProjectModal = () => setupStore.setShowCreateProjectModal(true); const createSandboxProject = () => { flowResult(setupStore.createSandboxProject()).catch(applicationStore.alertUnhandledError); }; // project search text const debouncedLoadProjects = useMemo(() => debounce((input) => { flowResult(setupStore.loadProjects(input)).catch(applicationStore.alertUnhandledError); }, 500), [applicationStore, setupStore]); const onProjectSearchTextChange = (value) => { if (value !== projectSearchText) { setProjectSearchText(value); debouncedLoadProjects.cancel(); debouncedLoadProjects(value); } }; // workspaces const workspaceOptions = setupStore.workspaces .map(buildWorkspaceOption) .sort(compareLabelFn); const selectedWorkspaceOption = setupStore.currentWorkspace ? buildWorkspaceOption(setupStore.currentWorkspace) : null; const onWorkspaceChange = (val) => { if (val) { setupStore.changeWorkspace(val.value); if (!setupStore.currentProjectConfigurationStatus?.isConfigured) { applicationStore.notificationService.notifyIllegalState(`Can't edit current workspace as the current project is not configured`); } goButtonRef.current?.focus(); } else { setupStore.resetWorkspace(); } }; const showCreateWorkspaceModal = () => setupStore.setShowCreateWorkspaceModal(true); const handleProceed = () => { if (setupStore.currentProject && setupStore.currentWorkspace) { applicationStore.navigationService.navigator.goToLocation(generateEditorRoute(setupStore.currentProject.projectId, setupStore.currentWorkspace.source, setupStore.currentWorkspace.workspaceId, setupStore.currentWorkspace.workspaceType)); } }; useEffect(() => { flowResult(setupStore.initialize(projectId, workspaceId, groupWorkspaceId)).catch(applicationStore.alertUnhandledError); }, [ setupStore, applicationStore, projectId, workspaceId, groupWorkspaceId, ]); useEffect(() => { flowResult(setupStore.loadProjects('')).catch(applicationStore.alertUnhandledError); flowResult(setupStore.loadSandboxProject()).catch(applicationStore.alertUnhandledError); }, [setupStore, applicationStore]); useApplicationNavigationContext(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.SETUP); return (_jsx("div", { className: "app__page", children: _jsxs("div", { className: "workspace-setup", children: [_jsxs("div", { className: "workspace-setup__body", children: [_jsx("div", { className: "activity-bar", children: _jsx(ActivityBarMenu, {}) }), _jsx("div", { className: "workspace-setup__content", "data-testid": LEGEND_STUDIO_TEST_ID.SETUP__CONTENT, children: _jsxs("div", { className: "workspace-setup__content__body", children: [_jsxs("div", { className: "workspace-setup__content__main", children: [_jsxs("div", { className: "workspace-setup__title", children: [_jsx("div", { className: "workspace-setup__logo", children: _jsx("img", { src: logoPath, className: "workspace-setup__logo__icon" }) }), _jsx("div", { className: "workspace-setup__title__header", children: "Welcome to Legend Studio" })] }), _jsx("div", { className: "workspace-setup__selectors", children: _jsxs("div", { className: "workspace-setup__selectors__container", children: [_jsxs("div", { className: "workspace-setup__selector", children: [_jsx("div", { className: "workspace-setup__selector__header", children: "Search for an existing project" }), _jsxs("div", { className: "workspace-setup__selector__content", children: [_jsx("div", { className: "workspace-setup__selector__content__icon", title: "project", children: _jsx(SearchIcon, { className: "workspace-setup__selector__content__icon--project" }) }), _jsx(CustomSelectorInput, { className: "workspace-setup__selector__content__input", options: projectOptions, isLoading: setupStore.loadProjectsState.isInProgress || setupStore.loadSandboxState.isInProgress, onInputChange: onProjectSearchTextChange, inputValue: projectSearchText, onChange: onProjectChange, value: selectedProjectOption, placeholder: "Search for project...", isClearable: true, escapeClearsValue: true, darkMode: !applicationStore.layoutService .TEMPORARY__isLightColorThemeEnabled, formatOptionLabel: getProjectOptionLabelFormatter(applicationStore, setupStore.currentProjectConfigurationStatus), optionCustomization: { rowHeight: window.innerHeight * 0.03, } })] })] }), _jsxs("div", { className: "workspace-setup__selector", children: [_jsx("div", { className: "workspace-setup__selector__header", children: "Choose an existing workspace" }), _jsxs("div", { className: "workspace-setup__selector__content", children: [_jsx("div", { className: "workspace-setup__selector__content__icon", title: "workspace", children: _jsx(GitBranchIcon, { className: "workspace-setup__selector__content__icon--workspace" }) }), _jsx(CustomSelectorInput, { className: "workspace-setup__selector__content__input", options: workspaceOptions, onKeyDown: (event) => { if (event.key === 'Enter') { goButtonRef.current?.focus(); handleProceed(); } }, disabled: !setupStore.currentProject || !setupStore.currentProjectConfigurationStatus || !setupStore.currentProjectConfigurationStatus .isConfigured || setupStore.loadProjectsState.isInProgress || setupStore.loadWorkspacesState.isInProgress, isLoading: setupStore.loadWorkspacesState.isInProgress, onChange: onWorkspaceChange, formatOptionLabel: formatWorkspaceOptionLabel, value: selectedWorkspaceOption, placeholder: setupStore.loadWorkspacesState.isInProgress ? 'Loading workspaces...' : !setupStore.currentProject ? 'In order to choose a workspace, a project must be chosen' : workspaceOptions.length ? 'Choose an existing workspace' : 'You have no workspaces. Please create one to proceed...', isClearable: true, escapeClearsValue: true, darkMode: !applicationStore.layoutService .TEMPORARY__isLightColorThemeEnabled, optionCustomization: { rowHeight: window.innerHeight * 0.03, } })] })] })] }) }), _jsx("div", { className: "workspace-setup__actions-combo", children: _jsxs("div", { className: "workspace-setup__actions", children: [_jsx("button", { className: "workspace-setup__new-workspace-btn", onClick: showCreateWorkspaceModal, title: "Create a Workspace after choosing one project", disabled: !setupStore.currentProject || !setupStore.currentProjectConfigurationStatus ?.isConfigured, children: `Need to create a new workspace?` }), _jsx("div", { className: "workspace-setup__actions__button", children: _jsxs("button", { className: "workspace-setup__go-btn btn--dark", onClick: handleProceed, ref: goButtonRef, disabled: !setupStore.currentProject || !setupStore.currentProjectConfigurationStatus || !setupStore.currentProjectConfigurationStatus .isConfigured || !setupStore.currentWorkspace || setupStore.createWorkspaceState.isInProgress || setupStore.createOrImportProjectState.isInProgress, children: [_jsx("div", { className: "workspace-setup__go-btn__label", children: "Go" }), _jsx(LongArrowRightIcon, { className: "workspace-setup__go-btn__icon" })] }) }), _jsx(DividerWithText, { className: "workspace-setup__divider", children: "OR" }), setupStore.sandboxModal && _jsx(SandboxAccessModal, {}), _jsxs("div", { className: "workspace-setup__actions__button", children: [_jsx("button", { className: "workspace-setup__new-btn btn--dark", onClick: showCreateProjectModal, title: "Create a Project", children: "Create New Project" }), setupStore.sandboxProject === true && setupStore.initState.hasCompleted && setupStore.supportsCreatingSandboxProject && (_jsx("button", { className: "workspace-setup__new-btn btn--dark", onClick: createSandboxProject, title: "Create Sandbox Project", children: "Create Sandbox Project" }))] })] }) })] }), _jsxs("div", { className: "workspace-setup__content__cards", children: [_jsx(RuleEngagementCard, {}), _jsx(ShowcaseCard, {}), _jsx(SandboxCard, {}), _jsx(ProductionCard, {})] }), setupStore.showCreateProjectModal && _jsx(CreateProjectModal, {}), setupStore.showCreateWorkspaceModal && setupStore.currentProject && (_jsx(CreateWorkspaceModal, { selectedProject: setupStore.currentProject }))] }) })] }), _jsxs("div", { "data-testid": LEGEND_STUDIO_TEST_ID.STATUS_BAR, className: "editor__status-bar", children: [_jsx("div", { className: "editor__status-bar__left" }), _jsx("div", { className: "editor__status-bar__right", children: _jsx("button", { className: clsx('editor__status-bar__action editor__status-bar__action__toggler', { 'editor__status-bar__action__toggler--active': !applicationStore.assistantService.isHidden, }), onClick: toggleAssistant, tabIndex: -1, title: "Toggle assistant", children: _jsx(AssistantIcon, {}) }) })] })] }) })); })); //# sourceMappingURL=WorkspaceSetup.js.map