From b75388628791706f7794a40493c7a85dd81b04a6 Mon Sep 17 00:00:00 2001
From: Leonardo Christino <leomilho@gmail.com>
Date: Mon, 4 Dec 2023 17:52:07 +0100
Subject: [PATCH] feat(fix): clear schema and QB on new db

If the database changes, schema and qb are cleared
---
 .../DatabaseManagement/DatabaseSelector.tsx   | 27 ++++++++++---
 libs/shared/lib/data-access/api/database.ts   |  8 +++-
 .../lib/data-access/store/schemaSlice.ts      | 40 ++-----------------
 .../lib/data-access/store/sessionSlice.ts     |  8 ++--
 4 files changed, 35 insertions(+), 48 deletions(-)

diff --git a/apps/web/src/components/navbar/DatabaseManagement/DatabaseSelector.tsx b/apps/web/src/components/navbar/DatabaseManagement/DatabaseSelector.tsx
index 6b1aeb256..bbe88a885 100644
--- a/apps/web/src/components/navbar/DatabaseManagement/DatabaseSelector.tsx
+++ b/apps/web/src/components/navbar/DatabaseManagement/DatabaseSelector.tsx
@@ -6,6 +6,8 @@ import { SettingsForm } from './forms/settings';
 import { NewDatabaseForm } from './forms/AddDatabase/newdatabase';
 import { LoadingSpinner } from '@graphpolaris/shared/lib/components/LoadingSpinner';
 import { addError } from '@graphpolaris/shared/lib/data-access/store/configSlice';
+import { clearQB } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice';
+import { clearSchema } from '@graphpolaris/shared/lib/data-access/store/schemaSlice';
 
 export default function DatabaseSelector({}) {
   const dispatch = useAppDispatch();
@@ -42,7 +44,9 @@ export default function DatabaseSelector({}) {
       timeoutId = setTimeout(() => {
         dispatch(addError("Couldn't establish connection"));
         setConnecting(false);
-        dispatch(updateCurrentDatabase(''));
+        dispatch(updateCurrentDatabase(undefined));
+        dispatch(clearQB());
+        dispatch(clearSchema());
       }, 10000);
     }
 
@@ -74,7 +78,10 @@ export default function DatabaseSelector({}) {
       >
         <div
           className="flex w-full px-4 py-2 hover:bg-slate-200 transition-colors duration-300"
-          onClick={() => setDbSelectionMenuOpen(!dbSelectionMenuOpen)}
+          onClick={() => {
+            if (session.databases?.length === 0) setAddDatabaseFormOpen(true);
+            else setDbSelectionMenuOpen(!dbSelectionMenuOpen);
+          }}
         >
           <div className="flex items-center w-full shrink-0">
             {connecting ? (
@@ -93,11 +100,15 @@ export default function DatabaseSelector({}) {
                   {session.currentDatabase}
                 </p>
               </>
-            ) : session.databases.length == 0 ? (
+            ) : session.databases === undefined ? (
               <>
                 <LoadingSpinner />
                 <p className="ml-2">Retrieving databases</p>
               </>
+            ) : session.databases?.length === 0 ? (
+              <>
+                <p className="ml-2">Add your first Database</p>
+              </>
             ) : (
               <>
                 <div className="h-2 w-2 rounded-full bg-slate-500" />
@@ -107,7 +118,7 @@ export default function DatabaseSelector({}) {
           </div>
           <ArrowDropDown />
         </div>
-        {dbSelectionMenuOpen && (
+        {dbSelectionMenuOpen && session.databases && (
           <div className="absolute w-full top-11 z-50 bg-slate-100 border">
             <div
               className="flex items-center p-2 hover:bg-slate-200"
@@ -119,7 +130,7 @@ export default function DatabaseSelector({}) {
               }}
               title="Add new database"
             >
-              {session.databases.length == 0 ? (
+              {session.databases.length === 0 ? (
                 <>
                   <Add />
                   <p className="ml-2">Add your first database</p>
@@ -141,6 +152,8 @@ export default function DatabaseSelector({}) {
                     setDbSelectionMenuOpen(false);
                     setConnecting(true);
                     dispatch(updateCurrentDatabase(db.Name));
+                    dispatch(clearQB());
+                    dispatch(clearSchema());
                   } else {
                     setDbSelectionMenuOpen(false);
                   }
@@ -174,7 +187,9 @@ export default function DatabaseSelector({}) {
                       className="text-slate-700 hover:text-slate-400 transition-colors duration-300"
                       onClick={(e) => {
                         e.preventDefault();
-                        dispatch(updateCurrentDatabase(''));
+                        dispatch(updateCurrentDatabase(undefined));
+                        dispatch(clearQB());
+                        dispatch(clearSchema());
                         api.DeleteDatabase(db.Name);
                       }}
                       title="Delete database"
diff --git a/libs/shared/lib/data-access/api/database.ts b/libs/shared/lib/data-access/api/database.ts
index 434d430f1..a8bd51911 100644
--- a/libs/shared/lib/data-access/api/database.ts
+++ b/libs/shared/lib/data-access/api/database.ts
@@ -2,6 +2,8 @@
 
 import { useAuth } from '../authorization';
 import { useAppDispatch, useSessionCache } from '../store';
+import { clearQB } from '../store/querybuilderSlice';
+import { clearSchema } from '../store/schemaSlice';
 import { updateCurrentDatabase, updateDatabaseList } from '../store/sessionSlice';
 
 export enum DatabaseType {
@@ -69,7 +71,11 @@ export const useDatabaseAPI = () => {
           if (!response.ok) {
             reject(response.statusText);
           }
-          if (setAsCurrent) dispatch(updateCurrentDatabase(request.name));
+          if (setAsCurrent){ 
+            dispatch(updateCurrentDatabase(request.name));
+            dispatch(clearQB());
+            dispatch(clearSchema());
+          }
           if (updateDatabaseCache) GetAllDatabases({ updateSessionCache: true }).catch(reject);
 
           resolve();
diff --git a/libs/shared/lib/data-access/store/schemaSlice.ts b/libs/shared/lib/data-access/store/schemaSlice.ts
index e3d2103c2..fd7244e55 100644
--- a/libs/shared/lib/data-access/store/schemaSlice.ts
+++ b/libs/shared/lib/data-access/store/schemaSlice.ts
@@ -27,49 +27,17 @@ export const initialState: schemaSliceI = {
 };
 export const schemaSlice = createSlice({
   name: 'schema',
-  // `createSlice` will infer the state type from the `initialState` argument
   initialState,
   reducers: {
     setSchema: (state, action: PayloadAction<SchemaGraph>) => {
-      console.log('setSchema', action);
       state.graph = action.payload;
     },
+    clearSchema: (state) => {
+      state.graph = new SchemaGraphology().export();
+    },
 
     readInSchemaFromBackend: (state, action: PayloadAction<SchemaFromBackend>) => {
       state.graph = SchemaUtils.schemaBackend2Graphology(action.payload).export();
-      // console.log('Updated schema from backend');
-      // The graph schema needs a node for each node AND edge. These need then be connected
-
-      // nodes.forEach((node) => {
-      //   schema.addNode(node.name, {
-      //     name: node.name,
-      //     attributes: node.attributes,
-      //     x: 0,
-      //     y: 0,
-      //   });
-      // });
-
-      // // The name of the edge will be name + from + to, since edge names are not unique
-      // edges.forEach((edge) => {
-      //   const edgeID = edge.name + edge.from + edge.to;
-
-      //   // This node is the actual edge
-      //   schema.addNode(edgeID, {
-      //     name: edge.name,
-      //     attributes: edge.attributes,
-      //     from: edge.from,
-      //     to: edge.to,
-      //     collection: edge.collection,
-      //     x: 0,
-      //     y: 0,
-      //   });
-
-      //   // These lines are simply for keeping the schema together
-      //   schema.addDirectedEdgeWithKey(edgeID + 'f', edge.from, edgeID);
-      //   schema.addDirectedEdgeWithKey(edgeID + 't', edgeID, edge.to);
-      // });
-
-      // state.graphologySerialized = schema.export();
     },
 
     setSchemaSettings: (state, action: PayloadAction<SchemaSettings>) => {
@@ -77,7 +45,7 @@ export const schemaSlice = createSlice({
     },
   },
 });
-export const { readInSchemaFromBackend, setSchema, setSchemaSettings } = schemaSlice.actions;
+export const { readInSchemaFromBackend, setSchema, setSchemaSettings, clearSchema } = schemaSlice.actions;
 
 export const schemaSettingsState = (state: RootState) => state.schema.settings;
 
diff --git a/libs/shared/lib/data-access/store/sessionSlice.ts b/libs/shared/lib/data-access/store/sessionSlice.ts
index f46828da4..89b6ead98 100644
--- a/libs/shared/lib/data-access/store/sessionSlice.ts
+++ b/libs/shared/lib/data-access/store/sessionSlice.ts
@@ -12,13 +12,13 @@ export type ErrorMessage = {
 /** Cache type */
 export type SessionCacheI = {
   currentDatabase?: string;
-  databases: DatabaseInfo[];
+  databases: DatabaseInfo[] | undefined;
 };
 
 // Define the initial state using that type
 export const initialState: SessionCacheI = {
   currentDatabase: undefined,
-  databases: [],
+  databases: undefined,
 };
 
 export const sessionSlice = createSlice({
@@ -26,9 +26,7 @@ export const sessionSlice = createSlice({
   // `createSlice` will infer the state type from the `initialState` argument
   initialState,
   reducers: {
-    updateCurrentDatabase(state, action: PayloadAction<string>) {
-      console.log('Updating current database', state.currentDatabase, action.payload);
-      
+    updateCurrentDatabase(state, action: PayloadAction<string|undefined>) {
       state.currentDatabase = action.payload;
     },
     updateDatabaseList(state, action: PayloadAction<DatabaseInfo[]>) {
-- 
GitLab