feat(versioning): implement version selection and context management across components

This commit is contained in:
2025-06-19 17:40:42 +05:30
parent 033a2799db
commit fa68118047
11 changed files with 161 additions and 31 deletions

View File

@@ -10,8 +10,8 @@ import {
import ShortcutHelper from "./shortcutHelper";
import useVersionHistoryVisibleStore, { useShortcutStore } from "../../store/builder/store";
import { usePlayButtonStore } from "../../store/usePlayButtonStore";
import { useVersionHistoryStore } from "../../store/builder/useVersionHistoryStore";
import useModuleStore, { useSubModuleStore } from "../../store/useModuleStore";
import { useVersionContext } from "../../modules/builder/version/versionContext";
const Footer: React.FC = () => {
const { logs, setIsLogListVisible } = useLogger();
@@ -22,7 +22,8 @@ const Footer: React.FC = () => {
const { setVersionHistoryVisible } = useVersionHistoryVisibleStore();
const { isPlaying } = usePlayButtonStore();
const { showShortcuts, setShowShortcuts } = useShortcutStore();
const { selectedVersion } = useVersionHistoryStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
return (
<div className="footer-container">

View File

@@ -8,9 +8,11 @@ import ComparisonResult from '../../ui/compareVersion/ComparisonResult';
import { useComparisonProduct, useMainProduct } from '../../../store/simulation/useSimulationStore';
import { usePlayButtonStore } from '../../../store/usePlayButtonStore';
import { useEffect, useState } from 'react';
import { useVersionHistoryStore } from '../../../store/builder/useVersionHistoryStore';
import { useVersionContext } from '../../../modules/builder/version/versionContext';
function ComparisonScene() {
const { isPlaying, setIsPlaying } = usePlayButtonStore();
const { isPlaying } = usePlayButtonStore();
const { products } = useProductStore();
const { isVersionSaved } = useSaveVersion();
const { activeModule } = useModuleStore();
@@ -21,6 +23,9 @@ function ComparisonScene() {
const { loadingProgress } = useLoadingProgress();
const { compareProductsData, setCompareProductsData } = useCompareProductDataStore();
const [shouldShowComparisonResult, setShouldShowComparisonResult] = useState(false);
const { versionHistory } = useVersionHistoryStore();
const { selectedVersionStore } = useVersionContext();
const { setSelectedVersion } = selectedVersionStore();
const handleSelectLayout = (option: string) => {
const product = products.find((product) => product.productName === option);
@@ -28,6 +33,13 @@ function ComparisonScene() {
setComparisonProduct(product.productUuid, product.productName);
}
};
useEffect(() => {
if (versionHistory.length > 0) {
setSelectedVersion(versionHistory[0])
}
}, [versionHistory])
// useEffect(() => {
// setCompareProductsData([
// {

View File

@@ -37,6 +37,11 @@ import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAs
import { useParams } from "react-router-dom";
import { getUserData } from "../../../functions/getUserData";
import { useSceneContext } from "../../../modules/scene/sceneContext";
import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionControl/getVersionHistoryApi";
import { useVersionHistoryStore } from "../../../store/builder/useVersionHistoryStore";
import { useVersionContext } from "../../../modules/builder/version/versionContext";
import VersionSaved from "../sidebarRight/versionHisory/VersionSaved";
import Footer from "../../footer/Footer";
function MainScene() {
const { products } = useProductStore();
@@ -59,6 +64,9 @@ function MainScene() {
const { setName } = assetStore();
const { projectId } = useParams()
const { isRenameMode, setIsRenameMode } = useRenameModeStore();
const { versionHistory } = useVersionHistoryStore();
const { selectedVersionStore } = useVersionContext();
const { setSelectedVersion } = selectedVersionStore();
const { organization } = getUserData();
useEffect(() => {
@@ -68,6 +76,12 @@ function MainScene() {
}
}, [activeModule])
useEffect(() => {
if (versionHistory.length > 0) {
setSelectedVersion(versionHistory[0])
}
}, [versionHistory])
const handleSelectLayout = (option: string) => {
const product = products.find((product) => product.productName === option);
if (product) {
@@ -99,7 +113,7 @@ function MainScene() {
{loadingProgress > 0 && <LoadingPage progress={loadingProgress} />}
{!isPlaying && (
<>
{toggleThreeD && <ModuleToggle />}
{toggleThreeD && !isVersionSaved && <ModuleToggle />}
<SideBarLeft />
<SideBarRight />
</>
@@ -156,6 +170,11 @@ function MainScene() {
/>
</div>
)}
{activeModule !== "market" && !selectedUser && <Footer />}
<VersionSaved />
</>
);
}

View File

@@ -6,25 +6,31 @@ import {
LocationIcon,
} from "../../../icons/ExportCommonIcons";
import RenameInput from "../../../ui/inputs/RenameInput";
import { getUserData } from "../../../../functions/getUserData";
import { useParams } from "react-router-dom";
import { useVersionHistoryStore } from "../../../../store/builder/useVersionHistoryStore";
import { useSubModuleStore } from "../../../../store/useModuleStore";
import useVersionHistoryVisibleStore from "../../../../store/builder/store";
import { useParams } from "react-router-dom";
import { getVersionDataApi } from "../../../../services/factoryBuilder/versionControl/getVersionDataApi";
import { useVersionContext } from "../../../../modules/builder/version/versionContext";
const VersionHistory = () => {
const { userName } = getUserData();
const { setSubModule } = useSubModuleStore();
const { setVersionHistoryVisible } = useVersionHistoryVisibleStore();
const { versionHistory, addVersion, selectedVersion, setSelectedVersion, setCreateNewVersion } = useVersionHistoryStore();
const { versionHistory, setCreateNewVersion } = useVersionHistoryStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { projectId } = useParams();
const addNewVersion = () => {
setCreateNewVersion(true);
};
const handleSelectVersion = (version: any) => {
const handleSelectVersion = (version: Version) => {
if (!projectId) return;
getVersionDataApi(projectId, version.versionId).then((verdionData) => {
console.log(verdionData);
})
};
const handleVersionNameChange = (newName: string, versionId: string) => {

View File

@@ -8,9 +8,12 @@ import { useVersionHistoryStore } from "../../../../store/builder/useVersionHist
import { createVersionApi } from "../../../../services/factoryBuilder/versionControl/addVersionApi";
import { useParams } from "react-router-dom";
import { getUserData } from "../../../../functions/getUserData";
import { useVersionContext } from "../../../../modules/builder/version/versionContext";
const VersionSaved = () => {
const { versionHistory, addVersion, createNewVersion, setCreateNewVersion, setSelectedVersion } = useVersionHistoryStore();
const { versionHistory, addVersion, createNewVersion, setCreateNewVersion } = useVersionHistoryStore();
const { selectedVersionStore } = useVersionContext();
const { setSelectedVersion } = selectedVersionStore();
const [newName, setNewName] = useState(new Date().toLocaleString("en-US", {
month: "short",
day: "numeric",

View File

@@ -204,16 +204,18 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
}
};
document.addEventListener('mousedown', onMouseDown);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
if (selectedZone.zoneName! === '' && activeModule === 'Builder') {
document.addEventListener('mousedown', onMouseDown);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
}
return () => {
document.removeEventListener('mousedown', onMouseDown);
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
}, []);
}, [selectedZone, activeModule]);
return (

View File

@@ -0,0 +1,37 @@
import { createContext, useContext, useMemo } from 'react';
import { createSelectedVersionStore, SelectedVersionType } from '../../../store/simulation/useSimulationStore';
type VersionContextValue = {
selectedVersionStore: SelectedVersionType,
};
const VersionContext = createContext<VersionContextValue | null>(null);
export function VersionProvider({
children,
}: {
readonly children: React.ReactNode;
}) {
const selectedVersionStore = useMemo(() => createSelectedVersionStore(), []);
const contextValue = useMemo(() => (
{
selectedVersionStore
}
), [selectedVersionStore]);
return (
<VersionContext.Provider value={contextValue}>
{children}
</VersionContext.Provider>
);
}
// Base hook to get the context
export function useVersionContext() {
const context = useContext(VersionContext);
if (!context) {
throw new Error('useVersionContext must be used within a VersionProvider');
}
return context;
}

View File

@@ -15,9 +15,7 @@ import FollowPerson from "../components/templates/FollowPerson";
import { useLogger } from "../components/ui/log/LoggerContext";
import RenderOverlay from "../components/templates/Overlay";
import LogList from "../components/ui/log/LogList";
import Footer from "../components/footer/Footer";
import { useToggleStore } from "../store/useUIToggleStore";
import VersionSaved from "../components/layout/sidebarRight/versionHisory/VersionSaved";
import { useProductStore } from "../store/simulation/useProductStore";
import { getAllProjects } from "../services/dashboard/getAllProjects";
import { viewProject } from "../services/dashboard/viewProject";
@@ -27,12 +25,13 @@ import { getUserData } from "../functions/getUserData";
import { SceneProvider } from "../modules/scene/sceneContext";
import { getVersionHistoryApi } from "../services/factoryBuilder/versionControl/getVersionHistoryApi";
import { useVersionHistoryStore } from "../store/builder/useVersionHistoryStore";
import { VersionProvider } from "../modules/builder/version/versionContext";
const Project: React.FC = () => {
let navigate = useNavigate();
const echo = useLogger();
const { setToggleUI } = useToggleStore();
const { activeModule, setActiveModule } = useModuleStore();
const { setActiveModule } = useModuleStore();
const { setUserName } = useUserName();
const { setOrganization } = useOrganization();
const { setWallItems } = useWallItems();
@@ -44,7 +43,7 @@ const Project: React.FC = () => {
const { userId, email, organization, userName } = getUserData();
const { selectedUser } = useSelectedUserStore();
const { isLogListVisible } = useLogger();
const { setVersions, setSelectedVersion } = useVersionHistoryStore();
const { setVersions } = useVersionHistoryStore();
useEffect(() => {
if (!email || !userId) {
@@ -76,7 +75,6 @@ const Project: React.FC = () => {
})
})
setVersions(versions);
setSelectedVersion(versions[0])
})
}, [projectId])
@@ -111,10 +109,14 @@ const Project: React.FC = () => {
return (
<div className="project-main">
<SceneProvider layout="Main Layout">
<MainSceneProvider />
<VersionProvider>
<MainSceneProvider />
</VersionProvider>
</SceneProvider>
<SceneProvider layout="Comparison Layout">
<ComparisonSceneProvider />
<VersionProvider>
<ComparisonSceneProvider />
</VersionProvider>
</SceneProvider>
{selectedUser && <FollowPerson />}
{isLogListVisible && (
@@ -122,8 +124,6 @@ const Project: React.FC = () => {
<LogList />
</RenderOverlay>
)}
{activeModule !== "market" && !selectedUser && <Footer />}
<VersionSaved />
</div>
);
};

View File

@@ -0,0 +1,32 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const getVersionDataApi = async (projectId: string, versionId: string) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/V1/version/${versionId}/${projectId}`,
{
method: "GET",
headers: {
Authorization: "Bearer <access_token>",
"Content-Type": "application/json",
token: localStorage.getItem("token") || "",
refresh_token: localStorage.getItem("refreshToken") || "",
}
}
);
if (!response.ok) {
throw new Error("Failed to get Version Data");
}
const result = await response.json();
return result;
} catch (error) {
echo.error("Failed to get Version Data");
if (error instanceof Error) {
console.log(error.message);
} else {
console.log("An unknown error occurred");
}
}
};

View File

@@ -4,10 +4,8 @@ import { immer } from 'zustand/middleware/immer';
interface VersionHistoryStore {
versionHistory: VersionHistory;
selectedVersion: Version | null;
createNewVersion: boolean;
setSelectedVersion: (version: Version | null) => void;
setCreateNewVersion: (createNewVersion: boolean) => void;
addVersion: (version: Version) => void;
@@ -26,12 +24,6 @@ export const useVersionHistoryStore = create<VersionHistoryStore>()(
selectedVersion: null,
createNewVersion: false,
setSelectedVersion: (version: Version | null) => {
set((state) => {
state.selectedVersion = version;
})
},
setCreateNewVersion: (createNewVersion: boolean) => {
set((state) => {
state.createNewVersion = createNewVersion;

View File

@@ -96,6 +96,32 @@ export const createSelectedProductStore = () => {
export type SelectedProductType = ReturnType<typeof createSelectedProductStore>;
interface SelectedVersionState {
selectedVersion: Version | null;
setSelectedVersion: (version: Version) => void;
clearSelectedVersion: () => void;
}
export const createSelectedVersionStore = () => {
return create<SelectedVersionState>()(
immer((set) => ({
selectedVersion: null,
setSelectedVersion: (version) => {
set((state) => {
state.selectedVersion = version;
});
},
clearSelectedVersion: () => {
set((state) => {
state.selectedVersion = null;
});
},
}))
)
}
export type SelectedVersionType = ReturnType<typeof createSelectedVersionStore>;
interface SelectedActionState {
selectedAction: { actionId: string | null; actionName: string | null };
setSelectedAction: (actionId: string, actionName: string) => void;