UNPKG

@finos/legend-studio

Version:
230 lines 28 kB
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 { forwardRef, useEffect, useState } from 'react'; import { observer } from 'mobx-react-lite'; import { LEGEND_STUDIO_TEST_ID } from '../../LegendStudioTestID.js'; import { Link } from 'react-router-dom'; import { clsx, CustomSelectorInput, ShareIcon, PanelLoadingIndicator, ContextMenu, SyncIcon, PencilIcon, InfoCircleIcon, TimesIcon, UsersIcon, UserIcon, ExternalLinkIcon, Dialog, } from '@finos/legend-art'; import { PROJECT_OVERVIEW_ACTIVITY_MODE } from '../../../stores/sidebar-state/ProjectOverviewState.js'; import { generateEditorRoute, generateViewProjectRoute, generateViewVersionRoute, generateReviewRoute, } from '../../../stores/LegendStudioRouter.js'; import { flowResult } from 'mobx'; import { NewVersionType, WorkspaceType, areWorkspacesEquivalent, } from '@finos/legend-server-sdlc'; import { useEditorStore } from '../EditorStoreProvider.js'; import { useApplicationStore } from '@finos/legend-application'; import { useLegendStudioApplicationStore } from '../../LegendStudioBaseStoreProvider.js'; const ShareProjectModal = observer((props) => { const { open, closeModal } = props; const editorStore = useEditorStore(); const applicationStore = useLegendStudioApplicationStore(); const versions = editorStore.sdlcState.projectVersions; const isDispatchingAction = editorStore.sdlcState.isFetchingProjectVersions; const isFetchingProject = editorStore.sdlcState.isFetchingProject; const [selectedVersion, setSelectedVersion] = useState(); const projectId = editorStore.sdlcState.activeProject.projectId; const projectLink = selectedVersion ? applicationStore.navigator.generateLocation(generateViewVersionRoute(projectId, selectedVersion.id.id)) : applicationStore.navigator.generateLocation(generateViewProjectRoute(projectId)); const copyProjectLink = () => { applicationStore .copyTextToClipboard(projectLink) .then(() => applicationStore.notifySuccess('Copied project link to clipboard')) .catch(applicationStore.alertUnhandledError) .finally(() => closeModal()); }; const renderOptions = versions.map((version) => ({ label: version.id.id, value: version, })); const onSelectionChange = (val) => setSelectedVersion(val?.value); return (_jsx(Dialog, { onClose: closeModal, open: open, children: _jsxs("div", { className: "modal modal--dark modal--no-padding", children: [_jsx(PanelLoadingIndicator, { isLoading: isDispatchingAction }), _jsxs("div", { className: "modal__body", children: [_jsxs("div", { className: "project-overview__share-project__modal__info-entry", children: [_jsx("div", { className: "project-overview__share-project__modal__info-entry__title", children: "Version:" }), _jsx("div", { className: "project-overview__share-project__modal__info-entry__value", children: versions.length > 0 ? (_jsx("div", { className: "project-overview__share-project__modal__select", children: _jsx(CustomSelectorInput, { className: "setup-selector__input", options: renderOptions, disabled: isDispatchingAction || !versions.length, onChange: onSelectionChange, value: selectedVersion ? { label: selectedVersion.id.id, value: selectedVersion, } : null, darkMode: true }) })) : ('Project has only one version') })] }), _jsxs("div", { className: "project-overview__share-project__modal__info-entry", children: [_jsx("div", { className: "project-overview__share-project__modal__info-entry__title", children: "Link:" }), _jsx("div", { className: "project-overview__share-project__modal__info-entry__value", children: _jsx("a", { href: projectLink, target: "_blank", rel: "noopener noreferrer", children: projectLink }) })] })] }), _jsx("div", { className: "modal__footer", children: _jsx("button", { className: "btn--wide btn--dark", disabled: isFetchingProject, onClick: copyProjectLink, children: "Copy Link" }) })] }) })); }); const WorkspaceViewerContextMenu = observer(forwardRef(function WorkspaceViewerContextMenu(props, ref) { const { workspace } = props; const editorStore = useEditorStore(); const applicationStore = useApplicationStore(); const deleteWorkspace = applicationStore.guardUnhandledError(() => flowResult(editorStore.projectOverviewState.deleteWorkspace(workspace))); return (_jsx("div", { ref: ref, className: "project-overview__context-menu", children: _jsx("div", { className: "project-overview__context-menu__item", onClick: deleteWorkspace, children: "Delete" }) })); })); const WorkspaceViewer = observer((props) => { const { workspace } = props; const editorStore = useEditorStore(); const isActive = areWorkspacesEquivalent(editorStore.sdlcState.activeWorkspace, workspace); const [isSelectedFromContextMenu, setIsSelectedFromContextMenu] = useState(false); const onContextMenuOpen = () => setIsSelectedFromContextMenu(true); const onContextMenuClose = () => setIsSelectedFromContextMenu(false); return (_jsx(ContextMenu, { content: _jsx(WorkspaceViewerContextMenu, { workspace: workspace }), menuProps: { elevation: 7 }, onOpen: onContextMenuOpen, onClose: onContextMenuClose, children: _jsx(Link, { className: clsx('side-bar__panel__item project-overview__item__link', { 'project-overview__item__link--selected-from-context-menu': isSelectedFromContextMenu && !isActive, }, { 'project-overview__item__link--active': isActive }), rel: "noopener noreferrer", target: "_blank", to: generateEditorRoute(workspace.projectId, workspace.workspaceId, workspace.workspaceType), title: 'Go to workspace detail', children: _jsxs("div", { className: "project-overview__item__link__content project-overview__workspace__viewer", children: [_jsx("div", { className: "project-overview__workspace__viewer-icon", children: workspace.workspaceType === WorkspaceType.GROUP ? (_jsx(UsersIcon, {})) : (_jsx(UserIcon, {})) }), _jsx("div", { className: "project-overview__item__link__content__name", children: workspace.workspaceId })] }) }) })); }); const WorkspacesViewer = observer(() => { const editorStore = useEditorStore(); const applicationStore = useApplicationStore(); const projectOverviewState = editorStore.projectOverviewState; const workspaces = projectOverviewState.projectWorkspaces; const isDispatchingAction = projectOverviewState.isDeletingWorkspace || projectOverviewState.isFetchingProjectWorkspaces; // since this can be affected by other users, we refresh it more proactively useEffect(() => { flowResult(projectOverviewState.fetchProjectWorkspaces()).catch(applicationStore.alertUnhandledError); }, [applicationStore, projectOverviewState]); return (_jsxs("div", { className: "panel side-bar__panel project-overview__panel project-overview__workspaces", children: [_jsxs("div", { className: "panel__header", children: [_jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__content", children: PROJECT_OVERVIEW_ACTIVITY_MODE.WORKSPACES }) }), _jsx("div", { className: "side-bar__panel__header__changes-count", "data-testid": LEGEND_STUDIO_TEST_ID.SIDEBAR_PANEL_HEADER__CHANGES_COUNT, children: workspaces.length })] }), _jsxs("div", { className: "panel__content project-overview__panel__content", children: [_jsx(PanelLoadingIndicator, { isLoading: isDispatchingAction }), _jsx("div", { "data-testid": LEGEND_STUDIO_TEST_ID.PANEL_CONTENT_LIST, className: "panel__content__list", children: workspaces.map((workspace) => (_jsx(WorkspaceViewer, { workspace: workspace }, `${workspace.workspaceType}.${workspace.workspaceId}`))) })] })] })); }); const ReleaseEditor = observer(() => { const editorStore = useEditorStore(); const applicationStore = useLegendStudioApplicationStore(); const projectOverviewState = editorStore.projectOverviewState; const commitedReviews = projectOverviewState.committedReviewsBetweenMostRecentVersionAndProjectLatest; const isDispatchingAction = projectOverviewState.isFetchingLatestVersion || projectOverviewState.isFetchingCurrentProjectRevision || projectOverviewState.isCreatingVersion; const { latestProjectVersion, currentProjectRevision } = projectOverviewState; const revisionInput = projectOverviewState.releaseVersion; const createMajorRelease = applicationStore.guardUnhandledError(() => flowResult(projectOverviewState.createVersion(NewVersionType.MAJOR))); const createMinorRelease = applicationStore.guardUnhandledError(() => flowResult(projectOverviewState.createVersion(NewVersionType.MINOR))); const createPatchRelease = applicationStore.guardUnhandledError(() => flowResult(projectOverviewState.createVersion(NewVersionType.PATCH))); const changeNotes = (event) => revisionInput.setNotes(event.target.value); const notFetchedLatestVersionAndCurrentRevision = latestProjectVersion === undefined || currentProjectRevision === undefined; const isCurrentProjectVersionLatest = Boolean(latestProjectVersion) && latestProjectVersion?.revisionId === currentProjectRevision?.id; const canCreateVersion = !isCurrentProjectVersionLatest && !isDispatchingAction && editorStore.sdlcServerClient.features.canCreateVersion; // since this can be affected by other users, we refresh it more proactively useEffect(() => { flowResult(projectOverviewState.fetchLatestProjectVersion()).catch(applicationStore.alertUnhandledError); }, [applicationStore, projectOverviewState]); return (_jsxs("div", { className: "panel side-bar__panel project-overview__panel project-overview__release", children: [_jsx("div", { className: "panel__header", children: _jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__content", children: PROJECT_OVERVIEW_ACTIVITY_MODE.RELEASE }) }) }), _jsxs("div", { className: "panel__content project-overview__release__panel__content project-overview__release__content", children: [_jsx(PanelLoadingIndicator, { isLoading: isDispatchingAction }), _jsxs("div", { className: "project-overview__release__editor", children: [_jsx("textarea", { className: "project-overview__release__editor__input input--dark", spellCheck: false, disabled: !canCreateVersion, value: revisionInput.notes, onChange: changeNotes, placeholder: 'Release notes' }), _jsxs("div", { className: "project-overview__release__editor__actions", children: [_jsx("button", { className: "project-overview__release__editor__action btn--dark btn--caution", onClick: createMajorRelease, disabled: !canCreateVersion, title: 'Create a major release which comes with backward-incompatible features', children: "MAJOR" }), _jsx("button", { className: "project-overview__release__editor__action btn--dark", onClick: createMinorRelease, disabled: !canCreateVersion, title: 'Create a minor release which comes with backward-compatible features', children: "MINOR" }), _jsx("button", { className: "project-overview__release__editor__action btn--dark", onClick: createPatchRelease, disabled: !canCreateVersion, title: 'Create a patch release which comes with backward-compatible bug fixes', children: "PATCH" })] })] }), !notFetchedLatestVersionAndCurrentRevision && (_jsxs("div", { className: "project-overview__release__info", children: [_jsxs("div", { className: "panel project-overview__release__info__current-version__container", children: [_jsx("div", { className: "panel__header", children: _jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__content", children: "LATEST RELEASE" }) }) }), _jsxs("div", { className: "panel__content", children: [latestProjectVersion && (_jsx("div", { className: "project-overview__release__info__current-version", children: _jsx(Link, { className: "project-overview__release__info__current-version__link", rel: "noopener noreferrer", target: "_blank", to: generateViewVersionRoute(latestProjectVersion.projectId, latestProjectVersion.id.id), children: _jsxs("div", { className: "project-overview__release__info__current-version__link__content", children: [_jsx("span", { className: "project-overview__release__info__current-version__link__content__name", children: latestProjectVersion.id.id }), _jsx("span", { className: "project-overview__release__info__current-version__link__content__info", children: latestProjectVersion.notes })] }) }) })), !latestProjectVersion && (_jsx("div", { className: "project-overview__release__info__current-version", children: _jsx("span", { className: "project-overview__release__info__current-version__no-version", children: "This project has no release" }) }))] })] }), _jsxs("div", { className: "panel project-overview__release__info__reviews", children: [_jsxs("div", { className: "panel__header", children: [_jsxs("div", { className: "panel__header__title", children: [_jsx("div", { className: "panel__header__title__content", children: "COMMITTED REVIEWS" }), _jsx("div", { className: "side-bar__panel__title__info", title: "All committed reviews in the project since the latest release", children: _jsx(InfoCircleIcon, {}) })] }), _jsx("div", { className: "side-bar__panel__header__changes-count", "data-testid": LEGEND_STUDIO_TEST_ID.SIDEBAR_PANEL_HEADER__CHANGES_COUNT, children: commitedReviews.length })] }), _jsx("div", { className: "panel__content", children: commitedReviews.map((review) => (_jsx(Link, { className: "side-bar__panel__item workspace-updater__review__link", rel: "noopener noreferrer", target: "_blank", to: generateReviewRoute(review.projectId, review.id), title: 'See review detail', children: _jsxs("div", { className: "workspace-updater__review", children: [_jsx("span", { className: "workspace-updater__review__name", children: review.title }), _jsx("span", { className: "workspace-updater__review__info", children: review.author.name })] }) }, review.id))) })] })] }))] })] })); }); const VersionsViewer = observer(() => { const editorStore = useEditorStore(); const applicationStore = useLegendStudioApplicationStore(); const versions = editorStore.sdlcState.projectVersions; const isDispatchingAction = editorStore.sdlcState.isFetchingProjectVersions; // since this can be affected by other users, we refresh it more proactively useEffect(() => { flowResult(editorStore.sdlcState.fetchProjectVersions()).catch(applicationStore.alertUnhandledError); }, [applicationStore, editorStore]); return (_jsxs("div", { className: "panel side-bar__panel project-overview__panel project-overview__versions", children: [_jsxs("div", { className: "panel__header", children: [_jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__content", children: PROJECT_OVERVIEW_ACTIVITY_MODE.VERSIONS }) }), _jsx("div", { className: "side-bar__panel__header__changes-count", "data-testid": LEGEND_STUDIO_TEST_ID.SIDEBAR_PANEL_HEADER__CHANGES_COUNT, children: versions.length })] }), _jsxs("div", { className: "panel__content project-overview__panel__content", children: [_jsx(PanelLoadingIndicator, { isLoading: isDispatchingAction }), _jsx("div", { className: "panel__content__list", children: versions.map((version) => (_jsx(Link, { className: "side-bar__panel__item project-overview__item__link", rel: "noopener noreferrer", target: "_blank", to: generateViewVersionRoute(version.projectId, version.id.id), title: 'See version detail', children: _jsxs("div", { className: "project-overview__item__link__content", children: [_jsx("span", { className: "project-overview__item__link__content__name", children: version.id.id }), _jsx("span", { className: "project-overview__item__link__content__info", children: version.notes })] }) }, version.id.id))) })] })] })); }); const OverviewViewer = observer(() => { const editorStore = useEditorStore(); const applicationStore = useApplicationStore(); const projectOverviewState = editorStore.projectOverviewState; const sdlcState = editorStore.sdlcState; const initialName = sdlcState.currentProject?.name ?? ''; const initialDescription = sdlcState.currentProject?.description ?? ''; const initialTags = sdlcState.currentProject?.tags ?? []; const isDispatchingAction = projectOverviewState.isUpdatingProject; const [projectIdentifier, setProjectIdentifier] = useState(initialName); const [description, setDescription] = useState(initialDescription); const [itemValue, setItemValue] = useState(''); const [tagsArray, setTagsArray] = useState(initialTags); const changeDescription = (event) => { setDescription(event.target.value); }; const changeProjectIdentifier = (event) => setProjectIdentifier(event.target.value); // NOTE: `showEditInput` is either boolean (to hide/show the add value button) or a number (index of the item being edited) const [showEditInput, setShowEditInput] = useState(false); const showAddItemInput = () => setShowEditInput(true); const showEditItemInput = (value, idx) => () => { setItemValue(value); setShowEditInput(idx); }; const hideAddOrEditItemInput = () => { setShowEditInput(false); setItemValue(''); }; const changeItemInputValue = (event) => setItemValue(event.target.value); const addValue = () => { if (itemValue && !tagsArray.includes(itemValue)) { setTagsArray([...tagsArray, itemValue]); } hideAddOrEditItemInput(); }; const updateValue = (idx) => () => { if (itemValue && !tagsArray.includes(itemValue)) { tagsArray[idx] = itemValue; setTagsArray(tagsArray); hideAddOrEditItemInput(); } }; const deleteValue = (idx) => () => { const tags = [...tagsArray]; tags.splice(idx, 1); setTagsArray(tags); // Since we keep track of the value currently being edited using the index, we have to account for it as we delete entry if (typeof showEditInput === 'number' && showEditInput > idx) { setShowEditInput(showEditInput - 1); } }; const handleUpdate = (event) => { event.preventDefault(); flowResult(projectOverviewState.updateProject(projectIdentifier, description, tagsArray)).catch(applicationStore.alertUnhandledError); }; return (_jsxs("div", { className: "panel side-bar__panel project-overview__panel project-overview__overview", children: [_jsxs("div", { className: "panel__header", children: [_jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__content", children: PROJECT_OVERVIEW_ACTIVITY_MODE.OVERVIEW }) }), _jsx("button", { className: "panel__header__action side-bar__header__action local-changes__sync-btn", onClick: handleUpdate, tabIndex: -1, title: "Update project", children: _jsx(SyncIcon, {}) })] }), _jsxs("div", { className: "panel__content project-overview__panel__content", children: [_jsx(PanelLoadingIndicator, { isLoading: isDispatchingAction }), _jsx("div", { className: "panel__content__form", children: _jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Project Name" }), _jsx("input", { className: "panel__content__form__section__input", title: "Project Name", spellCheck: false, value: projectIdentifier, onChange: changeProjectIdentifier })] }) }), _jsx("div", { className: "panel__content__form", children: _jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Description" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: "Description of the project" }), _jsx("textarea", { className: "panel__content__form__section__textarea", title: "PROJECT DESCRIPTION", spellCheck: false, value: description, onChange: changeDescription })] }) }), _jsx("div", { className: "panel__content__form", children: _jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Tags" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: "List of annotations to categorize projects" }), _jsx("div", { className: "panel__content__form__section__list" }), _jsxs("div", { className: "panel__content__form__section__list__items", "data-testid": LEGEND_STUDIO_TEST_ID.PANEL_CONTENT_FORM_SECTION_LIST_ITEMS, children: [tagsArray.map((value, idx) => ( // NOTE: since the value must be unique, we will use it as the key _jsx("div", { className: showEditInput === idx ? 'panel__content__form__section__list__new-item' : 'panel__content__form__section__list__item', children: showEditInput === idx ? (_jsxs(_Fragment, { children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: tagsArray.includes(itemValue), onClick: updateValue(idx), tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "panel__content__form__section__list__item__value", children: value }), _jsxs("div", { className: "panel__content__form__section__list__item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__item__edit-btn", onClick: showEditItemInput(value, idx), tabIndex: -1, children: _jsx(PencilIcon, {}) }), _jsx("button", { className: "panel__content__form__section__list__item__remove-btn", onClick: deleteValue(idx), tabIndex: -1, children: _jsx(TimesIcon, {}) })] })] })) }, value))), showEditInput === true && (_jsxs("div", { className: "panel__content__form__section__list__new-item", children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, value: itemValue, title: "TAG INPUT", onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: tagsArray.includes(itemValue), onClick: addValue, tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] }))] }), showEditInput !== true && (_jsx("div", { className: "panel__content__form__section__list__new-item__add", children: _jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", onClick: showAddItemInput, tabIndex: -1, children: "Add Value" }) }))] }) })] })] })); }); export const ProjectOverviewActivityBar = observer(() => { const editorStore = useEditorStore(); const projectOverviewState = editorStore.projectOverviewState; const changeActivity = (activity) => () => projectOverviewState.setActivityMode(activity); const activities = [ { mode: PROJECT_OVERVIEW_ACTIVITY_MODE.OVERVIEW, title: 'Overview' }, { mode: PROJECT_OVERVIEW_ACTIVITY_MODE.RELEASE, title: 'Release', }, { mode: PROJECT_OVERVIEW_ACTIVITY_MODE.VERSIONS, title: 'Versions' }, { mode: PROJECT_OVERVIEW_ACTIVITY_MODE.WORKSPACES, title: 'Workspaces' }, ].filter((activity) => Boolean(activity)); return (_jsx("div", { "data-testid": LEGEND_STUDIO_TEST_ID.PROJECT_OVERVIEW__ACTIVITY_BAR, className: "project-overview__activity-bar", children: _jsx("div", { className: "project-overview__activity-bar__items", children: activities.map((activity) => (_jsx("div", { className: clsx('project-overview__activity-bar__item', { 'project-overview__activity-bar__item--active': activity.mode === projectOverviewState.activityMode, }), onClick: changeActivity(activity.mode), tabIndex: -1, title: activity.title, children: _jsx("div", { className: "project-overview__activity-bar__item-mode", children: activity.mode }) }, activity.mode))) }) })); }); export const ProjectOverview = observer(() => { const editorStore = useEditorStore(); const applicationStore = useApplicationStore(); const [openShareModal, setOpenShareModal] = useState(false); const showShareModal = () => setOpenShareModal(true); const hideShareModal = () => setOpenShareModal(false); const projectOverviewState = editorStore.projectOverviewState; const openProjectWebUrl = () => applicationStore.navigator.openNewWindow(editorStore.sdlcState.activeProject.webUrl); const renderOverview = () => { switch (projectOverviewState.activityMode) { case PROJECT_OVERVIEW_ACTIVITY_MODE.OVERVIEW: return _jsx(OverviewViewer, {}); case PROJECT_OVERVIEW_ACTIVITY_MODE.RELEASE: return _jsx(ReleaseEditor, {}); case PROJECT_OVERVIEW_ACTIVITY_MODE.VERSIONS: return _jsx(VersionsViewer, {}); case PROJECT_OVERVIEW_ACTIVITY_MODE.WORKSPACES: return _jsx(WorkspacesViewer, {}); default: return null; } }; return (_jsxs("div", { className: "panel project-overview", children: [_jsxs("div", { className: "panel__header side-bar__header", children: [_jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__content side-bar__header__title__content", children: "PROJECT" }) }), _jsxs("div", { className: "panel__header__actions side-bar__header__actions", children: [_jsx("button", { className: "panel__header__action side-bar__header__action", disabled: !editorStore.sdlcState.currentProject, title: "Share...", onClick: showShareModal, children: _jsx(ShareIcon, {}) }), _jsx("button", { className: "panel__header__action side-bar__header__action", disabled: !editorStore.sdlcState.currentProject, onClick: openProjectWebUrl, tabIndex: -1, title: "Go to project in underlying VCS system", children: _jsx(ExternalLinkIcon, {}) })] })] }), _jsxs("div", { className: "panel__content side-bar__content project-overview__content", children: [_jsx(ProjectOverviewActivityBar, {}), renderOverview()] }), editorStore.sdlcState.currentProject && (_jsx(ShareProjectModal, { open: openShareModal, closeModal: hideShareModal }))] })); }); //# sourceMappingURL=ProjectOverview.js.map