/** * 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 { clsx, Dialog, PanelLoadingIndicator, TimesIcon, RefreshIcon, InfoCircleIcon, DownloadIcon, UploadIcon, CloudDownloadIcon, ResizablePanelGroup, ResizablePanel, ResizablePanelSplitter, ResizablePanelSplitterLine, CloudUploadIcon, PanelContent, Modal, ModalBody, ModalFooter, ModalHeader, ModalFooterButton, } from '@finos/legend-art'; import { EntityDiffViewState } from '../../../stores/editor/editor-state/entity-diff-editor-state/EntityDiffViewState.js'; import { EntityDiffSideBarItem } from '../editor-group/diff-editor/EntityDiffView.js'; import { LEGEND_STUDIO_TEST_ID } from '../../../__lib__/LegendStudioTesting.js'; import { flowResult } from 'mobx'; import type { EntityChange, EntityChangeConflict, EntityDiff, } from '@finos/legend-server-sdlc'; import { entityDiffSorter } from '../../../stores/editor/EditorSDLCState.js'; import { useEditorStore } from '../EditorStoreProvider.js'; import { useApplicationStore } from '@finos/legend-application'; import { useEffect } from 'react'; import { EntityChangeConflictEditorState } from '../../../stores/editor/editor-state/entity-diff-editor-state/EntityChangeConflictEditorState.js'; import { EntityChangeConflictSideBarItem } from '../editor-group/diff-editor/EntityChangeConflictEditor.js'; import { FormLocalChangesState } from '../../../stores/editor/sidebar-state/LocalChangesState.js'; import { GRAPH_EDITOR_MODE } from '../../../stores/editor/EditorConfig.js'; const PatchLoader = observer(() => { const editorStore = useEditorStore(); const applicationStore = editorStore.applicationStore; const localChangesState = editorStore.localChangesState; const patchState = localChangesState.patchLoaderState; const onClose = (): void => patchState.closeModal(); const onChange: React.ChangeEventHandler = (event) => { const file = event.target.files?.[0]; if (file) { patchState.loadPatchFile(file); } }; const upload = (): void => { patchState.applyChanges(); }; const deleteChange = (change: EntityChange): void => patchState.deleteChange(change); return (
{Boolean(patchState.overiddingChanges.length) && (
Overriding Changes
The following element changes will be overridden by the patch
{patchState.overiddingChanges.map((value) => (
{value.entityPath}
))}
)}
); }); export const LocalChanges = observer(() => { const editorStore = useEditorStore(); const sdlcState = editorStore.sdlcState; const applicationStore = useApplicationStore(); const localChangesState = editorStore.localChangesState; const updateState = localChangesState.workspaceSyncState; // Actions const downloadLocalChanges = (): void => localChangesState.downloadLocalChanges(); const uploadPatchChanges = (): void => localChangesState.patchLoaderState.openModal( editorStore.localChangesState.computeLocalEntityChanges(), ); const pushLocalChanges = applicationStore.guardUnhandledError(() => flowResult(localChangesState.pushLocalChanges()), ); const refreshLocalChanges = applicationStore.guardUnhandledError(() => flowResult(localChangesState.refreshLocalChanges()), ); const pullRemoteWorkspace = (): void => { if (!localChangesState.refreshWorkspaceSyncStatusState.isInProgress) { flowResult(updateState.pullChanges()).catch( applicationStore.alertUnhandledError, ); } }; const isDispatchingAction = localChangesState.pushChangesState.isInProgress || localChangesState.refreshLocalChangesDetectorState.isInProgress || localChangesState.workspaceSyncState.pullChangesState.isInProgress || localChangesState.refreshWorkspaceSyncStatusState.isInProgress; // Changes const currentTabState = editorStore.tabManagerState.currentTab; const isSelectedDiff = (diff: EntityDiff): boolean => currentTabState instanceof EntityDiffViewState && diff.oldPath === currentTabState.fromEntityPath && diff.newPath === currentTabState.toEntityPath; const changes = editorStore.changeDetectionState.workspaceLocalLatestRevisionState.changes; const openChange = (diff: EntityDiff): (() => void) => (): void => { if (localChangesState instanceof FormLocalChangesState) { localChangesState.openLocalChange(diff); } }; // Local/Remote Workspace Conflicts const conflicts = editorStore.changeDetectionState.potentialWorkspacePullConflicts; const isSelectedConflict = (conflict: EntityChangeConflict): boolean => currentTabState instanceof EntityChangeConflictEditorState && conflict.entityPath === currentTabState.entityPath; const openPotentialConflict = (conflict: EntityChangeConflict): (() => void) => (): void => { if (localChangesState instanceof FormLocalChangesState) { localChangesState.openPotentialWorkspacePullConflict(conflict); } }; // Local/Remote Workspace Changes const workspacePullChanges = editorStore.changeDetectionState.aggregatedWorkspaceRemoteChanges; const changesWithoutConflicts = workspacePullChanges.filter( (change) => !conflicts .map((conflict) => conflict.entityPath) .includes(change.entityPath), ); const openWorkspacePullChange = (diff: EntityDiff): (() => void) => (): void => { if (localChangesState instanceof FormLocalChangesState) { localChangesState.openWorkspacePullChange(diff); } }; // check if workspace is still in-sync useEffect(() => { flowResult(localChangesState.refreshWorkspaceSyncStatus()).catch( applicationStore.alertUnhandledError, ); }, [applicationStore, localChangesState]); return (
LOCAL CHANGES
{localChangesState.patchLoaderState.showModal && }
CHANGES
{changes.length}
{changes.toSorted(entityDiffSorter).map((diff) => ( ))}
INCOMING REMOTE REVISIONS
{updateState.incomingRevisions.length}
{updateState.incomingRevisions.map((revision) => (
{revision.message} {revision.committerName}
))}
INCOMING REMOTE CHANGES
{workspacePullChanges.length}
{conflicts .toSorted((a, b) => a.entityName.localeCompare(b.entityName)) .map((conflict) => ( ))} {Boolean(conflicts.length) && Boolean(changesWithoutConflicts.length) && (
)} {changesWithoutConflicts .toSorted(entityDiffSorter) .map((diff) => ( ))}
); });