From f332d951bf7a9ea9c0ff9171fc3e8cdc17ed7e70 Mon Sep 17 00:00:00 2001 From: Lucie <25330882+lihbr@users.noreply.github.com> Date: Tue, 24 Oct 2023 12:10:26 +0200 Subject: [PATCH] fix(slice-machine): reconcile state from filesystem when possible (#1100,DT-1705) (#1187) Co-authored-by: lihbr --- .../slice-machine/src/hooks/useServerState.ts | 66 +++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/packages/slice-machine/src/hooks/useServerState.ts b/packages/slice-machine/src/hooks/useServerState.ts index 061077da22..afb7631123 100644 --- a/packages/slice-machine/src/hooks/useServerState.ts +++ b/packages/slice-machine/src/hooks/useServerState.ts @@ -1,22 +1,79 @@ import { useEffect, useCallback } from "react"; +import * as Sentry from "@sentry/nextjs"; +import { useSelector } from "react-redux"; +import useSwr from "swr"; -import ServerState from "@lib/models/server/ServerState"; +import { hasLocal } from "@lib/models/common/ModelData"; import useSliceMachineActions from "@src/modules/useSliceMachineActions"; +import { isSelectedSliceTouched } from "@src/modules/selectedSlice/selectors"; +import { isSelectedCustomTypeTouched } from "@src/modules/selectedCustomType"; +import { SliceMachineStoreType } from "@src/redux/type"; +import ServerState from "@lib/models/server/ServerState"; import { getState } from "@src/apiClient"; -import useSwr from "swr"; -import * as Sentry from "@sentry/nextjs"; const useServerState = () => { - const { refreshState } = useSliceMachineActions(); + const { refreshState, initSliceStore, initCustomTypeStore } = + useSliceMachineActions(); // eslint-disable-next-line react-hooks/exhaustive-deps const handleRefreshState = useCallback(refreshState, []); const { data: serverState } = useSwr("getState", async () => { return await getState(); }); + // Whether or not current slice or custom type builder is touched, and its related server state. + const { + selectedSlice, + sliceIsTouched, + selectedCustomType, + customTypeIsTouched, + } = useSelector((store: SliceMachineStoreType) => ({ + selectedSlice: store.selectedSlice, + sliceIsTouched: isSelectedSliceTouched( + store, + store.selectedSlice?.from ?? "", + store.selectedSlice?.model.id ?? "", + ), + selectedCustomType: Boolean(store.selectedCustomType?.initialModel.id) + ? store.availableCustomTypes[ + store.selectedCustomType?.initialModel.id ?? "" + ] + : null, + customTypeIsTouched: isSelectedCustomTypeTouched(store), + })); + useEffect(() => { let canceled = false; if (serverState && !canceled) { + // If slice builder is untouched, update from server state. + if (selectedSlice && !sliceIsTouched) { + const serverSlice = serverState.libraries + .find((l) => l.name === selectedSlice?.from) + ?.components.find((c) => c.model.id === selectedSlice?.model.id); + + if (serverSlice) { + initSliceStore(serverSlice); + } + } + + // If custom type builder is untouched, update from server state. + if ( + selectedCustomType && + hasLocal(selectedCustomType) && + !customTypeIsTouched + ) { + const serverCustomType = serverState.customTypes.find( + (customType) => customType.id === selectedCustomType.local.id, + ); + + if (serverCustomType) { + const remoteCustomType = serverState.remoteCustomTypes.find( + (customType) => customType.id === selectedCustomType.local.id, + ); + + initCustomTypeStore(serverCustomType, remoteCustomType); + } + } + handleRefreshState(serverState); Sentry.setUser({ id: serverState.env.shortId }); @@ -29,6 +86,7 @@ const useServerState = () => { return () => { canceled = true; }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [serverState, handleRefreshState]); return;