diff --git a/app/src/components/footer/shortcutHelper.tsx b/app/src/components/footer/shortcutHelper.tsx
new file mode 100644
index 0000000..af6dacd
--- /dev/null
+++ b/app/src/components/footer/shortcutHelper.tsx
@@ -0,0 +1,7 @@
+import React from "react";
+
+const ShortcutHelper = () => {
+ return
diff --git a/app/src/components/layout/sidebarRight/versionHisory/VersionHistory.tsx b/app/src/components/layout/sidebarRight/versionHisory/VersionHistory.tsx
new file mode 100644
index 0000000..9e49b48
--- /dev/null
+++ b/app/src/components/layout/sidebarRight/versionHisory/VersionHistory.tsx
@@ -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 (
+
+ {/* Header */}
+
+
+ {/* Shortcut Info */}
+
+
i
+
+ Press Ctrl + Alt + S to add to version history while editing
+
+
+
+ {/* Current Version Display */}
+
+
+
+
+
+
+ Current Version ({selectedVersion.versionName})
+
+
+ {versions.length} Saved History
+
+
+
+
+ {/* Versions List */}
+
+ {versions.map((version, index) => (
+
+ ))}
+
+
+ );
+};
+
+export default VersionHistory;
diff --git a/app/src/components/ui/ModuleToggle.tsx b/app/src/components/ui/ModuleToggle.tsx
index a1583e1..63a11ee 100644
--- a/app/src/components/ui/ModuleToggle.tsx
+++ b/app/src/components/ui/ModuleToggle.tsx
@@ -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 (
@@ -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);
}}
>
diff --git a/app/src/components/ui/menu/menu.tsx b/app/src/components/ui/menu/menu.tsx
index 39508b6..c5f24a9 100644
--- a/app/src/components/ui/menu/menu.tsx
+++ b/app/src/components/ui/menu/menu.tsx
@@ -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
= ({ setOpenMenu }) => {
const [activeMenu, setActiveMenu] = useState(null);
const [activeSubMenu, setActiveSubMenu] = useState(null);
+ const { viewVersionHistory, setVersionHistory } = useVersionHistoryStore();
+ const { subModule, setSubModule } = useSubModuleStore();
+
// State to track selection for all menu items
const [selectedItems, setSelectedItems] = useState>(
{}
@@ -23,7 +28,7 @@ const MenuBar: React.FC = ({ setOpenMenu }) => {
}));
};
- function handleThemeChange(){
+ function handleThemeChange() {
toggleTheme();
window.location.reload();
}
@@ -373,6 +378,10 @@ const MenuBar: React.FC = ({ setOpenMenu }) => {
setActiveMenu(null);
setActiveSubMenu(null);
}}
+ onClick={() => {
+ setVersionHistory(true);
+ setSubModule("properties");
+ }}
>
Version history
diff --git a/app/src/store/store.ts b/app/src/store/store.ts
index 61d84d5..35ccdd5 100644
--- a/app/src/store/store.ts
+++ b/app/src/store/store.ts
@@ -435,3 +435,15 @@ export const useZoneAssetId = create
((set) => ({
zoneAssetId: null,
setZoneAssetId: (asset) => set({ zoneAssetId: asset }),
}));
+
+interface VersionHistoryState {
+ viewVersionHistory: boolean;
+ setVersionHistory: (value: boolean) => void;
+}
+
+const useVersionHistoryStore = create((set) => ({
+ viewVersionHistory: false,
+ setVersionHistory: (value) => set({ viewVersionHistory: value }),
+}));
+
+export default useVersionHistoryStore;
diff --git a/app/src/styles/layout/sidebar.scss b/app/src/styles/layout/sidebar.scss
index 4d321d4..efa77a3 100644
--- a/app/src/styles/layout/sidebar.scss
+++ b/app/src/styles/layout/sidebar.scss
@@ -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,
- rgba(37, 24, 51, 0) 0%,
- rgba(52, 41, 61, 0.5) 100%
- );
+ background: linear-gradient(0deg,
+ rgba(37, 24, 51, 0) 0%,
+ 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,7 +1690,8 @@
from {
height: 52px;
}
+
to {
height: 60%;
}
-}
+}
\ No newline at end of file