Develop Ui for Version history
This commit is contained in:
parent
8a0539d595
commit
21ff522f67
|
@ -0,0 +1,7 @@
|
|||
import React from "react";
|
||||
|
||||
const ShortcutHelper = () => {
|
||||
return <div className="shirtcut-helper-container"></div>;
|
||||
};
|
||||
|
||||
export default ShortcutHelper;
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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;
|
|
@ -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);
|
||||
}}
|
||||
>
|
||||
|
|
|
@ -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>>(
|
||||
{}
|
||||
|
@ -23,7 +28,7 @@ const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
|
|||
}));
|
||||
};
|
||||
|
||||
function handleThemeChange(){
|
||||
function handleThemeChange() {
|
||||
toggleTheme();
|
||||
window.location.reload();
|
||||
}
|
||||
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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%;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue