diff --git a/src/app/navbar/navbar.tsx b/src/app/navbar/navbar.tsx
index 0859d9bb49e1e67d9b9849a80c7aae86999084b1..230411c2ca029ed5fc68f6497e5e092008b3459e 100644
--- a/src/app/navbar/navbar.tsx
+++ b/src/app/navbar/navbar.tsx
@@ -13,7 +13,7 @@
 import React, { useState, useRef, useEffect } from 'react';
 import GpLogo from './gp-logo';
 import { getEnvVariable } from '@/config';
-import { useAuthentication, useAuthCache, useActiveSaveStateAuthorization, Button, DropdownItem, useAppDispatch } from '@/lib';
+import { useAuthentication, useAuthCache, Button, DropdownItem, useAppDispatch, useActiveSaveState } from '@/lib';
 import { FeatureEnabled } from '@/lib/components/featureFlags';
 import { Popover, PopoverTrigger, PopoverContent } from '@/lib/components/popover';
 import { ManagementViews, ManagementTrigger } from '@/lib/management';
@@ -24,7 +24,7 @@ export const Navbar = () => {
   const dropdownRef = useRef<HTMLDivElement>(null);
   const auth = useAuthentication();
   const authCache = useAuthCache();
-  const authorization = useActiveSaveStateAuthorization();
+  const ss = useActiveSaveState();
   const [menuOpen, setMenuOpen] = useState(false);
   const buildInfo = getEnvVariable('GRAPHPOLARIS_VERSION');
   const [managementOpen, setManagementOpen] = useState<boolean>(false);
@@ -106,7 +106,7 @@ export const Navbar = () => {
                       />
                     </FeatureEnabled>
                     <FeatureEnabled featureFlag="VIEWER_PERMISSIONS">
-                      {authCache.authorization?.savestate?.W && authorization.database?.W && (
+                      {authCache.authorization?.savestate?.W && ss?.authorization.database?.W && (
                         <DropdownItem
                           value="Viewer Permissions"
                           onClick={() => {
diff --git a/src/lib/components/dropdowns/index.tsx b/src/lib/components/dropdowns/index.tsx
index b3d667f8030bc1db28a206e1888faabfb0dad88c..d18577ba209558540cc76c1a43e677d228c60c95 100644
--- a/src/lib/components/dropdowns/index.tsx
+++ b/src/lib/components/dropdowns/index.tsx
@@ -63,7 +63,14 @@ export function DropdownTrigger({
       onClick();
     }
   };
-  if (popover) {
+
+  if (disabled) {
+    return (
+      <button className={`w-full ${disabled ? 'cursor-not-allowed opacity-50' : ''}`} disabled={disabled}>
+        {inner}
+      </button>
+    );
+  } else if (popover) {
     return (
       <PopoverTrigger className={`${disabled ? 'cursor-not-allowed opacity-50' : ''}`} onClick={handleClick}>
         {inner}
diff --git a/src/lib/data-access/api/eventBus.tsx b/src/lib/data-access/api/eventBus.tsx
index 9c15efe9f3b30c45cb768ecb1fb333b41d623d17..95857ef2afa589063862f80937f96cd9dc412ff6 100644
--- a/src/lib/data-access/api/eventBus.tsx
+++ b/src/lib/data-access/api/eventBus.tsx
@@ -27,23 +27,21 @@ import {
   wsDeleteStateSubscription,
   wsGetStateSubscription,
   wsTestSaveStateConnectionSubscription,
-  wsStateGetPolicy,
   DatabaseStatus,
   wsTestSaveStateConnection,
 } from '../broker/wsState';
 import {
   addSaveState,
   testedSaveState,
-  selectSaveState,
   updateSaveStateList,
   updateSelectedSaveState,
   setFetchingSaveStates,
-  setStateAuthorization,
   setActiveQueryID,
   setQueryState,
   setQuerybuilderNodes,
+  selectSaveState,
 } from '../store/sessionSlice';
-import { URLParams, getParam } from './url';
+import { URLParams, getParam, setParam } from './url';
 import { VisState, setVisualizationState } from '../store/visualizationSlice';
 import { isEqual } from 'lodash-es';
 import { clearSchema, setSchemaAttributeInformation, setSchemaLoading, setSchemaState } from '../store/schemaSlice';
@@ -52,15 +50,7 @@ import { unSelect } from '../store/interactionSlice';
 import { wsReconnectSubscription, wsUserGetPolicy } from '../broker/wsUser';
 import { authorized, setSessionID } from '../store/authSlice';
 import { asyncSetNewGraphQueryResult, queryingBackend } from '../store/graphQueryResultSlice';
-import {
-  SaveState,
-  SchemaGraphStats,
-  allMLTypes,
-  LinkPredictionInstance,
-  GraphQueryTranslationResultMessage,
-  wsReturnKey,
-  Schema,
-} from 'ts-common';
+import { SaveState, allMLTypes, LinkPredictionInstance, GraphQueryTranslationResultMessage, wsReturnKey, Schema } from 'ts-common';
 
 export const EventBus = (props: { onRunQuery: (useCached: boolean) => void; onAuthorized: () => void }) => {
   const { login } = useAuthentication();
@@ -129,7 +119,7 @@ export const EventBus = (props: { onRunQuery: (useCached: boolean) => void; onAu
     const unsubs: (() => void)[] = [];
 
     unsubs.push(
-      wsSchemaSubscription((data, status) => {
+      wsSchemaSubscription(({ data, status }) => {
         if (status !== 'success') {
           dispatch(addError('Failed to fetch schema'));
           dispatch(clearSchema({ error: true }));
@@ -146,8 +136,8 @@ export const EventBus = (props: { onRunQuery: (useCached: boolean) => void; onAu
     );
 
     unsubs.push(
-      wsQuerySubscription(data => {
-        if (!data) {
+      wsQuerySubscription(({ data, status }) => {
+        if (!data || status !== 'success') {
           dispatch(addError('Failed to fetch graph query result'));
           return;
         }
@@ -158,20 +148,21 @@ export const EventBus = (props: { onRunQuery: (useCached: boolean) => void; onAu
     );
 
     unsubs.push(
-      wsQueryErrorSubscription(data => {
+      wsQueryErrorSubscription(params => {
         dispatch(addError('Failed to fetch graph query result'));
-        console.error('Query Error', data);
+        console.error('Query Error', params.data);
         dispatch(resetGraphQueryResults());
       }),
     );
 
     unsubs.push(
-      wsTestSaveStateConnectionSubscription(data => {
+      wsTestSaveStateConnectionSubscription(params => {
+        const data = params.data;
         if (data?.status === 'success' && data.saveStateID) {
           dispatch(
             testedSaveState({
               saveStateID: data.saveStateID,
-              status: data.status == 'success' ? DatabaseStatus.online : DatabaseStatus.offline,
+              status: data.status === 'success' ? DatabaseStatus.online : DatabaseStatus.offline,
             }),
           );
         } else {
@@ -181,7 +172,8 @@ export const EventBus = (props: { onRunQuery: (useCached: boolean) => void; onAu
     );
 
     unsubs.push(
-      wsReconnectSubscription(data => {
+      wsReconnectSubscription(params => {
+        const data = params.data;
         if (data == null) return;
 
         if (!Broker.instance().checkSessionID(data.sessionID)) {
@@ -196,13 +188,15 @@ export const EventBus = (props: { onRunQuery: (useCached: boolean) => void; onAu
         dispatch(setFetchingSaveStates(true));
 
         // check authorizations
-        wsUserGetPolicy(null, res => {
-          if (res) dispatch(authorized(res));
+        wsUserGetPolicy(null, params => {
+          if (params.data) dispatch(authorized(params.data));
         });
 
-        wsGetStates(null, states => {
+        wsGetStates(null, params => {
+          const states = params.data;
           if (states) {
             dispatch(setFetchingSaveStates(false));
+            params.defaultCallback();
 
             // Process URL Params after states are fetched
             const paramSaveState = getParam(URLParams.saveState);
@@ -211,13 +205,26 @@ export const EventBus = (props: { onRunQuery: (useCached: boolean) => void; onAu
               const stateExists = states.some(state => state.id === paramSaveState);
               if (!stateExists) {
                 console.log('Shared save state not found in user states. Fetching:', paramSaveState);
-                wsGetState({ saveStateID: paramSaveState });
+                wsGetState({ saveStateID: paramSaveState }, ({ data, status }) => {
+                  if (!['success', 'unchanged'].includes(status) || !data) {
+                    dispatch(addError('Failed to fetch state'));
+                    return;
+                  }
+                  if (data.id !== nilUUID) {
+                    if (isEqual(data, session.saveStates[data.id])) {
+                      console.log('State unchanged, not updating');
+                      return;
+                    }
+                    console.log('State fetched', data, status);
+                    dispatch(addSaveState({ ss: data, select: true }));
+                  }
+                });
+              } else {
+                dispatch(selectSaveState(paramSaveState));
               }
             }
-            return true;
           } else {
             dispatch(addError('Failed to fetch states'));
-            return false;
           }
         });
 
@@ -229,47 +236,39 @@ export const EventBus = (props: { onRunQuery: (useCached: boolean) => void; onAu
       }),
     );
 
-    Broker.instance().subscribe((data: SchemaGraphStats) => {
-      dispatch(setSchemaAttributeInformation(data));
+    Broker.instance().subscribe(params => {
+      if (!params.data) {
+        dispatch(addError('Failed to fetch schema stats'));
+        return;
+      }
+      dispatch(setSchemaAttributeInformation(params.data));
       dispatch(addInfo('Received attribute information'));
     }, wsReturnKey.schemaStatsResult);
 
     // Broker.instance().subscribe((data: QueryBuilderState) => dispatch(setQuerybuilderNodes(data)), 'query_builder_state');
 
     allMLTypes.forEach(mlType => {
-      const id = Broker.instance().subscribe((data: LinkPredictionInstance[]) => {
+      const id = Broker.instance().subscribe(params => {
+        const data = params.data as unknown as LinkPredictionInstance[];
         dispatch(setMLResult({ type: mlType, result: data }));
       }, mlType);
       unsubs.push(() => Broker.instance().unSubscribe(mlType, id));
     });
 
     unsubs.push(
-      wsGetStatesSubscription((data, status) => {
-        console.debug('Save States updated', data, status);
-        if (status !== 'success' || !data) {
+      wsGetStatesSubscription(params => {
+        console.debug('Save States updated', params.data, params.status);
+        if (params.status !== 'success' || !params.data) {
           dispatch(addError('Failed to fetch states'));
           return;
         }
 
-        dispatch(updateSaveStateList(data));
-        const d = Object.fromEntries(data.map(x => [x.id, x]));
-        loadSaveState(session.currentSaveState, d);
-        data.forEach(ss => {
-          if (session.saveStatesAuthorization?.[ss.id] === undefined) {
-            wsStateGetPolicy({ saveStateID: ss.id }, ret => {
-              if (!ret) {
-                dispatch(addError('Failed to fetch state authorization'));
-                return;
-              }
-              dispatch(setStateAuthorization({ id: ss.id, authorization: ret }));
-            });
-          }
-        });
+        dispatch(updateSaveStateList(params.data));
       }),
     );
 
     unsubs.push(
-      wsGetStateSubscription((data, status) => {
+      wsGetStateSubscription(({ data, status }) => {
         if (!['success', 'unchanged'].includes(status) || !data) {
           dispatch(addError('Failed to fetch state'));
           return;
@@ -279,16 +278,8 @@ export const EventBus = (props: { onRunQuery: (useCached: boolean) => void; onAu
             console.log('State unchanged, not updating');
             return;
           }
-          dispatch(addSaveState(data));
-          dispatch(selectSaveState(data.id));
-          loadSaveState(data.id, session.saveStates);
-          wsStateGetPolicy({ saveStateID: data.id }, ret => {
-            if (!ret) {
-              dispatch(addError('Failed to fetch state authorization'));
-              return;
-            }
-            dispatch(setStateAuthorization({ id: data.id, authorization: ret }));
-          });
+          console.log('State fetched', data, status);
+          dispatch(addSaveState({ ss: data, select: false }));
         }
       }),
     );
@@ -316,7 +307,7 @@ export const EventBus = (props: { onRunQuery: (useCached: boolean) => void; onAu
   useEffect(() => {
     if (activeSS) {
       console.log('Query State Hash Updated', queryHash, activeSS.id);
-      wsUpdateState(activeSS, (data, status) => {
+      wsUpdateState(activeSS, ({ data, status }) => {
         // if (status === 'unchanged') {
         //  TODO: check if this is needed, but for now removed so that the query is always sent, solving issue with changing ss
         //   console.log('State unchanged, not updating');
diff --git a/src/lib/data-access/broker/broker.tsx b/src/lib/data-access/broker/broker.tsx
index 42afae9ed1a4d3a3adcb68548891b1bce9573b2f..e9d42179991ec2dab440b3585741db0c6ff27426 100644
--- a/src/lib/data-access/broker/broker.tsx
+++ b/src/lib/data-access/broker/broker.tsx
@@ -6,11 +6,9 @@
 
 import { getEnvVariable } from '@/config';
 import { UseIsAuthorizedState } from '../store/authSlice';
-import { WsMessageBackend2Frontend, WsMessageBody, wsReturnKeyWithML } from 'ts-common';
+import { ResponseCallback, ResponseCallbackParamsData, WsMessageBackend2Frontend, WsMessageBody, wsReturnKeyWithML } from 'ts-common';
 import { v4 as uuidv4 } from 'uuid';
 
-export type BrokerCallbackFunction = (data: any, status: string, routingKey?: string) => boolean | void;
-
 let keepAlivePing: ReturnType<typeof setInterval>;
 
 /**
@@ -29,9 +27,9 @@ let keepAlivePing: ReturnType<typeof setInterval>;
 export class Broker {
   private static singletonInstance: Broker;
 
-  private listeners: Record<string, Record<string, BrokerCallbackFunction>> = {};
-  private catchAllListener: BrokerCallbackFunction | undefined;
-  private callbackListeners: Record<string, BrokerCallbackFunction> = {};
+  private listeners: Record<string, Record<string, ResponseCallback<wsReturnKeyWithML>>> = {};
+  private catchAllListener: ResponseCallback<wsReturnKeyWithML> | undefined;
+  private callbackListeners: Record<string, ResponseCallback<wsReturnKeyWithML>> = {};
 
   private webSocket: WebSocket | undefined;
   private url: string;
@@ -53,9 +51,9 @@ export class Broker {
    * @param {string} routingKey The routingkey to subscribe to.
    * @param {boolean} consumeMostRecentMessage If true and there is a message for this routingkey available, notify the new listener. Default true.
    */
-  public subscribe(
-    newListener: BrokerCallbackFunction,
-    routingKey: wsReturnKeyWithML,
+  public subscribe<T extends wsReturnKeyWithML>(
+    newListener: ResponseCallback<T>,
+    routingKey: T,
     key: string = (Date.now() + Math.floor(Math.random() * 100)).toString(),
     consumeMostRecentMessage: boolean = false,
   ): string {
@@ -67,7 +65,12 @@ export class Broker {
 
       // Consume the most recent message
       if (consumeMostRecentMessage && routingKey in this.mostRecentMessages) {
-        newListener(this.mostRecentMessages[routingKey]!.value, this.mostRecentMessages[routingKey]!.status, routingKey);
+        newListener({
+          data: this.mostRecentMessages[routingKey]!.value as ResponseCallbackParamsData<T>,
+          status: this.mostRecentMessages[routingKey]!.status,
+          routingKey: routingKey,
+          defaultCallback: () => true,
+        });
       }
     }
 
@@ -80,7 +83,7 @@ export class Broker {
    * @param {string} routingKey The routingkey to subscribe to.
    * @param {boolean} consumeMostRecentMessage If true and there is a message for this routingkey available, notify the new listener. Default true.
    */
-  public subscribeDefault(newListener: BrokerCallbackFunction): void {
+  public subscribeDefault(newListener: ResponseCallback<wsReturnKeyWithML>): void {
     this.catchAllListener = newListener;
   }
 
@@ -195,7 +198,7 @@ export class Broker {
     setTimeout(() => Broker.instance().attemptReconnect(), 5000);
   }
 
-  public sendMessage(message: Omit<WsMessageBody, 'callID'>, callback?: BrokerCallbackFunction): void {
+  public sendMessage<R extends wsReturnKeyWithML>(message: Omit<WsMessageBody, 'callID'>, callback?: ResponseCallback<R>): void {
     console.debug('%cSending WS message: ', 'background: #222; color: #bada55', message);
 
     const uuid = uuidv4();
@@ -232,10 +235,25 @@ export class Broker {
     const status = jsonObject.status;
     const uuid = jsonObject.callID;
 
-    let stop = false; // check in case there is a specific callback listener and, if its response is true, also call the subscriptions
     this.mostRecentMessages[routingKey] = jsonObject;
     if (uuid in this.callbackListeners) {
-      stop = this.callbackListeners[uuid](data, status) !== true;
+      // If there is a callback listener, notify it, and not the others unless the callback listener says so
+      this.callbackListeners[uuid]({
+        data,
+        status,
+        routingKey,
+        defaultCallback: () => {
+          if (this.listeners[routingKey] && Object.keys(this.listeners[routingKey]).length != 0) {
+            if (this.catchAllListener) {
+              this.catchAllListener({ data, status, routingKey, defaultCallback: () => true });
+            }
+            Object.values(this.listeners[routingKey]).forEach(listener =>
+              listener({ data, status, routingKey, defaultCallback: () => true }),
+            );
+            console.debug('%c' + routingKey + ` WS response`, 'background: #222; color: #DBAB2F', data);
+          }
+        },
+      });
       console.debug(
         '%c' + routingKey + ` WS response WITH CALLBACK`,
         'background: #222; color: #DBAB2F',
@@ -245,19 +263,17 @@ export class Broker {
         stop,
       );
       delete this.callbackListeners[uuid];
-    }
-
-    if (!stop && this.listeners[routingKey] && Object.keys(this.listeners[routingKey]).length != 0) {
+    } else if (this.listeners[routingKey] && Object.keys(this.listeners[routingKey]).length != 0) {
+      // If there are listeners, notify them
       if (this.catchAllListener) {
-        this.catchAllListener(data, status, routingKey);
+        this.catchAllListener({ data, status, routingKey, defaultCallback: () => true });
       }
-      Object.values(this.listeners[routingKey]).forEach(listener => listener(data, status, routingKey));
+      Object.values(this.listeners[routingKey]).forEach(listener => listener({ data, status, routingKey, defaultCallback: () => true }));
       console.debug('%c' + routingKey + ` WS response`, 'background: #222; color: #DBAB2F', data);
-    }
-    // If there are no listeners, log the message
-    else if (!stop) {
+    } else {
+      // If there are no listeners, log the message
       if (this.catchAllListener) {
-        this.catchAllListener(data, status, routingKey);
+        this.catchAllListener({ data, status, routingKey, defaultCallback: () => true });
         console.debug(routingKey, `catch all used for message with routing key`, data);
       } else {
         console.debug('%c' + routingKey + ` no listeners for message with routing key`, 'background: #663322; color: #DBAB2F', data);
diff --git a/src/lib/data-access/broker/wsInsightSharing.ts b/src/lib/data-access/broker/wsInsightSharing.ts
index 42dbc5471e12820110869ff24b1bc329194d8d66..b857b731eb4b2a16c3fd7992b4854c77ff691044 100644
--- a/src/lib/data-access/broker/wsInsightSharing.ts
+++ b/src/lib/data-access/broker/wsInsightSharing.ts
@@ -1,4 +1,4 @@
-import { InsightModel, InsightRequest, ResponseCallback, WsFrontendCall, wsKeys, wsReturnKey, wsSubKeys } from 'ts-common';
+import { InsightRequest, ResponseCallback, WsFrontendCall, wsKeys, wsReturnKey, wsSubKeys } from 'ts-common';
 import { Broker } from './broker';
 
 export const wsGetInsights: WsFrontendCall<{ saveStateId: string }, wsReturnKey.insightResults> = (params, callback) => {
@@ -13,32 +13,30 @@ export const wsGetInsights: WsFrontendCall<{ saveStateId: string }, wsReturnKey.
 };
 
 export const wsCreateInsight: WsFrontendCall<InsightRequest, wsReturnKey.insightResult> = (params, callback) => {
-  Broker.instance().sendMessage(
+  Broker.instance().sendMessage<wsReturnKey.insightResult>(
     {
       key: wsKeys.insight,
       subKey: wsSubKeys.create,
       body: params,
     },
-    (data: InsightModel, status: string) => {
-      if (status === 'Bad Request') {
-        console.error('Failed to create insight:', data);
-        if (callback) callback(data, status);
+    params => {
+      if (params.status === 'Bad Request') {
+        console.error('Failed to create insight:', params.data);
+        if (callback) callback(params);
         return;
       }
 
-      if (!data || typeof data !== 'object') {
-        console.error('Invalid response data', data);
-        if (callback) callback(null, 'error');
+      if (!params.data || typeof params.data !== 'object') {
+        console.error('Invalid response data', params.data);
         return;
       }
 
-      if (!data.type || !data.id) {
-        console.error('Missing fields in response', data);
-        if (callback) callback(null, 'error');
+      if (!params.data.type || !params.data.id) {
+        console.error('Missing fields in response', params.data);
         return;
       }
 
-      if (callback) callback(data, status);
+      if (callback) callback(params);
     },
   );
 };
@@ -47,33 +45,33 @@ export const wsUpdateInsight: WsFrontendCall<{ id: number; insight: InsightReque
   params,
   callback,
 ) => {
-  Broker.instance().sendMessage(
+  Broker.instance().sendMessage<wsReturnKey.insightResult>(
     {
       key: wsKeys.insight,
       subKey: wsSubKeys.update,
       body: { id: params.id, insight: params.insight, generateEmail: params.generateEmail },
     },
-    (data: any, status: string) => {
-      if (status === 'Bad Request') {
-        console.error('Failed to update insight:', data);
+    params => {
+      if (params.status === 'Bad Request') {
+        console.error('Failed to update insight:', params.data);
       }
-      if (callback) callback(data, status);
+      if (callback) callback(params);
     },
   );
 };
 
 export const wsDeleteInsight: WsFrontendCall<{ id: number }, wsReturnKey.insightResult> = (params, callback) => {
-  Broker.instance().sendMessage(
+  Broker.instance().sendMessage<wsReturnKey.insightResult>(
     {
       key: wsKeys.insight,
       subKey: wsSubKeys.delete,
       body: { id: params.id },
     },
-    (data: any, status: string) => {
-      if (status === 'Bad Request') {
-        console.error('Failed to delete insight:', data);
+    params => {
+      if (params.status === 'Bad Request') {
+        console.error('Failed to delete insight:', params.data);
       }
-      if (callback) callback(data, status);
+      if (callback) callback(params);
     },
   );
 };
diff --git a/src/lib/data-access/broker/wsProject.ts b/src/lib/data-access/broker/wsProject.ts
index 6331bbff98c2f52d68b45a32cf70fc620a8c15c7..c74de8ee07c83702fe42b7595f93c6eb77ff6dbb 100644
--- a/src/lib/data-access/broker/wsProject.ts
+++ b/src/lib/data-access/broker/wsProject.ts
@@ -1,6 +1,6 @@
 import { ProjectModel, ProjectRequest } from 'ts-common/src/model/webSocket/project';
 import { Broker } from './broker';
-import { SaveState, wsKeys, wsReturnKey, wsSubKeys } from 'ts-common';
+import { ResponseCallback, SaveState, WsFrontendCall, wsKeys, wsReturnKey, wsSubKeys } from 'ts-common';
 
 type GetProjectResponse = (data: ProjectModel, status: string) => void;
 type GetProjectsResponse = (data: ProjectModel[], status: string) => void;
@@ -22,96 +22,64 @@ function transformToProjectModel(saveStates: SaveState[]): ProjectModel[] {
         }) as ProjectModel,
     );
 }
-
-export function wsGetProject(userID: number, parentID: number, callback?: GetProjectResponse) {
+export const wsGetProject: WsFrontendCall<{ userID: number; parentID: number }, wsReturnKey.project> = (params, callback) => {
   Broker.instance().sendMessage(
     {
       key: wsKeys.project,
       subKey: wsSubKeys.get,
-      body: { userID: userID, parentID: parentID },
-    },
-    (data: ProjectModel, status: string) => {
-      if (callback) {
-        callback(data, status);
-      }
+      body: { userID: params.userID, parentID: params.parentID },
     },
+    callback,
   );
-}
+};
 
-export function wsGetProjects(userID: number, parentID: number | null, callback?: GetProjectsResponse) {
+export const wsGetProjects: WsFrontendCall<{ userID: number; parentID: number | null }, wsReturnKey.projects> = (params, callback) => {
   Broker.instance().sendMessage(
     {
       key: wsKeys.project,
       subKey: wsSubKeys.getAll,
-      body: { parentID: parentID },
-    },
-    (data: ProjectModel[], status: string) => {
-      if (callback) callback(data, status);
+      body: { parentID: params.parentID },
     },
+    callback,
   );
-}
+};
 
-export function wsCreateProject(project: ProjectRequest, callback?: GetProjectResponse) {
+export const wsCreateProject: WsFrontendCall<{ project: ProjectRequest }, wsReturnKey.project> = (params, callback) => {
   Broker.instance().sendMessage(
     {
       key: wsKeys.project,
-      subKey: wsSubKeys.create,
-      body: project,
-    },
-    (data: ProjectModel, status: string) => {
-      if (callback) {
-        callback(data, status);
-      }
+      subKey: wsSubKeys.getAll,
+      body: params.project,
     },
+    callback,
   );
-}
+};
 
-export function wsUpdateProject(id: number, project: ProjectRequest, callback?: GetProjectResponse) {
+export const wsUpdateProject: WsFrontendCall<{ id: number; project: ProjectRequest }, wsReturnKey.project> = (params, callback) => {
   Broker.instance().sendMessage(
     {
       key: wsKeys.project,
       subKey: wsSubKeys.update,
-      body: { queryID: id, ...project },
-    },
-    (data: SaveState, status: string) => {
-      const projects = transformToProjectModel([data]);
-      if (callback && projects.length > 0) {
-        callback(projects[0], status);
-      } else if (callback) {
-        callback(
-          {
-            id: -1,
-            name: '',
-            parentId: null,
-            createdAt: '',
-            updatedAt: '',
-          },
-          'error',
-        );
-      }
+      body: { queryID: params.id, ...params.project },
     },
+    callback,
   );
-}
+};
 
-export function wsDeleteProject(id: number, callback?: (data: { success: boolean }, status: string) => void) {
+export const wsDeleteProject: WsFrontendCall<{ id: number }, wsReturnKey.project> = (params, callback) => {
   Broker.instance().sendMessage(
     {
       key: wsKeys.project,
       subKey: wsSubKeys.delete,
-      body: { id: id },
+      body: { id: params.id },
     },
     callback,
   );
-}
+};
 
-export function wsProjectSubscription(callback: (data: ProjectModel, status: string) => void) {
-  const id = Broker.instance().subscribe((data: SaveState, status: string) => {
-    const projects = transformToProjectModel([data]);
-    if (projects.length > 0) {
-      callback(projects[0], status);
-    }
-  }, wsReturnKey.project);
+export const wsProjectSubscription = (callback: ResponseCallback<wsReturnKey.project>) => {
+  const id = Broker.instance().subscribe(callback, wsReturnKey.project);
   return () => {
     Broker.instance().unSubscribe(wsReturnKey.project, id);
   };
-}
+};
diff --git a/src/lib/data-access/broker/wsState.ts b/src/lib/data-access/broker/wsState.ts
index be16f46350f73839db7ee03e2bff60c4a486f72a..10028798d9967408e17a1b956095a2d841ac5fe9 100644
--- a/src/lib/data-access/broker/wsState.ts
+++ b/src/lib/data-access/broker/wsState.ts
@@ -118,7 +118,7 @@ export const wsUpdateState: WsFrontendCall<SaveState, wsReturnKey.saveState> = (
 export const wsTestDatabaseConnection: WsFrontendCall<DatabaseInfo, wsReturnKey.testedConnection> = (dbConnection, callback) => {
   if (!dbConnection) {
     console.warn('dbConnection is undefined on wsTestDatabaseConnection');
-    if (callback) callback({ status: 'fail', saveStateID: '' }, 'error');
+    if (callback) callback({ data: { status: 'fail', saveStateID: '' }, status: 'error', defaultCallback: () => {} });
     return;
   }
   Broker.instance().sendMessage(
@@ -131,17 +131,6 @@ export const wsTestDatabaseConnection: WsFrontendCall<DatabaseInfo, wsReturnKey.
   );
 };
 
-export const wsStateGetPolicy: WsFrontendCall<{ saveStateID: string }, wsReturnKey.saveStatesModels> = (params, callback) => {
-  Broker.instance().sendMessage(
-    {
-      key: wsKeys.state,
-      subKey: wsSubKeys.getPolicy,
-      body: { saveStateID: params.saveStateID },
-    },
-    callback,
-  );
-};
-
 export const wsShareSaveState: WsFrontendCall<StateSetPolicyRequest, wsReturnKey.shareSaveState> = (request, callback) => {
   Broker.instance().sendMessage(
     {
diff --git a/src/lib/data-access/store/hooks.ts b/src/lib/data-access/store/hooks.ts
index 07b22cd3b06d6e4cca534e5470e1533725ae7718..6141da472e1f46381059f584d04702a851d474b3 100644
--- a/src/lib/data-access/store/hooks.ts
+++ b/src/lib/data-access/store/hooks.ts
@@ -4,14 +4,7 @@ import { schemaGraph, selectSchemaLayout, schemaSettingsState, schemaStatsState,
 import type { RootState, AppDispatch } from './store';
 import { ConfigStateI, configState } from '@/lib/data-access/store/configSlice';
 
-import {
-  activeSaveState,
-  activeSaveStateAuthorization,
-  activeSaveStateQuery,
-  selectQuerybuilderHash,
-  SessionCacheI,
-  sessionCacheState,
-} from './sessionSlice';
+import { activeSaveState, activeSaveStateQuery, selectQuerybuilderHash, SessionCacheI, sessionCacheState } from './sessionSlice';
 import { AuthSliceState, authState } from './authSlice';
 import { visualizationState, VisState, visualizationActive } from './visualizationSlice';
 import { allMLEnabled, selectML } from './mlSlice';
@@ -24,7 +17,6 @@ import {
   SearchCategoryMapI,
   CategoryDataI,
 } from './searchResultSlice';
-import { AllLayoutAlgorithms } from '../../graph-layout';
 import { SchemaGraph } from '../../schema';
 import { SelectionStateI, FocusStateI, focusState, selectionState } from './interactionSlice';
 import { VisualizationSettingsType } from '../../vis/common';
@@ -32,19 +24,20 @@ import { PolicyUsersState, selectPolicyState } from './authorizationUsersSlice';
 import { selectResourcesPolicyState } from './authorizationResourcesSlice';
 import { selectInsights } from './insightSharingSlice';
 import {
-  SchemaGraphStats,
-  QueryGraphEdgeHandle,
   PolicyResourcesState,
   InsightModel,
-  QueryBuilderSettings,
   ML,
   GraphStatistics,
   SaveState,
   SaveStateAuthorizationHeaders,
   Query,
   SchemaSettings,
+  SchemaStatsFromBackend,
+  SchemaGraphStats,
+  SaveStateWithAuthorization,
 } from 'ts-common';
 import { ProjectState, selectProject } from './projectSlice';
+import { AllLayoutAlgorithms } from 'ts-common/src/model/layouts';
 
 // Use throughout your app instead of plain `useDispatch` and `useSelector`
 export const useAppDispatch: () => AppDispatch = useDispatch;
@@ -73,8 +66,7 @@ export const useQuerybuilderHash: () => string = () => useAppSelector(selectQuer
 // Overall Configuration of the app
 export const useConfig: () => ConfigStateI = () => useAppSelector(configState);
 export const useSessionCache: () => SessionCacheI = () => useAppSelector(sessionCacheState);
-export const useActiveSaveState: () => SaveState | undefined = () => useAppSelector(activeSaveState);
-export const useActiveSaveStateAuthorization: () => SaveStateAuthorizationHeaders = () => useAppSelector(activeSaveStateAuthorization);
+export const useActiveSaveState: () => SaveStateWithAuthorization | undefined = () => useAppSelector(activeSaveState);
 export const useAuthCache: () => AuthSliceState = () => useAppSelector(authState);
 
 // Machine Learning Slices
diff --git a/src/lib/data-access/store/sessionSlice.ts b/src/lib/data-access/store/sessionSlice.ts
index 5ac64ef655b0e937a76e1f23d2d7263dfcb03cfb..cf7d308b0d7638852a209f270952781ae3b8d7a2 100644
--- a/src/lib/data-access/store/sessionSlice.ts
+++ b/src/lib/data-access/store/sessionSlice.ts
@@ -14,6 +14,7 @@ import {
   QueryUnionType,
   SaveState,
   SaveStateAuthorizationHeaders,
+  SaveStateWithAuthorization,
 } from 'ts-common';
 import { QueryMultiGraphology } from '@/lib/querybuilder';
 import { MultiGraph } from 'graphology';
@@ -29,8 +30,7 @@ export type ErrorMessage = {
 /** Cache type */
 export type SessionCacheI = {
   currentSaveState?: string; // id of the current save state
-  saveStates: Record<string, SaveState>;
-  saveStatesAuthorization: Record<string, SaveStateAuthorizationHeaders>;
+  saveStates: Record<string, SaveStateWithAuthorization>;
   fetchingSaveStates: boolean;
   testedSaveState: Record<string, DatabaseStatus>;
 };
@@ -47,7 +47,6 @@ const newStateAuthorizationHeaders: SaveStateAuthorizationHeaders = {
 export const initialState: SessionCacheI = {
   currentSaveState: undefined,
   saveStates: {},
-  saveStatesAuthorization: {},
   fetchingSaveStates: true, // default to true to prevent flashing of the UI
   testedSaveState: {},
 };
@@ -68,29 +67,21 @@ export const sessionSlice = createSlice({
       }
       setParam(URLParams.saveState, action.payload);
     },
-    updateSelectedSaveState: (state: SessionCacheI, action: PayloadAction<SaveState>) => {
+    updateSelectedSaveState: (state: SessionCacheI, action: PayloadAction<SaveStateWithAuthorization>) => {
       if (state.currentSaveState === action.payload.id && state.currentSaveState) state.saveStates[state.currentSaveState] = action.payload;
     },
-    updateSaveStateList: (state: SessionCacheI, action: PayloadAction<SaveState[]>) => {
+    updateSaveStateList: (state: SessionCacheI, action: PayloadAction<SaveStateWithAuthorization[]>) => {
       // Does NOT clear the states, just adds in new data
-      const newState: Record<string, SaveState> = {};
+      const newState: Record<string, SaveStateWithAuthorization> = {};
       if (!action.payload) return;
-      action.payload.forEach((ss: SaveState) => {
+      action.payload.forEach(ss => {
         newState[ss.id] = ss;
       });
       state.saveStates = { ...state.saveStates, ...newState };
-      const paramSaveState = getParam(URLParams.saveState);
-      if (!state.currentSaveState) {
-        if (paramSaveState && paramSaveState in state.saveStates) {
-          state.currentSaveState = paramSaveState;
-        } else if (Object.keys(state.saveStates).length > 0) {
-          state.currentSaveState = Object.keys(state.saveStates)[0];
-        } else state.currentSaveState = undefined;
-      }
     },
-    setSaveStateList: (state: SessionCacheI, action: PayloadAction<SaveState[]>) => {
+    setSaveStateList: (state: SessionCacheI, action: PayloadAction<SaveStateWithAuthorization[]>) => {
       // Clears the states and puts in new data
-      const newState: Record<string, SaveState> = {};
+      const newState: Record<string, SaveStateWithAuthorization> = {};
       action.payload.forEach(ss => {
         newState[ss.id] = ss;
       });
@@ -99,36 +90,39 @@ export const sessionSlice = createSlice({
       if (!state.currentSaveState) {
         if (paramSaveState && paramSaveState in state.saveStates) {
           state.currentSaveState = paramSaveState;
+          setParam(URLParams.saveState, paramSaveState);
         } else if (Object.keys(state.saveStates).length > 0) {
           state.currentSaveState = Object.keys(state.saveStates)[0];
-        } else state.currentSaveState = undefined;
+          setParam(URLParams.saveState, state.currentSaveState);
+        } else {
+          state.currentSaveState = undefined;
+          setParam(URLParams.saveState, undefined);
+        }
       }
     },
-    addSaveState: (state: SessionCacheI, action: PayloadAction<SaveState>) => {
+    addSaveState: (state: SessionCacheI, action: PayloadAction<{ ss: SaveStateWithAuthorization; select: boolean }>) => {
       if (state.saveStates === undefined) state.saveStates = {};
-      state.saveStates[action.payload.id] = action.payload;
-      state.currentSaveState = action.payload.id;
-      if (!state.saveStatesAuthorization[action.payload.id]) {
-        state.saveStatesAuthorization[action.payload.id] = cloneDeep(newStateAuthorizationHeaders);
+      state.saveStates[action.payload.ss.id] = action.payload.ss;
+      if (action.payload.select === true) {
+        state.currentSaveState = action.payload.ss.id;
+        setParam(URLParams.saveState, action.payload.ss.id);
       }
     },
     deleteSaveState: (state: SessionCacheI, action: PayloadAction<string>) => {
       delete state.saveStates[action.payload];
-      delete state.saveStatesAuthorization[action.payload];
       if (state.currentSaveState === action.payload) {
-        if (Object.keys(state.saveStates).length > 0) state.currentSaveState = Object.keys(state.saveStates)[0];
-        else state.currentSaveState = undefined;
+        if (Object.keys(state.saveStates).length > 0) {
+          state.currentSaveState = Object.keys(state.saveStates)[0];
+          setParam(URLParams.saveState, state.currentSaveState);
+        } else {
+          state.currentSaveState = undefined;
+          setParam(URLParams.saveState, undefined);
+        }
       }
     },
     testedSaveState: (state: SessionCacheI, action: PayloadAction<{ saveStateID: string; status: DatabaseStatus }>) => {
       state.testedSaveState = { ...state.testedSaveState, [action.payload.saveStateID]: action.payload.status };
     },
-    setStateAuthorization: (state: SessionCacheI, action: PayloadAction<{ id: string; authorization: SaveStateAuthorizationHeaders }>) => {
-      state.saveStatesAuthorization[action.payload.id] = action.payload.authorization;
-    },
-    deleteAuthorization: (state: SessionCacheI, action: PayloadAction<string>) => {
-      delete state.saveStatesAuthorization[action.payload];
-    },
     setQuerybuilderGraph: (state: SessionCacheI, action: PayloadAction<QueryMultiGraph>) => {
       const activeQuery = getActiveQuery(state);
       if (activeQuery) {
@@ -300,8 +294,6 @@ export const {
   testedSaveState,
   setFetchingSaveStates,
   updateSelectedSaveState,
-  setStateAuthorization,
-  deleteAuthorization,
   setQuerybuilderGraph,
   setQuerybuilderSettings,
   setActiveQueryID,
@@ -317,9 +309,10 @@ export const {
   setQueryUnionType,
 } = sessionSlice.actions;
 
-function getActiveSaveState(sessionCache: SessionCacheI): SaveState | undefined {
+function getActiveSaveState(sessionCache: SessionCacheI): SaveStateWithAuthorization | undefined {
   return sessionCache.saveStates?.[sessionCache.currentSaveState!];
 }
+
 function getActiveQuery(state: SessionCacheI): Query | undefined {
   const ss = getActiveSaveState(state);
   if (!ss || !ss.queryStates || !ss.queryStates.activeQueryId || ss.queryStates.activeQueryId === -1) {
@@ -351,9 +344,7 @@ export const toQuerybuilderGraphology = (graph: QueryMultiGraph): QueryMultiGrap
 
 // Other code such as selectors can use the imported `RootState` type
 export const sessionCacheState = (state: RootState) => state.sessionCache;
-export const activeSaveState = (state: RootState): SaveState | undefined => getActiveSaveState(state.sessionCache);
-export const activeSaveStateAuthorization = (state: RootState): SaveStateAuthorizationHeaders =>
-  state.sessionCache.saveStatesAuthorization?.[state.sessionCache.currentSaveState!] || newStateAuthorizationHeaders;
+export const activeSaveState = (state: RootState): SaveStateWithAuthorization | undefined => getActiveSaveState(state.sessionCache);
 
 export default sessionSlice.reducer;
 
diff --git a/src/lib/graph-layout/layoutCreatorUsecase.ts b/src/lib/graph-layout/layoutCreatorUsecase.ts
index aaef9951b2dadeb35a50c1ea4e4f50d8f20ecae8..36128f63ce1a5da26c28f9102533ab1a48e87135 100644
--- a/src/lib/graph-layout/layoutCreatorUsecase.ts
+++ b/src/lib/graph-layout/layoutCreatorUsecase.ts
@@ -1,14 +1,14 @@
-import { CytoscapeFactory } from './cytoscapeLayouts';
-import { DagreFactory } from './dagreLayout';
-import { GraphologyFactory } from './graphologyLayouts';
-import { ListLayoutFactory } from './listLayouts';
-import { AlgorithmToLayoutProvider } from './types';
 import {
   AllLayoutAlgorithms,
-  CytoscapeLayoutAlgorithms,
   GraphologyLayoutAlgorithms,
+  CytoscapeLayoutAlgorithms,
   ListLayoutAlgorithms,
 } from 'ts-common/src/model/layouts';
+import { CytoscapeFactory } from './cytoscapeLayouts';
+import { DagreFactory, DagreLayouts } from './dagreLayout';
+import { GraphologyFactory } from './graphologyLayouts';
+import { ListLayoutFactory } from './listLayouts';
+import { AlgorithmToLayoutProvider } from './types';
 
 export interface ILayoutFactory<Algorithm extends AllLayoutAlgorithms> {
   createLayout: (Algorithm: Algorithm) => AlgorithmToLayoutProvider<Algorithm> | null;
@@ -34,6 +34,10 @@ export class LayoutFactory implements ILayoutFactory<AllLayoutAlgorithms> {
   createLayout<Algorithm extends AllLayoutAlgorithms = AllLayoutAlgorithms>(
     layoutAlgorithm: Algorithm,
   ): AlgorithmToLayoutProvider<Algorithm> {
+    if (layoutAlgorithm == null) {
+      layoutAlgorithm = 'Dagre_Dagre' as Algorithm;
+    }
+
     if (this.isSpecificAlgorithm<GraphologyLayoutAlgorithms>(layoutAlgorithm, 'Graphology')) {
       return this.graphologyFactory.createLayout(layoutAlgorithm) as AlgorithmToLayoutProvider<Algorithm>;
     }
diff --git a/src/lib/insight-sharing/InsightDialog.tsx b/src/lib/insight-sharing/InsightDialog.tsx
index 6f9c4a1cf70b89033f401df287558575397e1e7f..0b5dbeb1ca911fed177092302224103d79206da0 100644
--- a/src/lib/insight-sharing/InsightDialog.tsx
+++ b/src/lib/insight-sharing/InsightDialog.tsx
@@ -30,7 +30,7 @@ export function InsightDialog(props: Props) {
       return;
     }
 
-    wsDeleteInsight({ id: insight.id }, (data, status) => {
+    wsDeleteInsight({ id: insight.id }, ({ data, status }) => {
       if (status === 'success') {
         dispatch(deleteInsight({ id: insight.id }));
         if (active === insight.id) {
@@ -48,7 +48,7 @@ export function InsightDialog(props: Props) {
   const handleSave = (insight: InsightModel | InsightRequest, generateEmail: boolean) => {
     if (Object.prototype.hasOwnProperty.call(insight, 'id')) {
       const updatedInsight = insight as InsightModel;
-      wsUpdateInsight({ id: updatedInsight.id, insight: updatedInsight, generateEmail }, (data, status) => {
+      wsUpdateInsight({ id: updatedInsight.id, insight: updatedInsight, generateEmail }, ({ data, status }) => {
         if (status === 'success' && data) {
           dispatch(updateInsight(data));
           dispatch(addSuccess(`${insight.type} updated successfully`));
@@ -60,7 +60,7 @@ export function InsightDialog(props: Props) {
       });
     } else {
       const newInsight = insight as InsightRequest;
-      wsCreateInsight(newInsight, (data, status) => {
+      wsCreateInsight(newInsight, ({ data, status }) => {
         if (status === 'success' && data) {
           dispatch(addInsight(data));
           dispatch(addSuccess(`${insight.type} created successfully`));
diff --git a/src/lib/insight-sharing/components/Sidebar.tsx b/src/lib/insight-sharing/components/Sidebar.tsx
index 75d418a9b0ee6f39bd3614feee97c32519849144..3cdefb473430ea292322d8160c794dc6c09acf04 100644
--- a/src/lib/insight-sharing/components/Sidebar.tsx
+++ b/src/lib/insight-sharing/components/Sidebar.tsx
@@ -5,6 +5,7 @@ import { useAppDispatch, useInsights } from '../../data-access';
 import { setInsights } from '../../data-access/store/insightSharingSlice';
 import { useSessionCache } from '../../data-access';
 import { wsGetInsights } from '../../data-access/broker/wsInsightSharing';
+import { addError } from '@/lib/data-access/store/configSlice';
 
 export type MonitorType = 'report' | 'alert';
 
@@ -20,7 +21,13 @@ export function Sidebar(props: SidebarProps) {
 
   useEffect(() => {
     if (session.currentSaveState && session.currentSaveState !== '') {
-      wsGetInsights({ saveStateId: session.currentSaveState }, (data: any) => {
+      wsGetInsights({ saveStateId: session.currentSaveState }, ({ data, status }) => {
+        if (status !== 'success') {
+          console.error('Failed to get insights:', data);
+          dispatch(addError('Failed to get insights'));
+          return;
+        }
+
         dispatch(setInsights(data));
       });
     }
diff --git a/src/lib/management/database/Databases.tsx b/src/lib/management/database/Databases.tsx
index a5db1e43832134c9a21a2300b5be532c0ece8a6d..78b3b14e3003556847f95e112706e07687cb512e 100644
--- a/src/lib/management/database/Databases.tsx
+++ b/src/lib/management/database/Databases.tsx
@@ -12,10 +12,10 @@ import {
   useSessionCache,
   wsDeleteState,
 } from '../..';
-import { clearQB, deleteSaveState, selectSaveState } from '../../data-access/store/sessionSlice';
+import { clearQB, deleteSaveState } from '../../data-access/store/sessionSlice';
 import { clearSchema } from '../../data-access/store/schemaSlice';
 import { useHandleDatabase } from './useHandleDatabase';
-import { CountQueryResultFromBackend, SaveState } from 'ts-common';
+import { SaveState } from 'ts-common';
 
 // --- Add the imports for project functionality ---
 import { addProject, setCurrentProject, setProjects, deleteProject, addToPath } from '../../data-access/store/projectSlice';
@@ -65,8 +65,6 @@ export function Databases({ onClose, saveStates, changeActive, setSelectedSaveSt
   const databaseHandler = useHandleDatabase();
   const [orderBy, setOrderBy] = useState<[DatabaseTableHeaderTypes, 'asc' | 'desc']>(['name', 'desc']);
   const [sharing, setSharing] = useState<boolean>(false);
-  const activeQuery = useActiveQuery();
-  const queryResult = useGraphQueryResult();
 
   const projectState = useProjects();
   const [showNewProjectDialog, setShowNewProjectDialog] = useState(false);
@@ -74,16 +72,10 @@ export function Databases({ onClose, saveStates, changeActive, setSelectedSaveSt
   const [showDifferentiation, setShowDifferentiation] = useState(false);
   const [showQueries, setShowQueries] = useState(false);
 
-  const configVisuals = {
-    classNameVisuals: 'h-10',
-    marginPercentage: { top: 0.1, right: 0.07, left: 0.07, bottom: 0.1 },
-    maxValue: 1,
-  };
-
   // load projects from DB on path change
   useEffect(() => {
-    wsGetProjects(authCache.authentication?.userID || -1, projectState.currentProject?.id ?? null, projects => {
-      dispatch(setProjects(projects));
+    wsGetProjects({ userID: authCache.authentication?.userID || -1, parentID: projectState.currentProject?.id ?? null }, ({ data }) => {
+      dispatch(setProjects(data));
     });
   }, [projectState.currentPath]);
 
@@ -141,68 +133,30 @@ export function Databases({ onClose, saveStates, changeActive, setSelectedSaveSt
     if (newProjectName) {
       wsCreateProject(
         {
-          name: newProjectName,
-          parent: projectState.currentProject?.id ?? null,
-          userID: authCache.authentication?.userID || -1,
+          project: {
+            name: newProjectName,
+            parent: projectState.currentProject?.id ?? null,
+            userID: authCache.authentication?.userID || -1,
+          },
         },
-        (data, status) => {
+        ({ data, status }) => {
           if (status === 'success' && data) {
             dispatch(addProject(data));
             setShowNewProjectDialog(false);
             setNewProjectName('');
 
-            wsGetProjects(authCache.authentication?.userID || -1, projectState.currentProject?.id ?? null, projects => {
-              dispatch(setProjects(projects));
-            });
+            wsGetProjects(
+              { userID: authCache.authentication?.userID || -1, parentID: projectState.currentProject?.id ?? null },
+              ({ data }) => {
+                dispatch(setProjects(data));
+              },
+            );
           }
         },
       );
     }
   };
 
-  function differentiationFor(saveStateId: string, queryIndex: number = 0) {
-    const saveState = session.saveStates[saveStateId];
-    const query = saveState?.queryStates.openQueryArray[queryIndex];
-
-    // For the current query, use the most up to date results from queryresultslice
-    let nodeCountsObj: CountQueryResultFromBackend | undefined;
-    if (activeQuery != null && activeQuery.id == query.id) {
-      nodeCountsObj = queryResult.nodeCounts ?? query.graph?.nodeCounts;
-    } else {
-      nodeCountsObj = query.graph?.nodeCounts;
-    }
-
-    if (nodeCountsObj == null || saveState?.schemas[0]?.stats == null) return 0;
-
-    const nodeCounts = query.graph.nodes
-      .filter(x => x.attributes.type == 'entity')
-      .map(x => ({ name: x.attributes.name, count: nodeCountsObj[`${x.key}_count`] ?? 0 }));
-
-    const totalCounts = query.graph.nodes
-      .filter(x => x.attributes.type == 'entity')
-      .map(x => ({ name: x.attributes.name, count: saveState?.schemas[0].stats?.nodes?.stats[x.attributes.name]?.count ?? 0 }));
-
-    const diffs = nodeCounts.map((x, i) => x.count / totalCounts[i].count);
-    const score = diffs.reduce((a, b) => a + b) / diffs.length;
-
-    return Math.round(score * 100) / 100;
-  }
-
-  function timestampFor(saveStateId: string, queryIndex: number = 0) {
-    const saveState = session.saveStates[saveStateId];
-    const query = saveState?.queryStates.openQueryArray[queryIndex];
-
-    if (query.graph?.nodeCounts == null || query.graph.nodeCounts.updatedAt == null) return 'unknown';
-
-    return new Date(query.graph.nodeCounts.updatedAt).toLocaleString('nl-NL', {
-      month: '2-digit',
-      day: '2-digit',
-      year: 'numeric',
-      hour: '2-digit',
-      minute: '2-digit',
-    });
-  }
-
   return (
     <div className="flex flex-col gap-4">
       <div className="flex justify-between items-start">
@@ -282,7 +236,7 @@ export function Databases({ onClose, saveStates, changeActive, setSelectedSaveSt
                   iconComponent="icon-[mdi--trash-outline]"
                   variant="ghost"
                   onClick={() => {
-                    wsDeleteProject(project.id);
+                    wsDeleteProject({ id: project.id });
                     dispatch(deleteProject(project.id));
                   }}
                 />
@@ -292,46 +246,43 @@ export function Databases({ onClose, saveStates, changeActive, setSelectedSaveSt
           ))}
 
           {orderedSaveStates.map(key => (
-            <>
-              <DatabaseLine
-                saveState={saveStates[key]}
-                onSelect={() => {
-                  if (key !== session.currentSaveState) {
-                    dispatch(clearSchema());
-                    dispatch(selectSaveState(key));
-                    onClose();
-                  }
-                }}
-                onUpdate={() => {
-                  changeActive('update');
-                  setSelectedSaveState(saveStates[key]);
-                }}
-                onClone={() => {
-                  databaseHandler.submitDatabaseChange(
-                    { ...saveStates[key], name: saveStates[key].name + ' (copy)', id: nilUUID },
-                    'add',
-                    true,
-                    () => {},
-                  );
-                  setSelectedSaveState(saveStates[key]);
-                }}
-                onDelete={() => {
-                  if (session.currentSaveState === key) {
-                    dispatch(clearQB());
-                    dispatch(clearSchema());
-                  }
-                  wsDeleteState({ saveStateID: key });
-                  dispatch(deleteSaveState(key));
-                }}
-                onShare={async () => {
-                  setSharing(true);
-                  await auth.shareLink();
-                  setSharing(false);
-                }}
-                showDifferentiation={showDifferentiation}
-                showQueries={showQueries}
-              />
-            </>
+            <DatabaseLine
+              key={key}
+              saveState={saveStates[key]}
+              onSelect={() => {
+                if (key !== session.currentSaveState) {
+                  onClose();
+                }
+              }}
+              onUpdate={() => {
+                changeActive('update');
+                setSelectedSaveState(saveStates[key]);
+              }}
+              onClone={() => {
+                databaseHandler.submitDatabaseChange(
+                  { ...saveStates[key], name: saveStates[key].name + ' (copy)', id: nilUUID },
+                  'add',
+                  true,
+                  () => {},
+                );
+                setSelectedSaveState(saveStates[key]);
+              }}
+              onDelete={() => {
+                if (session.currentSaveState === key) {
+                  dispatch(clearQB());
+                  dispatch(clearSchema());
+                }
+                wsDeleteState({ saveStateID: key });
+                dispatch(deleteSaveState(key));
+              }}
+              onShare={async () => {
+                setSharing(true);
+                await auth.shareLink();
+                setSharing(false);
+              }}
+              showDifferentiation={showDifferentiation}
+              showQueries={showQueries}
+            />
           ))}
         </tbody>
       </table>
diff --git a/src/lib/management/database/useHandleDatabase.ts b/src/lib/management/database/useHandleDatabase.ts
index 3bc79f09286ac7d917ce11e352be9b83265587f3..7f9512ce9e468f940851903f88334400c32b1b74 100644
--- a/src/lib/management/database/useHandleDatabase.ts
+++ b/src/lib/management/database/useHandleDatabase.ts
@@ -10,7 +10,7 @@ import {
 import { useState } from 'react';
 import { addSaveState, selectSaveState, testedSaveState } from '../../data-access/store/sessionSlice';
 import { setSchemaLoading } from '../../data-access/store/schemaSlice';
-import { PartialSaveState, SaveState } from 'ts-common';
+import { PartialSaveState, SaveState, SaveStateWithAuthorization } from 'ts-common';
 import { addError } from '@/lib/data-access/store/configSlice';
 import { wsAddQuery, wsUpdateQuery } from '@/lib/data-access/broker';
 
@@ -50,7 +50,8 @@ export const useHandleDatabase = () => {
       newSaveStateData.project = null;
     }
 
-    wsTestDatabaseConnection(newSaveStateData.dbConnections?.[0], data => {
+    wsTestDatabaseConnection(newSaveStateData.dbConnections?.[0], params => {
+      const data = params.data;
       if (!newSaveStateData) {
         console.error('formData is null');
         return;
@@ -72,66 +73,70 @@ export const useHandleDatabase = () => {
           const queryStateToClone = JSON.parse(JSON.stringify(newSaveStateData.queryStates ?? {}));
           delete newSaveStateData.queryStates;
 
-          wsCreateState(newSaveStateData, async newSaveState => {
-            if (!newSaveState) {
-              dispatch(addError('Failed to create new save state.'));
-              return;
-            }
-
-            // Only if we are adding a save state that is cloned and contains a queryState
-            if (newSaveStateData.queryStates != null) {
-              // Clone query state
-              for (const i in queryStateToClone.openQueryArray) {
-                const query = queryStateToClone.openQueryArray[i];
-                delete query.id;
+          wsCreateState(newSaveStateData, params => {
+            (async (newSaveState: SaveStateWithAuthorization) => {
+              if (!newSaveState) {
+                dispatch(addError('Failed to create new save state.'));
+                return;
+              }
 
-                await new Promise<void>((resolve, reject) => {
-                  if (Number(i) == 0) {
-                    query.id = newSaveState.queryStates.openQueryArray[0].id;
-                    queryStateToClone.activeQuery = query.id;
-                    wsUpdateQuery({ saveStateID: newSaveState.id, query: query }, query => {
-                      if (query == null) return reject();
-                      return resolve();
-                    });
-                  } else {
-                    wsAddQuery({ saveStateID: newSaveState.id }, newQuery => {
-                      if (newQuery == null) {
-                        return reject('Failed to create new save state (query state).');
-                      }
-                      query.id = newQuery.id;
-                      queryStateToClone.activeQueryId = query.id;
+              // Only if we are adding a save state that is cloned and contains a queryState
+              if (newSaveStateData.queryStates != null) {
+                // Clone query state
+                for (const i in queryStateToClone.openQueryArray) {
+                  const query = queryStateToClone.openQueryArray[i];
+                  delete query.id;
 
-                      wsUpdateQuery({ saveStateID: newSaveState.id, query: query }, query => {
-                        if (query == null) reject();
+                  await new Promise<void>((resolve, reject) => {
+                    if (Number(i) == 0) {
+                      query.id = newSaveState.queryStates.openQueryArray[0].id;
+                      queryStateToClone.activeQuery = query.id;
+                      wsUpdateQuery({ saveStateID: newSaveState.id, query: query }, params => {
+                        if (params.data == null) return reject();
                         return resolve();
                       });
-                    });
-                  }
-                });
-              }
+                    } else {
+                      wsAddQuery({ saveStateID: newSaveState.id }, params => {
+                        const newQuery = params.data;
+                        if (newQuery == null) {
+                          return reject('Failed to create new save state (query state).');
+                        }
+                        query.id = newQuery.id;
+                        queryStateToClone.activeQueryId = query.id;
 
-              newSaveState.queryStates = queryStateToClone;
-            }
+                        wsUpdateQuery({ saveStateID: newSaveState.id, query: query }, params => {
+                          if (params.data == null) reject();
+                          return resolve();
+                        });
+                      });
+                    }
+                  });
+                }
 
-            dispatch(addSaveState(newSaveState));
-            dispatch(testedSaveState({ saveStateID: newSaveState.id, status: DatabaseStatus.untested }));
-            setConnectionStatus({
-              updating: false,
-              status: null,
-              verified: null,
-            });
-            concludedCallback();
+                newSaveState.queryStates = queryStateToClone;
+              }
+
+              dispatch(addSaveState({ ss: newSaveState, select: true }));
+              setConnectionStatus({
+                updating: false,
+                status: null,
+                verified: null,
+              });
+              concludedCallback();
+            })(params.data);
           });
         } else {
           if (data.saveStateID) {
             dispatch(testedSaveState({ saveStateID: data.saveStateID, status: DatabaseStatus.untested }));
           }
-          wsUpdateState(newSaveStateData as SaveState, updatedSaveState => {
+          wsUpdateState(newSaveStateData as SaveState, params => {
+            const updatedSaveState = params.data;
+
             if (!updatedSaveState) {
               dispatch(addError('Failed to update save state.'));
               return;
             }
-            dispatch(addSaveState(updatedSaveState));
+            dispatch(addSaveState({ ss: updatedSaveState, select: true }));
             setConnectionStatus({
               updating: false,
               status: null,
diff --git a/src/lib/querybuilder/model/graphology/utils.ts b/src/lib/querybuilder/model/graphology/utils.ts
index ae91d32469639a37892e15b4a3ee7382444beda8..5e830e6f40ef9797e153da0e25f86766fb0f4271 100644
--- a/src/lib/querybuilder/model/graphology/utils.ts
+++ b/src/lib/querybuilder/model/graphology/utils.ts
@@ -51,7 +51,7 @@ export class QueryMultiGraphology extends MultiGraph<QueryGraphNodes, QueryGraph
     attributes.width = width;
     attributes.height = height;
 
-    if (!attributes.id) attributes.id = 'id_' + (Date.now() + Math.floor(Math.random() * 1000)).toString();
+    if (!attributes.id) attributes.id = 'id_' + this.nodes().length;
 
     // Add to the beginning the meta attributes, such as (# Connection)
     attributes.attributes = [...checkForMetaAttributes(attributes).map(a => ({ handleData: a })), ...attributes.attributes];
diff --git a/src/lib/querybuilder/panel/QueryBuilder.tsx b/src/lib/querybuilder/panel/QueryBuilder.tsx
index cb885cfe7abc6b13c5b761ea344372570bf102a2..2cc8c16338a67acde136b2fa1c60786af2c1cb6a 100644
--- a/src/lib/querybuilder/panel/QueryBuilder.tsx
+++ b/src/lib/querybuilder/panel/QueryBuilder.tsx
@@ -1,7 +1,6 @@
 import {
   useActiveQuery,
   useActiveSaveState,
-  useActiveSaveStateAuthorization,
   useAppDispatch,
   useConfig,
   useQuerybuilderHash,
@@ -64,9 +63,8 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => {
   const [toggleSettings, setToggleSettings] = useState<QueryBuilderToggleSettings>();
   const reactFlowWrapper = useRef<HTMLDivElement>(null);
   const reactFlowRef = useRef<HTMLDivElement>(null);
-  const activeSS = useActiveSaveState();
+  const ss = useActiveSaveState();
   const activeQuery = useActiveQuery();
-  const saveStateAuthorization = useActiveSaveStateAuthorization();
 
   const schemaGraph = useSchemaGraph();
   const schema = useMemo(() => toSchemaGraphology(schemaGraph), [schemaGraph]);
@@ -116,7 +114,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => {
    *  TODO: only works if the node is clicked and not moved (maybe use onSelectionChange)
    */
   function onNodesDelete(nodes: Node[]) {
-    if (!saveStateAuthorization.query.W) return;
+    if (!ss?.authorization.query.W) return;
     nodes.forEach(n => {
       graphologyGraph.dropNode(n.id);
     });
@@ -641,19 +639,19 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => {
             reactFlowInstanceRef.current = reactFlowInstance;
             onInit(reactFlowInstance);
           }}
-          onNodesChange={saveStateAuthorization.query.W ? onNodesChange : () => {}}
-          onDragOver={saveStateAuthorization.query.W ? onDragOver : () => {}}
-          onConnect={saveStateAuthorization.query.W ? onConnect : () => {}}
-          onConnectStart={saveStateAuthorization.query.W ? onConnectStart : () => {}}
-          onConnectEnd={saveStateAuthorization.query.W ? onConnectEnd : () => {}}
+          onNodesChange={ss?.authorization.query.W ? onNodesChange : () => {}}
+          onDragOver={ss?.authorization.query.W ? onDragOver : () => {}}
+          onConnect={ss?.authorization.query.W ? onConnect : () => {}}
+          onConnectStart={ss?.authorization.query.W ? onConnectStart : () => {}}
+          onConnectEnd={ss?.authorization.query.W ? onConnectEnd : () => {}}
           // onNodeMouseEnter={onNodeMouseEnter}
           // onNodeMouseLeave={onNodeMouseLeave}
-          onEdgeUpdate={saveStateAuthorization.query.W ? onEdgeUpdate : () => {}}
-          onEdgeUpdateStart={saveStateAuthorization.query.W ? onEdgeUpdateStart : () => {}}
-          onEdgeUpdateEnd={saveStateAuthorization.query.W ? onEdgeUpdateEnd : () => {}}
-          onDrop={saveStateAuthorization.query.W ? onDrop : () => {}}
+          onEdgeUpdate={ss?.authorization.query.W ? onEdgeUpdate : () => {}}
+          onEdgeUpdateStart={ss?.authorization.query.W ? onEdgeUpdateStart : () => {}}
+          onEdgeUpdateEnd={ss?.authorization.query.W ? onEdgeUpdateEnd : () => {}}
+          onDrop={ss?.authorization.query.W ? onDrop : () => {}}
           // onContextMenu={onContextMenu}
-          onNodeContextMenu={saveStateAuthorization.query.W ? onNodeContextMenu : () => {}}
+          onNodeContextMenu={ss?.authorization.query.W ? onNodeContextMenu : () => {}}
           // onNodesDelete={onNodesDelete}
           // onNodesChange={onNodesChange}
           deleteKeyCode="Backspace"
diff --git a/src/lib/querybuilder/panel/QueryBuilderNav.tsx b/src/lib/querybuilder/panel/QueryBuilderNav.tsx
index f5b6804eba8aebbe24def8b61a5675393b2d17f6..f8bc37f9bb185a28d15eb190d3ccc50db8d4d52f 100644
--- a/src/lib/querybuilder/panel/QueryBuilderNav.tsx
+++ b/src/lib/querybuilder/panel/QueryBuilderNav.tsx
@@ -1,14 +1,7 @@
 import { useEffect, useMemo, useRef, useState } from 'react';
 import { ControlContainer, TooltipProvider, Tooltip, TooltipTrigger, Button, TooltipContent, Input } from '@/lib/components';
 import { Popover, PopoverTrigger, PopoverContent } from '@/lib/components/popover';
-import {
-  useActiveQuery,
-  useActiveSaveState,
-  useActiveSaveStateAuthorization,
-  useAppDispatch,
-  useGraphQueryResult,
-  useML,
-} from '../../data-access';
+import { useActiveQuery, useActiveSaveState, useAppDispatch, useGraphQueryResult, useML } from '../../data-access';
 import {
   clearQB,
   setQuerybuilderSettings,
@@ -25,7 +18,6 @@ import { wsAddQuery, wsDeleteQuery, wsManualQueryRequest, wsUpdateQuery } from '
 import { Tabs, Tab } from '@/lib/components/tabs';
 import { addError } from '@/lib/data-access/store/configSlice';
 import Sortable from 'sortablejs';
-import { Query } from 'ts-common';
 import objectHash from 'object-hash';
 
 export type QueryBuilderToggleSettings = 'settings' | 'ml' | 'logic' | 'relatedNodes' | undefined;
@@ -41,14 +33,14 @@ export type QueryBuilderNavProps = {
 export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
   const dispatch = useAppDispatch();
   const activeQuery = useActiveQuery();
-  const activeSS = useActiveSaveState();
+  const ss = useActiveSaveState();
   const result = useGraphQueryResult();
   const resultSize = useMemo(() => {
     if (!result) return 0;
     return result.nodes.length;
   }, [result]);
   const totalSize = useMemo(() => {
-    if (!activeQuery || !result || !activeSS) return 0;
+    if (!activeQuery || !result || !ss) return 0;
 
     const nodeCounts = activeQuery.graph.nodes
       .filter(x => x.attributes.type == 'entity')
@@ -57,7 +49,6 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
     return nodeCounts.reduce((a, b) => a + b, 0);
   }, [result]);
   const ml = useML();
-  const saveStateAuthorization = useActiveSaveStateAuthorization();
   const [editingIdx, setEditingIdx] = useState<{ idx: number; text: string } | null>(null);
 
   /**
@@ -69,7 +60,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
 
   const tabsRef = useRef<HTMLDivElement | null>(null);
   useEffect(() => {
-    if (!activeSS || !tabsRef.current) return;
+    if (!ss || !tabsRef.current) return;
     const sortable = new Sortable(tabsRef.current, {
       animation: 150,
       draggable: '[data-type="tab"]',
@@ -87,7 +78,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
       },
     });
 
-    const sortedQueries = activeSS.queryStates.openQueryArray
+    const sortedQueries = ss.queryStates.openQueryArray
       .filter(query => query.id != null)
       .sort((a, b) => {
         return a.order < b.order ? -1 : 1;
@@ -97,7 +88,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
     return () => {
       sortable.destroy();
     };
-  }, [activeSS ? objectHash(Object.fromEntries(activeSS?.queryStates.openQueryArray.map(x => [x.id, x.order]))) : null]);
+  }, [ss ? objectHash(Object.fromEntries(ss?.queryStates.openQueryArray.map(x => [x.id, x.order]))) : null]);
 
   const mlEnabled = ml.linkPrediction.enabled || ml.centrality.enabled || ml.communityDetection.enabled || ml.shortestPath.enabled;
 
@@ -105,20 +96,20 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
     wsManualQueryRequest({ query: query });
   };
 
-  if (!activeSS || !activeQuery) {
+  if (!ss || !activeQuery) {
     console.debug('No active query found in query nav');
     return null;
   }
 
   function updateQueryName(text: string) {
-    if (!activeSS || !activeQuery) return;
+    if (!ss || !activeQuery) return;
     wsUpdateQuery(
       {
-        saveStateID: activeSS.id,
+        saveStateID: ss.id,
         query: { ...activeQuery, name: text },
       },
-      (data, state) => {
-        if (state !== 'success') {
+      ({ status }) => {
+        if (status !== 'success') {
           addError('Failed to update query');
         }
 
@@ -143,16 +134,17 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                 variant="ghost"
                 size="xs"
                 iconComponent="icon-[ic--baseline-add]"
+                disabled={!ss?.authorization.database?.W}
                 onClick={async () => {
-                  wsAddQuery({ saveStateID: activeSS.id }, (query, status) => {
-                    if (status !== 'success' || query == null || !query.id || query.id < 0) {
+                  wsAddQuery({ saveStateID: ss.id }, ({ data, status }) => {
+                    if (status !== 'success' || data == null || !data.id || data.id < 0) {
                       console.error('Failed to add query');
                       addError('Failed to add query');
                       return;
                     }
 
-                    console.log('Query added', query);
-                    dispatch(addNewQuery(query));
+                    console.log('Query added', data);
+                    dispatch(addNewQuery(data));
                   });
                 }}
               />
@@ -167,7 +159,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
         ref={tabsRef}
         className={`-my-px overflow-x-auto overflow-y-hidden no-scrollbar divide-x divide-secondary-200 border-x ${result.queryingBackend ? 'pointer-events-none' : ''}`}
       >
-        {activeSS.queryStates.openQueryArray
+        {ss.queryStates.openQueryArray
           .filter(query => query.id != null)
           .sort((a, b) => {
             return a.order < b.order ? -1 : 1;
@@ -220,18 +212,18 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                     {query.name ?? 'Query'}
                   </div>
                 )}
-                {activeSS.queryStates.openQueryArray.filter(query => query.id != null).length > 1 && (
+                {ss.queryStates.openQueryArray.filter(query => query.id != null).length > 1 && (
                   <Button
                     variantType="secondary"
                     variant="ghost"
-                    disabled={!saveStateAuthorization.database?.W}
+                    disabled={!ss?.authorization.database?.W}
                     rounded
                     size="3xs"
                     iconComponent="icon-[ic--baseline-close]"
                     onClick={e => {
                       e.stopPropagation();
                       if (query.id !== undefined) {
-                        wsDeleteQuery({ saveStateID: activeSS.id, queryID: query.id });
+                        wsDeleteQuery({ saveStateID: ss.id, queryID: query.id });
                         dispatch(removeQueryByID(query.id));
                       }
                     }}
@@ -264,10 +256,10 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                   variantType="secondary"
                   variant="ghost"
                   size="xs"
-                  disabled={!saveStateAuthorization.query.W}
+                  disabled={!ss?.authorization.query.W}
                   iconComponent="icon-[ic--baseline-delete]"
                   onClick={() => {
-                    if (saveStateAuthorization.query.W) clearAllNodes();
+                    if (ss?.authorization.query.W) clearAllNodes();
                   }}
                 />
               </TooltipTrigger>
@@ -297,7 +289,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                       variantType="secondary"
                       variant="ghost"
                       size="xs"
-                      disabled={!saveStateAuthorization.query.W}
+                      disabled={!ss?.authorization.query.W}
                       iconComponent="icon-[ic--baseline-settings]"
                       className="query-settings"
                     />
@@ -332,7 +324,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                   variantType="secondary"
                   variant="ghost"
                   size="xs"
-                  disabled={!saveStateAuthorization.query.W}
+                  disabled={!ss?.authorization.query.W}
                   iconComponent="icon-[ic--baseline-difference]"
                   onClick={props.onLogic}
                 />
@@ -349,7 +341,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                       variantType={mlEnabled ? 'primary' : 'secondary'}
                       variant={mlEnabled ? 'outline' : 'ghost'}
                       size="xs"
-                      disabled={!saveStateAuthorization.query.W}
+                      disabled={!ss?.authorization.query.W}
                       iconComponent="icon-[ic--baseline-lightbulb]"
                     />
                   </TooltipTrigger>
@@ -412,7 +404,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                       variantType={activeQuery.settings.limit <= resultSize ? 'primary' : 'secondary'}
                       variant={activeQuery.settings.limit <= resultSize ? 'outline' : 'ghost'}
                       size="xs"
-                      disabled={!saveStateAuthorization.query.W}
+                      disabled={!ss?.authorization.query.W}
                       iconComponent="icon-[ic--baseline-filter-alt]"
                     />
                   </TooltipTrigger>
@@ -442,7 +434,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
               </PopoverContent>
             </Popover>
             <Popover>
-              <PopoverTrigger disabled={!saveStateAuthorization.query.W}>
+              <PopoverTrigger disabled={!ss?.authorization.query.W}>
                 <Tooltip>
                   <TooltipTrigger>
                     <Button variantType="secondary" variant="ghost" size="xs" iconComponent="icon-[ic--baseline-search]" />
diff --git a/src/lib/schema/panel/Schema.tsx b/src/lib/schema/panel/Schema.tsx
index f687967385c46a09a361330f34a895f86b41b15b..814466fac3cef94ef948d85071554dc78bfd02b0 100644
--- a/src/lib/schema/panel/Schema.tsx
+++ b/src/lib/schema/panel/Schema.tsx
@@ -16,7 +16,7 @@ import {
   wsSchemaRequest,
 } from '../../data-access';
 import { setSchemaLoading, toSchemaGraphology } from '../../data-access/store/schemaSlice';
-import { AlgorithmToLayoutProvider, AllLayoutAlgorithms, LayoutFactory } from '../../graph-layout';
+import { AlgorithmToLayoutProvider, LayoutFactory } from '../../graph-layout';
 import { ConnectionDragLine, ConnectionLine } from '../../querybuilder';
 import { SchemaEntityPill } from '../pills/nodes/entity/SchemaEntityPill';
 import { SchemaListEntityPill } from '../pills/nodes/entity/SchemaListEntityPill';
@@ -27,6 +27,7 @@ import { SchemaSettings } from './SchemaSettings';
 import { NodeEdge } from '../pills/edges/NodeEdge';
 import { SelfEdge } from '../pills/edges/SelfEdge';
 import { SchemaLayoutConfig } from './LayoutDescription/SchemaLayoutConfig';
+import { AllLayoutAlgorithms } from 'ts-common/src/model/layouts';
 
 interface Props {
   content?: string;
@@ -55,7 +56,7 @@ const edgeTypes = {
 export const Schema = (props: Props) => {
   const session = useSessionCache();
   const settings = useSchemaSettings();
-  const activeSaveState = useActiveSaveState();
+  const ss = useActiveSaveState();
   const searchResults = useSearchResultSchema();
   const dispatch = useDispatch();
   const [nodes, setNodes, onNodesChange] = useNodesState([] as Node[]);
@@ -89,9 +90,9 @@ export const Schema = (props: Props) => {
   };
 
   const refreshSchema = (useCached: boolean) => {
-    if (!activeSaveState) return;
+    if (!ss) return;
     dispatch(setSchemaLoading(true));
-    wsSchemaRequest({ saveStateID: activeSaveState.id, useCached: useCached }); // No callback, this would override global behavior
+    wsSchemaRequest({ saveStateID: ss.id, useCached: useCached }); // No callback, this would override global behavior
   };
 
   useEffect(() => {
@@ -343,13 +344,14 @@ export const Schema = (props: Props) => {
             <Popover>
               <PopoverTrigger>
                 <Tooltip>
-                  <TooltipTrigger>
+                  <TooltipTrigger disabled={!ss?.authorization.schema.W}>
                     <Button
                       variantType="secondary"
                       variant="ghost"
                       size="xs"
                       iconComponent="icon-[ic--baseline-settings]"
                       className="schema-settings"
+                      disabled={!ss?.authorization.schema.W}
                     />
                   </TooltipTrigger>
                   <TooltipContent>
diff --git a/src/lib/schema/pills/nodes/entity/SchemaEntityPill.tsx b/src/lib/schema/pills/nodes/entity/SchemaEntityPill.tsx
index 0e5b5550770db41c7a47c4312c09b746723f607e..94681bbea81a222b1141e8b8d5a8ba5fb26c3763 100644
--- a/src/lib/schema/pills/nodes/entity/SchemaEntityPill.tsx
+++ b/src/lib/schema/pills/nodes/entity/SchemaEntityPill.tsx
@@ -1,7 +1,7 @@
 import { EntityPill } from '@/lib/components';
 import { Popover, PopoverContent, PopoverTrigger } from '@/lib/components/popover';
 import { NodeDetails } from '@/lib/components/nodeDetails';
-import { useSchemaStats } from '@/lib/data-access';
+import { useActiveSaveState, useSchemaStats } from '@/lib/data-access';
 import React, { useEffect, useMemo, useRef, useState } from 'react';
 import { Handle, NodeProps, Position, useViewport } from 'reactflow';
 import { SchemaReactflowNodeWithFunctions } from '../../../model/reactflow';
@@ -13,6 +13,7 @@ export const SchemaEntityPill = React.memo(({ id, selected, data }: NodeProps<Sc
 
   const viewport = useViewport();
   const schemaStats = useSchemaStats();
+  const ss = useActiveSaveState();
   const ref = useRef<HTMLDivElement>(null);
   /**
    * adds drag functionality in order to be able to drag the entityNode to the schema
@@ -62,7 +63,7 @@ export const SchemaEntityPill = React.memo(({ id, selected, data }: NodeProps<Sc
 
           setOpenPopupLocation(ref.current.getBoundingClientRect());
         }}
-        draggable
+        draggable={ss?.authorization.query.W}
         ref={ref}
       >
         {openPopupLocation !== null && (
@@ -88,7 +89,7 @@ export const SchemaEntityPill = React.memo(({ id, selected, data }: NodeProps<Sc
         )}
 
         <EntityPill
-          draggable
+          draggable={ss?.authorization.query.W}
           title={id}
           withHandles="vertical"
           handleUp={
diff --git a/src/lib/schema/pills/nodes/entity/SchemaListEntityPill.tsx b/src/lib/schema/pills/nodes/entity/SchemaListEntityPill.tsx
index f036c7026bb0b99f272a568fad2f3770b97d74b6..e2e1edda990d000ca376e1645b5f06bca4079667 100644
--- a/src/lib/schema/pills/nodes/entity/SchemaListEntityPill.tsx
+++ b/src/lib/schema/pills/nodes/entity/SchemaListEntityPill.tsx
@@ -1,7 +1,7 @@
 import { EntityPill } from '@/lib/components';
 import { Popover, PopoverContent, PopoverTrigger } from '@/lib/components/popover';
 import { NodeDetails } from '@/lib/components/nodeDetails';
-import { useSchemaStats } from '@/lib/data-access';
+import { useActiveSaveState, useSchemaStats } from '@/lib/data-access';
 import React, { useEffect, useMemo, useRef, useState } from 'react';
 import { Handle, NodeProps, Position, useViewport } from 'reactflow';
 import { SchemaReactflowNodeWithFunctions } from '../../../model/reactflow';
@@ -12,6 +12,7 @@ export const SchemaListEntityPill = React.memo(({ id, selected, data }: NodeProp
   const [openPopupLocation, setOpenPopupLocation] = useState<{ x: number; y: number } | null>(null);
 
   const viewport = useViewport();
+  const ss = useActiveSaveState();
   const schemaStats = useSchemaStats();
 
   const ref = useRef<HTMLDivElement>(null);
@@ -63,7 +64,7 @@ export const SchemaListEntityPill = React.memo(({ id, selected, data }: NodeProp
 
           setOpenPopupLocation(ref.current.getBoundingClientRect());
         }}
-        draggable
+        draggable={ss?.authorization.query.W}
         ref={ref}
       >
         {openPopupLocation !== null && (
@@ -89,7 +90,7 @@ export const SchemaListEntityPill = React.memo(({ id, selected, data }: NodeProp
         )}
 
         <EntityPill
-          draggable
+          draggable={ss?.authorization.query.W}
           title={
             <div className="flex flex-row justify-between items-center">
               <span className="line-clamp-1">{id || ''}</span>
diff --git a/src/lib/schema/pills/nodes/relation/SchemaListRelationPill.tsx b/src/lib/schema/pills/nodes/relation/SchemaListRelationPill.tsx
index c64e4016830570aa6d87ac4dbc8cdf2e7c7de915..c0d8aaf5c9341baf71f32ff6620a0cdb0697a163 100644
--- a/src/lib/schema/pills/nodes/relation/SchemaListRelationPill.tsx
+++ b/src/lib/schema/pills/nodes/relation/SchemaListRelationPill.tsx
@@ -5,7 +5,7 @@ import { SchemaReactflowRelationWithFunctions } from '../../../model/reactflow';
 
 import { Popover, PopoverContent, PopoverTrigger } from '@/lib/components/popover';
 import { NodeDetails } from '@/lib/components/nodeDetails';
-import { useSchemaStats } from '@/lib/data-access';
+import { useActiveSaveState, useSchemaStats } from '@/lib/data-access';
 import { SchemaPopUp } from '../SchemaPopUp/SchemaPopUp';
 import { SchemaEdge, QueryElementTypes } from 'ts-common';
 
@@ -13,6 +13,7 @@ export const SchemaListRelationPill = React.memo(({ id, selected, data, ...props
   const [openPopupLocation, setOpenPopupLocation] = useState<{ x: number; y: number } | null>(null);
 
   const viewport = useViewport();
+  const ss = useActiveSaveState();
   const schemaStats = useSchemaStats();
 
   const ref = useRef<HTMLDivElement>(null);
@@ -70,7 +71,7 @@ export const SchemaListRelationPill = React.memo(({ id, selected, data, ...props
 
           setOpenPopupLocation(ref.current.getBoundingClientRect());
         }}
-        draggable
+        draggable={ss?.authorization.query.W}
         ref={ref}
       >
         {openPopupLocation !== null && (
@@ -100,7 +101,7 @@ export const SchemaListRelationPill = React.memo(({ id, selected, data, ...props
           </Popover>
         )}
         <RelationPill
-          draggable
+          draggable={ss?.authorization.query.W}
           title={
             <div className="flex flex-row justify-between items-center">
               <span className="line-clamp-1">{data.collection || ''}</span>
diff --git a/src/lib/schema/pills/nodes/relation/SchemaRelationPill.tsx b/src/lib/schema/pills/nodes/relation/SchemaRelationPill.tsx
index 316c5d5d6916c2037304b41a22fd9989cf56976d..74a092707a0928c82ead183c578095437b7bd77a 100644
--- a/src/lib/schema/pills/nodes/relation/SchemaRelationPill.tsx
+++ b/src/lib/schema/pills/nodes/relation/SchemaRelationPill.tsx
@@ -6,12 +6,13 @@ import { RelationPill } from '@/lib/components';
 import { Popover, PopoverContent, PopoverTrigger } from '@/lib/components/popover';
 import { NodeDetails } from '@/lib/components/nodeDetails';
 import { SchemaPopUp } from '../SchemaPopUp/SchemaPopUp';
-import { useSchemaStats } from '@/lib/data-access';
+import { useActiveSaveState, useSchemaStats } from '@/lib/data-access';
 
 export const SchemaRelationPill = React.memo(({ id, selected, data, ...props }: NodeProps<SchemaReactflowRelationWithFunctions>) => {
   const [openPopupLocation, setOpenPopupLocation] = useState<{ x: number; y: number } | null>(null);
 
   const viewport = useViewport();
+  const ss = useActiveSaveState();
   const schemaStats = useSchemaStats();
 
   const ref = useRef<HTMLDivElement>(null);
@@ -69,7 +70,7 @@ export const SchemaRelationPill = React.memo(({ id, selected, data, ...props }:
 
           setOpenPopupLocation(ref.current.getBoundingClientRect());
         }}
-        draggable
+        draggable={ss?.authorization.query.W}
         ref={ref}
       >
         {openPopupLocation !== null && (
@@ -99,7 +100,7 @@ export const SchemaRelationPill = React.memo(({ id, selected, data, ...props }:
           </Popover>
         )}
         <RelationPill
-          draggable
+          draggable={ss?.authorization.query.W}
           title={data.collection}
           withHandles="vertical"
           handleUp={
diff --git a/src/lib/sidebar/index.tsx b/src/lib/sidebar/index.tsx
index b1639ef801721cc6ad7cc538f1fb3a51fd543c10..341e16e64bdaa225d08a9955b6bc672a9e5b5cc6 100644
--- a/src/lib/sidebar/index.tsx
+++ b/src/lib/sidebar/index.tsx
@@ -2,6 +2,7 @@ import React from 'react';
 import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../components';
 import ColorMode from '../components/color-mode';
 import { FeatureEnabled } from '@/lib/components/featureFlags';
+import { useActiveSaveState } from '..';
 
 export type SideNavTab = 'Schema' | 'Search' | undefined;
 
@@ -30,6 +31,8 @@ export function Sidebar({
   tab: SideNavTab;
   openMonitoringDialog: () => void;
 }) {
+  const ss = useActiveSaveState();
+
   return (
     <div className="side-bar w-fit h-full flex shrink">
       <TooltipProvider>
@@ -65,6 +68,7 @@ export function Sidebar({
                   size="lg"
                   iconComponent="icon-[ic--outline-analytics]"
                   onClick={openMonitoringDialog}
+                  disabled={!ss?.authorization.database.W}
                 />
               </TooltipTrigger>
               <TooltipContent>Insight Sharing</TooltipContent>
diff --git a/src/lib/vis/components/VisualizationPanel.tsx b/src/lib/vis/components/VisualizationPanel.tsx
index c42b3857f7020f51d2fe65f9f60440759e1aa302..049ec1417395d5581c05a55433bcd879bfa5c548 100644
--- a/src/lib/vis/components/VisualizationPanel.tsx
+++ b/src/lib/vis/components/VisualizationPanel.tsx
@@ -102,7 +102,7 @@ export const VisualizationPanel = ({ fullSize }: { fullSize: () => void }) => {
         {graphQueryResult.queryingBackend ? (
           <Querying />
         ) : graphQueryResult.nodes.length === 0 ? (
-          <NoData dataAvailable={!activeQuery || activeQuery.graph.nodes.length > 0} />
+          <NoData />
         ) : openVisualizationArray.length === 0 ? (
           <Recommender />
         ) : (
diff --git a/src/lib/vis/components/VisualizationTabBar.tsx b/src/lib/vis/components/VisualizationTabBar.tsx
index e66341543d3d43332fef3a2f7dd9650a9d542084..d916fab9371a494a6ca8affec9a3361d1f048c30 100644
--- a/src/lib/vis/components/VisualizationTabBar.tsx
+++ b/src/lib/vis/components/VisualizationTabBar.tsx
@@ -3,7 +3,7 @@ import { Button, DropdownContainer, DropdownItem, DropdownItemContainer, Dropdow
 import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../components/tooltip';
 import { ControlContainer } from '../../components/controls';
 import { Tabs, Tab } from '@/lib/components';
-import { useActiveSaveStateAuthorization, useAppDispatch, useVisualization } from '../../data-access';
+import { useActiveSaveState, useAppDispatch, useVisualization } from '../../data-access';
 import {
   addVisualization,
   removeVisualization,
@@ -19,9 +19,10 @@ import { resultSetFocus } from '@/lib/data-access/store/interactionSlice';
 
 export default function VisualizationTabBar(props: { fullSize: () => void; exportImage: () => void; handleSelect: () => void }) {
   const { activeVisualizationIndex, openVisualizationArray } = useVisualization();
-  const saveStateAuthorization = useActiveSaveStateAuthorization();
+
   const [open, setOpen] = useState(false);
   const dispatch = useAppDispatch();
+  const ss = useActiveSaveState();
   const [editingIdx, setEditingIdx] = useState<{ idx: number; text: string } | null>(null);
 
   const tabsRef = useRef<HTMLDivElement | null>(null);
@@ -96,8 +97,15 @@ export default function VisualizationTabBar(props: { fullSize: () => void; expor
           <Tooltip>
             <TooltipTrigger>
               <DropdownContainer open={open} onOpenChange={setOpen}>
-                <DropdownTrigger disabled={!saveStateAuthorization.database?.W} onClick={() => setOpen(v => !v)}>
-                  <Button as="a" variantType="secondary" variant="ghost" size="xs" iconComponent="icon-[ic--baseline-add]" />
+                <DropdownTrigger disabled={!ss?.authorization.database?.W} onClick={() => setOpen(v => !v)}>
+                  <Button
+                    as="a"
+                    variantType="secondary"
+                    variant="ghost"
+                    size="xs"
+                    iconComponent="icon-[ic--baseline-add]"
+                    disabled={!ss?.authorization.database?.W}
+                  />
                 </DropdownTrigger>
                 <DropdownItemContainer className="max-h-none">
                   {Object.values(VisualizationsConfig).map(({ id, displayName, icons }) => (
@@ -175,7 +183,7 @@ export default function VisualizationTabBar(props: { fullSize: () => void; expor
                   <Button
                     variantType="secondary"
                     variant="ghost"
-                    disabled={!saveStateAuthorization.database?.W}
+                    disabled={!ss?.authorization.database?.W}
                     rounded
                     size="3xs"
                     iconComponent="icon-[ic--baseline-close]"
diff --git a/src/lib/vis/views/NoData.tsx b/src/lib/vis/views/NoData.tsx
index f9c9cbc69081e275d10092c73ea153da5c3b1cc0..0454d47aa21d8765806089b90ab50977710b01fb 100644
--- a/src/lib/vis/views/NoData.tsx
+++ b/src/lib/vis/views/NoData.tsx
@@ -1,18 +1,27 @@
 import React from 'react';
 import { Button } from '../../components';
+import { useActiveQuery, useGraphQueryResult, useSessionCache } from '@/lib/data-access';
 
-type Props = { dataAvailable: boolean; error: boolean };
+export function NoData() {
+  const activeQuery = useActiveQuery();
+  const session = useSessionCache();
+  const graphResult = useGraphQueryResult();
+  const dataAvailable = !activeQuery || activeQuery.graph.nodes.length > 0;
 
-export function NoData({ dataAvailable, error }: Props) {
   return (
     <div className="flex justify-center items-center h-full">
       <div className="max-w-lg mx-auto text-left">
         <p className="text-xl font-normal text-secondary-600">No data available to be shown</p>
-        {error ? (
+        {graphResult.error ? (
           <div className="m-3 self-center text-center flex h-full flex-col justify-center">
             <p className="text-xl font-bold text-error">An error occurred while fetching data!</p>
             <p className="">Please retry or contact your Database's Administrator</p>
           </div>
+        ) : !session.currentSaveState ? (
+          <p>
+            <span>No database selected. </span>
+            <span>Please select a database using the database selector on the top left of your screen.</span>
+          </p>
         ) : dataAvailable ? (
           <p>Query resulted in empty dataset</p>
         ) : (
diff --git a/src/lib/vis/views/Recommender.tsx b/src/lib/vis/views/Recommender.tsx
index 209a3adda961dc6a695bf070f04c77513d317ea0..f1c6f5045b6ed825834b7dd4d22bd97fccf91b9d 100644
--- a/src/lib/vis/views/Recommender.tsx
+++ b/src/lib/vis/views/Recommender.tsx
@@ -1,17 +1,17 @@
 import { useState, useRef } from 'react';
 import Info from '../../components/info';
 import { addVisualization } from '../../data-access/store/visualizationSlice';
-import { useActiveSaveStateAuthorization, useAppDispatch } from '../../data-access';
+import { useActiveSaveState, useAppDispatch } from '../../data-access';
 import { Visualizations } from '../components/VisualizationPanel';
 import { VisualizationsConfig } from '../components/config/VisualizationConfig';
 import { resultSetFocus } from '@/lib/data-access/store/interactionSlice';
 
 export function Recommender() {
   const dispatch = useAppDispatch();
-  const saveStateAuthorization = useActiveSaveStateAuthorization();
   const [visualizationDescriptions] = useState(Object.values(VisualizationsConfig));
+  const ss = useActiveSaveState();
 
-  const ref = useRef<HTMLDivElement>();
+  const ref = useRef<HTMLDivElement>(null);
   return (
     <div className="p-4">
       <span className="text-md">Select a visualization</span>
@@ -22,13 +22,13 @@ export function Recommender() {
           return (
             <div
               key={id}
-              className={`group flex flex-row gap-1.5 items-start rounded-md relative p-2 border h-18 ${saveStateAuthorization.visualization.W ? 'cursor-pointer hover:bg-secondary-100' : 'cursor-not-allowed opacity-50'}`}
+              className={`group flex flex-row gap-1.5 items-start rounded-md relative p-2 border h-18 ${ss?.authorization.visualization.W ? 'cursor-pointer hover:bg-secondary-100' : 'cursor-not-allowed opacity-50'}`}
               onClick={async e => {
                 e.preventDefault();
                 // Ensure no new pointer events are passed, preventing doubleclick to open multiple visualizations.
-                ref.current.classList.add('pointer-events-none');
+                ref?.current?.classList.add('pointer-events-none');
 
-                if (!saveStateAuthorization.visualization.W) {
+                if (!ss?.authorization.visualization.W) {
                   console.debug('User blocked from editing query due to being a viewer');
                   return;
                 }
@@ -36,7 +36,7 @@ export function Recommender() {
                 const component = await Visualizations[id]();
                 dispatch(addVisualization({ ...component.default.settings, name: displayName, id }));
 
-                ref.current.classList.remove('pointer-events-none');
+                ref?.current?.classList.remove('pointer-events-none');
               }}
             >
               <div className="text-secondary-500 group-hover:text-secondary-700">