From 1f896dded49b804cffe3343c52f7629e179d14d6 Mon Sep 17 00:00:00 2001
From: Guste Gaubaite <219.guste@gmail.com>
Date: Tue, 21 Oct 2025 13:56:04 +0200
Subject: [PATCH 01/11] refactor(#558): Remove add collection and relation
 buttons from toolbar
---
 .../add-collection.component.tsx              | 55 -------------------
 .../components/add-collection/index.ts        |  1 -
 src/pods/toolbar/components/index.ts          |  2 -
 .../components/relation-button/index.ts       |  1 -
 .../relation-button.component.tsx             | 45 ---------------
 src/pods/toolbar/toolbar.pod.tsx              |  4 --
 6 files changed, 108 deletions(-)
 delete mode 100644 src/pods/toolbar/components/add-collection/add-collection.component.tsx
 delete mode 100644 src/pods/toolbar/components/add-collection/index.ts
 delete mode 100644 src/pods/toolbar/components/relation-button/index.ts
 delete mode 100644 src/pods/toolbar/components/relation-button/relation-button.component.tsx
diff --git a/src/pods/toolbar/components/add-collection/add-collection.component.tsx b/src/pods/toolbar/components/add-collection/add-collection.component.tsx
deleted file mode 100644
index 43e8a002..00000000
--- a/src/pods/toolbar/components/add-collection/add-collection.component.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import { useModalDialogContext } from '@/core/providers/modal-dialog-provider';
-import { EditTablePod } from '@/pods/edit-table';
-import { TableIcon } from '@/common/components/icons';
-import { useCanvasViewSettingsContext } from '@/core/providers';
-
-import {
-  TableVm,
-  useCanvasSchemaContext,
-} from '@/core/providers/canvas-schema';
-import { ADD_COLLECTION_TITLE } from '@/common/components/modal-dialog';
-import { ActionButton } from '@/common/components/action-button';
-import { SHORTCUTS } from '@/common/shortcut';
-
-const BORDER_MARGIN = 40;
-
-export const AddCollection = () => {
-  const { openModal, closeModal } = useModalDialogContext();
-  const { canvasSchema, addTable } = useCanvasSchemaContext();
-  const { canvasViewSettings, setLoadSample } = useCanvasViewSettingsContext();
-
-  const handleAddTable = (newTable: TableVm) => {
-    const updatedTable = {
-      ...newTable,
-      x: canvasViewSettings.scrollPosition.x + BORDER_MARGIN,
-      y: canvasViewSettings.scrollPosition.y + BORDER_MARGIN,
-    };
-
-    addTable(updatedTable);
-    closeModal();
-  };
-
-  const handleEditTableClick = () => {
-    setLoadSample(false);
-    openModal(
-      ,
-      ADD_COLLECTION_TITLE
-    );
-  };
-  const handleCloseModal = () => {
-    closeModal();
-  };
-  return (
-    }
-      label="Add Collection"
-      onClick={handleEditTableClick}
-      className="hide-mobile"
-      shortcutOptions={SHORTCUTS.addCollection}
-    />
-  );
-};
diff --git a/src/pods/toolbar/components/add-collection/index.ts b/src/pods/toolbar/components/add-collection/index.ts
deleted file mode 100644
index 0f5212cc..00000000
--- a/src/pods/toolbar/components/add-collection/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './add-collection.component';
diff --git a/src/pods/toolbar/components/index.ts b/src/pods/toolbar/components/index.ts
index 69373094..be8df17c 100644
--- a/src/pods/toolbar/components/index.ts
+++ b/src/pods/toolbar/components/index.ts
@@ -1,6 +1,5 @@
 export * from './theme-toggle-button';
 export * from './zoom-button';
-export * from './relation-button';
 export * from './canvas-setting-button';
 export * from './export-button';
 export * from './new-button';
@@ -9,7 +8,6 @@ export * from './save-button';
 export * from './undo-button';
 export * from './redo-button';
 export * from './delete-button';
-export * from './add-collection';
 export * from './about-button';
 export * from './duplicate-button';
 export * from './copy-button';
diff --git a/src/pods/toolbar/components/relation-button/index.ts b/src/pods/toolbar/components/relation-button/index.ts
deleted file mode 100644
index bc45f398..00000000
--- a/src/pods/toolbar/components/relation-button/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './relation-button.component';
diff --git a/src/pods/toolbar/components/relation-button/relation-button.component.tsx b/src/pods/toolbar/components/relation-button/relation-button.component.tsx
deleted file mode 100644
index 6010ed05..00000000
--- a/src/pods/toolbar/components/relation-button/relation-button.component.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import { useModalDialogContext } from '@/core/providers/modal-dialog-provider';
-import { EditRelationPod } from '@/pods/edit-relation';
-import { Relation } from '@/common/components/icons';
-import { ADD_RELATION_TITLE } from '@/common/components';
-import {
-  RelationVm,
-  useCanvasSchemaContext,
-} from '@/core/providers/canvas-schema';
-import { ActionButton } from '@/common/components/action-button';
-import { SHORTCUTS } from '@/common/shortcut';
-
-export const RelationButton = () => {
-  const { openModal, closeModal } = useModalDialogContext();
-  const { canvasSchema, addRelation } = useCanvasSchemaContext();
-
-  const handleChangeCanvasSchema = (relation: RelationVm) => {
-    addRelation(relation);
-    closeModal();
-  };
-  const handleCloseEditRelation = () => {
-    closeModal();
-  };
-
-  const handleRelationClick = () => {
-    openModal(
-      ,
-      ADD_RELATION_TITLE
-    );
-  };
-
-  return (
-    }
-      label="Add Relation"
-      onClick={handleRelationClick}
-      className="hide-mobile"
-      shortcutOptions={SHORTCUTS.addRelation}
-      disabled={canvasSchema.tables.length < 1}
-    />
-  );
-};
diff --git a/src/pods/toolbar/toolbar.pod.tsx b/src/pods/toolbar/toolbar.pod.tsx
index 1db89408..98d21997 100644
--- a/src/pods/toolbar/toolbar.pod.tsx
+++ b/src/pods/toolbar/toolbar.pod.tsx
@@ -3,8 +3,6 @@ import {
   // CanvasSettingButton,
   ZoomInButton,
   ZoomOutButton,
-  RelationButton,
-  AddCollection,
   ThemeToggleButton,
   ExportButton,
   NewButton,
@@ -29,9 +27,7 @@ export const ToolbarPod: React.FC = () => {
       
       
       
-      
       
-      
       
       
       
From 0c838f26f517e40bd23301ea25ef5b883422d4b9 Mon Sep 17 00:00:00 2001
From: Guste Gaubaite <219.guste@gmail.com>
Date: Tue, 21 Oct 2025 13:57:25 +0200
Subject: [PATCH 02/11] feat(#558): create and add floating bar component,
 integrate with main scene (desktop only)
---
 .../add-collection.component.tsx              | 58 +++++++++++++++++++
 .../components/add-collection/index.ts        |  1 +
 .../floating-bar-components.module.css        | 13 +++++
 src/pods/floating-bar/components/index.ts     |  2 +
 .../components/relation-button/index.ts       |  1 +
 .../relation-button.component.tsx             | 48 +++++++++++++++
 .../floating-bar/floating-bar.component.tsx   | 16 +++++
 .../floating-bar/floating-bar.pod.module.css  | 21 +++++++
 src/pods/floating-bar/floating-bar.pod.tsx    |  9 +++
 src/pods/floating-bar/index.ts                |  1 +
 src/scenes/main.scene.tsx                     |  5 +-
 11 files changed, 174 insertions(+), 1 deletion(-)
 create mode 100644 src/pods/floating-bar/components/add-collection/add-collection.component.tsx
 create mode 100644 src/pods/floating-bar/components/add-collection/index.ts
 create mode 100644 src/pods/floating-bar/components/floating-bar-components.module.css
 create mode 100644 src/pods/floating-bar/components/index.ts
 create mode 100644 src/pods/floating-bar/components/relation-button/index.ts
 create mode 100644 src/pods/floating-bar/components/relation-button/relation-button.component.tsx
 create mode 100644 src/pods/floating-bar/floating-bar.component.tsx
 create mode 100644 src/pods/floating-bar/floating-bar.pod.module.css
 create mode 100644 src/pods/floating-bar/floating-bar.pod.tsx
 create mode 100644 src/pods/floating-bar/index.ts
diff --git a/src/pods/floating-bar/components/add-collection/add-collection.component.tsx b/src/pods/floating-bar/components/add-collection/add-collection.component.tsx
new file mode 100644
index 00000000..be779cb7
--- /dev/null
+++ b/src/pods/floating-bar/components/add-collection/add-collection.component.tsx
@@ -0,0 +1,58 @@
+import { useModalDialogContext } from '@/core/providers/modal-dialog-provider';
+import { EditTablePod } from '@/pods/edit-table';
+import { TableIcon } from '@/common/components/icons';
+import { useCanvasViewSettingsContext } from '@/core/providers';
+
+import {
+  TableVm,
+  useCanvasSchemaContext,
+} from '@/core/providers/canvas-schema';
+import { ADD_COLLECTION_TITLE } from '@/common/components/modal-dialog';
+import { ActionButton } from '@/common/components/action-button';
+import { SHORTCUTS } from '@/common/shortcut';
+import classes from '../floating-bar-components.module.css';
+
+const BORDER_MARGIN = 40;
+
+export const AddCollection = () => {
+  const { openModal, closeModal } = useModalDialogContext();
+  const { canvasSchema, addTable } = useCanvasSchemaContext();
+  const { canvasViewSettings, setLoadSample } = useCanvasViewSettingsContext();
+
+  const handleAddTable = (newTable: TableVm) => {
+    const updatedTable = {
+      ...newTable,
+      x: canvasViewSettings.scrollPosition.x + BORDER_MARGIN,
+      y: canvasViewSettings.scrollPosition.y + BORDER_MARGIN,
+    };
+
+    addTable(updatedTable);
+    closeModal();
+  };
+
+  const handleEditTableClick = () => {
+    setLoadSample(false);
+    openModal(
+      ,
+      ADD_COLLECTION_TITLE
+    );
+  };
+  const handleCloseModal = () => {
+    closeModal();
+  };
+  return (
+    }
+      label="Add Collection"
+      onClick={handleEditTableClick}
+      className={`${classes.button} hide-mobile`}
+      shortcutOptions={SHORTCUTS.addCollection}
+      showLabel={false}
+      tooltipPosition="top"
+    />
+  );
+};
diff --git a/src/pods/floating-bar/components/add-collection/index.ts b/src/pods/floating-bar/components/add-collection/index.ts
new file mode 100644
index 00000000..0f5212cc
--- /dev/null
+++ b/src/pods/floating-bar/components/add-collection/index.ts
@@ -0,0 +1 @@
+export * from './add-collection.component';
diff --git a/src/pods/floating-bar/components/floating-bar-components.module.css b/src/pods/floating-bar/components/floating-bar-components.module.css
new file mode 100644
index 00000000..d7c157b8
--- /dev/null
+++ b/src/pods/floating-bar/components/floating-bar-components.module.css
@@ -0,0 +1,13 @@
+.button {
+  padding: 5px;
+}
+
+.button :global svg {
+  width: 1.8em;
+  height: 1.8em;
+}
+
+.button :global([role='tooltip']) {
+  transform: translate(0, -60px);
+  white-space: nowrap;
+}
diff --git a/src/pods/floating-bar/components/index.ts b/src/pods/floating-bar/components/index.ts
new file mode 100644
index 00000000..8e63fe90
--- /dev/null
+++ b/src/pods/floating-bar/components/index.ts
@@ -0,0 +1,2 @@
+export * from './add-collection';
+export * from './relation-button';
diff --git a/src/pods/floating-bar/components/relation-button/index.ts b/src/pods/floating-bar/components/relation-button/index.ts
new file mode 100644
index 00000000..bc45f398
--- /dev/null
+++ b/src/pods/floating-bar/components/relation-button/index.ts
@@ -0,0 +1 @@
+export * from './relation-button.component';
diff --git a/src/pods/floating-bar/components/relation-button/relation-button.component.tsx b/src/pods/floating-bar/components/relation-button/relation-button.component.tsx
new file mode 100644
index 00000000..79c6a72d
--- /dev/null
+++ b/src/pods/floating-bar/components/relation-button/relation-button.component.tsx
@@ -0,0 +1,48 @@
+import { useModalDialogContext } from '@/core/providers/modal-dialog-provider';
+import { EditRelationPod } from '@/pods/edit-relation';
+import { Relation } from '@/common/components/icons';
+import { ADD_RELATION_TITLE } from '@/common/components';
+import {
+  RelationVm,
+  useCanvasSchemaContext,
+} from '@/core/providers/canvas-schema';
+import { ActionButton } from '@/common/components/action-button';
+import { SHORTCUTS } from '@/common/shortcut';
+import classes from '../floating-bar-components.module.css';
+
+export const RelationButton = () => {
+  const { openModal, closeModal } = useModalDialogContext();
+  const { canvasSchema, addRelation } = useCanvasSchemaContext();
+
+  const handleChangeCanvasSchema = (relation: RelationVm) => {
+    addRelation(relation);
+    closeModal();
+  };
+  const handleCloseEditRelation = () => {
+    closeModal();
+  };
+
+  const handleRelationClick = () => {
+    openModal(
+      ,
+      ADD_RELATION_TITLE
+    );
+  };
+
+  return (
+    }
+      label="Add Relation"
+      onClick={handleRelationClick}
+      className={`${classes.button} hide-mobile`}
+      shortcutOptions={SHORTCUTS.addRelation}
+      disabled={canvasSchema.tables.length < 1}
+      showLabel={false}
+      tooltipPosition="top"
+    />
+  );
+};
diff --git a/src/pods/floating-bar/floating-bar.component.tsx b/src/pods/floating-bar/floating-bar.component.tsx
new file mode 100644
index 00000000..84fc7461
--- /dev/null
+++ b/src/pods/floating-bar/floating-bar.component.tsx
@@ -0,0 +1,16 @@
+import { AddCollection } from './components';
+import { RelationButton } from './components';
+import classes from './floating-bar.pod.module.css';
+
+export const FloatingBarComponent: React.FC = () => {
+  return (
+    <>
+      
+    >
+  );
+};
diff --git a/src/pods/floating-bar/floating-bar.pod.module.css b/src/pods/floating-bar/floating-bar.pod.module.css
new file mode 100644
index 00000000..d6caffd4
--- /dev/null
+++ b/src/pods/floating-bar/floating-bar.pod.module.css
@@ -0,0 +1,21 @@
+.floating-bar-container {
+  width: 100%;
+  position: fixed;
+  display: flex;
+  justify-content: center;
+  bottom: 80px;
+  z-index: 2;
+}
+
+.floating-bar {
+  position: relative;
+  height: 50px;
+  display: flex;
+  justify-content: center;
+  align-content: center;
+  padding: 6px 12px;
+  gap: var(--space-sm);
+  background-color: var(--bg-toolbar);
+  border-radius: var(--border-radius-m);
+  border: var(--border-toolbar);
+}
diff --git a/src/pods/floating-bar/floating-bar.pod.tsx b/src/pods/floating-bar/floating-bar.pod.tsx
new file mode 100644
index 00000000..c2d75712
--- /dev/null
+++ b/src/pods/floating-bar/floating-bar.pod.tsx
@@ -0,0 +1,9 @@
+import { FloatingBarComponent } from './floating-bar.component';
+
+export const FloatingBarPod: React.FC = () => {
+  return (
+    <>
+      
+    >
+  );
+};
diff --git a/src/pods/floating-bar/index.ts b/src/pods/floating-bar/index.ts
new file mode 100644
index 00000000..cfabbf59
--- /dev/null
+++ b/src/pods/floating-bar/index.ts
@@ -0,0 +1 @@
+export * from './floating-bar.pod';
diff --git a/src/scenes/main.scene.tsx b/src/scenes/main.scene.tsx
index 2c9837b6..34c4c066 100644
--- a/src/scenes/main.scene.tsx
+++ b/src/scenes/main.scene.tsx
@@ -1,17 +1,20 @@
 import { CanvasPod } from '@/pods/canvas/canvas.pod';
 import { ToolbarPod } from '@/pods/toolbar/toolbar.pod';
-import { useModalDialogContext } from '@/core/providers';
+import { useDeviceContext, useModalDialogContext } from '@/core/providers';
 import { ModalDialog } from '@/common/components';
 import classes from './main.scene.module.css';
 import { FooterPod } from '@/pods/footer';
+import { FloatingBarPod } from '@/pods/floating-bar';
 
 export const MainScene: React.FC = () => {
   const { modalDialog } = useModalDialogContext();
+  const { isTabletOrMobileDevice } = useDeviceContext();
   return (
     <>
       
         
         
+        {!isTabletOrMobileDevice && }
         
       
       
From 64b0c4e6940c8a0f5c9cac0b16831ee0a1ce3c81 Mon Sep 17 00:00:00 2001
From: Guste Gaubaite <219.guste@gmail.com>
Date: Wed, 22 Oct 2025 11:25:11 +0200
Subject: [PATCH 03/11] (#558) add extra class for E2E test selectors
---
 .../components/add-collection/add-collection.component.tsx      | 2 +-
 .../components/relation-button/relation-button.component.tsx    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pods/floating-bar/components/add-collection/add-collection.component.tsx b/src/pods/floating-bar/components/add-collection/add-collection.component.tsx
index be779cb7..78b1e2aa 100644
--- a/src/pods/floating-bar/components/add-collection/add-collection.component.tsx
+++ b/src/pods/floating-bar/components/add-collection/add-collection.component.tsx
@@ -49,7 +49,7 @@ export const AddCollection = () => {
       icon={}
       label="Add Collection"
       onClick={handleEditTableClick}
-      className={`${classes.button} hide-mobile`}
+      className={`${classes.button} hide-mobile add-collection-button`}
       shortcutOptions={SHORTCUTS.addCollection}
       showLabel={false}
       tooltipPosition="top"
diff --git a/src/pods/floating-bar/components/relation-button/relation-button.component.tsx b/src/pods/floating-bar/components/relation-button/relation-button.component.tsx
index 79c6a72d..e58aecd9 100644
--- a/src/pods/floating-bar/components/relation-button/relation-button.component.tsx
+++ b/src/pods/floating-bar/components/relation-button/relation-button.component.tsx
@@ -38,7 +38,7 @@ export const RelationButton = () => {
       icon={}
       label="Add Relation"
       onClick={handleRelationClick}
-      className={`${classes.button} hide-mobile`}
+      className={`${classes.button} hide-mobile relation-button`}
       shortcutOptions={SHORTCUTS.addRelation}
       disabled={canvasSchema.tables.length < 1}
       showLabel={false}
From 9d8443f86c1e86dc85bb43c38519f79a80cd7c82 Mon Sep 17 00:00:00 2001
From: Guste Gaubaite <219.guste@gmail.com>
Date: Wed, 22 Oct 2025 11:25:15 +0200
Subject: [PATCH 04/11] fix(#558): update E2E test to match UI changes (removed
 Add Collection label)
---
 e2e/add-new-collection.spec.ts | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/e2e/add-new-collection.spec.ts b/e2e/add-new-collection.spec.ts
index a9bab158..61c82454 100644
--- a/e2e/add-new-collection.spec.ts
+++ b/e2e/add-new-collection.spec.ts
@@ -12,9 +12,7 @@ test('opens MongoDB Designer, adds collection, and checks "New Collection" visib
   await expect(newButton).toBeVisible();
   await newButton.click();
 
-  const addCollectionButton = page
-    .getByRole('button', { name: 'Add Collection' })
-    .first();
+  const addCollectionButton = page.locator('.add-collection-button');
   await expect(addCollectionButton).toBeVisible();
   await addCollectionButton.click();
 
From e9716cedef793df124d40bd0a65e0b56af01b1f3 Mon Sep 17 00:00:00 2001
From: Guste Gaubaite <219.guste@gmail.com>
Date: Fri, 24 Oct 2025 06:54:58 +0200
Subject: [PATCH 05/11] =?UTF-8?q?fix(#558):=20replace=20alt=20key=20for=20?=
 =?UTF-8?q?ctrl=20in=20Windows,=20ctrl=20key=20for=20meta=20in=20MacOS=20a?=
 =?UTF-8?q?nd=20action=20button=20to=20show=20in=20tooltip=20ctrl=20for=20?=
 =?UTF-8?q?Windows/Linux,=20cmd=20(=E2=8C=98)=20for=20MacOS?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
 .../action-button/action-button.component.tsx |   2 +-
 src/common/shortcut/shortcut.const.ts         | 194 +++++++++---------
 src/common/shortcut/shortcut.hook.spec.tsx    |  18 +-
 src/common/shortcut/shortcut.hook.tsx         |   6 +-
 4 files changed, 110 insertions(+), 110 deletions(-)
diff --git a/src/common/components/action-button/action-button.component.tsx b/src/common/components/action-button/action-button.component.tsx
index 385a37e7..11a47689 100644
--- a/src/common/components/action-button/action-button.component.tsx
+++ b/src/common/components/action-button/action-button.component.tsx
@@ -25,7 +25,7 @@ export const ActionButton: React.FC = ({
   showLabel = true,
   tooltipPosition = 'bottom',
 }) => {
-  const shortcutCommand = isMacOS() ? 'Ctrl' : 'Alt';
+  const shortcutCommand = isMacOS() ? '⌘' : 'Ctrl';
   const showTooltip = shortcutOptions && !disabled;
   const tooltipText = `(${shortcutCommand} + ${shortcutOptions?.targetKeyLabel})`;
 
diff --git a/src/common/shortcut/shortcut.const.ts b/src/common/shortcut/shortcut.const.ts
index 3fee1730..23a36ff6 100644
--- a/src/common/shortcut/shortcut.const.ts
+++ b/src/common/shortcut/shortcut.const.ts
@@ -1,104 +1,104 @@
 import { ShortcutOptions } from './shortcut.model';
 
 interface Shortcut {
-	[key: string]: ShortcutOptions;
+  [key: string]: ShortcutOptions;
 }
 
 export const SHORTCUTS: Shortcut = {
-	addCollection: {
-		description: 'Add Collection',
-		id: 'add-collection-button-shortcut',
-		targetKey: ['c'],
-		targetKeyLabel: 'C',
-	},
-	addRelation: {
-		description: 'Add Relation',
-		id: 'add-relation-button-shortcut',
-		targetKey: ['r'],
-		targetKeyLabel: 'R',
-	},
-	delete: {
-		description: 'Delete',
-		id: 'delete-button-shortcut',
-		targetKey: ['backspace'],
-		targetKeyLabel: 'Backspace',
-	},
-	export: {
-		description: 'Export',
-		id: 'export-button-shortcut',
-		targetKey: ['e'],
-		targetKeyLabel: 'E',
-	},
-	new: {
-		description: 'New',
-		id: 'new-button-shortcut',
-		targetKey: ['n'],
-		targetKeyLabel: 'N',
-	},
-	open: {
-		description: 'Open',
-		id: 'open-button-shortcut',
-		targetKey: ['o'],
-		targetKeyLabel: 'O',
-	},
-	redo: {
-		description: 'Redo',
-		id: 'redo-button-shortcut',
-		targetKey: ['y'],
-		targetKeyLabel: 'Y',
-	},
-	save: {
-		description: 'Save',
-		id: 'save-button-shortcut',
-		targetKey: ['s'],
-		targetKeyLabel: 'S',
-	},
-	settings: {
-		description: 'Settings',
-		id: 'settings-button-shortcut',
-		targetKey: ['t'],
-		targetKeyLabel: 'T',
-	},
-	undo: {
-		description: 'Undo',
-		id: 'undo-button-shortcut',
-		targetKey: ['z'],
-		targetKeyLabel: 'Z',
-	},
-	zoomIn: {
-		description: 'Zoom In',
-		id: 'zoom-in-button-shortcut',
-		targetKey: ['=', '+'],
-		targetKeyLabel: '"+"',
-	},
-	zoomOut: {
-		description: 'Zoom Out',
-		id: 'zoom-out-button-shortcut',
-		targetKey: ['-', '-'],
-		targetKeyLabel: '"-"',
-	},
-	duplicate: {
-		description: 'Duplicate',
-		id: 'duplicate-button-shortcut',
-		targetKey: ['d'],
-		targetKeyLabel: 'D',
-	},
-	copy: {
-		description: 'Copy',
-		id: 'copy-button-shortcut',
-		targetKey: ['c'],
-		targetKeyLabel: 'C',
-	},
-	paste: {
-		description: 'Paste',
-		id: 'paste-button-shortcut',
-		targetKey: ['v'],
-		targetKeyLabel: 'V',
-	},
-	import: {
-		description: 'Import',
-		id: 'import-button-shortcut',
-		targetKey: ['i'],
-		targetKeyLabel: 'I',
-	},
+  addCollection: {
+    description: 'Add Collection',
+    id: 'add-collection-button-shortcut',
+    targetKey: ['c'],
+    targetKeyLabel: 'C',
+  },
+  addRelation: {
+    description: 'Add Relation',
+    id: 'add-relation-button-shortcut',
+    targetKey: ['r'],
+    targetKeyLabel: 'R',
+  },
+  delete: {
+    description: 'Delete',
+    id: 'delete-button-shortcut',
+    targetKey: ['backspace'],
+    targetKeyLabel: 'Backspace',
+  },
+  export: {
+    description: 'Export',
+    id: 'export-button-shortcut',
+    targetKey: ['e'],
+    targetKeyLabel: 'E',
+  },
+  new: {
+    description: 'New',
+    id: 'new-button-shortcut',
+    targetKey: ['n'],
+    targetKeyLabel: 'N',
+  },
+  open: {
+    description: 'Open',
+    id: 'open-button-shortcut',
+    targetKey: ['o'],
+    targetKeyLabel: 'O',
+  },
+  redo: {
+    description: 'Redo',
+    id: 'redo-button-shortcut',
+    targetKey: ['y'],
+    targetKeyLabel: 'Y',
+  },
+  save: {
+    description: 'Save',
+    id: 'save-button-shortcut',
+    targetKey: ['s'],
+    targetKeyLabel: 'S',
+  },
+  settings: {
+    description: 'Settings',
+    id: 'settings-button-shortcut',
+    targetKey: [','],
+    targetKeyLabel: ',',
+  },
+  undo: {
+    description: 'Undo',
+    id: 'undo-button-shortcut',
+    targetKey: ['z'],
+    targetKeyLabel: 'Z',
+  },
+  zoomIn: {
+    description: 'Zoom In',
+    id: 'zoom-in-button-shortcut',
+    targetKey: ['=', '+'],
+    targetKeyLabel: '"+"',
+  },
+  zoomOut: {
+    description: 'Zoom Out',
+    id: 'zoom-out-button-shortcut',
+    targetKey: ['-', '-'],
+    targetKeyLabel: '"-"',
+  },
+  duplicate: {
+    description: 'Duplicate',
+    id: 'duplicate-button-shortcut',
+    targetKey: ['d'],
+    targetKeyLabel: 'D',
+  },
+  copy: {
+    description: 'Copy',
+    id: 'copy-button-shortcut',
+    targetKey: ['c'],
+    targetKeyLabel: 'C',
+  },
+  paste: {
+    description: 'Paste',
+    id: 'paste-button-shortcut',
+    targetKey: ['v'],
+    targetKeyLabel: 'V',
+  },
+  import: {
+    description: 'Import',
+    id: 'import-button-shortcut',
+    targetKey: ['i'],
+    targetKeyLabel: 'I',
+  },
 };
diff --git a/src/common/shortcut/shortcut.hook.spec.tsx b/src/common/shortcut/shortcut.hook.spec.tsx
index 9c05d8a3..f3aeb6f7 100644
--- a/src/common/shortcut/shortcut.hook.spec.tsx
+++ b/src/common/shortcut/shortcut.hook.spec.tsx
@@ -22,7 +22,7 @@ describe('useShortcut', () => {
     const event = new KeyboardEvent('keydown', {
       key: 'a',
       code: 'KeyA',
-      ctrlKey: true,
+      metaKey: true,
     });
 
     window.dispatchEvent(event);
@@ -44,7 +44,7 @@ describe('useShortcut', () => {
     expect(callback).not.toHaveBeenCalled();
   });
 
-  it('should add "Alt" to the event if the user is on Windows or Linux', async () => {
+  it('should add "Ctrl" to the event if the user is on Windows or Linux', async () => {
     Object.defineProperty(window.navigator, 'userAgent', {
       value: 'Windows',
       configurable: true,
@@ -55,7 +55,7 @@ describe('useShortcut', () => {
     const event = new KeyboardEvent('keydown', {
       key: 'a',
       code: 'KeyA',
-      altKey: true,
+      ctrlKey: true,
     });
 
     window.dispatchEvent(event);
@@ -63,13 +63,13 @@ describe('useShortcut', () => {
     expect(callback).toHaveBeenCalled();
   });
 
-  it('should add "Ctrl" to the event if the user is on MacOS', async () => {
+  it('should add "⌘" to the event if the user is on MacOS', async () => {
     renderHook(() => useShortcut({ targetKey, callback }));
 
     const event = new KeyboardEvent('keydown', {
       key: 'a',
       code: 'KeyA',
-      ctrlKey: true,
+      metaKey: true,
     });
 
     window.dispatchEvent(event);
@@ -77,13 +77,13 @@ describe('useShortcut', () => {
     expect(callback).toHaveBeenCalled();
   });
 
-  it('should not call the callback when the user is on Mac and "Alt" is pressed', async () => {
+  it('should not call the callback when the user is on Mac and "Ctrl" is pressed', async () => {
     renderHook(() => useShortcut({ targetKey, callback }));
 
     const event = new KeyboardEvent('keydown', {
       key: 'a',
       code: 'KeyA',
-      altKey: true,
+      ctrlKey: true,
     });
 
     window.dispatchEvent(event);
@@ -91,7 +91,7 @@ describe('useShortcut', () => {
     expect(callback).not.toHaveBeenCalled();
   });
 
-  it('should not call the callback when the user is on Windows or Linux and "Ctrl" is pressed', async () => {
+  it('should not call the callback when the user is on Windows or Linux and "⌘" is pressed', async () => {
     Object.defineProperty(window.navigator, 'userAgent', {
       value: 'Windows',
       configurable: true,
@@ -102,7 +102,7 @@ describe('useShortcut', () => {
     const event = new KeyboardEvent('keydown', {
       key: 'a',
       code: 'KeyA',
-      ctrlKey: true,
+      metaKey: true,
     });
 
     window.dispatchEvent(event);
diff --git a/src/common/shortcut/shortcut.hook.tsx b/src/common/shortcut/shortcut.hook.tsx
index 1421f4b0..9904332a 100644
--- a/src/common/shortcut/shortcut.hook.tsx
+++ b/src/common/shortcut/shortcut.hook.tsx
@@ -17,12 +17,12 @@ export interface ShortcutHookProps {
 
 const useShortcut = ({ targetKey, callback }: ShortcutHookProps) => {
   const handleKeyPress = (event: KeyboardEvent) => {
-    const isAltKeyPressed = event.getModifierState('Alt');
+    const isMetaKeyPressed = event.getModifierState('Meta');
     const isCtrlKeyPressed = event.getModifierState('Control');
 
     if (
-      (isWindowsOrLinux() && isAltKeyPressed) ||
-      (isMacOS() && isCtrlKeyPressed)
+      (isWindowsOrLinux() && isCtrlKeyPressed) ||
+      (isMacOS() && isMetaKeyPressed)
     ) {
       if (targetKey.includes(event.key)) {
         event.preventDefault();
From e60a649689b3f606f744a5626190b1730b008ceb Mon Sep 17 00:00:00 2001
From: Guste Gaubaite <219.guste@gmail.com>
Date: Fri, 24 Oct 2025 06:58:16 +0200
Subject: [PATCH 06/11] fix(#558 paste-button): tooltip not showing
 (SHORTCUTS.Paste -> SHORTCUTS.paste)
---
 .../toolbar/components/paste-button/paste-button.component.tsx  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pods/toolbar/components/paste-button/paste-button.component.tsx b/src/pods/toolbar/components/paste-button/paste-button.component.tsx
index 58396731..acba62da 100644
--- a/src/pods/toolbar/components/paste-button/paste-button.component.tsx
+++ b/src/pods/toolbar/components/paste-button/paste-button.component.tsx
@@ -13,7 +13,7 @@ export const PasteButton = () => {
       onClick={pasteTable}
       className="hide-mobile"
       disabled={!hasClipboardContent}
-      shortcutOptions={SHORTCUTS.Paste}
+      shortcutOptions={SHORTCUTS.paste}
     />
   );
 };
From 774ebd9476b72cca03af805b0ae9bb714839cb17 Mon Sep 17 00:00:00 2001
From: Guste Gaubaite <219.guste@gmail.com>
Date: Fri, 24 Oct 2025 07:32:55 +0200
Subject: [PATCH 07/11] feat(#558 shortcuts): implement noModifier optional
 property and its handling to allow certain actions to use single-key
 shortscuts (add collection, add relation and backspace), update tests with
 noModifier functionality and ActionButton to show correct tooltip (without
 Ctrl/Cmd)
---
 .../action-button/action-button.component.tsx |  4 +-
 src/common/shortcut/shortcut.const.ts         |  7 ++-
 src/common/shortcut/shortcut.hook.spec.tsx    | 58 +++++++++++++++++++
 src/common/shortcut/shortcut.hook.tsx         | 23 +++++---
 src/common/shortcut/shortcut.model.ts         |  1 +
 5 files changed, 81 insertions(+), 12 deletions(-)
diff --git a/src/common/components/action-button/action-button.component.tsx b/src/common/components/action-button/action-button.component.tsx
index 11a47689..801368c9 100644
--- a/src/common/components/action-button/action-button.component.tsx
+++ b/src/common/components/action-button/action-button.component.tsx
@@ -27,7 +27,9 @@ export const ActionButton: React.FC = ({
 }) => {
   const shortcutCommand = isMacOS() ? '⌘' : 'Ctrl';
   const showTooltip = shortcutOptions && !disabled;
-  const tooltipText = `(${shortcutCommand} + ${shortcutOptions?.targetKeyLabel})`;
+  const tooltipText = shortcutOptions?.noModifier
+    ? `${shortcutOptions.targetKeyLabel}`
+    : `(${shortcutCommand} + ${shortcutOptions?.targetKeyLabel})`;
 
   const tooltipPositionClass =
     tooltipPosition === 'top' ? classes.tooltipTop : classes.tooltipBottom;
diff --git a/src/common/shortcut/shortcut.const.ts b/src/common/shortcut/shortcut.const.ts
index 23a36ff6..36f997c5 100644
--- a/src/common/shortcut/shortcut.const.ts
+++ b/src/common/shortcut/shortcut.const.ts
@@ -9,19 +9,22 @@ export const SHORTCUTS: Shortcut = {
     description: 'Add Collection',
     id: 'add-collection-button-shortcut',
     targetKey: ['c'],
-    targetKeyLabel: 'C',
+    targetKeyLabel: 'Collection "C"',
+    noModifier: true,
   },
   addRelation: {
     description: 'Add Relation',
     id: 'add-relation-button-shortcut',
     targetKey: ['r'],
-    targetKeyLabel: 'R',
+    targetKeyLabel: 'Relation "R"',
+    noModifier: true,
   },
   delete: {
     description: 'Delete',
     id: 'delete-button-shortcut',
     targetKey: ['backspace'],
     targetKeyLabel: 'Backspace',
+    noModifier: true,
   },
   export: {
     description: 'Export',
diff --git a/src/common/shortcut/shortcut.hook.spec.tsx b/src/common/shortcut/shortcut.hook.spec.tsx
index f3aeb6f7..d1803c40 100644
--- a/src/common/shortcut/shortcut.hook.spec.tsx
+++ b/src/common/shortcut/shortcut.hook.spec.tsx
@@ -109,4 +109,62 @@ describe('useShortcut', () => {
 
     expect(callback).not.toHaveBeenCalled();
   });
+
+  it('should call the callback when noModifier is true and only the key is pressed', () => {
+    renderHook(() =>
+      useShortcut({
+        targetKey,
+        callback,
+        noModifier: true,
+      })
+    );
+
+    const event = new KeyboardEvent('keydown', {
+      key: 'a',
+      code: 'KeyA',
+    });
+
+    window.dispatchEvent(event);
+
+    expect(callback).toHaveBeenCalled();
+  });
+
+  it('should not call the callback when noModifier is true and modifier is pressed', () => {
+    renderHook(() =>
+      useShortcut({
+        targetKey,
+        callback,
+        noModifier: true,
+      })
+    );
+
+    const event = new KeyboardEvent('keydown', {
+      key: 'a',
+      code: 'KeyA',
+      ctrlKey: true,
+    });
+
+    window.dispatchEvent(event);
+
+    expect(callback).not.toHaveBeenCalled();
+  });
+
+  it('should not call the callback when noModifier is false and no modifier is pressed', () => {
+    renderHook(() =>
+      useShortcut({
+        targetKey,
+        callback,
+        noModifier: false,
+      })
+    );
+
+    const event = new KeyboardEvent('keydown', {
+      key: 'a',
+      code: 'KeyA',
+    });
+
+    window.dispatchEvent(event);
+
+    expect(callback).not.toHaveBeenCalled();
+  });
 });
diff --git a/src/common/shortcut/shortcut.hook.tsx b/src/common/shortcut/shortcut.hook.tsx
index 9904332a..459753b6 100644
--- a/src/common/shortcut/shortcut.hook.tsx
+++ b/src/common/shortcut/shortcut.hook.tsx
@@ -4,6 +4,7 @@ import { useEffect } from 'react';
 export interface ShortcutHookProps {
   targetKey: string[];
   callback: () => void;
+  noModifier?: boolean;
 }
 
 /**
@@ -15,19 +16,23 @@ export interface ShortcutHookProps {
  * @return {void}
  */
 
-const useShortcut = ({ targetKey, callback }: ShortcutHookProps) => {
+const useShortcut = ({
+  targetKey,
+  callback,
+  noModifier,
+}: ShortcutHookProps) => {
   const handleKeyPress = (event: KeyboardEvent) => {
     const isMetaKeyPressed = event.getModifierState('Meta');
     const isCtrlKeyPressed = event.getModifierState('Control');
 
-    if (
-      (isWindowsOrLinux() && isCtrlKeyPressed) ||
-      (isMacOS() && isMetaKeyPressed)
-    ) {
-      if (targetKey.includes(event.key)) {
-        event.preventDefault();
-        callback();
-      }
+    const hasCorrectModifier = noModifier
+      ? !isMetaKeyPressed && !isCtrlKeyPressed
+      : (isWindowsOrLinux() && isCtrlKeyPressed) ||
+        (isMacOS() && isMetaKeyPressed);
+
+    if (hasCorrectModifier && targetKey.includes(event.key)) {
+      event.preventDefault();
+      callback();
     }
   };
 
diff --git a/src/common/shortcut/shortcut.model.ts b/src/common/shortcut/shortcut.model.ts
index 13bff58b..fa75155c 100644
--- a/src/common/shortcut/shortcut.model.ts
+++ b/src/common/shortcut/shortcut.model.ts
@@ -3,4 +3,5 @@ export interface ShortcutOptions {
   targetKey: string[];
   targetKeyLabel: string;
   description: string;
+  noModifier?: boolean;
 }
From cf582014e328645105a48defe56277e3a6cc6d1e Mon Sep 17 00:00:00 2001
From: Guste Gaubaite <219.guste@gmail.com>
Date: Fri, 24 Oct 2025 07:44:57 +0200
Subject: [PATCH 08/11] =?UTF-8?q?test(#558=20action=20button=20test):=20fi?=
 =?UTF-8?q?x=20tooltip=20to=20show=20updated=20modifier=20(=E2=8C=98=20for?=
 =?UTF-8?q?=20Mac,=20Ctrl=20for=20Windows),=20add=20test=20for=20no-modifi?=
 =?UTF-8?q?er=20shortcuts=20tooltip=20display?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
 .../action-button.component.spec.tsx          | 21 ++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/common/components/action-button/action-button.component.spec.tsx b/src/common/components/action-button/action-button.component.spec.tsx
index 03fd9978..13e3f888 100644
--- a/src/common/components/action-button/action-button.component.spec.tsx
+++ b/src/common/components/action-button/action-button.component.spec.tsx
@@ -64,7 +64,7 @@ describe('ActionButton', () => {
 
     const tooltip = getByRole('tooltip');
 
-    expect(tooltip.textContent).toContain('Ctrl + A');
+    expect(tooltip.textContent).toContain('⌘ + A');
   });
 
   it('should disable the button if the disabled prop is true', () => {
@@ -125,4 +125,23 @@ describe('ActionButton', () => {
     const tooltip = getByRole('tooltip');
     expect(tooltip.className).toContain('tooltipTop');
   });
+
+  it('should render the tooltip without modifier when noModifier is true', () => {
+    const shortcutOptionsNoMod = {
+      ...shortcutOptions,
+      noModifier: true,
+    };
+
+    const { getByRole } = render(
+      Icon}
+        label="Label"
+        onClick={onClick}
+        shortcutOptions={shortcutOptionsNoMod}
+      />
+    );
+
+    const tooltip = getByRole('tooltip');
+    expect(tooltip.textContent).toBe('A');
+  });
 });
From 56985bd272e64a9ef15936c76fc054e80e01b613 Mon Sep 17 00:00:00 2001
From: Guste Gaubaite <219.guste@gmail.com>
Date: Sun, 26 Oct 2025 08:26:42 +0100
Subject: [PATCH 09/11] fix(#558 shortcuts): if a modal is open, do not process
 shortcuts
---
 src/common/shortcut/shortcut.hook.tsx | 7 +++++++
 1 file changed, 7 insertions(+)
diff --git a/src/common/shortcut/shortcut.hook.tsx b/src/common/shortcut/shortcut.hook.tsx
index 459753b6..1b7bac10 100644
--- a/src/common/shortcut/shortcut.hook.tsx
+++ b/src/common/shortcut/shortcut.hook.tsx
@@ -1,4 +1,5 @@
 import { isMacOS, isWindowsOrLinux } from '@/common/helpers/platform.helpers';
+import { useModalDialogContext } from '@/core/providers';
 import { useEffect } from 'react';
 
 export interface ShortcutHookProps {
@@ -21,7 +22,13 @@ const useShortcut = ({
   callback,
   noModifier,
 }: ShortcutHookProps) => {
+  const { modalDialog } = useModalDialogContext();
+
   const handleKeyPress = (event: KeyboardEvent) => {
+    if (modalDialog.isOpen) {
+      return;
+    }
+
     const isMetaKeyPressed = event.getModifierState('Meta');
     const isCtrlKeyPressed = event.getModifierState('Control');
 
From cd653d8f6950bb25e1a1ed26cbe536944963958b Mon Sep 17 00:00:00 2001
From: Guste Gaubaite <219.guste@gmail.com>
Date: Sun, 26 Oct 2025 09:45:21 +0100
Subject: [PATCH 10/11] refactor(shortcuts): implement Alt modifier, improve
 modifier system to handle ctrl/cmd, alt and no-modifier cases, update tests
---
 .../action-button.component.spec.tsx          | 121 +++++++++++++-----
 .../action-button/action-button.component.tsx |  27 +++-
 src/common/shortcut/shortcut.const.ts         |   7 +-
 src/common/shortcut/shortcut.hook.spec.tsx    |  79 ++++++++++--
 src/common/shortcut/shortcut.hook.tsx         |  19 ++-
 src/common/shortcut/shortcut.model.ts         |   4 +-
 6 files changed, 202 insertions(+), 55 deletions(-)
diff --git a/src/common/components/action-button/action-button.component.spec.tsx b/src/common/components/action-button/action-button.component.spec.tsx
index 13e3f888..e1b8d2e1 100644
--- a/src/common/components/action-button/action-button.component.spec.tsx
+++ b/src/common/components/action-button/action-button.component.spec.tsx
@@ -2,12 +2,27 @@ import { fireEvent, render, screen } from '@testing-library/react';
 import { vi } from 'vitest';
 import { ActionButton } from './action-button.component';
 import { ShortcutOptions } from '@/common/shortcut';
+import { useModalDialogContext } from '@/core/providers';
+
+vi.mock('@/core/providers', () => ({
+  useModalDialogContext: vi.fn(),
+}));
 
 describe('ActionButton', () => {
   let onClick: () => void;
   let shortcutOptions: ShortcutOptions;
 
   beforeEach(() => {
+    vi.mocked(useModalDialogContext).mockReturnValue({
+      modalDialog: {
+        isOpen: false,
+        selectedComponent: null,
+        title: '',
+      },
+      openModal: vi.fn(),
+      closeModal: vi.fn(),
+    });
+
     onClick = vi.fn();
 
     shortcutOptions = {
@@ -52,19 +67,84 @@ describe('ActionButton', () => {
     expect(onClick).toHaveBeenCalled();
   });
 
-  it('should render the tooltip with the correct shortcut key', () => {
-    const { getByRole } = render(
-      Icon}
-        label="Label"
-        onClick={onClick}
-        shortcutOptions={shortcutOptions}
-      />
-    );
+  describe('tooltip display', () => {
+    it('should render system modifier correctly', () => {
+      // Test Mac
+      const { getByRole, rerender } = render(
+        Icon}
+          label="Label"
+          onClick={onClick}
+          shortcutOptions={{
+            ...shortcutOptions,
+            modifierType: 'system',
+          }}
+        />
+      );
+      expect(getByRole('tooltip').textContent).toBe('(⌘ + A)');
+
+      // Test Windows
+      Object.defineProperty(window.navigator, 'userAgent', {
+        value: 'Windows',
+        configurable: true,
+      });
+      rerender(
+        Icon}
+          label="Label"
+          onClick={onClick}
+          shortcutOptions={{
+            ...shortcutOptions,
+            modifierType: 'system',
+          }}
+        />
+      );
+      expect(getByRole('tooltip').textContent).toBe('(Ctrl + A)');
+    });
 
-    const tooltip = getByRole('tooltip');
+    it('should render alt tooltip correctly', () => {
+      const { getByRole } = render(
+        Icon}
+          label="Label"
+          onClick={onClick}
+          shortcutOptions={{
+            ...shortcutOptions,
+            modifierType: 'alt',
+          }}
+        />
+      );
+      expect(getByRole('tooltip').textContent).toBe('(Alt + A)');
+    });
+
+    it('should render mo-modifier tooltip correctly', () => {
+      const { getByRole } = render(
+        Icon}
+          label="Label"
+          onClick={onClick}
+          shortcutOptions={{
+            ...shortcutOptions,
+            modifierType: 'none',
+          }}
+        />
+      );
+      expect(getByRole('tooltip').textContent).toBe('(A)');
+    });
 
-    expect(tooltip.textContent).toContain('⌘ + A');
+    it('should not show tooltip when disabled', () => {
+      const { queryByRole } = render(
+        Icon}
+          label="Label"
+          onClick={onClick}
+          disabled
+          shortcutOptions={shortcutOptions}
+        />
+      );
+
+      expect(queryByRole('tooltip')).toBeNull();
+    });
   });
 
   it('should disable the button if the disabled prop is true', () => {
@@ -125,23 +205,4 @@ describe('ActionButton', () => {
     const tooltip = getByRole('tooltip');
     expect(tooltip.className).toContain('tooltipTop');
   });
-
-  it('should render the tooltip without modifier when noModifier is true', () => {
-    const shortcutOptionsNoMod = {
-      ...shortcutOptions,
-      noModifier: true,
-    };
-
-    const { getByRole } = render(
-      Icon}
-        label="Label"
-        onClick={onClick}
-        shortcutOptions={shortcutOptionsNoMod}
-      />
-    );
-
-    const tooltip = getByRole('tooltip');
-    expect(tooltip.textContent).toBe('A');
-  });
 });
diff --git a/src/common/components/action-button/action-button.component.tsx b/src/common/components/action-button/action-button.component.tsx
index 801368c9..69044b17 100644
--- a/src/common/components/action-button/action-button.component.tsx
+++ b/src/common/components/action-button/action-button.component.tsx
@@ -1,7 +1,7 @@
 import React from 'react';
 import { isMacOS } from '@/common/helpers/platform.helpers';
 import classes from './action-button.component.module.css';
-import { ShortcutOptions } from '@/common/shortcut';
+import { ModifierType, ShortcutOptions } from '@/common/shortcut';
 import useShortcut from '@/common/shortcut/shortcut.hook';
 
 interface Props {
@@ -25,11 +25,28 @@ export const ActionButton: React.FC = ({
   showLabel = true,
   tooltipPosition = 'bottom',
 }) => {
-  const shortcutCommand = isMacOS() ? '⌘' : 'Ctrl';
+  const getModifierSymbol = (modifierType: ModifierType = 'system') => {
+    switch (modifierType) {
+      case 'none':
+        return '';
+      case 'alt':
+        return 'Alt';
+      case 'system':
+      default:
+        return isMacOS() ? '⌘' : 'Ctrl';
+    }
+  };
+
+  const shortcutCommand = getModifierSymbol(shortcutOptions?.modifierType);
+
   const showTooltip = shortcutOptions && !disabled;
-  const tooltipText = shortcutOptions?.noModifier
-    ? `${shortcutOptions.targetKeyLabel}`
-    : `(${shortcutCommand} + ${shortcutOptions?.targetKeyLabel})`;
+  const tooltipText =
+    shortcutOptions &&
+    `(${
+      shortcutOptions.modifierType === 'none'
+        ? shortcutOptions.targetKeyLabel
+        : `${shortcutCommand} + ${shortcutOptions.targetKeyLabel}`
+    })`;
 
   const tooltipPositionClass =
     tooltipPosition === 'top' ? classes.tooltipTop : classes.tooltipBottom;
diff --git a/src/common/shortcut/shortcut.const.ts b/src/common/shortcut/shortcut.const.ts
index 36f997c5..25183cd5 100644
--- a/src/common/shortcut/shortcut.const.ts
+++ b/src/common/shortcut/shortcut.const.ts
@@ -10,21 +10,21 @@ export const SHORTCUTS: Shortcut = {
     id: 'add-collection-button-shortcut',
     targetKey: ['c'],
     targetKeyLabel: 'Collection "C"',
-    noModifier: true,
+    modifierType: 'none',
   },
   addRelation: {
     description: 'Add Relation',
     id: 'add-relation-button-shortcut',
     targetKey: ['r'],
     targetKeyLabel: 'Relation "R"',
-    noModifier: true,
+    modifierType: 'none',
   },
   delete: {
     description: 'Delete',
     id: 'delete-button-shortcut',
     targetKey: ['backspace'],
     targetKeyLabel: 'Backspace',
-    noModifier: true,
+    modifierType: 'none',
   },
   export: {
     description: 'Export',
@@ -37,6 +37,7 @@ export const SHORTCUTS: Shortcut = {
     id: 'new-button-shortcut',
     targetKey: ['n'],
     targetKeyLabel: 'N',
+    modifierType: 'alt',
   },
   open: {
     description: 'Open',
diff --git a/src/common/shortcut/shortcut.hook.spec.tsx b/src/common/shortcut/shortcut.hook.spec.tsx
index d1803c40..4f2bb940 100644
--- a/src/common/shortcut/shortcut.hook.spec.tsx
+++ b/src/common/shortcut/shortcut.hook.spec.tsx
@@ -1,12 +1,27 @@
 import { renderHook } from '@testing-library/react';
 import useShortcut from './shortcut.hook';
 import { vi } from 'vitest';
+import { useModalDialogContext } from '@/core/providers';
+
+vi.mock('@/core/providers', () => ({
+  useModalDialogContext: vi.fn(),
+}));
 
 describe('useShortcut', () => {
   let targetKey: string[];
   let callback: () => void;
 
   beforeEach(() => {
+    vi.mocked(useModalDialogContext).mockReturnValue({
+      modalDialog: {
+        isOpen: false,
+        selectedComponent: null,
+        title: '',
+      },
+      openModal: vi.fn(),
+      closeModal: vi.fn(),
+    });
+
     targetKey = ['a'];
     callback = vi.fn();
 
@@ -110,51 +125,51 @@ describe('useShortcut', () => {
     expect(callback).not.toHaveBeenCalled();
   });
 
-  it('should call the callback when noModifier is true and only the key is pressed', () => {
+  it('should call callback with alt modifier', () => {
     renderHook(() =>
       useShortcut({
         targetKey,
         callback,
-        noModifier: true,
+        modifierType: 'alt',
       })
     );
 
     const event = new KeyboardEvent('keydown', {
       key: 'a',
       code: 'KeyA',
+      altKey: true,
     });
 
     window.dispatchEvent(event);
-
     expect(callback).toHaveBeenCalled();
   });
 
-  it('should not call the callback when noModifier is true and modifier is pressed', () => {
+  it('should not call callback if other modifiers are pressed with alt', () => {
     renderHook(() =>
       useShortcut({
         targetKey,
         callback,
-        noModifier: true,
+        modifierType: 'alt',
       })
     );
 
     const event = new KeyboardEvent('keydown', {
       key: 'a',
       code: 'KeyA',
-      ctrlKey: true,
+      altKey: true,
+      ctrlKey: true, // No debería funcionar con otros modificadores
     });
 
     window.dispatchEvent(event);
-
     expect(callback).not.toHaveBeenCalled();
   });
 
-  it('should not call the callback when noModifier is false and no modifier is pressed', () => {
+  it('should call callback with no modifiers', () => {
     renderHook(() =>
       useShortcut({
         targetKey,
         callback,
-        noModifier: false,
+        modifierType: 'none',
       })
     );
 
@@ -164,7 +179,53 @@ describe('useShortcut', () => {
     });
 
     window.dispatchEvent(event);
+    expect(callback).toHaveBeenCalled();
+  });
 
+  it('should not call callback if any modifier is pressed', () => {
+    renderHook(() =>
+      useShortcut({
+        targetKey,
+        callback,
+        modifierType: 'none',
+      })
+    );
+
+    const event = new KeyboardEvent('keydown', {
+      key: 'a',
+      code: 'KeyA',
+      altKey: true,
+    });
+
+    window.dispatchEvent(event);
+    expect(callback).not.toHaveBeenCalled();
+  });
+
+  it('should not call callback when modal is open', () => {
+    vi.mocked(useModalDialogContext).mockReturnValueOnce({
+      modalDialog: {
+        isOpen: true,
+        selectedComponent: null,
+        title: '',
+      },
+      openModal: vi.fn(),
+      closeModal: vi.fn(),
+    });
+
+    renderHook(() =>
+      useShortcut({
+        targetKey,
+        callback,
+        modifierType: 'none',
+      })
+    );
+
+    const event = new KeyboardEvent('keydown', {
+      key: 'r',
+      code: 'KeyR',
+    });
+
+    window.dispatchEvent(event);
     expect(callback).not.toHaveBeenCalled();
   });
 });
diff --git a/src/common/shortcut/shortcut.hook.tsx b/src/common/shortcut/shortcut.hook.tsx
index 1b7bac10..aa4722fd 100644
--- a/src/common/shortcut/shortcut.hook.tsx
+++ b/src/common/shortcut/shortcut.hook.tsx
@@ -1,11 +1,12 @@
 import { isMacOS, isWindowsOrLinux } from '@/common/helpers/platform.helpers';
 import { useModalDialogContext } from '@/core/providers';
 import { useEffect } from 'react';
+import { ModifierType } from './shortcut.model';
 
 export interface ShortcutHookProps {
   targetKey: string[];
   callback: () => void;
-  noModifier?: boolean;
+  modifierType?: ModifierType;
 }
 
 /**
@@ -20,7 +21,7 @@ export interface ShortcutHookProps {
 const useShortcut = ({
   targetKey,
   callback,
-  noModifier,
+  modifierType = 'system',
 }: ShortcutHookProps) => {
   const { modalDialog } = useModalDialogContext();
 
@@ -31,13 +32,17 @@ const useShortcut = ({
 
     const isMetaKeyPressed = event.getModifierState('Meta');
     const isCtrlKeyPressed = event.getModifierState('Control');
+    const isAltKeyPressed = event.getModifierState('Alt');
 
-    const hasCorrectModifier = noModifier
-      ? !isMetaKeyPressed && !isCtrlKeyPressed
-      : (isWindowsOrLinux() && isCtrlKeyPressed) ||
-        (isMacOS() && isMetaKeyPressed);
+    const isValidModifier = {
+      none: !isMetaKeyPressed && !isCtrlKeyPressed && !isAltKeyPressed,
+      system:
+        (isWindowsOrLinux() && isCtrlKeyPressed) ||
+        (isMacOS() && isMetaKeyPressed),
+      alt: isAltKeyPressed && !isCtrlKeyPressed && !isMetaKeyPressed,
+    }[modifierType];
 
-    if (hasCorrectModifier && targetKey.includes(event.key)) {
+    if (isValidModifier && targetKey.includes(event.key)) {
       event.preventDefault();
       callback();
     }
diff --git a/src/common/shortcut/shortcut.model.ts b/src/common/shortcut/shortcut.model.ts
index fa75155c..4fc1bc49 100644
--- a/src/common/shortcut/shortcut.model.ts
+++ b/src/common/shortcut/shortcut.model.ts
@@ -1,7 +1,9 @@
+export type ModifierType = 'system' | 'alt' | 'none';
+
 export interface ShortcutOptions {
   id: string;
   targetKey: string[];
   targetKeyLabel: string;
   description: string;
-  noModifier?: boolean;
+  modifierType?: ModifierType;
 }
From 4d63182e1ce058b5142205661fc9f73bff19df1f Mon Sep 17 00:00:00 2001
From: Guste Gaubaite <219.guste@gmail.com>
Date: Mon, 27 Oct 2025 08:01:06 +0100
Subject: [PATCH 11/11] docs(shortcuts): update hook documentation with correct
 modifier descriptions
---
 src/common/shortcut/shortcut.hook.spec.tsx | 2 +-
 src/common/shortcut/shortcut.hook.tsx      | 8 +++++---
 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/common/shortcut/shortcut.hook.spec.tsx b/src/common/shortcut/shortcut.hook.spec.tsx
index 4f2bb940..0eeaa278 100644
--- a/src/common/shortcut/shortcut.hook.spec.tsx
+++ b/src/common/shortcut/shortcut.hook.spec.tsx
@@ -157,7 +157,7 @@ describe('useShortcut', () => {
       key: 'a',
       code: 'KeyA',
       altKey: true,
-      ctrlKey: true, // No debería funcionar con otros modificadores
+      ctrlKey: true,
     });
 
     window.dispatchEvent(event);
diff --git a/src/common/shortcut/shortcut.hook.tsx b/src/common/shortcut/shortcut.hook.tsx
index aa4722fd..d2c08182 100644
--- a/src/common/shortcut/shortcut.hook.tsx
+++ b/src/common/shortcut/shortcut.hook.tsx
@@ -10,11 +10,13 @@ export interface ShortcutHookProps {
 }
 
 /**
- * This hook is used to create a keyboard shortcut
- * it uses Ctrl + key for Windows and Cmd + key for Mac
- * to avoid conflicts with the browser shortcuts
+ * * This hook is used to create keyboard shortcuts with different modifier types:
+ * - system: Uses Ctrl (Windows/Linux) or Cmd (Mac) as modifier
+ * - alt: Uses Alt key as modifier (same behavior in all platforms)
+ * - none: No modifier required, direct key press
  * @param  {String[]} targetKey The key that will trigger the shortcut
  * @param  {Function} callback  The function to be called when the shortcut is triggered
+ * @param  {ModifierType} modifierType The type of modifier to use ('system' | 'alt' | 'none')
  * @return {void}
  */