diff --git a/.changeset/swift-gifts-shake.md b/.changeset/swift-gifts-shake.md index 6530231b75..5bdd8430a5 100644 --- a/.changeset/swift-gifts-shake.md +++ b/.changeset/swift-gifts-shake.md @@ -2,4 +2,4 @@ '@finos/legend-studio': minor --- -Support updload and load patch. +Support upload and load patch. diff --git a/packages/legend-shared/src/application/BrowserUtils.ts b/packages/legend-shared/src/application/BrowserUtils.ts new file mode 100644 index 0000000000..eb70020514 --- /dev/null +++ b/packages/legend-shared/src/application/BrowserUtils.ts @@ -0,0 +1,33 @@ +/** + * 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 { isString } from '../error/AssertionUtils'; +import { UnsupportedOperationError } from '../error/ErrorUtils'; + +export const readFileAsText = (file: File): Promise => + new Promise((resolve, reject) => { + const fileReader = new FileReader(); + fileReader.onload = (): void => { + const result = fileReader.result; + if (isString(result)) { + resolve(result); + } else { + throw new UnsupportedOperationError(`Cant read file`); + } + }; + fileReader.onerror = reject; + fileReader.readAsText(file); + }); diff --git a/packages/legend-shared/src/index.ts b/packages/legend-shared/src/index.ts index 8c0e713ce2..0a453b7748 100644 --- a/packages/legend-shared/src/index.ts +++ b/packages/legend-shared/src/index.ts @@ -36,6 +36,7 @@ export * from './application/SerializationUtils'; export * from './application/RandomizerUtils'; export * from './application/ActionState'; export * from './application/AbstractPluginManager'; +export * from './application/BrowserUtils'; export * from './data-structure/Pair'; export * from './data-structure/Stack'; diff --git a/packages/legend-shared/src/network/NetworkUtils.ts b/packages/legend-shared/src/network/NetworkUtils.ts index eb395d0927..ee3db1ff15 100644 --- a/packages/legend-shared/src/network/NetworkUtils.ts +++ b/packages/legend-shared/src/network/NetworkUtils.ts @@ -27,10 +27,7 @@ import { parse as _getQueryParams, parseUrl as _getQueryParamsFromUrl, } from 'query-string'; -import { - returnUndefOnError, - UnsupportedOperationError, -} from '../error/ErrorUtils'; +import { returnUndefOnError } from '../error/ErrorUtils'; /** * Unlike the download call (GET requests) which is gziped, the upload call send uncompressed data which is in megabytes realms @@ -496,21 +493,6 @@ export const downloadFile = ( } }; -export const readFileAsText = (file: File): Promise => - new Promise((resolve, reject) => { - const fileReader = new FileReader(); - fileReader.onload = (): void => { - const result = fileReader.result; - if (isString(result)) { - resolve(result); - } else { - throw new UnsupportedOperationError(`Cant read file`); - } - }; - fileReader.onerror = reject; - fileReader.readAsText(file); - }); - export const createUrlStringFromData = ( data: string, contentType: ContentType, diff --git a/packages/legend-studio/src/components/editor/side-bar/LocalChanges.tsx b/packages/legend-studio/src/components/editor/side-bar/LocalChanges.tsx index 53a1cfdf5b..c748a657c6 100644 --- a/packages/legend-studio/src/components/editor/side-bar/LocalChanges.tsx +++ b/packages/legend-studio/src/components/editor/side-bar/LocalChanges.tsx @@ -15,10 +15,10 @@ */ import { observer } from 'mobx-react-lite'; -import { clsx, PanelLoadingIndicator } from '@finos/legend-art'; +import { clsx, PanelLoadingIndicator, TimesIcon } from '@finos/legend-art'; import { EntityDiffViewState } from '../../../stores/editor-state/entity-diff-editor-state/EntityDiffViewState'; import { EntityDiffSideBarItem } from '../../editor/edit-panel/diff-editor/EntityDiffView'; -import { FaInfoCircle, FaDownload, FaUpload, FaTimes } from 'react-icons/fa'; +import { FaInfoCircle, FaDownload, FaUpload } from 'react-icons/fa'; import { MdRefresh } from 'react-icons/md'; import { GoSync } from 'react-icons/go'; import { LEGEND_STUDIO_TEST_ID } from '../../LegendStudioTestID'; @@ -29,7 +29,7 @@ import { useEditorStore } from '../EditorStoreProvider'; import { useApplicationStore } from '@finos/legend-application'; import { Dialog } from '@material-ui/core'; -const PatchLoaderEditor = observer(() => { +const PatchLoader = observer(() => { const editorStore = useEditorStore(); const localChangesState = editorStore.localChangesState; const patchState = localChangesState.patchLoaderState; @@ -88,7 +88,7 @@ const PatchLoaderEditor = observer(() => { onClick={(): void => deleteChange(value)} tabIndex={-1} > - + @@ -219,7 +219,7 @@ export const LocalChanges = observer(() => {
- {localChangesState.patchLoaderState.showModal && } + {localChangesState.patchLoaderState.showModal && }
diff --git a/packages/legend-studio/src/stores/sidebar-state/LocalChangesState.ts b/packages/legend-studio/src/stores/sidebar-state/LocalChangesState.ts index f4a7202e01..63d09fad93 100644 --- a/packages/legend-studio/src/stores/sidebar-state/LocalChangesState.ts +++ b/packages/legend-studio/src/stores/sidebar-state/LocalChangesState.ts @@ -31,8 +31,8 @@ import { HttpStatus, deleteEntry, assertTrue, - readFileAsText, UnsupportedOperationError, + readFileAsText, } from '@finos/legend-shared'; import { DATE_TIME_FORMAT, @@ -51,13 +51,6 @@ import { } from '@finos/legend-server-sdlc'; import { LEGEND_STUDIO_LOG_EVENT_TYPE } from '../LegendStudioLogEvent'; -const isValidEntityChange = (change: EntityChange): boolean => { - if (change.type !== EntityChangeType.DELETE && !change.content) { - return false; - } - return true; -}; - class PatchLoaderState { editorStore: EditorStore; sdlcState: EditorSDLCState; @@ -128,7 +121,7 @@ class PatchLoaderState { this.setPatchChanges(undefined); assertTrue( file.type === ContentType.APPLICATION_JSON, - 'Patch file expected to be of type `JSON`', + `Patch file expected to be of type 'JSON'`, ); const fileText = (yield readFileAsText(file)) as string; const entityChanges = JSON.parse(fileText) as { @@ -154,50 +147,58 @@ class PatchLoaderState { this.closeModal(); } } + applyEntityChanges( currentEntities: Entity[], entityChanges: EntityChange[], ): Entity[] { - entityChanges.filter(isValidEntityChange).forEach((change) => { - switch (change.type) { - case EntityChangeType.DELETE: - { - const elementIdx = currentEntities.findIndex( + entityChanges + .filter((change: EntityChange) => { + if (change.type !== EntityChangeType.DELETE && !change.content) { + return false; + } + return true; + }) + .forEach((change) => { + switch (change.type) { + case EntityChangeType.DELETE: + { + const elementIdx = currentEntities.findIndex( + (e) => e.path === change.entityPath, + ); + if (elementIdx !== -1) { + currentEntities.splice(elementIdx, 1); + } + } + break; + case EntityChangeType.CREATE: + { + if (!currentEntities.find((e) => e.path === change.entityPath)) { + const entity = new Entity(); + entity.content = change.content ?? {}; + entity.path = change.entityPath; + entity.classifierPath = change.classifierPath ?? ''; + currentEntities.push(entity); + } + } + break; + case EntityChangeType.MODIFY: { + const entity = currentEntities.find( (e) => e.path === change.entityPath, ); - if (elementIdx !== -1) { - currentEntities.splice(elementIdx, 1); - } - } - break; - case EntityChangeType.CREATE: - { - if (!currentEntities.find((e) => e.path === change.entityPath)) { - const entity = new Entity(); + if (entity) { entity.content = change.content ?? {}; - entity.path = change.entityPath; entity.classifierPath = change.classifierPath ?? ''; - currentEntities.push(entity); } + break; } - break; - case EntityChangeType.MODIFY: { - const entity = currentEntities.find( - (e) => e.path === change.entityPath, - ); - if (entity) { - entity.content = change.content ?? {}; - entity.classifierPath = change.classifierPath ?? ''; - } - break; + default: + throw new UnsupportedOperationError( + `Can't apply entity change`, + change, + ); } - default: - throw new UnsupportedOperationError( - `Can't apply entity change`, - change, - ); - } - }); + }); return currentEntities; } }