Develop Ui for Version history

This commit is contained in:
Nalvazhuthi 2025-05-12 18:01:45 +05:30
parent 8a0539d595
commit 21ff522f67
8 changed files with 354 additions and 13 deletions

View File

@ -0,0 +1,7 @@
import React from "react";
const ShortcutHelper = () => {
return <div className="shirtcut-helper-container"></div>;
};
export default ShortcutHelper;

View File

@ -947,3 +947,22 @@ export const ErrorIcon = () => {
</svg>
);
};
export const LocationIcon = () => {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M3 9.45984L10.4205 9.98901L11.085 17.5L18 2.5L3 9.45984Z"
fill="white"
/>
</svg>
);
};

View File

@ -13,7 +13,9 @@ import useToggleStore from "../../../store/useUIToggleStore";
import Visualization from "./visualization/Visualization";
import Analysis from "./analysis/Analysis";
import Simulations from "./simulation/Simulations";
import { useSelectedFloorItem } from "../../../store/store";
import useVersionHistoryStore, {
useSelectedFloorItem,
} from "../../../store/store";
import {
useSelectedEventData,
useSelectedEventSphere,
@ -22,6 +24,7 @@ import GlobalProperties from "./properties/GlobalProperties";
import AsstePropertiies from "./properties/AssetProperties";
import ZoneProperties from "./properties/ZoneProperties";
import EventProperties from "./properties/eventProperties/EventProperties";
import VersionHistory from "./versionHisory/VersionHistory";
const SideBarRight: React.FC = () => {
const { activeModule } = useModuleStore();
@ -30,6 +33,7 @@ const SideBarRight: React.FC = () => {
const { selectedFloorItem } = useSelectedFloorItem();
const { selectedEventData } = useSelectedEventData();
const { selectedEventSphere } = useSelectedEventSphere();
const { viewVersionHistory, setVersionHistory } = useVersionHistoryStore();
// Reset activeList whenever activeModule changes
useEffect(() => {
@ -64,7 +68,10 @@ const SideBarRight: React.FC = () => {
className={`sidebar-action-list ${
subModule === "properties" ? "active" : ""
}`}
onClick={() => setSubModule("properties")}
onClick={() => {
setSubModule("properties");
setVersionHistory(false);
}}
>
<div className="tooltip">properties</div>
<PropertiesIcon isActive={subModule === "properties"} />
@ -76,7 +83,10 @@ const SideBarRight: React.FC = () => {
className={`sidebar-action-list ${
subModule === "simulations" ? "active" : ""
}`}
onClick={() => setSubModule("simulations")}
onClick={() => {
setSubModule("simulations");
setVersionHistory(false);
}}
>
<div className="tooltip">simulations</div>
<SimulationIcon isActive={subModule === "simulations"} />
@ -85,7 +95,10 @@ const SideBarRight: React.FC = () => {
className={`sidebar-action-list ${
subModule === "mechanics" ? "active" : ""
}`}
onClick={() => setSubModule("mechanics")}
onClick={() => {
setSubModule("mechanics");
setVersionHistory(false);
}}
>
<div className="tooltip">mechanics</div>
<MechanicsIcon isActive={subModule === "mechanics"} />
@ -94,7 +107,10 @@ const SideBarRight: React.FC = () => {
className={`sidebar-action-list ${
subModule === "analysis" ? "active" : ""
}`}
onClick={() => setSubModule("analysis")}
onClick={() => {
setSubModule("analysis");
setVersionHistory(false);
}}
>
<div className="tooltip">analysis</div>
<AnalysisIcon isActive={subModule === "analysis"} />
@ -103,8 +119,18 @@ const SideBarRight: React.FC = () => {
)}
</div>
)}
{toggleUI && viewVersionHistory && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<VersionHistory />
</div>
</div>
)}
{/* process builder */}
{toggleUI &&
!viewVersionHistory &&
subModule === "properties" &&
activeModule !== "visualization" &&
!selectedFloorItem && (
@ -115,6 +141,7 @@ const SideBarRight: React.FC = () => {
</div>
)}
{toggleUI &&
!viewVersionHistory &&
subModule === "properties" &&
activeModule !== "visualization" &&
selectedFloorItem && (
@ -124,7 +151,9 @@ const SideBarRight: React.FC = () => {
</div>
</div>
)}
{toggleUI &&
!viewVersionHistory &&
subModule === "zoneProperties" &&
(activeModule === "builder" || activeModule === "simulation") && (
<div className="sidebar-right-container">
@ -134,7 +163,7 @@ const SideBarRight: React.FC = () => {
</div>
)}
{/* simulation */}
{toggleUI && activeModule === "simulation" && (
{toggleUI && !viewVersionHistory && activeModule === "simulation" && (
<>
{subModule === "simulations" && (
<div className="sidebar-right-container">

View File

@ -0,0 +1,116 @@
import React, { useState } from "react";
import {
AddIcon,
CloseIcon,
KebabIcon,
LocationIcon,
} from "../../../icons/ExportCommonIcons";
const VersionHistory = () => {
// Start with only v1.0
const initialVersions = [
{
versionName: "v1.0",
timestamp: "April 09, 2025",
savedBy: "Nanni",
},
];
const [versions, setVersions] = useState(initialVersions);
const [selectedVersion, setSelectedVersion] = useState(initialVersions[0]);
const userName = localStorage.getItem("userName") ?? "Anonymous";
// Function to simulate adding a new version
const addNewVersion = () => {
const newVersionNumber = versions.length + 1;
const newVersion = {
versionName: `v${newVersionNumber}.0`,
timestamp: new Date().toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "2-digit",
}),
savedBy: userName, // Simulate user name
};
const updated = [newVersion, ...versions];
setVersions(updated);
setSelectedVersion(newVersion);
};
// Handle user selecting a version
const handleSelectVersion = (version: any) => {
setSelectedVersion(version);
const reordered = [version, ...versions.filter((v) => v !== version)];
setVersions(reordered);
};
return (
<div className="version-history-container">
{/* Header */}
<div className="version-history-header">
<div className="version-history-title">Version History</div>
<div className="version-history-icons">
<button
className="icon add-icon"
onClick={addNewVersion}
style={{ cursor: "pointer" }}
>
<AddIcon />
</button>
<div className="icon kebab-icon">
<KebabIcon />
</div>
<div className="icon close-icon">
<CloseIcon />
</div>
</div>
</div>
{/* Shortcut Info */}
<div className="version-history-shortcut-info">
<div className="info-icon">i</div>
<div className="shortcut-text">
Press Ctrl + Alt + S to add to version history while editing
</div>
</div>
{/* Current Version Display */}
<div className="version-history-location">
<div className="location-label">
<LocationIcon />
</div>
<div className="location-details">
<div className="current-version">
Current Version ({selectedVersion.versionName})
</div>
<div className="saved-history-count">
{versions.length} Saved History
</div>
</div>
</div>
{/* Versions List */}
<div className="saved-versions-list">
{versions.map((version, index) => (
<button
key={index}
className={"saved-version"}
onClick={() => handleSelectVersion(version)}
>
<div className="version-name">{version.versionName}</div>
<div className="version-details">
<span className="timestamp">{version.timestamp}</span>
<span className="saved-by">
<div className="user-profile">{userName[0]}</div>
<div className="user-name">{version.savedBy}</div>
</span>
</div>
</button>
))}
</div>
</div>
);
};
export default VersionHistory;

View File

@ -7,10 +7,12 @@ import {
VisualizationIcon,
} from "../icons/ExportModuleIcons";
import useToggleStore from "../../store/useUIToggleStore";
import useVersionHistoryStore from "../../store/store";
const ModuleToggle: React.FC = () => {
const { activeModule, setActiveModule } = useModuleStore();
const { setToggleUI } = useToggleStore();
const { setVersionHistory } = useVersionHistoryStore();
return (
<div className="module-toggle-container">
@ -18,6 +20,7 @@ const ModuleToggle: React.FC = () => {
className={`module-list ${activeModule === "builder" ? "active" : ""}`}
onClick={() => {
setActiveModule("builder");
setVersionHistory(false);
setToggleUI(
localStorage.getItem("navBarUi")
? localStorage.getItem("navBarUi") === "true"
@ -36,6 +39,7 @@ const ModuleToggle: React.FC = () => {
}`}
onClick={() => {
setActiveModule("simulation");
setVersionHistory(false);
setToggleUI(
localStorage.getItem("navBarUi")
? localStorage.getItem("navBarUi") === "true"
@ -54,6 +58,7 @@ const ModuleToggle: React.FC = () => {
}`}
onClick={() => {
setActiveModule("visualization");
setVersionHistory(false);
setToggleUI(
localStorage.getItem("navBarUi")
? localStorage.getItem("navBarUi") === "true"
@ -70,6 +75,7 @@ const ModuleToggle: React.FC = () => {
className={`module-list ${activeModule === "market" ? "active" : ""}`}
onClick={() => {
setActiveModule("market");
setVersionHistory(false);
setToggleUI(false);
}}
>

View File

@ -1,6 +1,8 @@
import React, { useState } from "react";
import { ArrowIcon } from "../../icons/ExportCommonIcons";
import { toggleTheme } from "../../../utils/theme";
import useVersionHistoryStore from "../../../store/store";
import { useSubModuleStore } from "../../../store/useModuleStore";
interface MenuBarProps {
setOpenMenu: (isOpen: boolean) => void; // Function to update menu state
@ -10,6 +12,9 @@ const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
const [activeMenu, setActiveMenu] = useState<string | null>(null);
const [activeSubMenu, setActiveSubMenu] = useState<string | null>(null);
const { viewVersionHistory, setVersionHistory } = useVersionHistoryStore();
const { subModule, setSubModule } = useSubModuleStore();
// State to track selection for all menu items
const [selectedItems, setSelectedItems] = useState<Record<string, boolean>>(
{}
@ -373,6 +378,10 @@ const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
setActiveMenu(null);
setActiveSubMenu(null);
}}
onClick={() => {
setVersionHistory(true);
setSubModule("properties");
}}
>
<div className="menu-button">Version history</div>
</div>

View File

@ -435,3 +435,15 @@ export const useZoneAssetId = create<ZoneAssetState>((set) => ({
zoneAssetId: null,
setZoneAssetId: (asset) => set({ zoneAssetId: asset }),
}));
interface VersionHistoryState {
viewVersionHistory: boolean;
setVersionHistory: (value: boolean) => void;
}
const useVersionHistoryStore = create<VersionHistoryState>((set) => ({
viewVersionHistory: false,
setVersionHistory: (value) => set({ viewVersionHistory: value }),
}));
export default useVersionHistoryStore;

View File

@ -456,6 +456,144 @@
position: relative;
width: 304px;
.version-history-container {
max-height: calc(62vh - 12px);
display: flex;
flex-direction: column;
padding: 0 8px;
gap: 10px;
.version-history-header {
display: flex;
justify-content: space-between;
align-items: center;
.version-history-icons {
display: flex;
align-items: center;
gap: 6px;
.kebab-icon {
transform: rotate(90deg);
}
}
}
.version-history-shortcut-info {
display: flex;
gap: 6px;
border: 1px solid var(--border-color);
background: var(--background-color);
padding: 10px 8px;
border-radius: 13px;
.info-icon {
width: 12px;
height: 12px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
border: 1px solid var(--border-color);
padding: 4px;
font-size: 10px;
}
.shortcut-text {
color: var(--text-disabled);
}
}
.version-history-location {
display: flex;
align-items: center;
gap: 6px;
.location-details {
display: flex;
flex-direction: column;
gap: 4px;
.saved-history-count {
font-size: var(--font-size-tiny)
}
}
}
.saved-versions-list {
padding-top: 16px;
display: flex;
flex-direction: column;
gap: 20px;
.saved-version {
display: flex;
align-items: center;
gap: 12px;
.version-name {
background: var(--background-color);
border: 1px solid var(--border-color);
color: var(--text-color);
border-radius: 13px;
padding: 4px 8px;
position: relative;
/* Ensure position relative for ::after */
}
&:not(:first-child) .version-name::after {
content: "";
position: absolute;
top: -35px;
left: 50%;
transform: translateX(-50%);
width: 1px;
height: 32px;
background-color: var(--text-disabled);
}
.version-details {
display: flex;
flex-direction: column;
gap: 6px;
.saved-by {
display: flex;
align-items: center;
gap: 6px;
.user-profile {
background: var(--background-color-accent);
color: var(--text-button-color);
width: 20px;
height: 20px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
text-transform: uppercase;
}
.user-name {
text-transform: capitalize;
}
}
.timestamp {
text-align: start;
}
}
}
}
}
.no-event-selected {
color: #666;
padding: 16px;
@ -513,6 +651,7 @@
max-height: 60vh;
.sidebar-right-content-container {
.dataSideBar {
.inputs-wrapper {
display: flex;
@ -995,6 +1134,7 @@
margin: 6px 0;
padding-left: 16px;
position: relative;
&::after {
content: "";
rotate: -90deg;
@ -1009,6 +1149,7 @@
top: 0;
left: 4px;
}
&:last-child {
&::after {
display: none;
@ -1462,11 +1603,9 @@
width: 100%;
height: 100%;
font-size: var(--font-size-regular);
background: linear-gradient(
0deg,
background: linear-gradient(0deg,
rgba(37, 24, 51, 0) 0%,
rgba(52, 41, 61, 0.5) 100%
);
rgba(52, 41, 61, 0.5) 100%);
pointer-events: none;
backdrop-filter: blur(8px);
opacity: 0;
@ -1519,6 +1658,7 @@
.sidebar-right-wrapper.open {
height: fit-content;
animation: openSidebar 0.2s linear;
.sidebar-right-container,
.sidebar-left-container {
opacity: 0;
@ -1530,6 +1670,7 @@
from {
opacity: 0;
}
to {
opacity: 1;
}
@ -1539,6 +1680,7 @@
from {
height: 60%;
}
to {
height: 52px;
}
@ -1548,6 +1690,7 @@
from {
height: 52px;
}
to {
height: 60%;
}