/** * 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 { EntityDiffSideBarItem } from '../editor/editor-group/diff-editor/EntityDiffView.js'; import { clsx, PanelLoadingIndicator, TruncatedGitMergeIcon, RefreshIcon, TimesIcon, ArrowUpIcon, CheckIcon, InfoCircleIcon, PanelContent, } from '@finos/legend-art'; import { EntityDiffViewState } from '../../stores/editor/editor-state/entity-diff-editor-state/EntityDiffViewState.js'; import { LEGEND_STUDIO_TEST_ID } from '../../__lib__/LegendStudioTesting.js'; import { flowResult } from 'mobx'; import { type EntityDiff, ReviewState, EntityChangeType, getChangeTypeIconFromChange, } from '@finos/legend-server-sdlc'; import { entityDiffSorter } from '../../stores/editor/EditorSDLCState.js'; import { useProjectReviewerStore } from './ProjectReviewStoreProvider.js'; import { useEditorStore } from '../editor/EditorStoreProvider.js'; import { useApplicationStore } from '@finos/legend-application'; import { formatDistanceToNow } from '@finos/legend-shared'; import { SPECIAL_REVISION_ALIAS } from '../../stores/editor/editor-state/entity-diff-editor-state/EntityDiffEditorState.js'; import { ProjectConfigurationDiffEditorState } from '../../stores/editor/editor-state/diff-viewer-state/ProjectConfigurationDiffEditorState.js'; import { STUDIO_SDLC_USER_ERRORS } from '../shared/StudioSDLCErrors.js'; export const ProjectReviewerSideBar = observer(() => { const reviewStore = useProjectReviewerStore(); const editorStore = useEditorStore(); const applicationStore = useApplicationStore(); const workspaceContainsSnapshotDependencies = editorStore.projectConfigurationEditorState.containsSnapshotDependencies; const approvalString = reviewStore.approvalString; // Review infos const review = reviewStore.review; const currentUser = editorStore.sdlcServerClient.currentUser; let reviewStatus = ''; switch (review.state) { case ReviewState.OPEN: reviewStatus = `created ${formatDistanceToNow(review.createdAt, { includeSeconds: true, addSuffix: true, })} by ${review.author.name}`; break; case ReviewState.CLOSED: reviewStatus = review.closedAt ? `closed ${formatDistanceToNow(review.closedAt, { includeSeconds: true, addSuffix: true, })}` : 'review is closed'; break; case ReviewState.COMMITTED: reviewStatus = review.committedAt ? `committed ${formatDistanceToNow(review.committedAt, { includeSeconds: true, addSuffix: true, })}` : 'review is closed'; break; case ReviewState.UNKNOWN: reviewStatus = review.lastUpdatedAt ? `last updated ${formatDistanceToNow(review.lastUpdatedAt, { includeSeconds: true, addSuffix: true, })}` : 'review status is unknown'; break; default: } // Actions const isDispatchingAction = reviewStore.buildReviewReportState.isInProgress || reviewStore.approveState.isInProgress || reviewStore.closeState.isInProgress || reviewStore.commitState.isInProgress || reviewStore.reOpenState.isInProgress; const closeReview = applicationStore.guardUnhandledError(() => flowResult(reviewStore.closeReview()), ); const reOpenReview = applicationStore.guardUnhandledError(() => flowResult(reviewStore.reOpenReview()), ); const commitReview = applicationStore.guardUnhandledError(() => flowResult(reviewStore.commitReview()), ); const approveReview = applicationStore.guardUnhandledError(() => flowResult(reviewStore.approveReview()), ); const refresh = (): void => { reviewStore.refresh(); }; // Changes const changes = reviewStore.reviewReport?.diffs ?? []; const currentTabState = editorStore.tabManagerState.currentTab; const isSelectedDiff = (diff: EntityDiff): boolean => currentTabState instanceof EntityDiffViewState && diff.oldPath === currentTabState.fromEntityPath && diff.newPath === currentTabState.toEntityPath; const openChange = (diff: EntityDiff): (() => void) => (): void => reviewStore.openReviewChange(diff); const openConfiguration = (): void => { const diffs = reviewStore.reviewReport?.fromToProjectConfig; if (diffs) { const newTab = new ProjectConfigurationDiffEditorState( diffs[0], diffs[1], reviewStore.editorStore, SPECIAL_REVISION_ALIAS.WORKSPACE_BASE, SPECIAL_REVISION_ALIAS.WORKSPACE_HEAD, ); reviewStore.editorStore.tabManagerState.openTab( reviewStore.editorStore.tabManagerState.tabs.find((t) => t.match(newTab), ) ?? newTab, ); } }; return (