diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index 5b999efa470b056e329b4c23a73904e0794bdc2f..0000000000000000000000000000000000000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,10 +0,0 @@
-module.exports = {
-  root: true,
-  // This tells ESLint to load the config from the package `eslint-config-custom`
-  extends: ["custom"],
-  settings: {
-    next: {
-      rootDir: ["apps/*/"],
-    },
-  },
-};
diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index 06cc47d9a23e1a408d6a9e8ff053e019efdf5df2..0000000000000000000000000000000000000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
-  "root": true,
-  "ignorePatterns": ["**/*"],
-  "plugins": ["@nrwl/nx"],
-  "overrides": [
-    {
-      "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
-      "rules": {
-        "@nrwl/nx/enforce-module-boundaries": [
-          "error",
-          {
-            "enforceBuildableLibDependency": true,
-            "allow": [],
-            "depConstraints": [
-              {
-                "sourceTag": "*",
-                "onlyDependOnLibsWithTags": ["*"]
-              }
-            ]
-          }
-        ]
-      }
-    },
-    {
-      "files": ["*.ts", "*.tsx"],
-      "extends": ["plugin:@nrwl/nx/typescript"],
-      "rules": {}
-    },
-    {
-      "files": ["*.js", "*.jsx"],
-      "extends": ["plugin:@nrwl/nx/javascript"],
-      "rules": {}
-    }
-  ]
-}
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 983caf67d8c2ae056ce8d26bcc6d6c5ac76aefcc..bb4060bde39a31be311a9ac6d91e004748f1ec5f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -24,12 +24,12 @@ install:js:
     policy: push
   script:
     - pnpm install
-  only:
-    changes:
-      - pnpm-lock.yaml
-      - .gitlab-ci.yml
-      - apps/**/*
-      - libs/**/*
+  # only:
+  #   changes:
+  #     - pnpm-lock.yaml
+  #     - .gitlab-ci.yml
+  #     - apps/**/*
+  #     - libs/**/*
     # refs:
     #   - main
     #   - merge_requests
diff --git a/apps/web/.eslintignore b/apps/web/.eslintignore
new file mode 100644
index 0000000000000000000000000000000000000000..3421a7d280fba4a93386bc69ccf6ec0b9603a864
--- /dev/null
+++ b/apps/web/.eslintignore
@@ -0,0 +1,3 @@
+node_modules/*
+node_modules/
+node_modules
diff --git a/apps/web/.eslintrc.json b/apps/web/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..2707c1f4120744f9e9e9e736c8aad7cf59a0862c
--- /dev/null
+++ b/apps/web/.eslintrc.json
@@ -0,0 +1,25 @@
+{
+  "extends": ["plugin:react-hooks/recommended"],
+  "parserOptions": {
+    "sourceType": "module",
+    "ecmaVersion": "latest",
+    "ecmaFeatures": {
+      "jsx": true
+    }
+  },
+  "ignorePatterns": ["!**/*"],
+  "overrides": [
+    {
+      "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
+      "rules": {}
+    },
+    {
+      "files": ["*.ts", "*.tsx"],
+      "rules": {}
+    },
+    {
+      "files": ["*.js", "*.jsx"],
+      "rules": {}
+    }
+  ]
+}
diff --git a/apps/web/cssmodule.d.ts b/apps/web/cssmodule.d.ts
deleted file mode 100644
index b98cabe7350407801f45073eb94c0f09a709f8d9..0000000000000000000000000000000000000000
--- a/apps/web/cssmodule.d.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-declare module '*.module.css' {
-    const classes: { readonly [key: string]: string };
-    export default classes;
-}
-
-declare module '*.module.scss' {
-    const classes: { readonly [key: string]: string };
-    export default classes;
-}
-
-declare module '*.module.sass' {
-    const classes: { readonly [key: string]: string };
-    export default classes;
-}
-
-declare module '*.module.less' {
-    const classes: { readonly [key: string]: string };
-    export default classes;
-}
-
-declare module '*.module.styl' {
-    const classes: { readonly [key: string]: string };
-    export default classes;
-}
diff --git a/apps/web/image.d.ts b/apps/web/image.d.ts
deleted file mode 100644
index 9cc005a335c64c1432ee3ebd11d5dcba9b37c0fc..0000000000000000000000000000000000000000
--- a/apps/web/image.d.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/// <reference types="react" />
-/// <reference types="react-dom" />
-
-declare module '*.svg' {
-    import * as React from 'react';
-
-    export const ReactComponent: React.FunctionComponent<
-        React.SVGProps<SVGSVGElement> & { title?: string }
-    >;
-
-    const src: string;
-    export default src;
-}
-
-declare module '*.bmp' {
-    const src: string;
-    export default src;
-}
-
-declare module '*.gif' {
-    const src: string;
-    export default src;
-}
-
-declare module '*.jpg' {
-    const src: string;
-    export default src;
-}
-
-declare module '*.jpeg' {
-    const src: string;
-    export default src;
-}
-
-declare module '*.png' {
-    const src: string;
-    export default src;
-}
-
-declare module '*.avif' {
-    const src: string;
-    export default src;
-}
-
-declare module '*.webp' {
-    const src: string;
-    export default src;
-}
diff --git a/apps/web/package.json b/apps/web/package.json
index 8dd5c441d60f7f287683060569365d39409ec378..7b5586514ec9f3e800540e537476b8013013dec5 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -4,13 +4,17 @@
   "version": "0.0.0",
   "type": "module",
   "scripts": {
-    "dev": "vite",
+    "dev": "vite --host local.graphpolaris.com --port 4200",
+    "dev2": "vite --host local.graphpolaris.com --port 4200",
     "build": "tsc && vite build",
-    "preview": "vite preview"
+    "preview": "vite preview",
+    "lint": "eslint *.ts*",
+    "test": "vitest run"
   },
   "dependencies": {
     "@graphpolaris/shared": "workspace:*",
     "@mui/base": "5.0.0-alpha.118",
+    "@mui/icons-material": "^5.11.11",
     "@mui/material": "^5.11.13",
     "@reduxjs/toolkit": "^1.9.2",
     "graphology": "^0.25.1",
@@ -29,11 +33,13 @@
     "@types/react-dom": "^18.0.11",
     "@types/react-grid-layout": "^1.3.2",
     "@types/styled-components": "^5.1.26",
+    "@vitejs/plugin-basic-ssl": "^1.0.1",
     "@vitejs/plugin-react-swc": "^3.0.0",
     "graphology-types": "^0.24.7",
     "react-is": "^18.2.0",
     "typescript": "^4.9.3",
     "vite": "^4.2.0",
+    "vite-plugin-dts": "^2.1.0",
     "vitest": "^0.29.2"
   }
 }
diff --git a/apps/web/public/assets/icons/ExportIcon.png b/apps/web/public/assets/icons/ExportIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..62976b8a7902bc100cad532959e3d9e0d5fea42c
Binary files /dev/null and b/apps/web/public/assets/icons/ExportIcon.png differ
diff --git a/apps/web/public/assets/login-screen/github.png b/apps/web/public/assets/login-screen/github.png
new file mode 100644
index 0000000000000000000000000000000000000000..55f90676824d4901f6fe7a50ed11f6d4af3d6fef
Binary files /dev/null and b/apps/web/public/assets/login-screen/github.png differ
diff --git a/apps/web/public/assets/login-screen/google.png b/apps/web/public/assets/login-screen/google.png
new file mode 100644
index 0000000000000000000000000000000000000000..f27bb2433042aea5fc34e19fcf90944430ec331b
Binary files /dev/null and b/apps/web/public/assets/login-screen/google.png differ
diff --git a/apps/web/src/app/app.tsx b/apps/web/src/app/app.tsx
index 3b13b1f87fc0d001489670417004f1c10c2327d0..9ae2badfaf7eceda8e4dcb1a6792d14e5751e0b5 100644
--- a/apps/web/src/app/app.tsx
+++ b/apps/web/src/app/app.tsx
@@ -5,47 +5,37 @@ import Panel from '../components/panels/panel';
 import { RawJSONVis } from '@graphpolaris/shared/lib/vis/rawjsonvis/rawjsonvis';
 import SemanticSubstrates from '@graphpolaris/shared/lib/vis/semanticsubstrates/semanticsubstrates';
 import { Schema } from '@graphpolaris/shared/lib/schema/panel';
-import { GetUserInfo } from '@graphpolaris/shared/lib/data-access/api';
-import { QueryBuilder } from '@graphpolaris/shared/lib/querybuilder/panel';
+import {
+  GetAllDatabases,
+  GetUserInfo,
+} from '@graphpolaris/shared/lib/data-access/api';
+import { QueryBuilder } from '@graphpolaris/shared/lib/querybuilder';
 import {
   assignNewGraphQueryResult,
   useAppDispatch,
 } from '@graphpolaris/shared/lib/data-access/store';
-import { AuthorizationHandler } from '@graphpolaris/shared/lib/data-access/authorization';
-
-function useIsAuthorized() {
-  const [userAuthorized, setUserAuthorized] = useState(false);
-
-  const authCallback = async () => {
-    setUserAuthorized(true);
-
-    // Print the user that is currently logged in
-    const user = await GetUserInfo();
-    console.log(user);
-  };
-
-  AuthorizationHandler.instance().setCallback(authCallback);
-
-  // Attempt to Authorize the user
-  const authorize = async () => {
-    const authorized = await AuthorizationHandler.instance().Authorize();
-    setUserAuthorized(authorized);
-  };
-
-  useEffect(() => {
-    authorize();
-  }, []);
-
-  return userAuthorized;
-}
+import {
+  AuthorizationHandler,
+  useAuthorization,
+} from '@graphpolaris/shared/lib/data-access/authorization';
+import { Navbar } from '../components/navbar/navbar';
 
 export function App() {
   const dispatch = useAppDispatch();
-  const userIsAuthorized = useIsAuthorized();
+  const authorization = useAuthorization();
+
+  useEffect(() => {
+    if (authorization.userAuthorized) {
+      GetAllDatabases().then((d) => {
+        console.log(d);
+      });
+    }
+  }, [authorization.userAuthorized]);
 
   return (
     <>
-      {/* {!userIsAuthorized && <LoginScreen />} */}
+      {!authorization.userAuthorized && <LoginScreen />}
+      <Navbar />
       <GridLayout
         className="layout"
         cols={10}
diff --git a/apps/web/src/components/navbar/AddDatabaseForm/add-database-form.module.scss b/apps/web/src/components/navbar/AddDatabaseForm/add-database-form.module.scss
new file mode 100644
index 0000000000000000000000000000000000000000..97642ae3758a844a1c36c7afcb9185993e8c419b
--- /dev/null
+++ b/apps/web/src/components/navbar/AddDatabaseForm/add-database-form.module.scss
@@ -0,0 +1,75 @@
+.wrapper {
+  height: 100vh;
+  display: flex;
+  align-items: center;
+  width: 100vw;
+  background-color: rgba(0, 0, 0, 0.87);
+  position: absolute;
+  z-index: 1225;
+}
+
+.authWrapper {
+  font-family: Poppins, sans-serif;
+  display: flex;
+  flex-direction: column;
+  flex-wrap: wrap;
+  justify-content: center;
+  max-width: 400px;
+  margin: auto;
+  overflow: auto;
+  min-height: 300px;
+  background-color: #f7f8fc;
+  padding: 30px;
+  border-radius: 5px;
+  padding-bottom: 300px;
+}
+
+.header {
+  text-align: center;
+}
+
+.formWrapper {
+}
+
+.loginContainer {
+  margin: 5px 0px !important;
+}
+
+.loginContainerRow {
+  display: flex;
+  flex-direction: row;
+  margin: 5px 0px;
+}
+
+.loginContainerButton {
+  margin-top: 10px !important;
+
+  & button {
+    width: 100%;
+  }
+}
+
+.hostLabel {
+  flex: 1 0 66.66667%;
+
+  & div {
+    width: 95%;
+  }
+}
+
+.portLabel {
+  flex: 1 0 33.33334%;
+}
+
+.userLabel {
+  width: 100%;
+}
+
+passLabel {
+  width: 100%;
+}
+
+cancelButton {
+  margin-top: 2.5%;
+}
+
diff --git a/apps/web/src/components/navbar/AddDatabaseForm/index.tsx b/apps/web/src/components/navbar/AddDatabaseForm/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..54c1b0ac0b9e9aa2066161670b3184a40e82907e
--- /dev/null
+++ b/apps/web/src/components/navbar/AddDatabaseForm/index.tsx
@@ -0,0 +1,205 @@
+/**
+ * This program has been developed by students from the bachelor Computer Science at
+ * Utrecht University within the Software Project course.
+ * © Copyright Utrecht University (Department of Information and Computing Sciences)
+ */
+
+/* istanbul ignore file */
+/* The comment above was added so the code coverage wouldn't count this file towards code coverage.
+ * We do not test components/renderfunctions/styling files.
+ * See testing plan for more details.*/
+import React, { useState } from 'react';
+import { TextField, Button, NativeSelect } from '@mui/material';
+import styles from './add-database-form.module.scss';
+import {
+  AddDatabaseRequest,
+  DatabaseType,
+  databaseNameMapping,
+} from '@graphpolaris/shared/lib/data-access';
+
+/** AddDatabaseFormProps is an interface containing the AuthViewModel. */
+export interface AddDatabaseFormProps {
+  open: boolean;
+  onClose(): void;
+  onSubmit(data: AddDatabaseRequest): void;
+}
+
+/** AddDatabaseFormState is an interface containing the databasehost information. */
+export interface AddDatabaseFormState extends AddDatabaseRequest {
+  // username: string;
+  // password: string;
+  // hostname: string;
+  // port: number;
+  // databaseName: string;
+  // internalDatabase: string;
+  // databaseType: string;
+  // styles: Record<string, string>; // TODO: check if needed
+}
+
+/** AddDatabaseForm is the View implementation for the connect screen that will be rendered. */
+export default function AddDatabaseForm(props: AddDatabaseFormProps) {
+  const [state, setState] = useState<AddDatabaseFormState>({
+    username: 'root',
+    password: 'DikkeDraak',
+    url: 'https://datastrophe.science.uu.nl/',
+    port: 8529,
+    name: 'Tweede Kamer Dataset',
+    internal_database_name: 'TweedeKamer',
+    // styles: props.styles, // FIXME
+    type: DatabaseType.ArangoDB,
+  });
+
+  /**
+   * Validates if the port value is numerical. Only then will the state be updated.
+   * @param port The new port value.
+   */
+  function handlePortChanged(port: string): void {
+    if (!isNaN(Number(port))) setState({ ...state, port: Number(port) });
+  }
+
+  /** Handles the submit button click. Calls the onSubmit in the props with all the fields. */
+  function handleSubmitClicked(): void {
+    props.onSubmit(state);
+  }
+
+  return props.open ? (
+    <div
+      className={styles.wrapper}
+      onMouseDown={() => {
+        props.onClose();
+      }}
+    >
+      <div
+        className={styles.authWrapper}
+        onMouseDown={(e) => {
+          e.stopPropagation();
+        }}
+      >
+        <h1 className={styles.header}>Database Connect</h1>
+        <form
+          className={styles.formWrapper}
+          onSubmit={(event: React.FormEvent) => {
+            event.preventDefault();
+            handleSubmitClicked();
+          }}
+        >
+          <div className={styles.loginContainer}>
+            <TextField
+              className={styles.passLabel}
+              label="Database name"
+              type="databaseName"
+              value={state.name}
+              onChange={(event) =>
+                setState({
+                  ...state,
+                  name: event.currentTarget.value,
+                })
+              }
+              required
+            />
+          </div>
+          <div className={styles.loginContainer}>
+            <NativeSelect
+              className={styles.passLabel}
+              value={databaseNameMapping[state.type]}
+              onChange={(event) => {
+                setState({
+                  ...state,
+                  type: databaseNameMapping.indexOf(event.currentTarget.value),
+                });
+              }}
+            >
+              {databaseNameMapping.map((dbName) => (
+                <option value={dbName}>{dbName}</option>
+              ))}
+            </NativeSelect>
+          </div>
+          <div className={styles.loginContainerRow}>
+            <TextField
+              className={styles.hostLabel}
+              label="Hostname/IP"
+              type="hostname"
+              value={state.url}
+              onChange={(event) =>
+                setState({
+                  ...state,
+                  url: event.currentTarget.value,
+                })
+              }
+              required
+            />
+            <TextField
+              className={styles.portLabel}
+              label="Port"
+              type="port"
+              value={state.port}
+              onChange={(event) => handlePortChanged(event.currentTarget.value)}
+              required
+            />
+          </div>
+          <div className={styles.loginContainer}>
+            <TextField
+              className={styles.userLabel}
+              label="Username"
+              type="username"
+              value={state.username}
+              onChange={(event) =>
+                setState({
+                  ...state,
+                  username: event.currentTarget.value,
+                })
+              }
+              required
+            />
+          </div>
+          <div className={styles.loginContainer}>
+            <TextField
+              className={styles.passLabel}
+              label="Password"
+              type="password"
+              value={state.password}
+              onChange={(event) =>
+                setState({
+                  ...state,
+                  password: event.currentTarget.value,
+                })
+              }
+              required
+            />
+          </div>
+          <div className={styles.loginContainer}>
+            <TextField
+              className={styles.passLabel}
+              label="Internal database"
+              type="internalDatabaseName"
+              value={state.internal_database_name}
+              onChange={(event) =>
+                setState({
+                  ...state,
+                  internal_database_name: event.currentTarget.value,
+                })
+              }
+              required
+            />
+          </div>
+          <div className={styles.loginContainerButton}>
+            <Button variant="outlined" type="submit">
+              Submit
+            </Button>
+            <Button
+              className={styles.cancelButton}
+              variant="outlined"
+              onClick={() => {
+                props.onClose();
+              }}
+            >
+              Cancel
+            </Button>
+          </div>
+        </form>
+      </div>
+    </div>
+  ) : (
+    <></>
+  );
+}
diff --git a/apps/web/src/components/navbar/MenuList.scss b/apps/web/src/components/navbar/MenuList.scss
new file mode 100644
index 0000000000000000000000000000000000000000..af7f9f647753753c0c3077e7a1994ada4454fcbb
--- /dev/null
+++ b/apps/web/src/components/navbar/MenuList.scss
@@ -0,0 +1,17 @@
+/* This file is dependent on src/data/domain/entity/customization/colours.tsx 
+*  You can match a class name with a colour palette by naming the class 'menuList-' + colour palette name
+*/
+
+.menuList-default{
+    .MuiPaper-root{
+        background-color: #fffdfa;
+        color: #000000;
+    }
+}
+
+.menuList-dark{
+    .MuiPaper-root{
+        background-color: #171721;
+        color: #ffffff;
+    }
+}
\ No newline at end of file
diff --git a/apps/web/src/components/navbar/logogp.png b/apps/web/src/components/navbar/logogp.png
new file mode 100644
index 0000000000000000000000000000000000000000..cebd2d5f6a7e895c4858d7b9b0153a245fd0d7f9
Binary files /dev/null and b/apps/web/src/components/navbar/logogp.png differ
diff --git a/apps/web/src/components/navbar/logogpwhite.png b/apps/web/src/components/navbar/logogpwhite.png
new file mode 100644
index 0000000000000000000000000000000000000000..c83f02998f92e8b99c7c51416ac62968fe5fb302
Binary files /dev/null and b/apps/web/src/components/navbar/logogpwhite.png differ
diff --git a/apps/web/src/components/navbar/navbar.module.scss b/apps/web/src/components/navbar/navbar.module.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e1faa9a7863fcca1b4c52135300e3951de0e5b8e
--- /dev/null
+++ b/apps/web/src/components/navbar/navbar.module.scss
@@ -0,0 +1,44 @@
+.root {
+  display: flex;
+  overflow: hidden;
+}
+
+.appBar {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  background-color: #fff;
+  height: 50px;
+}
+
+.menubox {
+  display: flex;
+  flex-direction: row;
+  justify-content: flex-end;
+  width: 100%;
+}
+
+.menuText {
+  margin: 5px;
+  color: #181520;
+  font-family: Poppins, sans-serif;
+  font-weight: 400;
+  font-size: 15px;
+  align-self: flex-end;
+  text-transform: none;
+}
+
+.logo {
+  margin: auto;
+  display: block;
+}
+
+.loginButton {
+  margin: 6px;
+}
+
+.loginButtonText {
+  color: black;
+  font-weight: bold;
+}
+
diff --git a/apps/web/src/components/navbar/navbar.tsx b/apps/web/src/components/navbar/navbar.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..ef3d9c91ec3ddf61b1b4d975fea0285372bd95db
--- /dev/null
+++ b/apps/web/src/components/navbar/navbar.tsx
@@ -0,0 +1,325 @@
+/**
+ * This program has been developed by students from the bachelor Computer Science at
+ * Utrecht University within the Software Project course.
+ * © Copyright Utrecht University (Department of Information and Computing Sciences)
+ */
+
+/* istanbul ignore file */
+/* The comment above was added so the code coverage wouldn't count this file towards code coverage.
+ * We do not test components/renderfunctions/styling files.
+ * See testing plan for more details.*/
+import React, { useState } from 'react';
+import {
+  AppBar,
+  Toolbar,
+  CssBaseline,
+  Typography,
+  MenuItem,
+  ListItemText,
+  Menu,
+  IconButton,
+  Button,
+} from '@mui/material';
+import { AccountCircle } from '@mui/icons-material';
+import logo from './logogp.png';
+import logo_white from './logogpwhite.png';
+import AddDatabaseForm from './AddDatabaseForm';
+import { useTheme } from '@mui/material/styles';
+import styles from './navbar.module.scss';
+import {
+  AddDatabase,
+  AddDatabaseRequest,
+  GetAllDatabases,
+  RequestSchema,
+  useAuthorization,
+} from '@graphpolaris/shared/lib/data-access';
+import {
+  updateCurrentDatabase,
+  updateDatabaseList,
+} from '@graphpolaris/shared/lib/data-access/store/sessionSlice';
+
+/** NavbarComponentProps is an interface containing the NavbarViewModel. */
+export interface NavbarComponentProps {
+  // changeColourPalette: () => void; FIXME move to redux
+}
+
+/** NavbarComponentState is an interface containing the type of visualizations. */
+export interface NavbarComponentState {
+  isAuthorized: boolean;
+  clientID: string;
+  sessionID: string;
+  databases: string[];
+  currentDatabase: string;
+
+  // The anchor for rendering the user data (clientID, sessionID, add database, etc) menu
+  userMenuAnchor?: Element;
+  // The anchor for rendering the menu for selecting a database to use
+  selectDatabaseMenuAnchor?: Element;
+  // Determines if the addDatabaseForm will be shown
+  showAddDatabaseForm: boolean;
+}
+
+/** NavbarComponent is the View implementation for Navbar */
+export const Navbar = (props: NavbarComponentProps) => {
+  const theme = useTheme();
+  const authorization = useAuthorization();
+
+  // const { navbarViewModel, currentColours } = props;
+  // this.navbarViewModel = navbarViewModel;
+
+  const [state, setState] = useState<NavbarComponentState>({
+    isAuthorized: false,
+    clientID: authorization.userAuthorized ? authorization.userId || '' : '',
+    sessionID: authorization.sessionId || '',
+    databases: [],
+    currentDatabase: '',
+
+    userMenuAnchor: undefined,
+    selectDatabaseMenuAnchor: undefined,
+    showAddDatabaseForm: false,
+  });
+
+  /** Closes the user menu. Also closes all nested menu's. */
+  function closeUserMenu(): void {
+    // If a nested window is open, close the main user menu a bit later
+    if (state.selectDatabaseMenuAnchor != undefined) {
+      setState({ ...state, selectDatabaseMenuAnchor: undefined });
+      setTimeout(() => setState({ ...state, userMenuAnchor: undefined }), 100);
+    } else setState({ ...state, userMenuAnchor: undefined });
+  }
+
+  function changeColourPalette() {
+    // TODO
+  }
+
+  /**
+   * Called when the user clicks on the 'submit' button of the add database form.
+   */
+  function onAddDatabaseFormSubmit(
+    request: AddDatabaseRequest
+  ): Promise<void | Response> {
+    return AddDatabase(request).then(() =>
+      GetAllDatabases().then((databases) => {
+        updateDatabaseList(databases);
+        updateCurrentDatabase(request.name);
+        // When the database changes, request the new schema
+        console.log('databases ' + databases);
+        RequestSchema(request.name);
+      })
+    );
+  }
+
+  const currentLogo = theme.palette.custom.logo == 'white' ? logo_white : logo;
+
+  return (
+    <div className={styles.root}>
+      <CssBaseline />
+      <AppBar
+        title="GraphPolaris"
+        style={{
+          zIndex: 1250,
+          backgroundColor: theme.palette.custom.background,
+        }}
+        position="fixed"
+        className={styles.appBar}
+      >
+        <Toolbar style={{ marginLeft: -5 }}>
+          <a href="https://graphpolaris.com/" className={styles.logo}>
+            <img src={currentLogo} className={styles.logo} />
+          </a>
+          <div className={styles.menubox}>
+            <Button
+              className={styles.menuText}
+              style={{ color: theme.palette.custom.menuText }}
+              onClick={changeColourPalette}
+            >
+              Change Palette
+            </Button>
+            <Button
+              href="https://graphpolaris.com/"
+              className={styles.menuText}
+              style={{ color: theme.palette.custom.menuText }}
+            >
+              Home
+            </Button>
+            <Button
+              href="https://graphpolaris.com/index.php/products/"
+              className={styles.menuText}
+              style={{ color: theme.palette.custom.menuText }}
+            >
+              Products
+            </Button>
+            <Button
+              href="https://graphpolaris.com#usecases"
+              className={styles.menuText}
+              style={{ color: theme.palette.custom.menuText }}
+            >
+              Use Cases
+            </Button>
+            <Button
+              href="https://graphpolaris.com#earlyadoption"
+              className={styles.menuText}
+              style={{ color: theme.palette.custom.menuText }}
+            >
+              Contact
+            </Button>
+            {state.isAuthorized ? (
+              <div>
+                <IconButton
+                  color="inherit"
+                  onClick={(event) =>
+                    setState({
+                      ...state,
+                      userMenuAnchor: event.currentTarget,
+                    })
+                  }
+                >
+                  <AccountCircle htmlColor={theme.palette.custom.menuText} />
+                </IconButton>
+                <Menu
+                  id="user-menus"
+                  anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
+                  transformOrigin={{ vertical: 'top', horizontal: 'left' }}
+                  anchorEl={state.userMenuAnchor}
+                  keepMounted
+                  open={Boolean(state.userMenuAnchor)}
+                  onClose={() => closeUserMenu()}
+                >
+                  <MenuItem>
+                    <ListItemText primary={'clientID: ' + state.clientID} />
+                  </MenuItem>
+                  <MenuItem>
+                    <ListItemText primary={'sessionID: ' + state.sessionID} />
+                  </MenuItem>
+                  {/* <MenuItem
+                    onClick={() =>
+                      navbarViewModel.handleLoginButtonClicked('google')
+                    }
+                  >
+                    <ListItemText primary={'request new'} />
+                  </MenuItem> */}
+                  {/*<MenuItem onClick={() => LocalStorage.instance().Reset()}>*/}
+                  {/*  <ListItemText primary={'Empty localstorage'} />*/}
+                  {/*</MenuItem>*/}
+                  <MenuItem
+                    onClick={() =>
+                      setState({
+                        ...state,
+                        userMenuAnchor: undefined,
+                        showAddDatabaseForm: true,
+                      })
+                    }
+                  >
+                    <ListItemText primary={'Add database'} />
+                  </MenuItem>
+                  <MenuItem
+                    onClick={(event) =>
+                      setState({
+                        ...state,
+                        selectDatabaseMenuAnchor: event.currentTarget,
+                      })
+                    }
+                  >
+                    <ListItemText primary={'Change database'} />
+                  </MenuItem>
+                  <Menu
+                    id="databases-menus"
+                    anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
+                    transformOrigin={{ vertical: 'top', horizontal: 'right' }}
+                    anchorEl={state.selectDatabaseMenuAnchor}
+                    keepMounted
+                    disableAutoFocusItem
+                    open={Boolean(state.selectDatabaseMenuAnchor)}
+                    onClose={() => closeUserMenu()}
+                  >
+                    {state.databases.length > 0 ? (
+                      state.databases.map((database) => (
+                        <MenuItem
+                          key={database}
+                          selected={database == state.currentDatabase}
+                          onClick={() => {
+                            if (state.currentDatabase != database) {
+                              updateCurrentDatabase(database);
+                              closeUserMenu();
+                            }
+                          }}
+                        >
+                          <ListItemText primary={database} />
+                        </MenuItem>
+                      ))
+                    ) : (
+                      <MenuItem key="placeholder" value="" disabled>
+                        no databases connected
+                      </MenuItem>
+                    )}
+                  </Menu>
+                </Menu>
+              </div>
+            ) : (
+              <div>
+                <Button
+                  className={styles.loginButton}
+                  onClick={(event) =>
+                    setState({
+                      ...state,
+                      userMenuAnchor: event.currentTarget,
+                    })
+                  }
+                >
+                  <span
+                    className={styles.loginButtonText}
+                    style={{
+                      color: theme.palette.custom.menuText,
+                    }}
+                  >
+                    Login
+                  </span>
+                </Button>
+                {/* <Menu
+                  id="user-menus"
+                  getContentAnchorEl={null}
+                  anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
+                  transformOrigin={{ vertical: 'top', horizontal: 'left' }}
+                  anchorEl={state.userMenuAnchor}
+                  keepMounted
+                  open={Boolean(state.userMenuAnchor)}
+                  onClose={() => closeUserMenu()}
+                >
+                  <MenuItem
+                    onClick={() =>
+                      navbarViewModel.handleLoginButtonClicked('google')
+                    }
+                  >
+                    <ListItemText primary={'Login with Google'} />
+                  </MenuItem>
+                  <MenuItem
+                    onClick={() =>
+                      navbarViewModel.handleLoginButtonClicked('github')
+                    }
+                  >
+                    <ListItemText primary={'Login with GitHub'} />
+                  </MenuItem>
+                  <MenuItem
+                    onClick={() =>
+                      navbarViewModel.handleLoginButtonClicked('free')
+                    }
+                  >
+                    <ListItemText primary={'Login with free (debug)'} />
+                  </MenuItem>
+                </Menu> */}
+              </div>
+            )}
+          </div>
+        </Toolbar>
+      </AppBar>
+      <AddDatabaseForm
+        open={state.showAddDatabaseForm}
+        onClose={() => setState({ ...state, showAddDatabaseForm: false })}
+        onSubmit={(...params) => {
+          onAddDatabaseFormSubmit(...params);
+          setState({ ...state, showAddDatabaseForm: false });
+        }}
+      />
+    </div>
+  );
+};
diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts
index 05136727df33393019f3b7a458b6f4b08148f23c..4fcc697290865b9615b091c8566157fe91a4f1c8 100644
--- a/apps/web/vite.config.ts
+++ b/apps/web/vite.config.ts
@@ -1,14 +1,22 @@
 /// <reference types="vitest" />
-import { defineConfig } from 'vite'
-import react from '@vitejs/plugin-react-swc'
-import path from 'path'
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react-swc';
+import path from 'path';
+import basicSsl from '@vitejs/plugin-basic-ssl';
+import dts from 'vite-plugin-dts';
 
 // https://vitejs.dev/config/
 export default defineConfig({
-  plugins: [react()],
+  plugins: [react(), basicSsl(),
+  dts({
+    insertTypesEntry: true,
+  }),],
   resolve: {
     alias: {
-      '@graphpolaris/shared/lib': path.resolve(__dirname, '../../libs/shared/lib')
+      '@graphpolaris/shared/lib': path.resolve(
+        __dirname,
+        '../../libs/shared/lib'
+      ),
     },
-  }
-})
+  },
+});
diff --git a/libs/shared/.eslintrc.json b/libs/shared/.eslintrc.json
index a2bdc3e17c8a27c5e5501052719644ccdca31270..2707c1f4120744f9e9e9e736c8aad7cf59a0862c 100644
--- a/libs/shared/.eslintrc.json
+++ b/libs/shared/.eslintrc.json
@@ -1,5 +1,12 @@
 {
   "extends": ["plugin:react-hooks/recommended"],
+  "parserOptions": {
+    "sourceType": "module",
+    "ecmaVersion": "latest",
+    "ecmaFeatures": {
+      "jsx": true
+    }
+  },
   "ignorePatterns": ["!**/*"],
   "overrides": [
     {
diff --git a/libs/shared/index.tsx b/libs/shared/index.tsx
index df7053eff68c1380c1c131b6851d0617cff4ccf1..1dc5085e331fb44e9d690b7269b34a92d2a7fe03 100644
--- a/libs/shared/index.tsx
+++ b/libs/shared/index.tsx
@@ -1 +1 @@
-export * from './index'
+// export * from './index';
diff --git a/libs/shared/lib/data-access/api/database.ts b/libs/shared/lib/data-access/api/database.ts
index deabbe0f590ed058772363cb224fabd758425a88..b627ba76dd56946a53719b29f5d66f787bc67c28 100644
--- a/libs/shared/lib/data-access/api/database.ts
+++ b/libs/shared/lib/data-access/api/database.ts
@@ -2,6 +2,13 @@
 
 import { AuthorizationHandler } from '@graphpolaris/shared/lib/data-access/authorization';
 
+export enum DatabaseType {
+  ArangoDB = 0,
+  Neo4j = 1,
+}
+
+export const databaseNameMapping: string[] = ['arangodb', 'neo4j'];
+
 export type AddDatabaseRequest = {
   name: string;
   internal_database_name: string;
@@ -9,7 +16,7 @@ export type AddDatabaseRequest = {
   port: number;
   username: string;
   password: string;
-  type: number; // Database type. 0 = ArangoDB, 1 = Neo4j
+  type: DatabaseType; // Database type. 0 = ArangoDB, 1 = Neo4j
 };
 
 export function AddDatabase(request: AddDatabaseRequest): Promise<void> {
@@ -34,22 +41,24 @@ export function AddDatabase(request: AddDatabaseRequest): Promise<void> {
 
 export function GetAllDatabases(): Promise<Array<string>> {
   return new Promise<Array<string>>((resolve, reject) => {
+    console.log(AuthorizationHandler.instance().AccessToken());
     fetch('https://api.graphpolaris.com/user/database', {
       method: 'GET',
-      credentials: 'same-origin',
+      // credentials: 'same-origin',
       headers: new Headers({
         Authorization:
           'Bearer ' + AuthorizationHandler.instance().AccessToken(),
       }),
     })
       .then((response: Response) => {
-        if (!response.ok) {
-          reject(response.statusText);
-        }
+        // if (!response.ok) {
+        //   reject(response.statusText);
+        // }
 
         return response.json();
       })
       .then((json: any) => {
+        console.log(json);
         resolve(json.databases);
       });
   });
diff --git a/libs/shared/lib/data-access/api/index.ts b/libs/shared/lib/data-access/api/index.ts
index 94a2ddb8716278114077b272a51852400dbb44b9..eed07d0e97fe3d9e4353a511b074d44726399bcb 100644
--- a/libs/shared/lib/data-access/api/index.ts
+++ b/libs/shared/lib/data-access/api/index.ts
@@ -1,2 +1,3 @@
 export * from './database'
-export * from './user'
\ No newline at end of file
+export * from './user'
+export * from './schema'
\ No newline at end of file
diff --git a/libs/shared/lib/data-access/api/schema.ts b/libs/shared/lib/data-access/api/schema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..004a8b8e87db1eae3242b84e4f0c7d2e841b66aa
--- /dev/null
+++ b/libs/shared/lib/data-access/api/schema.ts
@@ -0,0 +1,7 @@
+// All database related API calls
+
+import { AuthorizationHandler } from '@graphpolaris/shared/lib/data-access/authorization';
+
+
+export function RequestSchema(databaseName: string) {
+}
\ No newline at end of file
diff --git a/libs/shared/lib/data-access/api/user.ts b/libs/shared/lib/data-access/api/user.ts
index 06296ae3a3d7547cb1eaaa4ec9f85fe081ab2bed..825538a8278a9d8d0234c64d01a6e7d074a5c2e4 100644
--- a/libs/shared/lib/data-access/api/user.ts
+++ b/libs/shared/lib/data-access/api/user.ts
@@ -10,12 +10,12 @@ export type User = {
 
 export function GetUserInfo(): Promise<User> {
   return new Promise<User>((resolve, reject) => {
+    const auth = AuthorizationHandler.instance();
     fetch('https://api.graphpolaris.com/user/', {
       method: 'GET',
       credentials: 'same-origin',
       headers: new Headers({
-        Authorization:
-          'Bearer ' + AuthorizationHandler.instance().AccessToken(),
+        Authorization: 'Bearer ' + auth.AccessToken(),
       }),
     })
       .then((response: Response) => {
diff --git a/libs/shared/lib/data-access/authorization/authorizationHandler.ts b/libs/shared/lib/data-access/authorization/authorizationHandler.ts
index bc6001fd2aed8d24d60abf15411167af64629e81..d8f2d1b7457571a856eb64f1eec4c6a0e976e8ae 100644
--- a/libs/shared/lib/data-access/authorization/authorizationHandler.ts
+++ b/libs/shared/lib/data-access/authorization/authorizationHandler.ts
@@ -36,6 +36,7 @@ export class AuthorizationHandler {
       // Store them
       this.userID = authResponse.userID ?? '';
       this.sessionID = authResponse.sessionID ?? '';
+
       this.SetAccessToken(authResponse.accessToken ?? '');
     }
 
@@ -93,19 +94,25 @@ export class AuthorizationHandler {
       // Set the new access token
       this.accessToken = authResponse.accessToken ?? '';
 
-      // Initialise the new refresh token
-      this.initialiseRefreshToken();
+      if (this.accessToken !== '') {
+        // Initialise the new refresh token
+        this.initializeRefreshToken();
+      }
     }
   }
 
   /**
-   * initialiseRefreshToken attempts to initialise a refresh token
+   * initializeRefreshToken attempts to initialize a refresh token
    */
-  private async initialiseRefreshToken() {
-    fetch('https://api.graphpolaris.com/auth/refresh', {
-      method: 'POST',
-      credentials: 'include',
-    })
+  private async initializeRefreshToken() {
+    fetch(
+      'https://api.graphpolaris.com/auth/refresh?access_token=' +
+      this.accessToken,
+      {
+        method: 'GET',
+        credentials: 'include',
+      }
+    )
       .then((response) => {
         if (!response.ok) {
           throw Error(response.statusText);
@@ -158,10 +165,8 @@ export class AuthorizationHandler {
   async SetAccessToken(accessToken: string) {
     this.accessToken = accessToken;
 
-    console.log(this.accessToken);
-
     // Activate the refresh token
-    this.initialiseRefreshToken();
+    this.initializeRefreshToken();
 
     // Start the automatic refreshing every 10 minutes
     setInterval(() => {
diff --git a/libs/shared/lib/data-access/authorization/authorizationHook.tsx b/libs/shared/lib/data-access/authorization/authorizationHook.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..4110005e881aa28f62ecda514643609294a6b0fa
--- /dev/null
+++ b/libs/shared/lib/data-access/authorization/authorizationHook.tsx
@@ -0,0 +1,41 @@
+import { useEffect, useState } from 'react';
+import { AuthorizationHandler } from '@graphpolaris/shared/lib/data-access';
+
+interface useIsAuthorizedState {
+  userAuthorized: boolean;
+  userId?: string;
+  sessionId?: string;
+}
+
+export function useAuthorization() {
+  const [state, setState] = useState<useIsAuthorizedState>({
+    userAuthorized: false,
+  });
+  const authInstance = AuthorizationHandler.instance();
+
+  const authCallback = async () => {
+    setState({
+      userAuthorized: authInstance.Authorized(),
+      userId: authInstance.UserID(),
+      sessionId: authInstance.SessionID(),
+    });
+
+    // Print the user that is currently logged in
+    // const user = await GetUserInfo();
+    // console.log(user);
+  };
+
+  authInstance.setCallback(authCallback);
+
+  // Attempt to Authorize the user
+  const authorize = async () => {
+    const authorized = await authInstance.Authorize();
+    if (authorized) authCallback();
+  };
+
+  useEffect(() => {
+    authorize();
+  }, []);
+
+  return state;
+}
diff --git a/libs/shared/lib/data-access/authorization/index.ts b/libs/shared/lib/data-access/authorization/index.ts
index 40d36480605c0faae067cdd01ace9cba3252d171..0cf2dd57d11433d17c7556f071f558b458c14c2d 100644
--- a/libs/shared/lib/data-access/authorization/index.ts
+++ b/libs/shared/lib/data-access/authorization/index.ts
@@ -1 +1,2 @@
 export { AuthorizationHandler } from './authorizationHandler';
+export * from './authorizationHook';
diff --git a/libs/shared/lib/data-access/theme/colorPaletteConfigSlice.ts b/libs/shared/lib/data-access/store/colorPaletteConfigSlice.ts
similarity index 93%
rename from libs/shared/lib/data-access/theme/colorPaletteConfigSlice.ts
rename to libs/shared/lib/data-access/store/colorPaletteConfigSlice.ts
index 6d79706f0e881fd176d771685d404510e6d6d295..3973055833f7e1d4ee0575201a2156f8811075b2 100644
--- a/libs/shared/lib/data-access/theme/colorPaletteConfigSlice.ts
+++ b/libs/shared/lib/data-access/store/colorPaletteConfigSlice.ts
@@ -1,22 +1,22 @@
 import { createSlice, PayloadAction } from '@reduxjs/toolkit';
-import type { RootState } from '../store/store';
+import type { RootState } from './store';
 
 /** Extra properties that are not present in the default PaletteOptions of mui. For autocompletion */
 export interface ExtraColorsForMui5 {
   /** Colors that can be used for data visualisation, e.g. nodes, edges */
   dataPointColors: string[];
 
-  nodes: Array<string>,
-  nodesBase: [string],
+  nodes: Array<string>;
+  nodesBase: [string];
   elements: {
-    entityBase: [string, string, string], // normal, lighter, darker
-    entitySecond: [string]
-    relation: [string, string, string],
-    relationBase: [string, string, string],
-    relationSecond: [string],
-    attribute: [string, string, string],
-    function: [string, string, string],
-  },
+    entityBase: [string, string, string]; // normal, lighter, darker
+    entitySecond: [string];
+    relation: [string, string, string];
+    relationBase: [string, string, string];
+    relationSecond: [string];
+    attribute: [string, string, string];
+    function: [string, string, string];
+  };
   visEdge: string;
   nodeHighlightedEdge: string;
   background: string;
@@ -72,7 +72,6 @@ export interface ColorPaletteConfig {
   darkMode: boolean;
 }
 
-
 const defaultPallete: ColorPalette = {
   custom: {
     dataPointColors: ['#ff0000', '#00ff00', '#0000ff'],
@@ -147,7 +146,7 @@ const defaultPallete: ColorPalette = {
     main: '#9c27b0',
     // dark: '#7b1fa2',
   },
-}
+};
 
 // This looks very much like the mui Palette interface,
 // But we don't reference that type directly here to stay decoupled
diff --git a/libs/shared/lib/data-access/store/configSlice.ts b/libs/shared/lib/data-access/store/configSlice.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9e8f71a7bad08713f5b6e918e4e939be4b390260
--- /dev/null
+++ b/libs/shared/lib/data-access/store/configSlice.ts
@@ -0,0 +1,26 @@
+import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+import type { RootState } from './store';
+
+// Define the initial state using that type
+export const initialState = {
+  queryListOpen: false,
+  queryStatusList: { queries: {}, queryIDsOrder: [] },
+  functionsMenuOpen: false,
+  currentDatabaseKey: '',
+  elementsperDatabaseObject: {},
+  autoSendQueries: true,
+};
+
+export const configSlice = createSlice({
+  name: 'config',
+  // `createSlice` will infer the state type from the `initialState` argument
+  initialState,
+  reducers: {},
+});
+
+export const {} = configSlice.actions;
+
+// Other code such as selectors can use the imported `RootState` type
+export const configState = (state: RootState) => state.config;
+
+export default configSlice.reducer;
diff --git a/libs/shared/lib/data-access/store/hooks.ts b/libs/shared/lib/data-access/store/hooks.ts
index 5f3e0cfac785fbdb47a145199026a5f98e5c8941..e1c5935f4bd900657af37422a67b5e24b670acf2 100644
--- a/libs/shared/lib/data-access/store/hooks.ts
+++ b/libs/shared/lib/data-access/store/hooks.ts
@@ -1,11 +1,20 @@
 import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
 import { selectGraphQueryResult } from './graphQueryResultSlice';
-import { selectSchema, selectSchemaLayout } from './schemaSlice';
-import { selectQuerybuilderNodes } from './querybuilderSlice';
+import {
+  schemaGraph,
+  schemaGraphology,
+  selectSchemaLayout,
+} from './schemaSlice';
 import type { RootState, AppDispatch } from './store';
+import { configState } from '@graphpolaris/shared/lib/data-access/store/configSlice';
+import {
+  selectQuerybuilderGraph,
+  selectQuerybuilderGraphology,
+} from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice';
+import { sessionCacheState } from './sessionSlice';
 
 // Use throughout your app instead of plain `useDispatch` and `useSelector`
-export const useAppDispatch: () => AppDispatch = useDispatch
+export const useAppDispatch: () => AppDispatch = useDispatch;
 // export const useAppDispatch = () => useDispatch<AppDispatch>();
 export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
 
@@ -13,9 +22,16 @@ export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
 export const useGraphQueryResult = () => useAppSelector(selectGraphQueryResult);
 
 // Gives the schema form the store (as a graphology object)
-export const useSchema = () => useAppSelector(selectSchema);
+export const useSchemaGraphology = () => useAppSelector(schemaGraphology);
+export const useSchemaGraph = () => useAppSelector(schemaGraph);
 
 // Gives the schema form the store (as a graphology object)
 export const useSchemaLayout = () => useAppSelector(selectSchemaLayout);
-export const useQuerybuilderNodes = () =>
-  useAppSelector(selectQuerybuilderNodes);
+export const useQuerybuilderGraphology = () =>
+  useAppSelector(selectQuerybuilderGraphology);
+export const useQuerybuilderGraph = () =>
+  useAppSelector(selectQuerybuilderGraph);
+
+// Overall Configuration of the app
+export const useConfig = () => useAppSelector(configState);
+export const useSessionCache = () => useAppSelector(sessionCacheState);
diff --git a/libs/shared/lib/data-access/store/index.ts b/libs/shared/lib/data-access/store/index.ts
index ebce9ab02837a640a24374307645d54b404dcae3..43667f97745a6be086df9e2adeaadc19662fa7f4 100644
--- a/libs/shared/lib/data-access/store/index.ts
+++ b/libs/shared/lib/data-access/store/index.ts
@@ -5,14 +5,9 @@ export {
   setSchema,
   readInSchemaFromBackend,
   schemaSlice,
-  selectSchemaLayout
+  selectSchemaLayout,
 } from './schemaSlice';
-export {
-  querybuilderSlice,
-  setQuerybuilderNodes,
-  updateQBAttributeOperator,
-  updateQBAttributeValue,
-} from './querybuilderSlice';
+export { querybuilderSlice, setQuerybuilderNodes } from './querybuilderSlice';
 export {
   selectGraphQueryResult,
   selectGraphQueryResultLinks,
@@ -27,11 +22,11 @@ export {
   toggleDarkMode,
   selectColorPaletteConfig,
   colorPaletteConfigSlice,
-} from '../theme/colorPaletteConfigSlice';
+} from './colorPaletteConfigSlice';
 
 // Exported types
 export type { Node, Edge, GraphQueryResult } from './graphQueryResultSlice';
 export type {
   ColorPaletteConfig,
   ExtraColorsForMui5,
-} from '../theme/colorPaletteConfigSlice';
+} from './colorPaletteConfigSlice';
diff --git a/libs/shared/lib/data-access/store/querybuilderSlice.ts b/libs/shared/lib/data-access/store/querybuilderSlice.ts
index 877444a06b9ebe70c06a866e9ecc6d28efc001b5..f2e3cd62b3cf06a8fc1bddcdfff346be228b065b 100644
--- a/libs/shared/lib/data-access/store/querybuilderSlice.ts
+++ b/libs/shared/lib/data-access/store/querybuilderSlice.ts
@@ -2,10 +2,14 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit';
 import type { RootState } from './store';
 import { MultiGraph } from 'graphology';
 import { Attributes, SerializedGraph } from 'graphology-types';
+import {
+  QueryMultiGraph,
+  QueryMultiGraphExport,
+} from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils';
 
 // Define the initial state using that type
 export const initialState = {
-  graphologySerialized: new MultiGraph().export(),
+  graphologySerialized: new QueryMultiGraph().export(),
   // schemaLayout: 'Graphology_noverlap',
 };
 
@@ -18,13 +22,15 @@ export const querybuilderSlice = createSlice({
       state,
       action: PayloadAction<SerializedGraph<Attributes, Attributes, Attributes>>
     ) => {
-      state.graphologySerialized = action.payload;
+      state.graphologySerialized = QueryMultiGraph.from(
+        action.payload
+      ).export() as QueryMultiGraphExport;
     },
     updateQBAttributeOperator: (
       state,
       action: PayloadAction<{ id: string; operator: string }>
     ) => {
-      const graph = MultiGraph.from(state.graphologySerialized);
+      const graph = QueryMultiGraph.from(state.graphologySerialized);
       graph.setNodeAttribute(
         action.payload.id,
         'operator',
@@ -36,10 +42,13 @@ export const querybuilderSlice = createSlice({
       state,
       action: PayloadAction<{ id: string; value: string }>
     ) => {
-      const graph = MultiGraph.from(state.graphologySerialized);
+      const graph = QueryMultiGraph.from(state.graphologySerialized);
       graph.setNodeAttribute(action.payload.id, 'value', action.payload.value);
       state.graphologySerialized = graph.export();
     },
+    clearQB: (state) => {
+      state.graphologySerialized = new QueryMultiGraph().export();
+    },
     // addQuerybuilderNode: (
     //   state,
     //   action: PayloadAction<{ id: string; attributes: Attributes }>
@@ -58,14 +67,26 @@ export const {
   setQuerybuilderNodes,
   updateQBAttributeOperator,
   updateQBAttributeValue,
+  clearQB,
 } = querybuilderSlice.actions;
 
+/** Select the querybuilder nodes in serialized fromat */
+export const selectQuerybuilderGraphology = (
+  state: RootState
+): QueryMultiGraph => {
+  // This is really weird but for some reason all the attributes appeared as read-only otherwise
+
+  let ret = new QueryMultiGraph();
+  ret.import(MultiGraph.from(state.querybuilder.graphologySerialized).export());
+  return ret;
+};
+
 /** Select the querybuilder nodes and convert it to a graphology object */
-export const selectQuerybuilderNodes = (state: RootState): MultiGraph => {
+export const selectQuerybuilderGraph = (
+  state: RootState
+): QueryMultiGraphExport => {
   // This is really weird but for some reason all the attributes appeared as read-only otherwise
-  return MultiGraph.from(
-    MultiGraph.from(state.querybuilder.graphologySerialized).export()
-  );
+  return state.querybuilder.graphologySerialized as QueryMultiGraphExport;
 };
 
 // /**
diff --git a/libs/shared/lib/data-access/store/schemaSlice.spec.ts b/libs/shared/lib/data-access/store/schemaSlice.spec.ts
index 2e28c3371a13b348dc2ed8a38753a9bc0fa13f42..1cbc52aeb5cd2abf3671109a5edb617a587eadac 100644
--- a/libs/shared/lib/data-access/store/schemaSlice.spec.ts
+++ b/libs/shared/lib/data-access/store/schemaSlice.spec.ts
@@ -1,10 +1,14 @@
 import Graph from 'graphology';
 import AbstractGraph, { DirectedGraph, MultiGraph } from 'graphology';
-import { useSchema } from '..';
-import reducer, { selectSchema, setSchema, initialState } from './schemaSlice';
+import { useSchemaGraphology } from '..';
+import reducer, {
+  schemaGraphology,
+  setSchema,
+  initialState,
+} from './schemaSlice';
 // import { deleteBook, updateBook, addNewBook } from '../redux/bookSlice';
 import { store } from './store';
-import { assert, describe, expect, it } from "vitest";
+import { assert, describe, expect, it } from 'vitest';
 
 describe('SchemaSlice Tests', () => {
   it('should make a graphology graph', () => {
diff --git a/libs/shared/lib/data-access/store/schemaSlice.ts b/libs/shared/lib/data-access/store/schemaSlice.ts
index 936b1e700ac531426e8277dd856b33111b385f57..bd3d0b4b70a92774e5fd947a83228e8f9b88d7f3 100644
--- a/libs/shared/lib/data-access/store/schemaSlice.ts
+++ b/libs/shared/lib/data-access/store/schemaSlice.ts
@@ -4,6 +4,7 @@ import { SerializedGraph } from 'graphology-types';
 import { SchemaFromBackend } from '@graphpolaris/shared/lib/model/backend';
 import type { RootState } from './store';
 import { AllLayoutAlgorithms } from '@graphpolaris/shared/lib/graph-layout';
+import { QueryMultiGraph } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils';
 
 /**************************************************************** */
 
@@ -78,11 +79,19 @@ export const { readInSchemaFromBackend, setSchema } = schemaSlice.actions;
 /**
  * Select the schema and convert it to a graphology object
  * */
-export const selectSchema = (state: RootState) => {
+export const schemaGraphology = (state: RootState) => {
   // This is really weird but for some reason all the attributes appeared as read-only otherwise
-  return MultiGraph.from(
-    MultiGraph.from(state.schema.graphologySerialized).export()
-  );
+  let ret = new MultiGraph();
+  ret.import(MultiGraph.from(state.schema.graphologySerialized).export());
+  return ret;
+};
+
+/**
+ * Select the schema
+ * */
+export const schemaGraph = (state: RootState) => {
+  // This is really weird but for some reason all the attributes appeared as read-only otherwise
+  return state.schema.graphologySerialized;
 };
 
 // /**
diff --git a/libs/shared/lib/data-access/store/sessionSlice.ts b/libs/shared/lib/data-access/store/sessionSlice.ts
new file mode 100644
index 0000000000000000000000000000000000000000..979f7f028dd9fa46a7128671f63c92f5ae647874
--- /dev/null
+++ b/libs/shared/lib/data-access/store/sessionSlice.ts
@@ -0,0 +1,35 @@
+import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+import type { RootState } from './store';
+
+// Define the initial state using that type
+export const initialState: {
+  currentDatabase: string;
+  databases: string[];
+} = {
+  currentDatabase: '',
+  databases: [],
+};
+
+export const sessionSlice = createSlice({
+  name: 'session',
+  // `createSlice` will infer the state type from the `initialState` argument
+  initialState,
+  reducers: {
+    updateCurrentDatabase(state, action: PayloadAction<string>) {
+      state.currentDatabase = action.payload;
+    },
+    updateDatabaseList(state, action: PayloadAction<string[]>) {
+      state.databases = action.payload;
+    }
+  },
+});
+
+export const {
+  updateCurrentDatabase,
+  updateDatabaseList
+} = sessionSlice.actions;
+
+// Other code such as selectors can use the imported `RootState` type
+export const sessionCacheState = (state: RootState) => state.sessionCache;
+
+export default sessionSlice.reducer;
diff --git a/libs/shared/lib/data-access/store/store.ts b/libs/shared/lib/data-access/store/store.ts
index a1346f58f2c1ef877b4c5ff4c30491e6ec161655..ef639a9206b474aae0bf000ed34b2111fcadbea5 100644
--- a/libs/shared/lib/data-access/store/store.ts
+++ b/libs/shared/lib/data-access/store/store.ts
@@ -1,8 +1,10 @@
 import { configureStore } from '@reduxjs/toolkit';
-import colorPaletteConfigSlice from '../theme/colorPaletteConfigSlice';
+import colorPaletteConfigSlice from './colorPaletteConfigSlice';
 import graphQueryResultSlice from './graphQueryResultSlice';
 import querybuilderSlice from './querybuilderSlice';
 import schemaSlice from './schemaSlice';
+import configSlice from './configSlice';
+import sessionSlice from './sessionSlice';
 
 export const store = configureStore({
   reducer: {
@@ -10,7 +12,18 @@ export const store = configureStore({
     schema: schemaSlice,
     colorPaletteConfig: colorPaletteConfigSlice,
     querybuilder: querybuilderSlice,
+    sessionCache: sessionSlice,
+    config: configSlice,
   },
+  middleware: (getDefaultMiddleware) =>
+    getDefaultMiddleware({
+      serializableCheck: {
+        ignoredPaths: [
+          'schema.graphologySerialized',
+          'querybuilder.graphologySerialized',
+        ],
+      },
+    }),
 });
 
 // Infer the `RootState` and `AppDispatch` types from the store itself
diff --git a/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.tsx b/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.tsx
index bb04af952f810393c468a600774cc42e60255e3c..191b3606fc76d9eb90d112640bf871c3c896f607 100644
--- a/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.tsx
+++ b/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.tsx
@@ -6,7 +6,7 @@ import {
   useAppSelector,
 } from '../../data-access/store';
 import { createTheme, ThemeOptions, ThemeProvider } from '@mui/material/styles';
-import { ColorPalette } from './colorPaletteConfigSlice';
+import { ColorPalette } from '../store/colorPaletteConfigSlice';
 
 // Add custom theme variables to the mui theme types
 declare module '@mui/material/styles' {
diff --git a/libs/shared/lib/graph-layout/layout-creator-usecase.ts b/libs/shared/lib/graph-layout/layout-creator-usecase.ts
index 930200eea101f2b6c6c977a3705f5986ef2d864d..7370db47f1fb4b90cc43ddf62eec595c03847faf 100644
--- a/libs/shared/lib/graph-layout/layout-creator-usecase.ts
+++ b/libs/shared/lib/graph-layout/layout-creator-usecase.ts
@@ -49,7 +49,7 @@ export class LayoutFactory implements ILayoutFactory<AllLayoutAlgorithms> {
 
   createLayout<Algorithm extends AllLayoutAlgorithms>(
     layoutAlgorithm: Algorithm
-  ): AlgorithmToLayoutProvider<Algorithm> | null {
+  ): AlgorithmToLayoutProvider<Algorithm> {
     if (
       this.isSpecificAlgorithm<GraphologyLayoutAlgorithms>(
         layoutAlgorithm,
@@ -72,6 +72,6 @@ export class LayoutFactory implements ILayoutFactory<AllLayoutAlgorithms> {
       ) as AlgorithmToLayoutProvider<Algorithm>;
     }
 
-    return null;
+    throw Error('Invalid layout algorithm');
   }
 }
diff --git a/libs/shared/lib/querybuilder/graph/graphology/JSONParser.tsx b/libs/shared/lib/querybuilder/graph/graphology/JSONParser.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..7d645f7457888aa32c25af47fd8868eaaa74dde5
--- /dev/null
+++ b/libs/shared/lib/querybuilder/graph/graphology/JSONParser.tsx
@@ -0,0 +1,85 @@
+/**
+ * This program has been developed by students from the bachelor Computer Science at
+ * Utrecht University within the Software Project course.
+ * © Copyright Utrecht University (Department of Information and Computing Sciences)
+ */
+
+/** JSON query format used to send a query to the backend. */
+export interface TranslatedJSONQuery {
+  return: {
+    entities: number[];
+    relations: number[];
+    groupBys: number[];
+  };
+  entities: Entity[];
+  relations: Relation[];
+  groupBys: GroupBy[];
+  machineLearning: MachineLearning[];
+  limit: number;
+}
+
+/** Interface for an entity in the JSON for the query. */
+export interface Entity {
+  name: string;
+  ID: number;
+  constraints: Constraint[];
+}
+
+/** Interface for an relation in the JSON for the query. */
+export interface Relation {
+  name: string;
+  ID: number;
+  fromType: string;
+  fromID: number;
+  toType: string;
+  toID: number;
+  depth: { min: number; max: number };
+  constraints: Constraint[];
+}
+
+/**
+ * Constraint datatypes created from the attributes of a relation or entity.
+ *
+ * string MatchTypes: exact/contains/startswith/endswith.
+ * int    MatchTypes: GT/LT/EQ.
+ * bool   MatchTypes: EQ/NEQ.
+ */
+export interface Constraint {
+  attribute: string;
+  dataType: string;
+
+  matchType: string;
+  value: string;
+}
+
+/** Interface for a function in the JSON for the query. */
+export interface GroupBy {
+  ID: number;
+
+  groupType: string;
+  groupID: number[];
+  groupAttribute: string;
+
+  byType: string;
+  byID: number[];
+  byAttribute: string;
+
+  appliedModifier: string;
+  relationID: number;
+  constraints: Constraint[];
+}
+
+/** Interface for Machine Learning algorithm */
+export interface MachineLearning {
+  ID?: number;
+  queuename: string;
+  parameters: string[];
+}
+/** Interface for what the JSON needs for link predicition */
+export interface LinkPrediction {
+  queuename: string;
+  parameters: {
+    key: string;
+    value: string;
+  }[];
+}
diff --git a/libs/shared/lib/querybuilder/graph/graphology/model.ts b/libs/shared/lib/querybuilder/graph/graphology/model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..194ed07c768ce1725b8e59171c115cd368d96567
--- /dev/null
+++ b/libs/shared/lib/querybuilder/graph/graphology/model.ts
@@ -0,0 +1,49 @@
+import { Attributes as GAttributes } from 'graphology-types';
+import {
+  AttributeData,
+  AttributeNode,
+  EntityData,
+  EntityNode,
+  FunctionNode,
+  ModifierNode,
+  RelationData,
+  RelationNode,
+} from '../reactflow/model';
+import { XYPosition } from 'reactflow';
+import {
+  setQuerybuilderNodes,
+  store,
+} from '@graphpolaris/shared/lib/data-access';
+import { MultiGraph } from 'graphology';
+import { calcWidthHeightOfPill } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils';
+import './utils';
+
+// export interface Attributes extends EntityNode | RelationNode | AttributeNode | FunctionNode | ModifierNode  {
+// }
+
+export type NodeAttributes = XYPosition &
+  AttributeData & {
+    type: string;
+    width?: number;
+    height?: number;
+  };
+
+export type EntityNodeAttributes = XYPosition &
+  EntityData & {
+    type: string;
+    width?: number;
+    height?: number;
+  };
+
+export type RelationNodeAttributes = XYPosition &
+  RelationData & {
+    type: string;
+    width?: number;
+    height?: number;
+  };
+
+export type QueryGraph = MultiGraph<
+  NodeAttributes | EntityNodeAttributes | RelationNodeAttributes,
+  GAttributes,
+  GAttributes
+>;
diff --git a/libs/shared/lib/querybuilder/graph/graphology/utils.ts b/libs/shared/lib/querybuilder/graph/graphology/utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b55a4597dc2822e03d619c09c70212c214a2f79c
--- /dev/null
+++ b/libs/shared/lib/querybuilder/graph/graphology/utils.ts
@@ -0,0 +1,131 @@
+import {
+  setQuerybuilderNodes,
+  store,
+} from '@graphpolaris/shared/lib/data-access/store';
+import Graph, { MultiGraph } from 'graphology';
+import {
+  Attributes as GAttributes,
+  Attributes,
+  SerializedGraph,
+} from 'graphology-types';
+import {
+  EntityNodeAttributes,
+  NodeAttributes,
+  QueryGraph,
+  RelationNodeAttributes,
+} from './model';
+import { XYPosition } from 'reactflow';
+
+/** monospace fontsize table */
+const widthPerFontsize = {
+  6: 3.6167,
+  7: 4.2167,
+  10: 6.0167,
+};
+
+export type QueryMultiGraphExport = SerializedGraph<
+  NodeAttributes | EntityNodeAttributes | RelationNodeAttributes,
+  GAttributes,
+  GAttributes
+>;
+
+export class QueryMultiGraph extends MultiGraph<
+  NodeAttributes | EntityNodeAttributes | RelationNodeAttributes,
+  GAttributes,
+  GAttributes
+> {
+  public addPill2Graphology(
+    attributes: NodeAttributes | EntityNodeAttributes | RelationNodeAttributes,
+    id: string = (Date.now() + Math.floor(Math.random() * 1000)).toString()
+  ): string | null {
+    const { type, name } = attributes;
+    if (!type || !name) return null;
+    let { x, y } = attributes;
+
+    // Check if x and y are present, otherwise set them to 0
+    if (!x) x = 0;
+    if (!y) y = 0;
+
+    // Get the width and height of a node
+    const { width, height } = calcWidthHeightOfPill(attributes);
+
+    // Add a node to the graphology object
+    const nodeId = this.addNode(id, { ...attributes, x, y, width, height });
+
+    // Set the new nodes in the query builder slice TODO: maybe remove for efficiency
+    store.dispatch(setQuerybuilderNodes(this.export()));
+
+    return nodeId;
+  }
+}
+
+/** Calculates the width and height of a query builder pill.
+ * DEPENDS ON STYLING, if styling changed, change this.
+ */
+export function calcWidthHeightOfPill(attributes: Attributes): {
+  width: number;
+  height: number;
+} {
+  const { type, name } = attributes;
+
+  let w = 0;
+  let h = 0;
+  switch (type) {
+    case 'entity': {
+      // calculate width and height of entity pill
+      w = Math.min(name.length, 20) * widthPerFontsize[10]; // for fontsize 10px
+
+      const widthOfPillWithoutText = 42.1164; // WARNING: depends on styling
+      w += widthOfPillWithoutText;
+      h = 20;
+      break;
+    }
+    case 'relation': {
+      // calculate width and height of relation pill
+      w = Math.min(name.length, 20) * widthPerFontsize[10]; // for fontsize 10px
+
+      const widthOfPillWithoutText = 56.0666; // WARNING: depends on styling
+      w += widthOfPillWithoutText;
+      h = 20;
+      break;
+    }
+    case 'attribute': {
+      // calculate width and height of relation pill
+      const pixelsPerChar = widthPerFontsize[6]; // for fontsize 10px
+      w = name.length * pixelsPerChar;
+
+      const { datatype, operator } = attributes;
+      let value = attributes['value'];
+      if (!datatype || !operator) return { width: 0, height: 0 };
+      if (!value) value = '?';
+
+      // Add width of operator
+      w += operator.length * widthPerFontsize[7];
+      // use a max of 10, because max-width is set to 10ch;
+      w += Math.min(value.length, 10) * widthPerFontsize[6];
+
+      const widthOfPillWithoutText = 25.6666; // WARNING: depends on styling
+      w += widthOfPillWithoutText;
+      h = 12;
+      break;
+    }
+  }
+
+  return { width: w, height: h };
+}
+
+/** Interface for x and y position of node */
+export interface NodePosition extends XYPosition {}
+
+/** Returns from-position of relation node */
+export function RelationPosToFromEntityPos(position: XYPosition): NodePosition {
+  return { x: position.x - 60, y: position.y - 40 };
+}
+
+/** Returns to-position of relation node */
+export function RelationPosToToEntityPos(position: XYPosition): NodePosition {
+  return { x: position.x + 400, y: position.y };
+}
+
+/** Default position; x=0, y=0 */
+export const DefaultPosition = { x: 0, y: 0 };
diff --git a/libs/shared/lib/querybuilder/graph/logic/queryFunctions.tsx b/libs/shared/lib/querybuilder/graph/logic/queryFunctions.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..404f2f3ea0fbbf5e1fcc4efa7c3518441f00003c
--- /dev/null
+++ b/libs/shared/lib/querybuilder/graph/logic/queryFunctions.tsx
@@ -0,0 +1,148 @@
+/**
+ * This program has been developed by students from the bachelor Computer Science at
+ * Utrecht University within the Software Project course.
+ * © Copyright Utrecht University (Department of Information and Computing Sciences)
+ */
+
+import { AnyNode, FunctionArgs } from '../reactflow/model';
+
+/** What functions exist
+ *  Default is for the functions in the function bar that don't exist yet.
+ */
+export enum FunctionTypes {
+  GroupBy = 'groupBy',
+  link = 'linkPrediction',
+  communityDetection = 'communityDetection',
+  centrality = 'centrality',
+  shortestPath = 'shortestPath',
+  default = 'default',
+}
+
+export enum FunctionArgTypes {
+  group = 'group',
+  by = 'by',
+  relation = 'relation',
+  modifier = 'modifier',
+  constraints = 'constraints',
+  result = 'result',
+  ID1 = 'ID1',
+  ID2 = 'ID2',
+}
+/** All arguments that groupby pill needs */
+export const DefaultGroupByArgs: FunctionArgs = {
+  group: { displayName: 'Group', connectable: true, value: '', visible: true },
+  by: { displayName: 'By', connectable: true, value: '_id', visible: true },
+  relation: {
+    displayName: 'On',
+    connectable: true,
+    value: undefined,
+    visible: true,
+  },
+  modifier: {
+    displayName: 'Modifier: ',
+    connectable: false,
+    value: '',
+    visible: true,
+  },
+  constraints: {
+    displayName: 'Constraints: ',
+    connectable: true,
+    value: undefined,
+    visible: true,
+  },
+  result: {
+    displayName: 'Result: ',
+    connectable: true,
+    value: undefined,
+    visible: true,
+  },
+};
+/** All arguments that linkprediction pill needs */
+export const DefaultLinkPredictionArgs: FunctionArgs = {
+  linkprediction: {
+    //currently the querybuilder shows this name instead of the display name that needs to be changed.
+    displayName: 'linkprediction',
+    connectable: false,
+    value: undefined,
+    visible: true,
+  },
+};
+
+/** All arguments that CommunictyDetection pill needs */
+export const DefaultCommunictyDetectionArgs: FunctionArgs = {
+  CommunityDetection: {
+    displayName: 'CommunityDetection',
+    connectable: false,
+    value: undefined,
+    visible: true,
+  },
+};
+
+/** All arguments that centrality pill needs */
+export const DefaultCentralityArgs: FunctionArgs = {
+  centrality: {
+    displayName: 'centrality',
+    connectable: false,
+    value: undefined,
+    visible: true,
+  },
+};
+
+/** All arguments that centrality pill needs */
+export const DefaultShortestPathArgs: FunctionArgs = {
+  shortestPath: {
+    displayName: 'shortestPath',
+    connectable: false,
+    value: undefined,
+    visible: true,
+  },
+};
+
+// TODO: fix this to somehow make use of the enum
+/** Returns the correct arguments depending on the type */
+export const DefaultFunctionArgs: { [type: string]: FunctionArgs } = {
+  groupBy: DefaultGroupByArgs,
+  linkPrediction: DefaultLinkPredictionArgs,
+  communityDetection: DefaultCommunictyDetectionArgs,
+  centrality: DefaultCentralityArgs,
+  shortestPath: DefaultShortestPathArgs,
+};
+
+/** Interface for what function descriptions need */
+export interface FunctionDescription {
+  name: string;
+  type: FunctionTypes;
+  description: string;
+}
+
+/** All available functions in the function bar. */
+export const AvailableFunctions: Record<string, FunctionDescription> = {
+  centrality: {
+    name: 'centrality',
+    type: FunctionTypes.centrality,
+    description: 'W.I.P. Shows the importance of nodes',
+  },
+  communityDetection: {
+    name: 'Community Detection',
+    type: FunctionTypes.communityDetection,
+    description:
+      'Group entities connected by a relation based on how interconnected they are.',
+  },
+  groupBy: {
+    name: 'Group By',
+    type: FunctionTypes.GroupBy,
+    description:
+      'W.I.P. Per entity of type A, generate aggregate statistics of an attribute of either all links of a relation, or all nodes of an entity of type B connected to the type A entity by a relation.',
+  },
+  link: {
+    name: 'Link Prediction',
+    type: FunctionTypes.link,
+    description:
+      'For each pair of entities from a given type, determine the overlap between nodes they are connect to by a given relation.',
+  },
+  shortestPath: {
+    name: 'shortestPath',
+    type: FunctionTypes.shortestPath,
+    description: 'W.I.P. shortest path. Shows the shortest path between nodes',
+  },
+};
diff --git a/libs/shared/lib/querybuilder/graph/reactflow/handles.tsx b/libs/shared/lib/querybuilder/graph/reactflow/handles.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..71a09d2066cd6ebdf0919769e715aa6ee90c7e89
--- /dev/null
+++ b/libs/shared/lib/querybuilder/graph/reactflow/handles.tsx
@@ -0,0 +1,81 @@
+/**
+ * This program has been developed by students from the bachelor Computer Science at
+ * Utrecht University within the Software Project course.
+ * © Copyright Utrecht University (Department of Information and Computing Sciences)
+ */
+
+/**
+ * Enums for possible values for handles of nodes in the query builder.
+ * Possible handles for an entity node.
+ */
+import { FunctionArgTypes } from '../logic/queryFunctions';
+import { AnyNode, QueryElementTypes } from './model';
+
+/** Links need handles to what they are connected to (and which side) */
+export enum Handles {
+  RelationLeft = 'leftEntityHandle', //target
+  RelationRight = 'rightEntityHandle', //target
+  ToAttribute = 'attributesHandle', //target
+  ToRelation = 'relationsHandle', //source
+  OnAttribute = 'onAttributeHandle', //source
+  ReceiveFunction = 'receiveFunctionHandle', //target
+  FunctionBase = 'functionHandle_', // + name from FunctionTypes args //source
+}
+
+/** returns a boolean that check whether the handle is a function handle */
+export function isFunctionHandle(handle: string): boolean {
+  return handle.startsWith(Handles.FunctionBase);
+}
+
+/**
+ *  returns the functionargumenttype
+ *  Currently only working for groupby but made that in the future other functions can use this as well.
+ */
+export function functionHandleToType(handle: string): FunctionArgTypes {
+  if (isFunctionHandle(handle))
+    return handle.slice(Handles.FunctionBase.length) as FunctionArgTypes;
+  else
+    throw new Error('Incorrectly trying to assert handle to function handle');
+}
+/** Creates a handle from a functiontype */
+export function typeToFunctionHandle(type: FunctionArgTypes): string {
+  return Handles.FunctionBase + type;
+}
+
+/**
+ * Return a list of handles to which a connection can be made by dragging a node nearby
+ */
+export function nodeToHandlesThatCanReceiveDragconnect(
+  node: AnyNode
+): string[] {
+  switch (node.type) {
+    case QueryElementTypes.Entity:
+      return [Handles.ToAttribute];
+    case QueryElementTypes.Relation:
+      return [Handles.RelationLeft, Handles.RelationRight, Handles.ToAttribute];
+    case QueryElementTypes.Function:
+      return [Handles.ToAttribute];
+    case QueryElementTypes.Attribute:
+      return [];
+    default:
+      throw new Error('Unsupported node');
+  }
+}
+
+/**
+ * Return a list of handles from which a connection can be made while dragging the node they are on
+ */
+export function nodeToHandlesThatCanSendDragconnect(node: AnyNode): string[] {
+  switch (node.type) {
+    case QueryElementTypes.Entity:
+      return [Handles.ToRelation];
+    case QueryElementTypes.Relation:
+      return [];
+    case QueryElementTypes.Function:
+      return [];
+    case QueryElementTypes.Attribute:
+      return [Handles.OnAttribute];
+    default:
+      throw new Error('Unsupported node');
+  }
+}
diff --git a/libs/shared/lib/querybuilder/graph/reactflow/model.tsx b/libs/shared/lib/querybuilder/graph/reactflow/model.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..fddca14b89b5c917ad821ff5f1257381e3801d13
--- /dev/null
+++ b/libs/shared/lib/querybuilder/graph/reactflow/model.tsx
@@ -0,0 +1,130 @@
+/**
+ * This program has been developed by students from the bachelor Computer Science at
+ * Utrecht University within the Software Project course.
+ * © Copyright Utrecht University (Department of Information and Computing Sciences)
+ */
+import { Edge as ReactEdge, NodeProps } from 'reactflow';
+
+/** Enums for the possible types of query elements */
+export enum QueryElementTypes {
+  Entity = 'entity',
+  Relation = 'relation',
+  Attribute = 'attribute',
+  Function = 'function',
+}
+
+/** List of possible query element types */
+export const possibleTypes: string[] = [
+  QueryElementTypes.Entity,
+  QueryElementTypes.Relation,
+  QueryElementTypes.Attribute,
+  QueryElementTypes.Function,
+];
+
+/** All the possible react flow nodes. */
+export type AnyNode = EntityNode | RelationNode | AttributeNode | FunctionNode;
+export type Edge = ReactEdge<any>;
+export type AnyElement = AnyNode | Edge;
+export type AnyNodeData =
+  | EntityData
+  | RelationData
+  | AttributeData
+  | FunctionData;
+
+export type EntityNode = NodeProps<EntityData>;
+export type RelationNode = NodeProps<RelationData>;
+export type AttributeNode = NodeProps<AttributeData>;
+export type FunctionNode = NodeProps<FunctionData>;
+export type ModifierNode = NodeProps<ModifierData>;
+
+export interface NodeData {
+  fadeIn: boolean;
+}
+
+export interface ModifierData {
+  type: string;
+}
+
+/** Interface for the data in an entity node. */
+export interface EntityData extends NodeData {
+  name: string;
+}
+
+/** Interface for the data in an relation node. */
+export interface RelationData extends NodeData {
+  name: string;
+  collection: string;
+  depth: { min: number; max: number };
+}
+
+/** Interface for the data in an attribute node.
+ * Can have multiple constraint datatypes.
+ * string MatchTypes: exact/contains/startswith/endswith.
+ * int    MatchTypes: GT/LT/EQ.
+ * bool   MatchTypes: EQ/NEQ.
+ */
+export interface AttributeData extends NodeData {
+  name: string;
+  value: string;
+  dataType: string;
+  matchType: string;
+}
+
+export interface FunctionArg {
+  displayName: string;
+  connectable: boolean; // does this arg have a connectable handle?
+  value: string | undefined; // undefined means no text input
+  visible: boolean; // for implicit connections
+}
+
+export interface FunctionArgs {
+  [name: string]: FunctionArg;
+}
+
+/** Interface for the data in a function node. */
+export interface FunctionData extends NodeData {
+  functionType: string;
+  args: FunctionArgs;
+}
+
+/** Interface for updating the edges. */
+export interface updateEdges {
+  newEdge: Edge | undefined;
+  removeEdge: Edge | undefined;
+}
+
+/**
+ * Checks if a node is an entityNode.
+ * @param {AnyNode} node The node that has to checked.
+ * @returns True and casts if the node is an EntityNode.
+ */
+export function isEntityNode(node: AnyNode): node is EntityNode {
+  return node.type == QueryElementTypes.Entity;
+}
+
+/**
+ * Checks if a node is a RelationNode.
+ * @param {AnyNode} node The node that has to checked.
+ * @returns True and casts if the node is an RelationNode.
+ */
+export function isRelationNode(node: AnyNode): node is RelationNode {
+  return node.type == QueryElementTypes.Relation;
+}
+
+/**
+ * Checks if a node is an AttributeNode.
+ * @param {AnyNode} node The node that has to checked.
+ * @returns True and casts if the node is an AttributeNode.
+ */
+export function isAttributeNode(node: AnyNode): node is AttributeNode {
+  return node.type == QueryElementTypes.Attribute;
+}
+
+/**
+ * Checks if a node is an FunctionNode.
+ * @param {AnyNode} node The node that has to checked.
+ * @returns True and casts if the node is an FunctionNode.
+ */
+export function isFunctionNode(node: AnyNode): node is FunctionNode {
+  return node.type == QueryElementTypes.Function;
+}
diff --git a/libs/shared/lib/querybuilder/usecases/pillHandles.ts b/libs/shared/lib/querybuilder/graph/reactflow/pillHandles.ts
similarity index 100%
rename from libs/shared/lib/querybuilder/usecases/pillHandles.ts
rename to libs/shared/lib/querybuilder/graph/reactflow/pillHandles.ts
diff --git a/libs/shared/lib/querybuilder/usecases/createReactFlowElements.ts b/libs/shared/lib/querybuilder/graph/reactflow/utils.ts
similarity index 95%
rename from libs/shared/lib/querybuilder/usecases/createReactFlowElements.ts
rename to libs/shared/lib/querybuilder/graph/reactflow/utils.ts
index 9b288187a4c8daa39507a879ac07f87572c1e2b7..2bdf0acdb9a18b0a4af7e672e876f1d4eef39ea1 100644
--- a/libs/shared/lib/querybuilder/usecases/createReactFlowElements.ts
+++ b/libs/shared/lib/querybuilder/graph/reactflow/utils.ts
@@ -54,9 +54,8 @@ export function createReactFlowElements(graph: Graph): {
     }
     // Each pill should have a name and type
     data = {
+      ...attributes,
       ...data,
-      name: attributes.name,
-      suggestedForConnection: attributes.suggestedForConnection, // Highlights the pill, with shadow or something
     };
 
     const RFNode: Node = {
@@ -71,7 +70,7 @@ export function createReactFlowElements(graph: Graph): {
   // Add the reactflow edges
   graph.forEachEdge((edge, attributes, source, target): void => {
     // connection from attributes don't have visible connection lines
-    if (attributes.type == 'attribute_connection') return;
+    // if (attributes.type == 'attribute_connection') return;
 
     const RFEdge: Edge = {
       id: edge,
diff --git a/libs/shared/lib/querybuilder/index.ts b/libs/shared/lib/querybuilder/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e9ce65c3e91230655ae841d7f2721a41496155ec
--- /dev/null
+++ b/libs/shared/lib/querybuilder/index.ts
@@ -0,0 +1,2 @@
+export * from './panel';
+export * from './pills';
\ No newline at end of file
diff --git a/libs/shared/lib/ui/pills/shared-ui-pills.module.scss b/libs/shared/lib/querybuilder/panel/nodeUtils.ts
similarity index 100%
rename from libs/shared/lib/ui/pills/shared-ui-pills.module.scss
rename to libs/shared/lib/querybuilder/panel/nodeUtils.ts
diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.module.scss b/libs/shared/lib/querybuilder/panel/querybuilder.module.scss
index db83f46964a46bd398e50188c6d83bd06769b52c..e1a5d48d0e6acd88f1c7480891248c9c8fa8c2c7 100644
--- a/libs/shared/lib/querybuilder/panel/querybuilder.module.scss
+++ b/libs/shared/lib/querybuilder/panel/querybuilder.module.scss
@@ -6,3 +6,27 @@
   //   z-index: 4 !important;
   // }
 }
+
+
+//controls
+.controls {
+  left: auto !important;
+  bottom: auto !important;
+  top: 10px;
+  right: 20px;
+  width: auto !important;
+}
+.buttons {
+  left: auto !important;
+  bottom: auto !important;
+  top: 10px;
+  right: 20px;
+  & svg {
+    transform: scale(1.4);
+  };
+}
+
+.menuText {
+  font-size: small;
+  font-family: Poppins, sans-serif;
+}
\ No newline at end of file
diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.module.scss.d.ts b/libs/shared/lib/querybuilder/panel/querybuilder.module.scss.d.ts
index f2549523cf5819bcf6e47ed740eb243f828124aa..8d93e99522d001e896de5c3835789220b11e33b2 100644
--- a/libs/shared/lib/querybuilder/panel/querybuilder.module.scss.d.ts
+++ b/libs/shared/lib/querybuilder/panel/querybuilder.module.scss.d.ts
@@ -1,4 +1,7 @@
 declare const classNames: {
   readonly reactflow: 'reactflow';
+  readonly controls: 'controls';
+  readonly buttons: 'buttons';
+  readonly menuText: 'menuText';
 };
 export = classNames;
diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.stories.tsx b/libs/shared/lib/querybuilder/panel/querybuilder.stories.tsx
index b6bb2f30266d55e7a3db3f677336867bdde391e8..1bc0f5778bdbdbb158887faee1fb2728b71a34c5 100644
--- a/libs/shared/lib/querybuilder/panel/querybuilder.stories.tsx
+++ b/libs/shared/lib/querybuilder/panel/querybuilder.stories.tsx
@@ -3,99 +3,130 @@ import {
   colorPaletteConfigSlice,
   querybuilderSlice,
   setQuerybuilderNodes,
+  store,
 } from '@graphpolaris/shared/lib/data-access/store';
 import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme';
 import { configureStore } from '@reduxjs/toolkit';
-import { Meta, ComponentStory } from '@storybook/react';
+import { Meta } from '@storybook/react';
 import { Provider } from 'react-redux';
 import QueryBuilder from './querybuilder';
-import { MultiGraph } from 'graphology';
-import {
-  addPill,
-  handles,
-} from '@graphpolaris/shared/lib/querybuilder/usecases';
+import { Handles } from '../graph/reactflow/handles';
+import { QueryMultiGraph } from '../graph/graphology/utils';
 
 const Component: Meta<typeof QueryBuilder> = {
   component: QueryBuilder,
-  title: 'Panels/QueryBuilder',
+  title: 'QueryBuilder/Panel',
   decorators: [
     (story) => (
-      <Provider store={mockStore}>
-        <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider>
+      <Provider store={store}>
+        <GraphPolarisThemeProvider>
+          <div
+            style={{
+              width: '100%',
+              height: '95vh',
+            }}
+          >
+            {story()}
+          </div>
+        </GraphPolarisThemeProvider>
       </Provider>
     ),
   ],
 };
 
-// Mock palette store
-const mockStore = configureStore({
-  reducer: {
-    colorPaletteConfig: colorPaletteConfigSlice.reducer,
-    querybuilder: querybuilderSlice.reducer,
-  },
-});
-const graph = new MultiGraph();
-addPill('0', { type: 'entity', x: 100, y: 100, name: 'Entity Pill' }, graph);
-// graph.addNode('0', { type: 'entity', x: 100, y: 100, name: 'Entity Pill' });
-addPill(
-  '1',
-  { type: 'relation', x: 140, y: 140, name: 'Relation Pill' },
-  graph
-);
-addPill(
-  '2',
-  {
-    type: 'attribute',
-    x: 170,
-    y: 160,
-    name: 'Attr string',
-    datatype: 'string',
-    operator: 'EQ',
-    value: 'mark',
-  },
-  graph
+const graph = new QueryMultiGraph();
+graph.addPill2Graphology(
+  { type: 'entity', x: 100, y: 100, name: 'Entity Pill', fadeIn: false },
+  '0'
 );
-addPill(
-  '3',
-  {
-    type: 'attribute',
-    x: 170,
-    y: 170,
-    name: 'Attr number',
-    datatype: 'float',
-    operator: 'EQ',
-  },
-  graph
+graph.addPill2Graphology(
+  { type: 'entity', x: 200, y: 200, name: 'Entity Pill 2', fadeIn: false },
+  '10'
 );
-addPill(
-  '4',
+// graph.addNode('0', { type: 'entity', x: 100, y: 100, name: 'Entity Pill' });
+graph.addPill2Graphology(
   {
-    type: 'attribute',
-    x: 130,
-    y: 120,
-    name: 'Attr bool',
-    datatype: 'bool',
-    operator: 'EQ',
-    value: 'true',
+    type: 'relation',
+    x: 140,
+    y: 140,
+    name: 'Relation Pill',
+    depth: { min: 0, max: 1 },
+    fadeIn: false,
   },
-  graph
+  '1'
 );
-console.log(graph.getNodeAttributes('2'));
-graph.addEdge('2', '1', { type: 'attribute_connection' });
-graph.addEdge('3', '1', { type: 'attribute_connection' });
-graph.addEdge('4', '0', { type: 'attribute_connection' });
+// addPill2Graphology(
+//   '2',
+//   {
+//     type: 'attribute',
+//     x: 170,
+//     y: 160,
+//     name: 'Attr string',
+//     dataType: 'string',
+//     matchType: 'EQ',
+//     value: 'mark',
+//     depth: { min: 0, max: 1 },
+//     fadeIn: false,
+//   },
+//   graph
+// );
+// addPill2Graphology(
+//   '3',
+//   {
+//     type: 'attribute',
+//     x: 170,
+//     y: 170,
+//     name: 'Attr number',
+//     dataType: 'float',
+//     matchType: 'EQ',
+//     depth: { min: 0, max: 1 },
+//     fadeIn: false,
+//   },
+//   graph
+// );
+// addPill2Graphology(
+//   '4',
+//   {
+//     type: 'attribute',
+//     x: 130,
+//     y: 120,
+//     name: 'Attr bool',
+//     dataType: 'bool',
+//     matchType: 'EQ',
+//     value: 'true',
+//     depth: { min: 0, max: 1 },
+//     fadeIn: false,
+//   },
+//   graph
+// );
 graph.addEdge('0', '1', {
-  type: 'entity_relation',
-  targetHandle: handles.relation.fromEntity,
+  type: 'connection',
+  sourceHandle: Handles.ToRelation,
+  targetHandle: Handles.RelationLeft,
+});
+graph.addEdge('10', '1', {
+  type: 'connection',
+  sourceHandle: Handles.ToRelation,
+  targetHandle: Handles.RelationRight,
 });
+// console.log(graph.getNodeAttributes('2'));
+// graph.addEdge('2', '1', { type: 'attribute_connection' });
+// graph.addEdge('3', '1', { type: 'attribute_connection' });
+// graph.addEdge('4', '0', { type: 'attribute_connection' });
+// graph.addEdge('0', '1', {
+//   type: 'entity_relation',
+//   targetHandle: handles.relation.fromEntity,
+// });
 // graph.addEdge('1', '0', {
 //   type: 'entity_relation',
 //   sourceHandle: handles.relation.entity,
 // });
-mockStore.dispatch(setQuerybuilderNodes(graph.export()));
 
 export const Simple = {
   args: {},
+  play: async () => {
+    store.dispatch(setQuerybuilderNodes(graph.export()));
+  },
 };
 
 export default Component;
diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.tsx b/libs/shared/lib/querybuilder/panel/querybuilder.tsx
index 0892485b2bb5d9994e1f06b7bbc2ae1c3ed6ff8a..aca3c482a87d8d899a5dfd2b3d938eb518d1bb52 100644
--- a/libs/shared/lib/querybuilder/panel/querybuilder.tsx
+++ b/libs/shared/lib/querybuilder/panel/querybuilder.tsx
@@ -1,13 +1,9 @@
-import {
-  createReactFlowElements,
-  dragPill,
-  dragPillStarted,
-  dragPillStopped,
-} from '@graphpolaris/shared/lib/querybuilder/usecases';
 import {
   setQuerybuilderNodes,
   useAppDispatch,
-  useQuerybuilderNodes,
+  useConfig,
+  useQuerybuilderGraph,
+  useQuerybuilderGraphology,
 } from '@graphpolaris/shared/lib/data-access/store';
 import ReactFlow, {
   ReactFlowProvider,
@@ -15,99 +11,318 @@ import ReactFlow, {
   Node,
   isNode,
   ReactFlowInstance,
+  Controls,
+  ControlButton,
+  NodeChange,
+  ConnectionMode,
 } from 'reactflow';
 import styles from './querybuilder.module.scss';
+
+import React, { ReactComponentElement, useMemo, useRef } from 'react';
 import {
-  EntityRFPill,
-  RelationRFPill,
-  AttributeRFPill,
+  AttributePill,
   ConnectionDragLine,
   ConnectionLine,
-} from '@graphpolaris/shared/lib/ui/pills';
-
-import { useMemo, useRef } from 'react';
+  EntityFlowElement,
+  RelationPill,
+} from '../pills';
+import { createReactFlowElements } from '../graph/reactflow/utils';
+import {
+  dragPillStarted,
+  dragPillStopped,
+  movePillTo,
+} from '../pills/dragging/dragPill';
+import {
+  Settings as SettingsIcon,
+  Delete as DeleteIcon,
+  ImportExport as ExportIcon,
+} from '@mui/icons-material';
+import { clearQB } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice';
+import {
+  EntityNode,
+  QueryElementTypes,
+  RelationNode,
+} from '@graphpolaris/shared/lib/querybuilder/graph/reactflow/model';
+import {
+  RelationPosToFromEntityPos,
+  RelationPosToToEntityPos,
+} from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils';
+import { Handles } from '@graphpolaris/shared/lib/querybuilder/graph/reactflow/handles';
+import { useDispatch } from 'react-redux';
 
 const nodeTypes = {
-  entity: EntityRFPill,
-  relation: RelationRFPill,
-  attribute: AttributeRFPill,
+  entity: EntityFlowElement,
+  relation: RelationPill,
+  attribute: AttributePill,
 };
 const edgeTypes = {
   connection: ConnectionLine,
+  attribute_connection: ConnectionLine,
 };
 
-const onInit = (reactFlowInstance: ReactFlowInstance) => {
-  setTimeout(() => reactFlowInstance.fitView(), 0);
-};
-
-export const QueryBuilder = (props: any) => {
-  const nodes = useQuerybuilderNodes();
-  const dispatch = useAppDispatch();
+/**
+ * This is the main querybuilder component. It is responsible for holding all pills and fire off the visual part of the querybuilder panel logic
+ */
+export const QueryBuilder: React.FC = () => {
+  const graphologyGraph = useQuerybuilderGraphology();
+  const graph = useQuerybuilderGraph();
+  const config = useConfig();
+  const dispatch = useDispatch();
   const isDraggingPill = useRef(false);
-  console.log('inputnodes', nodes);
+  // console.log('inputnodes', nodes);
+  const reactFlowInstanceRef = useRef<ReactFlowInstance>();
+  const divRef = useRef<HTMLDivElement>(null);
+
+  const onInit = (reactFlowInstance: ReactFlowInstance) => {
+    reactFlowInstanceRef.current = reactFlowInstance;
+    setTimeout(() => reactFlowInstance.fitView(), 0);
+  };
 
-  const elements = useMemo(() => createReactFlowElements(nodes), [nodes]);
+  const elements = useMemo(
+    () => createReactFlowElements(graphologyGraph),
+    [graphologyGraph]
+  );
 
+  /**
+   * Called when a node is dragged in querybuilder to allow for movement
+   * @param event
+   * @param node
+   */
   const onNodeDrag = (
     event: React.MouseEvent<Element, MouseEvent>,
     node: Node<any>
   ) => {
     // Get the node in the elements list to get the previous location
-    const pNode = elements.nodes.find((e) => e.id === node.id);
+    const pNode = elements.nodes.find((e) => e?.id === node?.id);
     if (!(pNode && isNode(pNode))) return;
     // This is then used to calculate the delta position
     const dx = node.position.x - pNode.position.x;
     const dy = node.position.y - pNode.position.y;
 
+    // console.log(node, pNode);
     // Check if we started dragging, if so, call the drag started usecase
     if (!isDraggingPill.current) {
-      dragPillStarted(node.id, nodes);
+      dragPillStarted(node.id, graphologyGraph);
       isDraggingPill.current = true;
     }
 
     // Call the drag usecase
-    dragPill(node.id, nodes, dx, dy, node.position);
+    movePillTo(node.id, graphologyGraph, dx, dy, node.position);
 
     // Dispatch the new graphology object, so reactflow will get rerendered
-    dispatch(setQuerybuilderNodes(nodes.export()));
+    dispatch(setQuerybuilderNodes(graphologyGraph.export()));
   };
+
+  /**
+   * Called when a node is released from dragging in querybuilder
+   * @param event
+   * @param node
+   **/
   const onNodeDragStop = (
     event: React.MouseEvent<Element, MouseEvent>,
     node: Node<any>
   ) => {
-    isDraggingPill.current = false;
+    // isDraggingPill.current = false;
+    //
+    // // Call the drag pill stopped usecase
+    // dragPillStopped(node.id, graphologyGraph);
+    //
+    // // Dispatch the new graphology object, so reactflow will get rerendered
+    // dispatch(setQuerybuilderNodes(graphologyGraph.export()));
+  };
 
-    // Call the drag pill stopped usecase
-    dragPillStopped(node.id, nodes);
+  /**
+   * Clears all nodes in the graph.
+   */
+  function clearAllNodes() {
+    dispatch(clearQB());
+  }
 
-    // Dispatch the new graphology object, so reactflow will get rerendered
-    dispatch(setQuerybuilderNodes(nodes.export()));
+  /**
+   * Clears all nodes in the graph.
+   *  TODO: only works if the node is clicked and not moved (maybe use onSelectionChange)
+   */
+  function onNodesDelete(nodes: Node[]) {
+    nodes.forEach((n) => {
+      graphologyGraph.dropNode(n.id);
+    });
+
+    // Dispatch the new graphology object, so reactflow will get re-rendered
+    dispatch(setQuerybuilderNodes(graphologyGraph.export()));
+  }
+
+  /**
+   * TODO?
+   */
+  function onNodesChange(nodes: NodeChange[]) {
+    // console.log(nodes);
+    nodes.forEach((n) => {
+      // console.log(graphologyGraph.findNode((gn) => gn === n?.id));
+      if (n.type !== 'position') {
+        // updated = true;
+        // graphologyGraph.updateAttributes(n.id, n.data);
+      }
+    });
+  }
+
+  const onDragOver = (event: React.DragEvent<HTMLDivElement>): void => {
+    event.preventDefault();
+    event.dataTransfer.dropEffect = 'move';
   };
 
-  console.log(elements);
+  /**
+   * The onDrop is called when the user drops an element from the schema onto the QueryBuilder.
+   * In the onDrop query elements will be created based on the data stored in the drag event (datastrasfer).
+   * @param event Drag event.
+   */
+  const onDrop = (event: React.DragEvent<HTMLDivElement>): void => {
+    event.preventDefault();
+
+    // The dropped element should be a valid reactflow element
+    const data: string = event.dataTransfer.getData('application/reactflow');
+    if (data.length == 0 || !reactFlowInstanceRef?.current) return;
+
+    const dragData = JSON.parse(data);
+    const reactFlow = divRef.current as HTMLDivElement;
+    const reactFlowBounds = reactFlow.getBoundingClientRect();
+    const position = reactFlowInstanceRef.current.project({
+      //TODO: this position should be centre of entity, rather than topleft
+      x: event.clientX - reactFlowBounds.left,
+      y: event.clientY - reactFlowBounds.top,
+    });
+
+    switch (dragData.type) {
+      case QueryElementTypes.Entity:
+        graphologyGraph.addPill2Graphology({
+          type: QueryElementTypes.Entity,
+          x: position.x,
+          y: position.y,
+          name: dragData.name,
+          fadeIn: dragData.fadeIn,
+        });
+        break;
+      // Creates a relation element and will also create the 2 related entities together with the connections
+      case QueryElementTypes.Relation:
+        const relationId = graphologyGraph.addPill2Graphology({
+          type: QueryElementTypes.Relation,
+          x: position.x,
+          y: position.y,
+          depth: { min: 0, max: 1 },
+          name: dragData.name,
+          fadeIn: dragData.fadeIn,
+        });
+        const leftEntityId = graphologyGraph.addPill2Graphology({
+          type: QueryElementTypes.Entity,
+          ...RelationPosToFromEntityPos(position),
+          name: dragData.from,
+          fadeIn: true,
+        });
+        const rightEntityId = graphologyGraph.addPill2Graphology({
+          type: QueryElementTypes.Entity,
+          ...RelationPosToToEntityPos(position),
+          name: dragData.to,
+          fadeIn: true,
+        });
+
+        graphologyGraph.addEdge(leftEntityId, relationId, {
+          type: 'connection',
+          sourceHandle: Handles.ToRelation,
+          targetHandle: Handles.RelationLeft,
+        });
+        graphologyGraph.addEdge(rightEntityId, relationId, {
+          type: 'connection',
+          sourceHandle: Handles.ToRelation,
+          targetHandle: Handles.RelationRight,
+        });
+
+        if (config.autoSendQueries) {
+          // sendQuery();
+        }
+
+        dispatch(setQuerybuilderNodes(graphologyGraph.export()));
+        break;
+      // Creates an attribute element with the correct dataType
+      // case QueryElementTypes.Attribute:
+      //   createNodeFromSchema(
+      //     QueryElementTypes.Attribute,
+      //     position,
+      //     dragData.name,
+      //     dragData.fadeIn,
+      //     dragData.datatype
+      //   );
+      //   break;
+    }
+  };
 
   return (
     <div
       style={{
         width: '100%',
-        height: '100vh',
+        height: '100%',
       }}
+      ref={divRef}
     >
       <ReactFlowProvider>
         <ReactFlow
           edges={elements.edges}
           nodes={elements.nodes}
           snapGrid={[10, 10]}
-          // snapToGrid
+          snapToGrid
           nodeTypes={nodeTypes}
           edgeTypes={edgeTypes}
           connectionLineComponent={ConnectionDragLine}
+          // connectionMode={ConnectionMode.Loose}
           onInit={onInit}
           onNodeDrag={onNodeDrag}
           onNodeDragStop={onNodeDragStop}
+          onDragOver={onDragOver}
+          // onConnect={this.queryBuilderViewModel.onConnect}
+          onDrop={onDrop}
+          onNodesDelete={onNodesDelete}
+          onNodesChange={onNodesChange}
+          deleteKeyCode="Backspace"
           className={styles.reactflow}
         >
           <Background gap={10} size={0.7} />
+          <Controls
+            showZoom={false}
+            showInteractive={false}
+            className={styles.controls}
+          >
+            <ControlButton
+              className={styles.buttons}
+              title={'Remove all elements'}
+              onClick={() => clearAllNodes()}
+            >
+              <DeleteIcon />
+            </ControlButton>
+            <ControlButton
+              className={styles.buttons}
+              title={'Export querybuilder'}
+              onClick={(event) => {
+                event.stopPropagation();
+                // this.setState({
+                //   ...this.state,
+                //   exportMenuAnchor: event.currentTarget,
+                // });
+              }}
+            >
+              <ExportIcon />
+            </ControlButton>
+            <ControlButton
+              className={styles.buttons}
+              title={'Other settings'}
+              onClick={(event) => {
+                event.stopPropagation();
+                // this.setState({
+                //   ...this.state,
+                //   settingsMenuAnchor: event.currentTarget,
+                // });
+              }}
+            >
+              <SettingsIcon />
+            </ControlButton>
+          </Controls>
         </ReactFlow>
       </ReactFlowProvider>
     </div>
diff --git a/libs/shared/lib/querybuilder/panel/shemaquerybuilder.stories.tsx b/libs/shared/lib/querybuilder/panel/shemaquerybuilder.stories.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..61625236bcd0383d923520946dee33e4a77bcc80
--- /dev/null
+++ b/libs/shared/lib/querybuilder/panel/shemaquerybuilder.stories.tsx
@@ -0,0 +1,78 @@
+import React from 'react';
+import { Meta } from '@storybook/react';
+import { Provider } from 'react-redux';
+import {
+  colorPaletteConfigSlice,
+  graphQueryResultSlice,
+  querybuilderSlice,
+  schemaSlice,
+  setQuerybuilderNodes,
+  setSchema,
+  store,
+} from '@graphpolaris/shared/lib/data-access/store';
+import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme';
+import { SchemaUtils } from '@graphpolaris/shared/lib/schema/schema-utils';
+import { Schema } from '@graphpolaris/shared/lib/schema/panel';
+import { movieSchemaRaw } from '@graphpolaris/shared/lib/mock-data';
+import { QueryBuilder } from '@graphpolaris/shared/lib/querybuilder';
+import { configureStore } from '@reduxjs/toolkit';
+import { configSlice } from '@graphpolaris/shared/lib/data-access/store/configSlice';
+import { QueryGraph } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/model';
+import { MultiGraph } from 'graphology';
+import { QueryMultiGraph } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils';
+
+const SchemaAndQueryBuilder = () => {
+  return (
+    <div
+      style={{
+        display: 'flex',
+        height: '100%',
+        flexDirection: 'row',
+        width: '100%',
+        columnGap: '20px',
+      }}
+    >
+      <div style={{ width: '100%', height: '100%' }}>
+        <Schema />
+      </div>
+      <div style={{ width: '100%', height: '100%' }}>
+        <QueryBuilder />
+      </div>
+    </div>
+  );
+};
+
+const Component: Meta = {
+  component: SchemaAndQueryBuilder,
+  title: 'Panel',
+  decorators: [
+    // using the real store here
+    (story) => (
+      <Provider store={store}>
+        <GraphPolarisThemeProvider>
+          <div
+            style={{
+              width: '100%',
+              height: '95vh',
+            }}
+          >
+            {story()}
+          </div>
+        </GraphPolarisThemeProvider>
+      </Provider>
+    ),
+  ],
+};
+
+export const SchemaAndQueryBuilderInteractivity = {
+  play: async () => {
+    const dispatch = store.dispatch;
+    const schema = SchemaUtils.schemaBackend2Graphology(movieSchemaRaw);
+
+    const graph = new QueryMultiGraph();
+    dispatch(setQuerybuilderNodes(graph.export()));
+    dispatch(setSchema(schema.export()));
+  },
+};
+
+export default Component;
diff --git a/libs/shared/lib/querybuilder/pills/customFlowLines/connection.tsx b/libs/shared/lib/querybuilder/pills/customFlowLines/connection.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..50625840f09ca900ea4aa5c0916ba04322ced175
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowLines/connection.tsx
@@ -0,0 +1,80 @@
+import React from 'react';
+import { EdgeProps, getSmoothStepPath, Position } from 'reactflow';
+import { handles } from '../../graph/reactflow/pillHandles';
+
+/**
+ * A custom query element edge line component.
+ * @param {EdgeProps} param0 The coordinates for the start and end point, the id and the style.
+ */
+//  export const EntityRFPill = React.memo(({ data }: { data: any }) => {
+export function ConnectionLine({
+  id,
+  sourceX,
+  sourceY,
+  targetX,
+  targetY,
+  style,
+  sourceHandleId,
+  targetHandleId,
+  source,
+  target,
+  sourcePosition,
+  targetPosition,
+}: EdgeProps) {
+  //Centering the line
+  // sourceY -= 3;
+  // targetY -= 3;
+
+  // Correct line positions with hardcoded numbers, because react flow lacks this functionality
+  // if (sourceHandleId == ) sourceX += 2;
+
+  // if (targetHandleId == Handles.ToAttributeHandle) targetX += 2;
+
+  let spos: Position = sourcePosition;
+  // if (sourceHandleId == handles.relation.fromEntity) {
+  //   spos = Position.Left;
+  //   sourceX += 7;
+  //   sourceY += 3;
+  // } else if (sourceHandleId == handles.relation.toEntity) {
+  //   spos = Position.Right;
+  //   sourceX -= 2;
+  //   sourceY -= 3;
+  // } else if (
+  //   sourceHandleId !== undefined &&
+  //   sourceHandleId !== null &&
+  //   sourceHandleId.includes('functionHandle')
+  // ) {
+  //   spos = Position.Top;
+  //   sourceX -= 4;
+  //   sourceY += 3;
+  // }
+
+  let tpos: Position = targetPosition;
+  // if (targetHandleId == handles.relation.fromEntity) {
+  //   tpos = Position.Left;
+  //   targetX += 7;
+  //   targetY += 3;
+  // } else if (targetHandleId == handles.relation.toEntity) {
+  //   tpos = Position.Right;
+  //   targetX -= 2;
+  //   targetY -= 3;
+  // }
+
+  // Create smoothstep line
+  const path = getSmoothStepPath({
+    sourceX: sourceX,
+    sourceY: sourceY,
+    sourcePosition: spos,
+    targetX: targetX,
+    targetY: targetY,
+    targetPosition: tpos,
+  });
+
+  // console.log(source, target, path);
+
+  return (
+    <g stroke="#2e2e2e">
+      <path id={id} fill="none" strokeWidth={3} style={style} d={path[0]} />
+    </g>
+  );
+}
diff --git a/libs/shared/lib/ui/pills/customFlowLines/connectionDrag.tsx b/libs/shared/lib/querybuilder/pills/customFlowLines/connectionDrag.tsx
similarity index 100%
rename from libs/shared/lib/ui/pills/customFlowLines/connectionDrag.tsx
rename to libs/shared/lib/querybuilder/pills/customFlowLines/connectionDrag.tsx
diff --git a/libs/shared/lib/ui/pills/customFlowLines/index.ts b/libs/shared/lib/querybuilder/pills/customFlowLines/index.ts
similarity index 100%
rename from libs/shared/lib/ui/pills/customFlowLines/index.ts
rename to libs/shared/lib/querybuilder/pills/customFlowLines/index.ts
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill-full.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill-full.stories.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..196afa73c2f61830f6c8d6a073bf4e6d713e9f83
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill-full.stories.tsx
@@ -0,0 +1,59 @@
+import React from 'react';
+import {
+  colorPaletteConfigSlice,
+  querybuilderSlice,
+  setQuerybuilderNodes,
+} from '@graphpolaris/shared/lib/data-access/store';
+import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme';
+import { configureStore } from '@reduxjs/toolkit';
+import { Meta } from '@storybook/react';
+import { Provider } from 'react-redux';
+import { MultiGraph } from 'graphology';
+import { QueryBuilder } from '../../../panel';
+import { QueryGraph } from '../../../graph/graphology/model';
+import { circular } from 'graphology-layout';
+import { QueryMultiGraph } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils';
+
+const Component: Meta<typeof QueryBuilder> = {
+  component: QueryBuilder,
+  title: 'Querybuilder/Pills/AttributePill',
+  decorators: [
+    (story) => (
+      <Provider store={mockStore}>
+        <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider>
+      </Provider>
+    ),
+  ],
+};
+
+// Mock palette store
+const mockStore = configureStore({
+  reducer: {
+    colorPaletteConfig: colorPaletteConfigSlice.reducer,
+    querybuilder: querybuilderSlice.reducer,
+  },
+});
+const graph = new QueryMultiGraph();
+graph.addPill2Graphology(
+  {
+    type: 'attribute',
+    x: 170,
+    y: 160,
+    name: 'Attr string',
+    dataType: 'string',
+    matchType: 'NEQ',
+    value: 'mark',
+    fadeIn: false,
+    // depth: { min: 0, max: 1 },
+  },
+  '2'
+);
+console.log(graph.export());
+
+mockStore.dispatch(setQuerybuilderNodes(graph.export()));
+
+export const Flow = {
+  args: {},
+};
+
+export default Component;
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.module.scss
new file mode 100644
index 0000000000000000000000000000000000000000..880216ca8cced12e4a78c98955880278d4e7a1e8
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.module.scss
@@ -0,0 +1,151 @@
+@use './variables.module.scss';
+@import '../../querypills.module.scss';
+
+.attribute {
+  display: flex;
+  font-family: monospace;
+  font-weight: bold;
+  font-size: variables.$fontsize;
+  border-radius: 2px;
+}
+
+// .handle {
+//   border: 0px;
+//   border-radius: 10px;
+//   left: 12px;
+//   width: 7px;
+//   height: 7px;
+//   margin-bottom: 11px;
+//   background: rgba(255; 255; 255; 0.6);
+//   box-shadow: 0 0 0 1px rgba(0; 0; 0; 0.3);
+//   transform-origin: center;
+// }
+
+.contentWrapper {
+  display: flex;
+  align-items: center;
+
+  .content {
+    padding: variables.$ypad 0 variables.$ypad 1ch;
+    max-width: 15ch;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    white-space: nowrap;
+  }
+}
+
+// Attribute Element
+.attributeMain {
+  background: #bfb6af;
+  color: #fff;
+  border-radius: 18px;
+  font-family: monospace;
+  font-weight: bold;
+  font-size: 11px;
+  padding-top: 0.1em;
+  padding-right: 0.5em;
+  padding-bottom: 0.1em;
+  padding-left: 0.5em;
+}
+
+.attributeHandleLeft {
+  left: 4px !important;
+  background: rgba(0, 0, 0, 0.3);
+  &::before {
+    content: '';
+    width: 6;
+    height: 6;
+    left: 1;
+    bottom: 1;
+    border: 0;
+    border-radius: 5;
+    background: rgba(255, 255, 255, 0.6);
+    z-index: -1;
+    display: inline-block;
+    position: fixed;
+  }
+}
+
+.attributeInput {
+  float: right;
+  padding: 0 1ch 0 0;
+  display: flex;
+  align-items: center;
+
+  input {
+    background-color: rgba(100, 100, 100, 0.1);
+    font-family: monospace;
+    font-size: variables.$fontsize;
+    border: 1px solid rgba(100, 100, 100, 0.3);
+    border-radius: 2px;
+    height: variables.$height;
+    outline: none;
+    transition: border 0.3s;
+    color: black;
+    &::placeholder {
+      color: black;
+    }
+
+    &:focus {
+      border: 1px solid rgba(0, 0, 0, 0.3);
+    }
+  }
+}
+
+.attributeWrapper {
+  height: 100%;
+  color: black;
+  display: flex;
+  align-items: center;
+  gap: 0.6em;
+  margin-left: 0.8em;
+}
+.attributeWrapperSpan {
+  margin-left: 4px;
+}
+
+// Attribute select component
+.matchTypeSelect {
+  background-color: rgba(255, 255, 255, 0.6);
+  border-radius: 2px;
+  display: flex;
+  pointer-events: all;
+  cursor: pointer;
+  & select {
+    background: transparent;
+    border: none;
+    appearance: none;
+
+    font-family: monospace;
+    font-size: 11px;
+    text-align: center;
+  }
+  & option {
+    font-family: monospace;
+    font-size: 11px;
+  }
+}
+.matchModifierTypeSelect {
+  background-color: rgba(255, 255, 255, 0.6);
+  border-radius: 2px;
+
+  text-align: center;
+  & select {
+    background: transparent;
+    border: none;
+    appearance: none;
+    font-family: monospace;
+    font-weight: bolder;
+    color: black;
+    font-size: 11;
+  }
+  & option {
+    font-family: monospace;
+    font-size: 11px;
+  }
+}
+
+.disable {
+  opacity: 1 !important;
+  pointer-events: none;
+}
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.module.scss.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d44a6b42fca61b196da056f690d2db24b92a2e0d
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.module.scss.d.ts
@@ -0,0 +1,24 @@
+declare const classNames: {
+  readonly 'react-flow__node': 'react-flow__node';
+  readonly selected: 'selected';
+  readonly entityWrapper: 'entityWrapper';
+  readonly hidden: 'hidden';
+  readonly 'react-flow__edges': 'react-flow__edges';
+  readonly 'react-flow__edge-default': 'react-flow__edge-default';
+  readonly handleConnectedFill: 'handleConnectedFill';
+  readonly handleConnectedBorderRight: 'handleConnectedBorderRight';
+  readonly handleConnectedBorderLeft: 'handleConnectedBorderLeft';
+  readonly handleFunction: 'handleFunction';
+  readonly attribute: 'attribute';
+  readonly contentWrapper: 'contentWrapper';
+  readonly content: 'content';
+  readonly attributeMain: 'attributeMain';
+  readonly attributeHandleLeft: 'attributeHandleLeft';
+  readonly attributeInput: 'attributeInput';
+  readonly attributeWrapper: 'attributeWrapper';
+  readonly attributeWrapperSpan: 'attributeWrapperSpan';
+  readonly matchTypeSelect: 'matchTypeSelect';
+  readonly matchModifierTypeSelect: 'matchModifierTypeSelect';
+  readonly disable: 'disable';
+};
+export = classNames;
diff --git a/libs/shared/lib/ui/pills/customFlowPills/attributepill/attributepill.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.stories.tsx
similarity index 85%
rename from libs/shared/lib/ui/pills/customFlowPills/attributepill/attributepill.stories.tsx
rename to libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.stories.tsx
index 5013499164e08eccdc9136807585112d043dce0a..eec408f5a00677e37e7144b00a74b3929b0cf5ca 100644
--- a/libs/shared/lib/ui/pills/customFlowPills/attributepill/attributepill.stories.tsx
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.stories.tsx
@@ -1,6 +1,6 @@
 import React from 'react';
 import { Meta } from '@storybook/react';
-import AttributeRFPill from './attributepill';
+import AttributePill from './attributepill';
 import { configureStore } from '@reduxjs/toolkit';
 import { Provider } from 'react-redux';
 import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme';
@@ -12,13 +12,13 @@ import {
 } from '@graphpolaris/shared/lib/data-access/store';
 import { ReactFlowProvider } from 'reactflow';
 
-const Component: Meta<typeof AttributeRFPill> = {
+const Component: Meta<typeof AttributePill> = {
   /* 👇 The title prop is optional.
    * See https://storybook.js.org/docs/react/configure/overview#configure-story-loading
    * to learn how to generate automatic titles
    */
-  title: 'Components/Pills/AttributeRFPill',
-  component: AttributeRFPill,
+  title: 'Querybuilder/Pills/AttributePill',
+  component: AttributePill,
   decorators: [
     (story) => (
       <Provider store={Mockstore}>
@@ -41,7 +41,7 @@ const Mockstore = configureStore({
   },
 });
 
-export const Default = {
+export const Simple = {
   args: {
     data: {
       name: 'TestEntity',
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..26d4bb0bc7c6fd19e1e286a8788e19cfa40d37e7
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx
@@ -0,0 +1,153 @@
+import { useTheme } from '@mui/material';
+import React, { useMemo, useState } from 'react';
+import styles from './attributepill.module.scss';
+import { Handle, NodeProps, Position } from 'reactflow';
+import { AttributeOperatorSelect } from './operator';
+import Select from './select-component';
+import { AttributeNode } from '../../../graph/reactflow/model';
+import { Handles } from '../../../graph/reactflow/handles';
+
+/**
+ * Component to render an attribute flow element
+ * @param {FlowElement<EntityData>)} param0 The data of an entity flow element.
+ */
+export const AttributePill = React.memo(({ id, data }: AttributeNode) => {
+  const theme = useTheme();
+  const [read, setRead] = useState(true);
+  // console.log('AttributePill', data);
+
+  /**
+   * Check if the pressed key is enter in order to send the new query.
+   * @param event Key press event.
+   */
+  const _onKeyDown = (event: any): void => {
+    if (event.key == 'Enter') setRead(true);
+  };
+
+  /**
+   * Checks if the string input is a number.
+   * @param x String input.
+   * @returns {boolean} True if input is a number.
+   */
+  const isNumber = (x: string): boolean => {
+    {
+      if (typeof x != 'string') return false;
+      return !Number.isNaN(x) && !Number.isNaN(parseFloat(x));
+    }
+  };
+
+  /**
+   * Calculates the width of an element based on the length of a monospaced font.
+   * @param str Input string.
+   * @returns {string} Containing the length in css format.
+   */
+  const calcWidth = (str: string) => {
+    if (str == '') {
+      return 1.5 + 'ch';
+    }
+    return str.length + 0.5 + 'ch';
+  };
+
+  /**
+   * Input contraint checker for the attribute input fields.
+   * @param type Data.dataType.
+   * @param str Input string.
+   * @returns {string} Result string after the contraints are applied.
+   */
+  const inputConstraint = (type: string, str: string): string => {
+    let res = '';
+    switch (type) {
+      case 'string':
+        res = str;
+        break;
+      case 'bool':
+        res = str;
+        break; // TODO: only false and true live update will break since it will not allow to write more that 1 letter
+      case 'int':
+        isNumber(str) ? (res = str) : (res = '');
+        break; // TODO: check if letters after number
+      default:
+        res = str;
+        break;
+    }
+    return res;
+  };
+
+  //TODO: docstrings
+  const className =
+    styles.attributeHandleLeft +
+    ' ' +
+    (false ? styles.handleConnectedFill : '');
+
+  const onChange = (e: any) => {
+    if (data != undefined) {
+      data.value = inputConstraint(data.dataType, e.target.value);
+      e.target.style.maxWidth = calcWidth(data.value);
+    }
+  };
+
+  /**Constraint datatypes back end.
+   * string		  MatchTypes: EQ/NEQ/contains/excludes.
+   * int   MatchTypes: EQ/NEQ/GT/LT/GET/LET.
+   * bool     MatchTypes: EQ/NEQ.
+   */
+  //TODO: fix use of relation boilerplate styling
+
+  return (
+    <div
+      className={styles.attributeMain}
+      style={{ backgroundColor: theme.palette.custom.elements.attribute[0] }}
+    >
+      <Handle
+        id={Handles.OnAttribute}
+        type="source"
+        position={Position.Left}
+        className={
+          styles.attributeHandleLeft +
+          ' ' +
+          (false ? styles.handleConnectedFill : '')
+        }
+        style={{ backgroundColor: theme.palette.custom.elements.attribute[1] }}
+      />
+      <Handle
+        id={Handles.ToAttribute}
+        type="source"
+        position={Position.Left}
+        className={
+          styles.attributeHandleLeft +
+          ' ' +
+          (false ? styles.handleConnectedFill : '')
+        }
+        style={{
+          backgroundColor: theme.palette.custom.elements.attribute[1],
+          left: 50,
+        }}
+      />
+      <div className={styles.attributeWrapper}>
+        <span className={styles.attributeWrapperSpan}>{data?.name}</span>
+        <Select data={data} />
+        <span className={styles.attributeInput}>
+          <input type="hidden"></input>
+          <input
+            style={{ maxWidth: calcWidth(data?.value || '') }}
+            type="string"
+            readOnly={read}
+            placeholder={'?'}
+            value={data?.value || ''}
+            onChange={onChange}
+            onDoubleClick={() => {
+              setRead(false);
+            }}
+            onBlur={() => {
+              setRead(true);
+            }}
+            onKeyDown={_onKeyDown}
+          ></input>
+        </span>
+      </div>
+    </div>
+  );
+});
+AttributePill.displayName = 'AttributePill';
+
+export default AttributePill;
diff --git a/libs/shared/lib/querybuilder/usecases/attribute/checkInput.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/checkInput.ts
similarity index 100%
rename from libs/shared/lib/querybuilder/usecases/attribute/checkInput.ts
rename to libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/checkInput.ts
diff --git a/libs/shared/lib/querybuilder/usecases/attribute/getAttributeBoolOperators.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/getAttributeBoolOperators.ts
similarity index 100%
rename from libs/shared/lib/querybuilder/usecases/attribute/getAttributeBoolOperators.ts
rename to libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/getAttributeBoolOperators.ts
diff --git a/libs/shared/lib/ui/pills/customFlowPills/attributepill/index.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/index.ts
similarity index 100%
rename from libs/shared/lib/ui/pills/customFlowPills/attributepill/index.ts
rename to libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/index.ts
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/index.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fe9dde909b79825b1cb1e46e3402762141b2d25f
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/index.ts
@@ -0,0 +1 @@
+export * from './operatorselect';
diff --git a/libs/shared/lib/ui/pills/customFlowPills/attributepill/operatorselect.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.module.scss
similarity index 97%
rename from libs/shared/lib/ui/pills/customFlowPills/attributepill/operatorselect.module.scss
rename to libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.module.scss
index 1c31d2744f029e77c53efbfac2aae8983640770a..286fa1da405db69f96f095a6801d825502da3e6c 100644
--- a/libs/shared/lib/ui/pills/customFlowPills/attributepill/operatorselect.module.scss
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.module.scss
@@ -1,4 +1,4 @@
-@use './variables.module.scss';
+@use '../variables.module.scss';
 
 .container {
   position: relative;
diff --git a/libs/shared/lib/ui/pills/customFlowPills/attributepill/operatorselect.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.module.scss.d.ts
similarity index 100%
rename from libs/shared/lib/ui/pills/customFlowPills/attributepill/operatorselect.module.scss.d.ts
rename to libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.module.scss.d.ts
diff --git a/libs/shared/lib/ui/pills/customFlowPills/attributepill/operatorselect.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.tsx
similarity index 96%
rename from libs/shared/lib/ui/pills/customFlowPills/attributepill/operatorselect.tsx
rename to libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.tsx
index cf1d9726a11921e9988dea44cf958cd22ae07222..d62e39a1d07924099950b54f9ddc16626a18269a 100644
--- a/libs/shared/lib/ui/pills/customFlowPills/attributepill/operatorselect.tsx
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.tsx
@@ -21,7 +21,7 @@ interface Props {
   changed?: (newSelected: SelectOption<string>) => void;
 }
 
-function AttributeOperatorSelect({
+export function AttributeOperatorSelect({
   options,
   selected,
   changed = () => {
@@ -83,5 +83,3 @@ function AttributeOperatorSelect({
     </div>
   );
 }
-
-export default AttributeOperatorSelect;
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/select-component.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/select-component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..38a35b85e5ebfd44f7c68d9bb1b2a753ad4a2cca
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/select-component.tsx
@@ -0,0 +1,88 @@
+/**
+ * This program has been developed by students from the bachelor Computer Science at
+ * Utrecht University within the Software Project course.
+ * © Copyright Utrecht University (Department of Information and Computing Sciences)
+ */
+
+/* istanbul ignore file */
+/* The comment above was added so the code coverage wouldn't count this file towards code coverage.
+ * We do not test components/renderfunctions/styling files.
+ * See testing plan for more details.*/
+import { useTheme } from '@mui/material';
+import React, { useState } from 'react';
+import styles from './attributepill.module.scss';
+import { AttributeData } from '../../../graph/reactflow/model';
+
+export default function SelectComponent({ data }: { data: AttributeData }) {
+  const theme = useTheme();
+
+  /**
+   * Calculate the width of the select element based on the displayed value.
+   * @param str Input string.
+   * @returns {string} Containing the length in css format.
+   */
+  const calcSelectWidth = (str: string): string => {
+    if (str == '') {
+      return 1.5 + 'ch';
+    }
+    return str.length + 1.5 + 'ch';
+  };
+
+  /**
+   * Constant switch to append the right options for the select element based on the data.dataType.
+   * @returns {JSX.Element} Option list using React.Fragment as parent element.
+   */
+  const list = (): JSX.Element => {
+    switch (data.dataType) {
+      case 'string':
+        return (
+          <React.Fragment>
+            <option value="EQ">==</option>
+            <option value="NEQ">!=</option>
+            <option value="contains">contains</option>
+            <option value="excludes">excludes</option>
+          </React.Fragment>
+        );
+      case 'int':
+      case 'float':
+        return (
+          <React.Fragment>
+            <option value="EQ">==</option>
+            <option value="NEQ">!=</option>
+            <option value="GT">{'>'}</option>
+            <option value="LT">{'<'}</option>
+            <option value="GET">{'>='}</option>
+            <option value="LET">{'<='}</option>
+          </React.Fragment>
+        );
+      case 'bool':
+        return (
+          <React.Fragment>
+            <option value="EQ">==</option>
+            <option value="NEQ">!=</option>
+          </React.Fragment>
+        );
+      default:
+        return <option>Error</option>;
+    }
+  };
+
+  return (
+    <div
+      className={styles.matchTypeSelect}
+      style={{ backgroundColor: theme.palette.custom.elements.attribute[1] }}
+    >
+      <select
+        style={{ maxWidth: calcSelectWidth('==') }}
+        value={data.matchType}
+        name="operators"
+        onChange={(e) => {
+          data.matchType = e.target.value;
+          e.target.style.maxWidth = calcSelectWidth(e.target.value);
+        }}
+      >
+        {list()}
+      </select>
+    </div>
+  );
+}
diff --git a/libs/shared/lib/ui/pills/customFlowPills/attributepill/variables.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/variables.module.scss
similarity index 100%
rename from libs/shared/lib/ui/pills/customFlowPills/attributepill/variables.module.scss
rename to libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/variables.module.scss
diff --git a/libs/shared/lib/ui/pills/shared-ui-pills.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/variables.module.scss.d.ts
similarity index 100%
rename from libs/shared/lib/ui/pills/shared-ui-pills.module.scss.d.ts
rename to libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/variables.module.scss.d.ts
diff --git a/libs/shared/lib/ui/pills/customFlowLines/connection.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/edge-line.tsx
similarity index 54%
rename from libs/shared/lib/ui/pills/customFlowLines/connection.tsx
rename to libs/shared/lib/querybuilder/pills/customFlowPills/edge-line.tsx
index 646b6f4f24159628ca7d82aa1a85162ac0c89d2b..2d9006f6712a37cbe4b503e53e6fd991d420edd9 100644
--- a/libs/shared/lib/ui/pills/customFlowLines/connection.tsx
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/edge-line.tsx
@@ -1,13 +1,22 @@
-import { handles } from '@graphpolaris/shared/lib/querybuilder/usecases';
+/**
+ * This program has been developed by students from the bachelor Computer Science at
+ * Utrecht University within the Software Project course.
+ * © Copyright Utrecht University (Department of Information and Computing Sciences)
+ */
+
+/* istanbul ignore file */
+/* The comment above was added so the code coverage wouldn't count this file towards code coverage.
+ * We do not test components/renderfunctions/styling files.
+ * See testing plan for more details.*/
 import React from 'react';
 import { EdgeProps, getSmoothStepPath, Position } from 'reactflow';
+import { Handles } from '../../graph-reactflow/handles';
 
 /**
  * A custom query element edge line component.
  * @param {EdgeProps} param0 The coordinates for the start and end point, the id and the style.
  */
-//  export const EntityRFPill = React.memo(({ data }: { data: any }) => {
-export function ConnectionLine({
+export default function EdgeLine({
   id,
   sourceX,
   sourceY,
@@ -22,16 +31,16 @@ export function ConnectionLine({
   targetY -= 3;
 
   // Correct line positions with hardcoded numbers, because react flow lacks this functionality
-  // if (sourceHandleId == ) sourceX += 2;
+  if (sourceHandleId == Handles.ToAttributeHandle) sourceX += 2;
 
-  // if (targetHandleId == Handles.ToAttributeHandle) targetX += 2;
+  if (targetHandleId == Handles.ToAttributeHandle) targetX += 2;
 
   let spos: Position = Position.Bottom;
-  if (sourceHandleId == handles.relation.fromEntity) {
+  if (sourceHandleId == Handles.RelationLeft) {
     spos = Position.Left;
     sourceX += 7;
     sourceY += 3;
-  } else if (sourceHandleId == handles.relation.toEntity) {
+  } else if (sourceHandleId == Handles.RelationRight) {
     spos = Position.Right;
     sourceX -= 2;
     sourceY -= 3;
@@ -46,11 +55,11 @@ export function ConnectionLine({
   }
 
   let tpos: Position = Position.Bottom;
-  if (targetHandleId == handles.relation.fromEntity) {
+  if (targetHandleId == Handles.RelationLeft) {
     tpos = Position.Left;
     targetX += 7;
     targetY += 3;
-  } else if (targetHandleId == handles.relation.toEntity) {
+  } else if (targetHandleId == Handles.RelationRight) {
     tpos = Position.Right;
     targetX -= 2;
     targetY -= 3;
@@ -67,8 +76,14 @@ export function ConnectionLine({
   });
 
   return (
-    <g stroke="#2e2e2e">
-      <path id={id} fill="none" strokeWidth={3} style={style} d={path[0]} />
+    <g stroke="black">
+      <path
+        id={id}
+        fill="none"
+        strokeWidth={5}
+        style={style}
+        d={path.toString()} //TODO: Check
+      />
     </g>
   );
 }
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..18b65e8be65a8550fd1feed2a693888d604f1a37
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx
@@ -0,0 +1,49 @@
+import React from 'react';
+import {
+  colorPaletteConfigSlice,
+  querybuilderSlice,
+  setQuerybuilderNodes,
+} from '@graphpolaris/shared/lib/data-access/store';
+import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme';
+import { configureStore } from '@reduxjs/toolkit';
+import { Meta } from '@storybook/react';
+import { Provider } from 'react-redux';
+import { MultiGraph } from 'graphology';
+import { QueryBuilder } from '../../../panel';
+import { QueryGraph } from '../../../graph/graphology/model';
+import { circular } from 'graphology-layout';
+import { QueryMultiGraph } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils';
+
+const Component: Meta<typeof QueryBuilder> = {
+  component: QueryBuilder,
+  title: 'Querybuilder/Pills/EntityPill',
+  decorators: [
+    (story) => (
+      <Provider store={mockStore}>
+        <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider>
+      </Provider>
+    ),
+  ],
+};
+
+// Mock palette store
+const mockStore = configureStore({
+  reducer: {
+    colorPaletteConfig: colorPaletteConfigSlice.reducer,
+    querybuilder: querybuilderSlice.reducer,
+  },
+});
+const graph = new QueryMultiGraph();
+graph.addPill2Graphology(
+  { type: 'entity', x: 100, y: 100, name: 'Entity Pill', fadeIn: false },
+  '2'
+);
+console.log(graph.export());
+
+mockStore.dispatch(setQuerybuilderNodes(graph.export()));
+
+export const Flow = {
+  args: {},
+};
+
+export default Component;
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss
new file mode 100644
index 0000000000000000000000000000000000000000..79e336437fe02d1ddbe85db273c5488ec7bf6bce
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss
@@ -0,0 +1,175 @@
+@import '../../querypills.module.scss';
+
+.entity {
+  display: flex;
+  font-family: monospace;
+  font-weight: bold;
+  font-size: 10px;
+  padding: 4px 2ch;
+  border-radius: 3px;
+}
+
+.highlighted {
+  box-shadow: black 0 0 2px;
+}
+
+.handleLeft {
+  border: 0px;
+  border-radius: 0px;
+  left: 12px;
+  width: 7px;
+  height: 7px;
+  margin-bottom: 11px;
+  background: rgba(255, 255, 255, 0.6);
+  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);
+  transform-origin: center;
+}
+
+// .handleBottom {
+//   border: 0px;
+//   border-radius: 0px;
+//   width: 7px;
+//   height: 7px;
+//   left: 27.5px;
+//   margin-bottom: 11px;
+//   background: rgba(255, 255, 255, 0.6);
+//   box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);
+//   transform: rotate(-45deg);
+//   transform-origin: center;
+// }
+
+.react-flow__edges {
+  zindex: 3;
+}
+.react-flow__nodes {
+}
+.react-flow__pane {
+}
+.react-flow__edge-default .selected {
+  stroke: gray !important;
+}
+
+.contentWrapper {
+  margin-left: 3ch;
+
+  span {
+    max-width: 20ch;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    white-space: nowrap;
+    display: block;
+  }
+}
+
+// Entity element
+.entity {
+  background: #e9e9e9;
+  display: flex;
+  border-radius: 1px;
+  font-family: monospace;
+  font-weight: bold;
+  font-size: 11px;
+  color: black;
+  padding-left: 45px;
+}
+
+.entityFade {
+  opacity: 1;
+  animation-iteration-count: 1;
+  animation: fade-id, 600ms, cubic-bezier(0.4, 0, 1, 1);
+  @keyframes fade-id {
+    0% {
+      opacity: 0;
+    }
+    40% {
+      opacity: 0;
+    }
+    100% {
+      opacity: 1;
+    }
+  }
+}
+
+.entityHandleLeft {
+  border: 0;
+  border-radius: 0;
+  left: 12;
+  width: 8;
+  height: 8;
+  margin-bottom: 15;
+  background: rgba(0, 0, 0, 0.3);
+  transform-origin: center;
+  &::before {
+    content: '';
+    width: 6;
+    height: 6;
+    left: 1;
+    bottom: 1;
+    border: 0;
+    border-radius: 0;
+    background: rgba(255, 255, 255, 0.6);
+    z-index: -1;
+    display: inline-block;
+    position: fixed;
+  }
+}
+
+.entityHandleBottom {
+  border: 0;
+  border-radius: 0;
+  width: 8;
+  height: 8;
+  left: 27.5;
+  margin-bottom: 15;
+  background: rgba(0, 0, 0, 0.3);
+  transform: rotate(-45deg);
+  transform-origin: center;
+  &::before {
+    content: '';
+    width: 6;
+    height: 6;
+    left: 1;
+    bottom: 1;
+    border: 0;
+    border-radius: 0;
+    background: rgba(255, 255, 255, 0.6);
+    z-index: -1;
+    display: inline-block;
+    position: fixed;
+  }
+}
+
+.entityWrapper {
+  display: block;
+}
+
+.entitySpan {
+  display: block;
+}
+
+// General style
+.ToRelationHandle {
+  border-radius: 1px !important;
+  left: 10px !important;
+  top: 35% !important;
+  background: rgba(0, 0, 0, 0.3) !important;
+}
+
+.ToAttributeHandle {
+  border-radius: 1px !important;
+  left: 20px !important;
+  top: 35% !important;
+  background: rgba(0, 0, 0, 0.3) !important;
+  transform: rotate(45deg) scale(0.9) !important;
+  transform-origin: center, center;
+}
+
+.ReceiveFunctionHandle {
+  left: 37px !important;
+  top: 35% !important;
+  background: rgba(0, 0, 0, 0.3) !important;
+}
+
+.handleFunctionEntity {
+  margin-left: 5px;
+}
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bc2a7aa4bd34d49f3d40e760930d461ab62dce48
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss.d.ts
@@ -0,0 +1,25 @@
+declare const classNames: {
+  readonly 'react-flow__node': 'react-flow__node';
+  readonly selected: 'selected';
+  readonly entityWrapper: 'entityWrapper';
+  readonly hidden: 'hidden';
+  readonly 'react-flow__edges': 'react-flow__edges';
+  readonly 'react-flow__edge-default': 'react-flow__edge-default';
+  readonly handleConnectedFill: 'handleConnectedFill';
+  readonly handleConnectedBorderRight: 'handleConnectedBorderRight';
+  readonly handleConnectedBorderLeft: 'handleConnectedBorderLeft';
+  readonly handleFunction: 'handleFunction';
+  readonly entity: 'entity';
+  readonly highlighted: 'highlighted';
+  readonly handleLeft: 'handleLeft';
+  readonly contentWrapper: 'contentWrapper';
+  readonly entityFade: 'entityFade';
+  readonly entityHandleLeft: 'entityHandleLeft';
+  readonly entityHandleBottom: 'entityHandleBottom';
+  readonly entitySpan: 'entitySpan';
+  readonly ToRelationHandle: 'ToRelationHandle';
+  readonly ToAttributeHandle: 'ToAttributeHandle';
+  readonly ReceiveFunctionHandle: 'ReceiveFunctionHandle';
+  readonly handleFunctionEntity: 'handleFunctionEntity';
+};
+export = classNames;
diff --git a/libs/shared/lib/ui/pills/customFlowPills/entitypill/entitypill.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.stories.tsx
similarity index 78%
rename from libs/shared/lib/ui/pills/customFlowPills/entitypill/entitypill.stories.tsx
rename to libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.stories.tsx
index 6c79fefe619d57705a6dac9f1c2feddb630276fa..87d7a9e8ce85b6e08c8f2e90c6d723cf761405d8 100644
--- a/libs/shared/lib/ui/pills/customFlowPills/entitypill/entitypill.stories.tsx
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.stories.tsx
@@ -1,6 +1,6 @@
 import React from 'react';
-import { Meta } from '@storybook/react';
-import EntityRFPill from './entitypill';
+import { Meta, StoryObj } from '@storybook/react';
+import EntityFlowElement from './entitypill';
 import { configureStore } from '@reduxjs/toolkit';
 import { Provider } from 'react-redux';
 import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme';
@@ -11,14 +11,15 @@ import {
   schemaSlice,
 } from '@graphpolaris/shared/lib/data-access/store';
 import { ReactFlowProvider } from 'reactflow';
+import { EntityData, EntityNode } from '../../../graph-reactflow/model';
 
-const Component: Meta<typeof EntityRFPill> = {
+const Component: Meta<typeof EntityFlowElement> = {
   /* 👇 The title prop is optional.
    * See https://storybook.js.org/docs/react/configure/overview#configure-story-loading
    * to learn how to generate automatic titles
    */
-  title: 'Components/Pills/EntityRFPill',
-  component: EntityRFPill,
+  title: 'Querybuilder/Pills/EntityPill',
+  component: EntityFlowElement,
   decorators: [
     (story) => (
       <Provider store={Mockstore}>
@@ -43,10 +44,11 @@ const Mockstore = configureStore({
 
 // const Template = (args: any) => <EntityRFPill {...args} />;
 
-export const Default = {
+export const Default: StoryObj<{ data: EntityData }> = {
   args: {
     data: {
       name: 'TestEntity',
+      fadeIn: true,
     },
   },
 };
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..51f8aa0742044a27707d2359d7bc86bdb7b10288
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx
@@ -0,0 +1,65 @@
+// import { handles } from '@graphpolaris/shared/lib/querybuilder/usecases';
+import { useTheme } from '@mui/material';
+import React, { useEffect } from 'react';
+import { ReactFlow, Handle, Position } from 'reactflow';
+import styles from './entitypill.module.scss';
+import { EntityNode } from '../../../graph/reactflow/model';
+import { Handles } from '../../../graph/reactflow/handles';
+
+/**
+ * Component to render an entity flow element
+ * @param {NodeProps} param0 The data of an entity flow element.
+ */
+export const EntityFlowElement = React.memo(({ data }: EntityNode) => {
+  const theme = useTheme();
+  // console.log('EntityPill', data);
+
+  // TODO: Change flow element width when text overflows
+  const animation = data.fadeIn ? styles.entityFade : '';
+
+  return (
+    <div
+      className={`${styles.entity} ${animation} query_builder-entity`}
+      style={{ backgroundColor: theme.palette.custom.elements.entityBase[0] }}
+    >
+      <Handle
+        id={Handles.ToRelation}
+        type="source"
+        position={Position.Bottom}
+        className={
+          styles.ToRelationHandle +
+          ' ' +
+          (false ? styles.handleConnectedFill : '')
+        }
+      />
+      <Handle
+        id={Handles.ToAttribute}
+        type="target"
+        position={Position.Bottom}
+        className={
+          styles.ToAttributeHandle +
+          ' ' +
+          (false ? styles.handleConnectedFill : '')
+        }
+      />
+      <Handle
+        id={Handles.ReceiveFunction}
+        type="target"
+        position={Position.Bottom}
+        className={
+          styles.ReceiveFunctionHandle +
+          ' ' +
+          (false ? styles.handleConnectedFill : '')
+        }
+      />
+
+      <div className={styles.entityWrapper}>
+        <span className={styles.entitySpan}>{data.name}</span>
+      </div>
+    </div>
+  );
+});
+
+EntityFlowElement.displayName = 'EntityFlowElement';
+
+export default EntityFlowElement;
diff --git a/libs/shared/lib/ui/pills/customFlowPills/entitypill/index.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/index.ts
similarity index 100%
rename from libs/shared/lib/ui/pills/customFlowPills/entitypill/index.ts
rename to libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/index.ts
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/SelectFunction.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/SelectFunction.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..60e40cbb5cef53dc371846d23c38fda82ef7076f
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/SelectFunction.tsx
@@ -0,0 +1,89 @@
+/**
+ * This program has been developed by students from the bachelor Computer Science at
+ * Utrecht University within the Software Project course.
+ * © Copyright Utrecht University (Department of Information and Computing Sciences)
+ */
+
+/* istanbul ignore file */
+/* The comment above was added so the code coverage wouldn't count this file towards code coverage.
+ * We do not test components/renderfunctions/styling files.
+ * See testing plan for more details.*/
+import React, { useState } from 'react';
+import { makeStyles } from '@material-ui/core/styles';
+import { useStyles } from '../../QueryBuilderStylesheet';
+
+// Create style constant to prevent rereaction of styles
+const madeStyles = makeStyles(useStyles);
+
+/**
+ * The flow element for the modifier.
+ * @param param0 The data of the modifier flow element.
+ */
+export default function ModifierFlowElement({ data }: any) {
+  const styles = madeStyles();
+  const [disable, setDisable] = useState(true);
+  const [disClass, setDisClass] = useState(styles.disable);
+
+  /**
+   * Calculate the width of the select element based on the displayed value.
+   * @param str Input string.
+   * @returns String containg the length in css format.
+   */
+  const calcSelectWidth = (str: string): string => {
+    if (str == '') return 1.5 + 'ch';
+    return str.length + 1.5 + 'ch';
+  };
+
+  /** Disable the select field */
+  const disableSelect = (): void => {
+    setDisable(true);
+    setDisClass(styles.disable);
+  };
+
+  /** Enable the select field */
+  const enableSelect = (): void => {
+    setDisable(false);
+    setDisClass('');
+  };
+
+  /**
+   * Constant switch to append the right options for the select element based on the data.type.
+   * @returns {JSX.Element} Option list using React.Fragment as parent element.
+   */
+  const list = (): JSX.Element => {
+    return (
+      <React.Fragment>
+        <option color="black" value="COUNT">
+          COUNT
+        </option>
+        <option value="SUM">SUM</option>
+        <option value="MIN">MIN</option>
+        <option value="MAX">MAX</option>
+      </React.Fragment>
+    );
+  };
+
+  return (
+    <div
+      className={styles.matchModifierTypeSelect}
+      onBlur={disableSelect}
+      onDoubleClick={enableSelect}
+    >
+      <select
+        style={{
+          color: disable ? 'black' : 'black',
+          maxWidth: calcSelectWidth('COUNT'),
+        }}
+        name="operators"
+        className={disClass}
+        disabled={disable}
+        onChange={(e) => {
+          data.type = e.target.value;
+          e.target.style.maxWidth = calcSelectWidth(e.target.value);
+        }}
+      >
+        {list()}
+      </select>
+    </div>
+  );
+}
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss
new file mode 100644
index 0000000000000000000000000000000000000000..7e589ded73a5eb5010a10401e4f25fefc54460ad
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss
@@ -0,0 +1,167 @@
+@import '../entitypill/entitypill.module.scss';
+
+$baseColor: #8c75c9;
+
+// Function element
+.function {
+  background-color: $baseColor;
+  display: 'flex';
+  border-radius: '1px';
+  font-family: monospace;
+  font-weight: 'bold';
+  font-size: 11px;
+  color: black;
+  min-width: '140px';
+  text-align: 'center';
+  line-height: 20px;
+  padding-top: 2;
+  padding-right: 5;
+  padding-bottom: 4;
+  padding-left: 5;
+
+  &::before {
+    position: 'absolute';
+    content: '""';
+    width: '100%';
+    left: '0px';
+    top: '0px';
+    height: '100%';
+    border-radius: '3px';
+    z-index: -1;
+    background-color: $baseColor;
+    border-bottom: 'none';
+  }
+
+  &::after {
+    position: 'absolute';
+    content: '""';
+    width: '100%';
+    left: '0px';
+    top: '0';
+    height: '100%';
+    border-radius: '3px';
+    z-index: -1;
+    background-color: $baseColor;
+    border-top: 'none';
+  }
+}
+
+.functionWrapper {
+  display: 'block';
+  width: 'inherit';
+  align-items: 'center';
+  justify-content: 'space-between';
+}
+.functionHandleFiller {
+  flex: '1 1 0';
+  display: 'flow-root';
+}
+.functionHandle {
+  border: 0;
+  border-radius: 0;
+  width: 8;
+  height: 8;
+  left: 9;
+  top: 7;
+  background: 'rgba(0, 0, 0, 0.3)';
+  transform-origin: 'center';
+  position: 'relative';
+  float: 'right';
+  margin-right: '20px';
+  &::before {
+    content: '""';
+    width: 6;
+    height: 6;
+    left: 1;
+    bottom: 1;
+    border: 0;
+    border-radius: 0;
+    background: 'rgba(255, 255, 255, 0.6)';
+    z-index: -1;
+    display: 'inline-block';
+    position: 'fixed';
+  }
+}
+.functionHandleBottom {
+  border: 0;
+  border-radius: 0;
+  width: 8;
+  height: 8;
+  left: 27.5;
+  margin-bottom: 10;
+  background-color: 'rgba(255, 255, 255, 0.6)';
+  transform: 'rotate(-45deg)';
+  transform-origin: 'center';
+  &::before {
+    content: '""';
+    width: 6;
+    height: 6;
+    left: 1;
+    bottom: 1;
+    border: 0;
+    border-radius: 0;
+    background-color: 'rgba(255, 255, 255, 0.6)';
+    z-index: -1;
+    display: 'inline-block';
+    position: 'fixed';
+  }
+}
+.functionInputHolder {
+  display: 'flex';
+  float: 'right';
+  margin-right: '20px';
+  margin-top: '4px';
+  margin-left: '5px';
+  max-width: '80px';
+  background-color: 'rgba(255, 255, 255, 0.6)';
+  border-radius: '2px';
+  align-items: 'center';
+  max-height: '12px';
+}
+.functionInput {
+  z-index: 1;
+  cursor: 'text';
+  min-width: '0px';
+  max-width: '1.5ch';
+  height: '14px';
+  border: 'none';
+  background-color: 'rgba(255, 255, 255, 0.6)';
+  text-align: 'center';
+  font-family: 'monospace';
+  font-weight: 'bold';
+  font-size: '11px';
+  color: '#181520';
+  user-select: 'none';
+  font-style: 'italic';
+  float: 'right';
+  margin: '3px 0';
+  margin-right: '10px';
+  &:focus {
+    outline: 'none';
+    user-select: 'none';
+  }
+  &::placeholder {
+    outline: 'none';
+    user-select: 'none';
+    font-style: 'italic';
+  }
+}
+.functionReadonly {
+  cursor: 'grab !important';
+  color: '#181520 !important';
+  user-select: 'none';
+  font-style: 'normal !important';
+}
+.functionSpan {
+  float: 'left';
+  margin-left: 20;
+  margin-right: 20;
+}
+.functionSpanRight {
+  float: 'right';
+  margin-right: 10;
+}
+
+.functionDataWrapper {
+  display: block;
+}
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..924514ea12818ede4d522342249d6035c47abe82
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss.d.ts
@@ -0,0 +1,36 @@
+declare const classNames: {
+  readonly 'react-flow__node': 'react-flow__node';
+  readonly selected: 'selected';
+  readonly entityWrapper: 'entityWrapper';
+  readonly hidden: 'hidden';
+  readonly 'react-flow__edges': 'react-flow__edges';
+  readonly 'react-flow__edge-default': 'react-flow__edge-default';
+  readonly handleConnectedFill: 'handleConnectedFill';
+  readonly handleConnectedBorderRight: 'handleConnectedBorderRight';
+  readonly handleConnectedBorderLeft: 'handleConnectedBorderLeft';
+  readonly handleFunction: 'handleFunction';
+  readonly entity: 'entity';
+  readonly highlighted: 'highlighted';
+  readonly handleLeft: 'handleLeft';
+  readonly contentWrapper: 'contentWrapper';
+  readonly entityFade: 'entityFade';
+  readonly entityHandleLeft: 'entityHandleLeft';
+  readonly entityHandleBottom: 'entityHandleBottom';
+  readonly entitySpan: 'entitySpan';
+  readonly ToRelationHandle: 'ToRelationHandle';
+  readonly ToAttributeHandle: 'ToAttributeHandle';
+  readonly ReceiveFunctionHandle: 'ReceiveFunctionHandle';
+  readonly handleFunctionEntity: 'handleFunctionEntity';
+  readonly function: 'function';
+  readonly functionWrapper: 'functionWrapper';
+  readonly functionHandleFiller: 'functionHandleFiller';
+  readonly functionHandle: 'functionHandle';
+  readonly functionHandleBottom: 'functionHandleBottom';
+  readonly functionInputHolder: 'functionInputHolder';
+  readonly functionInput: 'functionInput';
+  readonly functionReadonly: 'functionReadonly';
+  readonly functionSpan: 'functionSpan';
+  readonly functionSpanRight: 'functionSpanRight';
+  readonly functionDataWrapper: 'functionDataWrapper';
+};
+export = classNames;
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.stories.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..2488295e09b2e2b682a60dde06359a59a526640c
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.stories.tsx
@@ -0,0 +1,74 @@
+import React from 'react';
+import { Meta, StoryObj } from '@storybook/react';
+import FunctionFlowElement from './functionpill';
+import { configureStore } from '@reduxjs/toolkit';
+import { Provider } from 'react-redux';
+import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme';
+
+import {
+  colorPaletteConfigSlice,
+  querybuilderSlice,
+  schemaSlice,
+} from '@graphpolaris/shared/lib/data-access/store';
+import { ReactFlowProvider } from 'reactflow';
+import {
+  EntityData,
+  EntityNode,
+  FunctionData,
+} from '../../../graph-reactflow/model';
+
+const Component: Meta<typeof FunctionFlowElement> = {
+  /* 👇 The title prop is optional.
+   * See https://storybook.js.org/docs/react/configure/overview#configure-story-loading
+   * to learn how to generate automatic titles
+   */
+  title: 'Querybuilder/Pills/FunctionPill',
+  component: FunctionFlowElement,
+  decorators: [
+    (story) => (
+      <Provider store={Mockstore}>
+        <GraphPolarisThemeProvider>
+          <ReactFlowProvider>{story()}</ReactFlowProvider>
+        </GraphPolarisThemeProvider>
+      </Provider>
+    ),
+  ],
+};
+
+export default Component;
+
+// A super-simple mock of a redux store
+const Mockstore = configureStore({
+  reducer: {
+    colorPaletteConfig: colorPaletteConfigSlice.reducer,
+    querybuilder: querybuilderSlice.reducer,
+    // schema: schemaSlice.reducer,
+  },
+});
+
+// const Template = (args: any) => <EntityRFPill {...args} />;
+
+export const Default: StoryObj<{ data: FunctionData }> = {
+  args: {
+    data: {
+      functionType: 'test',
+      fadeIn: true,
+      args: {
+        string: {
+          displayName: 'testarg',
+          connectable: false,
+          value: 'testvalue',
+          visible: true,
+        },
+      },
+    },
+  },
+};
+
+// Default.decorators = [
+//   (story) => (
+//     <Provider store={Mockstore}>
+//       <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider>
+//     </Provider>
+//   ),
+// ];
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..c0edcaff21c16a0f102d965fa5da96759bc23495
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.tsx
@@ -0,0 +1,166 @@
+/**
+ * This program has been developed by students from the bachelor Computer Science at
+ * Utrecht University within the Software Project course.
+ * © Copyright Utrecht University (Department of Information and Computing Sciences)
+ */
+
+/* istanbul ignore file */
+/* The comment above was added so the code coverage wouldn't count this file towards code coverage.
+ * We do not test components/renderfunctions/styling files.
+ * See testing plan for more details.*/
+import React, { useState } from 'react';
+import { Handle, Position } from 'reactflow';
+import styles from './functionpill.module.scss';
+import { useTheme } from '@mui/material';
+import { FunctionData, FunctionNode } from '../../../graph/reactflow/model';
+import { Handles } from '../../../graph/reactflow/handles';
+
+const countArgs = (data: FunctionData | undefined) => {
+  if (data !== undefined) {
+    let count = 0;
+
+    for (const name in data.args) {
+      if (data.args[name].visible) {
+        count++;
+      }
+    }
+    return count;
+  }
+  return 1;
+};
+
+/**
+ * Capitalize the first letter of a string.
+ * @param string This is the given string.
+ * @returns {string} This is the modified string.
+ */
+export const capitalizeFirstLetter = (string: string) => {
+  return string.charAt(0).toUpperCase() + string.slice(1);
+};
+
+/**
+ * Component to render a relation flow element
+ * @param { FlowElement<FunctionData>} param0 The data of a relation flow element.
+ */
+export default function RelationFlowElement({ data }: FunctionNode) {
+  const [read, setRead] = useState(true);
+  const theme = useTheme();
+
+  const numOfArgs = countArgs(data);
+  const height = numOfArgs * 20;
+
+  const _onKeyDown = (event: any): void => {
+    if (event.key == 'Enter') setRead(true);
+  };
+
+  const getArgs = (
+    styles: any,
+    data: FunctionData | undefined,
+    setRead: any
+  ) => {
+    let rows: JSX.Element[] = [];
+
+    if (data != undefined) {
+      let index = 0;
+
+      for (const name in data.args) {
+        const item = data.args[name];
+        if (item.visible) {
+          rows.push(
+            <span className={styles.functionHandleFiller} key={name}>
+              <span className={styles.functionSpan}>
+                {capitalizeFirstLetter(name)}
+              </span>
+              <Handle
+                id={Handles.FunctionBase + name}
+                type="source"
+                position={Position.Top}
+                className={
+                  styles.functionHandle +
+                  ' ' +
+                  (false ? styles.handleConnectedFill : '')
+                }
+                style={{
+                  visibility: item.connectable ? 'inherit' : 'hidden',
+                }}
+              />
+              {item.value !== undefined && (
+                <input
+                  className={styles.functionInput}
+                  style={{ maxWidth: 50 }}
+                  type="string"
+                  placeholder={'?'}
+                  value={item.value}
+                  onChange={(e) => {
+                    if (item.value != undefined) {
+                      item.value = e.target.value;
+                      //TODO restore SetElementsUseCase.updateFunctionCompleteness(data);
+                    }
+                  }}
+                  onDoubleClick={() => {
+                    setRead(false);
+                  }}
+                  onBlur={() => {
+                    setRead(true);
+                  }}
+                  onKeyDown={_onKeyDown}
+                ></input>
+              )}
+            </span>
+          );
+          index++;
+        }
+      }
+    }
+
+    return rows;
+  };
+
+  const rows = getArgs(styles, data, setRead);
+  const entity = undefined; //TODO fix: data !== undefined ? data.entityName : undefined;
+
+  return (
+    <div>
+      <div
+        className={styles.function}
+        style={{
+          minHeight: height,
+          background: theme.palette.custom.nodesBase[0],
+          borderTop: `4px solid ${theme.palette.custom.nodesBase[0]}`,
+          borderBottom: `6px solid ${theme.palette.custom.elements.function[0]}`,
+        }}
+      >
+        <div className={styles.functionWrapper}>{rows}</div>
+      </div>
+      <div
+        className={`${styles.entity} entityWrapper ${
+          entity === undefined ? 'hidden' : ''
+        }`}
+      >
+        <Handle
+          id={Handles.ToRelation}
+          type="source"
+          position={Position.Bottom}
+          className={
+            styles.entityHandleLeft +
+            ' ' +
+            (false ? styles.handleConnectedFill : '')
+          }
+        />
+        <Handle
+          id={Handles.ToAttribute}
+          type="source"
+          position={Position.Bottom}
+          className={
+            styles.entityHandleBottom +
+            ' ' +
+            (false ? styles.handleConnectedFill : '')
+          }
+        />
+        <div className={styles.entityWrapper}>
+          <span className={styles.entitySpan}>{entity ? entity : ''}</span>
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/index.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..865e20fa5725210913b8332ba393e3488059092a
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/index.ts
@@ -0,0 +1 @@
+export * from './functionpill'
\ No newline at end of file
diff --git a/libs/shared/lib/ui/pills/customFlowPills/index.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/index.ts
similarity index 100%
rename from libs/shared/lib/ui/pills/customFlowPills/index.ts
rename to libs/shared/lib/querybuilder/pills/customFlowPills/index.ts
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.module.scss
new file mode 100644
index 0000000000000000000000000000000000000000..2e259083fc99e05883812b703d90b10380bcb4e6
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.module.scss
@@ -0,0 +1,55 @@
+@import '../../querypills.module.scss';
+
+.modifier {
+  color: '#181520';
+  background-color: #d56a50;
+  border-radius: 5px;
+  font-family: monospace;
+  font-weight: bolder;
+  font-size: 11;
+  padding-top: 2;
+  padding-right: 5;
+  padding-bottom: 12;
+  padding-left: 5;
+}
+.modifierWrapper {
+  height: 6;
+  margin-left: 5;
+  margin-right: 5;
+  color: black;
+}
+.modifierInput {
+  float: right;
+  background-color: #ee917a;
+  border-radius: 2px;
+  padding-left: 2px;
+  padding-right: 2px;
+  display: flex;
+}
+.modifierSpan {
+  float: left;
+}
+
+.matchModifierTypeSelect {
+  float: left;
+  background-color: rgba(255, 255, 255, 0.6);
+  border-radius: 2px;
+  text-align: center;
+  & select {
+    background: transparent;
+    border: none;
+    appearance: none;
+    font-family: monospace;
+    font-weight: bolder;
+    color: black;
+    font-size: 11;
+  }
+  & option {
+    font-family: monospace;
+    font-size: 11px;
+  }
+}
+.disable {
+  opacity: 1 !important;
+  pointer-events: none;
+}
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.module.scss.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d22770e4487c411c24d1fedf852dbe55ea42f79c
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.module.scss.d.ts
@@ -0,0 +1,19 @@
+declare const classNames: {
+  readonly 'react-flow__node': 'react-flow__node';
+  readonly selected: 'selected';
+  readonly entityWrapper: 'entityWrapper';
+  readonly hidden: 'hidden';
+  readonly 'react-flow__edges': 'react-flow__edges';
+  readonly 'react-flow__edge-default': 'react-flow__edge-default';
+  readonly handleConnectedFill: 'handleConnectedFill';
+  readonly handleConnectedBorderRight: 'handleConnectedBorderRight';
+  readonly handleConnectedBorderLeft: 'handleConnectedBorderLeft';
+  readonly handleFunction: 'handleFunction';
+  readonly modifier: 'modifier';
+  readonly modifierWrapper: 'modifierWrapper';
+  readonly modifierInput: 'modifierInput';
+  readonly modifierSpan: 'modifierSpan';
+  readonly matchModifierTypeSelect: 'matchModifierTypeSelect';
+  readonly disable: 'disable';
+};
+export = classNames;
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..6041c775e13891b6f55ad41588ddd523fbfda34d
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/modifierpill.tsx
@@ -0,0 +1,33 @@
+/**
+ * This program has been developed by students from the bachelor Computer Science at
+ * Utrecht University within the Software Project course.
+ * © Copyright Utrecht University (Department of Information and Computing Sciences)
+ */
+
+/* istanbul ignore file */
+/* The comment above was added so the code coverage wouldn't count this file towards code coverage.
+ * We do not test components/renderfunctions/styling files.
+ * See testing plan for more details.*/
+import React from 'react';
+import { Handle, NodeProps, Position } from 'reactflow';
+import Select from './select-modifier';
+import styles from './modifierpill.module.scss';
+import { ModifierData, ModifierNode } from '../../../graph-reactflow/model';
+
+/**
+ * Component to render an entity flow element
+ * @param param0 Data of the flow element.
+ */
+export default function ModifierFlowElement({ data }: ModifierNode) {
+  return (
+    <div className={styles.modifier}>
+      <div className={styles.modifierWrapper}>
+        <span className={styles.modifierInput}>
+          <span className={styles.modifierSpan}>
+            <Select data={data} />
+          </span>
+        </span>
+      </div>
+    </div>
+  );
+}
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/mopdifierpill.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/mopdifierpill.stories.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..480fe054e9465947e2e0c47d8b0a981aef0c9548
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/mopdifierpill.stories.tsx
@@ -0,0 +1,66 @@
+import React from 'react';
+import { Meta, StoryObj } from '@storybook/react';
+import ModifierPill from './modifierpill';
+import { configureStore } from '@reduxjs/toolkit';
+import { Provider } from 'react-redux';
+import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme';
+
+import {
+  colorPaletteConfigSlice,
+  querybuilderSlice,
+  schemaSlice,
+} from '@graphpolaris/shared/lib/data-access/store';
+import { ReactFlowProvider } from 'reactflow';
+import {
+  EntityData,
+  EntityNode,
+  FunctionData,
+  ModifierData,
+} from '../../../graph-reactflow/model';
+
+const Component: Meta<typeof ModifierPill> = {
+  /* 👇 The title prop is optional.
+   * See https://storybook.js.org/docs/react/configure/overview#configure-story-loading
+   * to learn how to generate automatic titles
+   */
+  title: 'Querybuilder/Pills/ModifierPill',
+  component: ModifierPill,
+  decorators: [
+    (story) => (
+      <Provider store={Mockstore}>
+        <GraphPolarisThemeProvider>
+          <ReactFlowProvider>{story()}</ReactFlowProvider>
+        </GraphPolarisThemeProvider>
+      </Provider>
+    ),
+  ],
+};
+
+export default Component;
+
+// A super-simple mock of a redux store
+const Mockstore = configureStore({
+  reducer: {
+    colorPaletteConfig: colorPaletteConfigSlice.reducer,
+    querybuilder: querybuilderSlice.reducer,
+    // schema: schemaSlice.reducer,
+  },
+});
+
+// const Template = (args: any) => <EntityRFPill {...args} />;
+
+export const Default: StoryObj<{ data: ModifierData }> = {
+  args: {
+    data: {
+      type: 'SUM',
+    },
+  },
+};
+
+// Default.decorators = [
+//   (story) => (
+//     <Provider store={Mockstore}>
+//       <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider>
+//     </Provider>
+//   ),
+// ];
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/select-modifier.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/select-modifier.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..86ebf29a76fea48ad15da5e287a18c719ec3f141
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/modifierpill/select-modifier.tsx
@@ -0,0 +1,88 @@
+/**
+ * This program has been developed by students from the bachelor Computer Science at
+ * Utrecht University within the Software Project course.
+ * © Copyright Utrecht University (Department of Information and Computing Sciences)
+ */
+
+/* istanbul ignore file */
+/* The comment above was added so the code coverage wouldn't count this file towards code coverage.
+ * We do not test components/renderfunctions/styling files.
+ * See testing plan for more details.*/
+import React, { useState } from 'react';
+import { NodeProps } from 'reactflow';
+import styles from './modifierpill.module.scss';
+import { ModifierData } from '../../../graph-reactflow/model';
+
+// Create style constant to prevent rereaction of styles
+
+/**
+ * The flow element for the modifier.
+ * @param param0 The data of the modifier flow element.
+ */
+export default function SelectModifier({ data }: { data: ModifierData }) {
+  const [disable, setDisable] = useState(true);
+  const [disClass, setDisClass] = useState<string>(styles.disable);
+
+  /**
+   * Calculate the width of the select element based on the displayed value.
+   * @param str Input string.
+   * @returns String containg the length in css format.
+   */
+  const calcSelectWidth = (str: string): string => {
+    if (str == '') return 1.5 + 'ch';
+    return str.length + 1.5 + 'ch';
+  };
+
+  /** Disable the select field */
+  const disableSelect = (): void => {
+    setDisable(true);
+    setDisClass(styles.disable);
+  };
+
+  /** Enable the select field */
+  const enableSelect = (): void => {
+    setDisable(false);
+    setDisClass('');
+  };
+
+  /**
+   * Constant switch to append the right options for the select element based on the data.type.
+   * @returns {JSX.Element} Option list using React.Fragment as parent element.
+   */
+  const list = (): JSX.Element => {
+    return (
+      <React.Fragment>
+        <option color="black" value="COUNT">
+          COUNT
+        </option>
+        <option value="SUM">SUM</option>
+        <option value="MIN">MIN</option>
+        <option value="MAX">MAX</option>
+      </React.Fragment>
+    );
+  };
+
+  return (
+    <div
+      className={styles.matchModifierTypeSelect}
+      onBlur={disableSelect}
+      onDoubleClick={enableSelect}
+    >
+      <select
+        style={{
+          color: disable ? 'black' : 'black',
+          maxWidth: calcSelectWidth('COUNT'),
+        }}
+        name="operators"
+        className={disClass}
+        disabled={disable}
+        onChange={(e) => {
+          data.type = e.target.value;
+          e.target.style.maxWidth = calcSelectWidth(e.target.value);
+        }}
+      >
+        {list()}
+      </select>
+    </div>
+  );
+}
diff --git a/libs/shared/lib/ui/pills/customFlowPills/relationpill/index.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/index.ts
similarity index 100%
rename from libs/shared/lib/ui/pills/customFlowPills/relationpill/index.ts
rename to libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/index.ts
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full.stories.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..b01ffd8f39dff716a8c90e804f3ef9329bd1fea6
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full.stories.tsx
@@ -0,0 +1,55 @@
+import React from 'react';
+import {
+  colorPaletteConfigSlice,
+  querybuilderSlice,
+  setQuerybuilderNodes,
+} from '@graphpolaris/shared/lib/data-access/store';
+import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme';
+import { configureStore } from '@reduxjs/toolkit';
+import { Meta } from '@storybook/react';
+import { Provider } from 'react-redux';
+import { MultiGraph } from 'graphology';
+import { QueryBuilder } from '../../../panel';
+import { QueryGraph } from '../../../graph/graphology/model';
+import { circular } from 'graphology-layout';
+
+const Component: Meta<typeof QueryBuilder> = {
+  component: QueryBuilder,
+  title: 'Querybuilder/Pills/relationPill',
+  decorators: [
+    (story) => (
+      <Provider store={mockStore}>
+        <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider>
+      </Provider>
+    ),
+  ],
+};
+
+// Mock palette store
+const mockStore = configureStore({
+  reducer: {
+    colorPaletteConfig: colorPaletteConfigSlice.reducer,
+    querybuilder: querybuilderSlice.reducer,
+  },
+});
+const graph: QueryGraph = new MultiGraph();
+graph.addPill2Graphology(
+  {
+    type: 'relation',
+    x: 140,
+    y: 140,
+    name: 'Relation Pill',
+    depth: { min: 0, max: 1 },
+    fadeIn: false,
+  },
+  '2'
+);
+console.log(graph.export());
+
+mockStore.dispatch(setQuerybuilderNodes(graph.export()));
+
+export const Flow = {
+  args: {},
+};
+
+export default Component;
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill copy.txt b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill copy.txt
new file mode 100644
index 0000000000000000000000000000000000000000..805e3f3fc78bd04389de1363e61d22592aa70044
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill copy.txt	
@@ -0,0 +1,242 @@
+import React, { memo, useRef, useState } from 'react';
+
+import { handles } from '@graphpolaris/shared/lib/querybuilder/usecases';
+import { useTheme } from '@mui/material';
+import { Handle, Position } from 'reactflow';
+import cn from 'classnames';
+
+import styles from './relationpill.module.scss';
+import { Handles } from '../../../structures/Handles';
+import { RelationNode } from '../../../structures/Nodes';
+
+// export type RelationRFPillProps = {
+//   data: {
+//     name: string;
+//     suggestedForConnection: any;
+//     isFromEntityConnected?: boolean;
+//     isToEntityConnected?: boolean;
+//   };
+// };
+
+/**
+ * Component to render a relation flow element
+ * @param { FlowElement<RelationData>} param0 The data of a relation flow element.
+ */
+export const RelationPill = memo(({ data }: RelationNode) => {
+  // export default function RelationRFPill({ data }: { data: any }) {
+  const theme = useTheme();
+  // console.log('RelationRFPill', data);
+
+  const minRef = useRef<HTMLInputElement>(null);
+  const maxRef = useRef<HTMLInputElement>(null);
+
+  const [readOnlyMin, setReadOnlyMin] = useState(true);
+  const [readOnlyMax, setReadOnlyMax] = useState(true);
+
+  const onDepthChanged = (depth: string) => {
+    // Don't allow depth above 99
+    const limit = 99;
+    if (data?.depth != undefined) {
+      data.depth.min = data.depth.min >= limit ? limit : data.depth.min;
+      data.depth.max = data.depth.max >= limit ? limit : data.depth.max;
+
+      // Check for for valid depth: min <= max
+      if (depth == 'min') {
+        if (data.depth.min > data.depth.max) data.depth.max = data.depth.min;
+        setReadOnlyMin(true);
+      } else if (depth == 'max') {
+        if (data.depth.max < data.depth.min) data.depth.min = data.depth.max;
+        setReadOnlyMax(true);
+      }
+
+      // Set to the correct width
+      if (maxRef.current)
+        maxRef.current.style.maxWidth = calcWidth(data.depth.max);
+      if (minRef.current)
+        minRef.current.style.maxWidth = calcWidth(data.depth.min);
+    }
+  };
+
+  const isNumber = (x: string) => {
+    {
+      if (typeof x != 'string') return false;
+      return !Number.isNaN(x) && !Number.isNaN(parseFloat(x));
+    }
+  };
+
+  const calcWidth = (data: number) => {
+    return data.toString().length + 0.5 + 'ch';
+  };
+
+  return (
+    <div
+      className={styles.relation}
+      style={{
+        background: theme.palette.custom.nodesBase[0],
+        borderTop: `4px solid ${theme.palette.custom.nodesBase[0]}`,
+        borderBottom: `6px solid ${theme.palette.custom.elements.relationBase[0]}`,
+      }}
+    >
+      <div className={styles.relationWrapper}>
+        <div
+          className={[
+            styles.relationNodeTriangleGeneral,
+            styles.relationNodeTriangleLeft,
+          ].join(' ')}
+          style={{ borderRightColor: theme.palette.custom.nodesBase[0] }}
+        >
+          <span className={styles.relationHandleFiller}>
+            <Handle
+              id={Handles.RelationLeft}
+              type="target"
+              position={Position.Left}
+              className={
+                styles.relationHandleLeft +
+                ' ' +
+                (false ? styles.handleConnectedBorderLeft : '')
+              }
+            />
+          </span>
+        </div>
+        <div
+          className={[
+            styles.relationNodeTriangleGeneral,
+            styles.relationNodeSmallTriangleLeft,
+          ].join(' ')}
+          style={{
+            borderRightColor: theme.palette.custom.elements.relationBase[0],
+          }}
+        ></div>
+        <div
+          className={[
+            styles.relationNodeTriangleGeneral,
+            styles.relationNodeTriangleRight,
+          ].join(' ')}
+          style={{ borderLeftColor: theme.palette.custom.nodesBase[0] }}
+        >
+          <span className={styles.relationHandleFiller}>
+            <Handle
+              id={Handles.RelationRight}
+              type="target"
+              position={Position.Right}
+              className={
+                styles.relationHandleRight +
+                ' ' +
+                (false ? styles.handleConnectedBorderRight : '')
+              }
+            />
+          </span>
+        </div>
+        <div
+          className={[
+            styles.relationNodeTriangleGeneral,
+            styles.relationNodeSmallTriangleRight,
+          ].join(' ')}
+          style={{
+            borderLeftColor: theme.palette.custom.elements.relationBase[0],
+          }}
+        ></div>
+
+        <span className={styles.relationHandleFiller}>
+          <Handle
+            id={Handles.ToAttributeHandle}
+            type="target"
+            position={Position.Bottom}
+            className={
+              styles.relationHandleBottom +
+              ' ' +
+              (false ? styles.handleConnectedFill : '')
+            }
+          />
+        </span>
+        <div className={styles.relationDataWrapper}>
+          <span className={styles.relationSpan}>{data?.name}</span>
+          <span className={styles.relationInputHolder}>
+            <span>[</span>
+            <input
+              className={
+                styles.relationInput +
+                ' ' +
+                (readOnlyMin ? styles.relationReadonly : '')
+              }
+              ref={minRef}
+              type="string"
+              min={0}
+              readOnly={readOnlyMin}
+              placeholder={'?'}
+              value={data?.depth.min}
+              onChange={(e) => {
+                if (data != undefined) {
+                  data.depth.min = isNumber(e.target.value)
+                    ? parseInt(e.target.value)
+                    : 0;
+                  e.target.style.maxWidth = calcWidth(data.depth.min);
+                }
+              }}
+              onDoubleClick={() => {
+                setReadOnlyMin(false);
+              }}
+              onBlur={(e) => {
+                onDepthChanged('min');
+              }}
+              onKeyDown={(e) => {
+                if (e.key === 'Enter') {
+                  onDepthChanged('min');
+                }
+              }}
+            ></input>
+            <span>..</span>
+            <input
+              className={
+                styles.relationInput +
+                ' ' +
+                (readOnlyMax ? styles.relationReadonly : '')
+              }
+              ref={maxRef}
+              type="string"
+              min={0}
+              readOnly={readOnlyMax}
+              placeholder={'?'}
+              value={data?.depth.max}
+              onChange={(e) => {
+                if (data != undefined) {
+                  data.depth.max = isNumber(e.target.value)
+                    ? parseInt(e.target.value)
+                    : 0;
+                  e.target.style.maxWidth = calcWidth(data.depth.max);
+                }
+              }}
+              onDoubleClick={() => {
+                setReadOnlyMax(false);
+              }}
+              onBlur={(e) => {
+                onDepthChanged('max');
+              }}
+              onKeyDown={(e) => {
+                if (e.key === 'Enter') {
+                  onDepthChanged('max');
+                }
+              }}
+            ></input>
+            <span>]</span>
+          </span>
+        </div>
+        <Handle
+          id={Handles.ReceiveFunction}
+          type="target"
+          position={Position.Bottom}
+          className={
+            styles.relationHandleFunction +
+            ' ' +
+            styles.handleFunction +
+            ' ' +
+            (false ? styles.handleConnectedFill : '')
+          }
+        />
+      </div>
+    </div>
+  );
+});
+
+RelationPill.displayName = 'RelationPill';
+export default RelationPill;
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module copy.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module copy.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e7dd844ff495b98f1ff9ceebf1e57b41dc9fede0
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module copy.scss	
@@ -0,0 +1,304 @@
+@import '../../querypills.module.scss';
+
+.relation {
+  display: flex;
+  text-align: center;
+  font-family: monospace;
+  font-weight: bold;
+  font-size: 10px;
+  background-color: transparent;
+}
+
+.highlighted {
+  box-shadow: black 0 0 2px;
+}
+
+.contentWrapper {
+  display: flex;
+  align-items: center;
+
+  .handleLeft {
+    position: relative;
+    z-index: 3;
+
+    top: 25%;
+    border: 0px;
+    border-radius: 0px;
+
+    background: transparent;
+    transform-origin: center;
+
+    width: 0;
+    height: 0;
+    border-top: 5px solid transparent;
+    border-bottom: 5px solid transparent;
+    border-right: rgba(255, 255, 255, 0.7) 6px solid;
+
+    &::after {
+      content: '';
+      display: block;
+      position: absolute;
+      width: 0;
+      height: 0;
+      border-top: 7px solid transparent;
+      border-bottom: 7px solid transparent;
+      border-right: rgba(0, 0, 0, 0.1) 8px solid;
+      top: -7px;
+      right: -7px;
+    }
+  }
+  .highlighted {
+    z-index: -1;
+    box-shadow: 0 0 2px 1px gray;
+  }
+
+  .content {
+    margin: 0 2ch;
+    padding: 3px 0;
+    max-width: 20ch;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    white-space: nowrap;
+    // pointer-events: none;
+  }
+
+  .handleRight {
+    position: relative;
+    top: 25%;
+    border: 0px;
+    border-radius: 0px;
+
+    background: transparent;
+    transform-origin: center;
+
+    width: 0;
+    height: 0;
+    border-top: 5px solid transparent;
+    border-bottom: 5px solid transparent;
+    border-left: rgba(255, 255, 255, 0.7) 6px solid;
+
+    &::after {
+      content: '';
+      display: block;
+      position: absolute;
+      width: 0;
+      height: 0;
+      border-top: 7px solid transparent;
+      border-bottom: 7px solid transparent;
+      border-left: rgba(0, 0, 0, 0.1) 8px solid;
+      top: -7px;
+      left: -7px;
+    }
+  }
+}
+
+$height: 10px;
+.arrowLeft {
+  z-index: 2;
+  width: 0;
+  height: 0;
+  border-top: $height solid transparent;
+  border-bottom: $height solid transparent;
+  transform: scale(1.028) translate(0.3px 0px);
+
+  border-right: $height solid;
+}
+
+.arrowRight {
+  width: 0;
+  height: 0;
+  border-top: $height solid transparent;
+  border-bottom: $height solid transparent;
+  transform: scale(1.02) translate(-0.3px 0px);
+
+  border-left: $height solid;
+}
+
+// Relation element
+.relation {
+  height: 36;
+  min-width: 240px;
+  display: flex;
+  text-align: center;
+  color: black;
+  line-height: 20px;
+  font-family: monospace;
+  font-weight: bold;
+  font-size: 11px;
+}
+
+.relationWrapper {
+  display: inherit;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.relationNodeTriangleGeneral {
+  position: absolute;
+  width: 0;
+  height: 0;
+  margin: auto 0;
+  border-style: solid;
+  border-color: transparent;
+}
+
+.relationNodeTriangleLeft {
+  transform: translateX(-100%);
+  top: 0px;
+  border-width: 18px 24px 18px 0;
+}
+
+.relationNodeSmallTriangleLeft {
+  transform: translateX(-100%);
+  top: 30px;
+  border-width: 0 8px 6px 0;
+}
+
+.relationNodeTriangleRight {
+  right: -24px;
+  top: 0px;
+  border-width: 18px 0 18px 24px;
+}
+
+.relationNodeSmallTriangleRight {
+  right: -8px;
+  top: 30px;
+  border-width: 0 0 6px 8px;
+}
+
+.relationHandleFiller {
+  display: block;
+}
+
+.relationHandleLeft {
+  position: absolute;
+  top: 50%;
+  margin-left: 15px;
+  border-style: solid;
+  border-width: 8px 12px 8px 0;
+  border-radius: 0px;
+  left: unset;
+  border-color: transparent rgba(0, 0, 0, 0.3) transparent transparent;
+  background: transparent;
+  &::before {
+    content: '';
+    border-style: solid;
+    border-width: 6px 8px 6px 0;
+    border-color: transparent rgba(255, 255, 255, 0.6) transparent transparent;
+    background: transparent;
+    z-index: -1;
+    display: inline-block;
+    position: absolute;
+    top: -0.5em;
+    left: 0.25em;
+  }
+}
+
+.relationHandleRight {
+  position: absolute;
+  margin-right: 19px;
+  border-style: solid;
+  border-width: 8px 0 8px 12px;
+  border-radius: 0px;
+  left: unset;
+  border-color: transparent transparent transparent rgba(0, 0, 0, 0.3);
+  background: transparent;
+  &::before {
+    content: '';
+    border-style: solid;
+    border-width: 6px 0 6px 8px;
+    border-color: transparent transparent transparent rgba(255, 255, 255, 0.6);
+    background: transparent;
+    z-index: -1;
+    display: inline-block;
+    position: absolute;
+    top: -0.5em;
+    right: 0.25em;
+  }
+}
+
+.relationHandleBottom {
+  border: 0;
+  border-radius: 0;
+  width: 8;
+  height: 8;
+  left: unset;
+  margin-bottom: 18;
+  margin-left: 40;
+  background: rgba(0, 0, 0, 0.3);
+  transform: rotate(-45deg);
+  transform-origin: center;
+  margin: 5px;
+  &::before {
+    content: '';
+    width: 6;
+    height: 6;
+    left: 1;
+    bottom: 1;
+    border: 0;
+    border-radius: 0;
+    background: rgba(255, 255, 255, 0.6);
+    z-index: -1;
+    display: inline-block;
+    position: fixed;
+  }
+}
+
+.relationDataWrapper {
+  margin-left: 80;
+}
+
+.relationSpan {
+  float: left;
+  margin-left: 5;
+}
+
+.relationInputHolder {
+  display: flex;
+  float: right;
+  margin-right: 20px;
+  margin-top: 4px;
+  margin-left: 5px;
+  max-width: 80px;
+  background-color: rgba(255, 255, 255, 0.6);
+  border-radius: 2px;
+  align-items: center;
+  max-height: 12px;
+}
+
+.relationInput {
+  z-index: 1;
+  cursor: text;
+  min-width: 0px;
+  max-width: 1.5ch;
+  border: none;
+  background: transparent;
+  text-align: center;
+  font-family: monospace;
+  font-weight: bold;
+  font-size: 11px;
+  color: #181520;
+  user-select: none;
+  font-style: italic;
+  &:focus {
+    outline: none;
+    user-select: none;
+  }
+  &::placeholder {
+    outline: none;
+    user-select: none;
+    font-style: italic;
+  }
+}
+
+.relationReadonly {
+  cursor: grab !important;
+  color: #181520 !important;
+  user-select: none;
+  font-style: normal !important;
+}
+
+.relationHandleFunction {
+  margin-left: 20;
+  margin-bottom: 18px !important;
+}
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss
new file mode 100644
index 0000000000000000000000000000000000000000..1f8d81b42bb9dd2606b65c17253f93274824547c
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss
@@ -0,0 +1,317 @@
+@import '../../querypills.module.scss';
+
+// .relation {
+//   display: flex;
+//   text-align: center;
+//   font-family: monospace;
+//   font-weight: bold;
+//   font-size: 10px;
+//   background-color: blue;
+// }
+
+.highlighted {
+  box-shadow: black 0 0 2px;
+}
+
+.contentWrapper {
+  display: flex;
+  align-items: center;
+
+  .handleLeft {
+    position: relative;
+    z-index: 3;
+
+    top: 25%;
+    border: 0px;
+    border-radius: 0px;
+
+    background: transparent;
+    transform-origin: center;
+
+    width: 0;
+    height: 0;
+    border-top: 5px solid transparent;
+    border-bottom: 5px solid transparent;
+    border-right: rgba(255, 255, 255, 0.7) 6px solid;
+
+    &::after {
+      content: '';
+      display: block;
+      position: absolute;
+      width: 0;
+      height: 0;
+      border-top: 7px solid transparent;
+      border-bottom: 7px solid transparent;
+      border-right: rgba(0, 0, 0, 0.1) 8px solid;
+      top: -7px;
+      right: -7px;
+    }
+  }
+  .highlighted {
+    z-index: -1;
+    box-shadow: 0 0 2px 1px gray;
+  }
+
+  .content {
+    margin: 0 2ch;
+    padding: 3px 0;
+    max-width: 20ch;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    white-space: nowrap;
+    // pointer-events: none;
+  }
+
+  .handleRight {
+    position: relative;
+    top: 25%;
+    border: 0px;
+    border-radius: 0px;
+
+    background: transparent;
+    transform-origin: center;
+
+    width: 0;
+    height: 0;
+    border-top: 5px solid transparent;
+    border-bottom: 5px solid transparent;
+    border-left: rgba(255, 255, 255, 0.7) 6px solid;
+
+    &::after {
+      content: '';
+      display: block;
+      position: absolute;
+      width: 0;
+      height: 0;
+      border-top: 7px solid transparent;
+      border-bottom: 7px solid transparent;
+      border-left: rgba(0, 0, 0, 0.1) 8px solid;
+      top: -7px;
+      left: -7px;
+    }
+  }
+}
+
+$height: 10px;
+.arrowLeft {
+  z-index: 2;
+  width: 0;
+  height: 0;
+  border-top: $height solid transparent;
+  border-bottom: $height solid transparent;
+  transform: scale(1.028) translate(0.3px 0px);
+
+  border-right: $height solid;
+}
+
+.arrowRight {
+  width: 0;
+  height: 0;
+  border-top: $height solid transparent;
+  border-bottom: $height solid transparent;
+  transform: scale(1.02) translate(-0.3px 0px);
+
+  border-left: $height solid;
+}
+
+$width: 325;
+// Relation element
+.relation {
+  position: relative;
+  display: flex;
+  width: $width + px;
+  background: transparent;
+  text-align: center;
+  text-decoration: none;
+  color: black;
+  box-sizing: border-box;
+  line-height: 20px;
+  font-family: monospace;
+  font-weight: bold;
+  font-size: 11px;
+}
+
+.rightArrow {
+  border-style: solid;
+  border-width: $height 0 $height $height * 1.5;
+  border-color: transparent transparent transparent black;
+  margin-top: 0.5;
+  background: transparent;
+  display: inline-block;
+  position: absolute;
+  right: -$height * 1.5;
+  transform: translate(-0.2px, 0px) scale(1.02);
+}
+.leftArrow {
+  border-style: solid;
+  border-width: $height $height * 1.5 $height 0;
+  border-color: transparent black transparent transparent;
+  margin-top: 0.5;
+  background: transparent;
+  display: inline-block;
+  position: absolute;
+  z-index: -1;
+  left: -$height * 1.5;
+  transform: translate(0.2px, 0px) scale(1.02);
+}
+.relationTop {
+  position: absolute;
+  content: '';
+  width: inherit;
+  left: 0px;
+  height: $height + px;
+  z-index: -1;
+  background-color: #1fa2a2;
+  transform: perspective(15px) rotateX(5deg);
+  border-bottom: none;
+}
+.relationBottom {
+  position: absolute;
+  content: '';
+  width: inherit;
+  left: 0px;
+  height: $height + px;
+  z-index: -1;
+  background-color: #1fa2a2;
+  top: $height + px;
+  transform: perspective(15px) rotateX(-5deg);
+  border-top: none;
+}
+.relationWrapper {
+  display: inherit;
+  width: inherit;
+  align-items: center;
+  justify-content: space-between;
+}
+.relationHandleFiller {
+  flex: 1 1 0;
+}
+
+.relationHandleLeft {
+  // FIRST ONE
+  position: absolute !important;
+  border-style: solid !important;
+  border-width: 6px 10px 6px 0 !important;
+  border-radius: 0px !important;
+  border-color: transparent rgba(0, 0, 0, 0.3) transparent transparent !important;
+  background: transparent !important;
+  min-height: 0 !important;
+  min-width: 0 !important;
+  width: 0 !important;
+  height: 0px !important;
+
+  &::before {
+    content: '';
+    border-style: solid;
+    border-width: 4px 7.5px 4px 0;
+    border-color: transparent rgba(255, 255, 255, 0.6) transparent transparent;
+    margin-top: 0.5;
+    background: transparent;
+    z-index: -1;
+    display: inline-block;
+    position: absolute;
+    top: -4px;
+    left: 2px;
+  }
+}
+
+.relationHandleAttribute {
+  // SECOND ONE
+  border-radius: 1px !important;
+  left: 22.5px !important;
+  background: rgba(255, 255, 255, 0.6) !important;
+  transform: rotate(45deg) translate(-68%, 0) scale(0.9) !important;
+  border-color: rgba(22, 110, 110, 1) !important;
+  border-width: 1px !important;
+  transform-origin: center, center;
+}
+
+.relationHandleFunction {
+  // THIRD ONE
+  left: 39px !important;
+  background: rgba(255, 255, 255, 0.6) !important;
+  border-color: rgba(22, 110, 110, 1) !important;
+  border-width: 1px !important;
+  transform-origin: center, center;
+}
+
+.relationHandleRight {
+  // LAST ONE
+  width: 0 !important;
+  height: 0 !important;
+  position: absolute !important;
+
+  border-radius: 1px !important;
+  border-width: 6px 0px 6px 10px !important;
+  border-color: transparent transparent transparent rgba(0, 0, 0, 0.3) !important;
+  background: transparent !important;
+  min-height: 0 !important;
+  min-width: 0 !important;
+
+  &::before {
+    content: '';
+    border-style: solid;
+    border-width: 4px 0 4px 7.5px;
+    border-color: transparent transparent transparent rgba(255, 255, 255, 0.6);
+    margin-top: 0.5;
+    background: transparent;
+    z-index: -1;
+    display: inline-block;
+    position: absolute;
+    top: -4px;
+    right: 2px;
+  }
+}
+
+.relationInputHolder {
+  display: flex;
+  float: right;
+  margin-right: 20px;
+  margin-top: 4px;
+  margin-left: 5px;
+  max-width: 80px;
+  background-color: rgba(255, 255, 255, 0.6);
+  border-radius: 2px;
+  align-items: center;
+  max-height: 12px;
+}
+.relationInput {
+  z-index: 1;
+  cursor: text;
+  min-width: 0px;
+  max-width: 1.5ch;
+  border: none;
+  background: transparent;
+  text-align: center;
+  font-family: monospace;
+  font-weight: bold;
+  font-size: 11px;
+  color: #181520;
+  user-select: none;
+  font-style: italic;
+  &:focus {
+    outline: none;
+    user-select: none;
+  }
+  &::placeholder {
+    outline: none;
+    user-select: none;
+    font-style: italic;
+  }
+}
+.relationReadonly {
+  cursor: grab !important;
+  color: #181520 !important;
+  user-select: none;
+  font-style: normal !important;
+}
+.relationSpan {
+  float: left;
+  margin-left: 5;
+}
+
+.relationDataWrapper {
+  display: flex;
+  width: 100%;
+  justify-content: center;
+}
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a0a450e53cc824b7f609036a0e336970b3f601a4
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss.d.ts
@@ -0,0 +1,36 @@
+declare const classNames: {
+  readonly 'react-flow__node': 'react-flow__node';
+  readonly selected: 'selected';
+  readonly entityWrapper: 'entityWrapper';
+  readonly hidden: 'hidden';
+  readonly 'react-flow__edges': 'react-flow__edges';
+  readonly 'react-flow__edge-default': 'react-flow__edge-default';
+  readonly handleConnectedFill: 'handleConnectedFill';
+  readonly handleConnectedBorderRight: 'handleConnectedBorderRight';
+  readonly handleConnectedBorderLeft: 'handleConnectedBorderLeft';
+  readonly handleFunction: 'handleFunction';
+  readonly highlighted: 'highlighted';
+  readonly contentWrapper: 'contentWrapper';
+  readonly handleLeft: 'handleLeft';
+  readonly content: 'content';
+  readonly handleRight: 'handleRight';
+  readonly arrowLeft: 'arrowLeft';
+  readonly arrowRight: 'arrowRight';
+  readonly relation: 'relation';
+  readonly rightArrow: 'rightArrow';
+  readonly leftArrow: 'leftArrow';
+  readonly relationTop: 'relationTop';
+  readonly relationBottom: 'relationBottom';
+  readonly relationWrapper: 'relationWrapper';
+  readonly relationHandleFiller: 'relationHandleFiller';
+  readonly relationHandleLeft: 'relationHandleLeft';
+  readonly relationHandleAttribute: 'relationHandleAttribute';
+  readonly relationHandleFunction: 'relationHandleFunction';
+  readonly relationHandleRight: 'relationHandleRight';
+  readonly relationInputHolder: 'relationInputHolder';
+  readonly relationInput: 'relationInput';
+  readonly relationReadonly: 'relationReadonly';
+  readonly relationSpan: 'relationSpan';
+  readonly relationDataWrapper: 'relationDataWrapper';
+};
+export = classNames;
diff --git a/libs/shared/lib/ui/pills/customFlowPills/relationpill/relationpill.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.stories.tsx
similarity index 76%
rename from libs/shared/lib/ui/pills/customFlowPills/relationpill/relationpill.stories.tsx
rename to libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.stories.tsx
index 735c0acb419d063aa5f469cae92f55a73430b69d..35171325cb14ef9d80de42d8470862b9a5895e47 100644
--- a/libs/shared/lib/ui/pills/customFlowPills/relationpill/relationpill.stories.tsx
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.stories.tsx
@@ -1,6 +1,6 @@
 import React from 'react';
-import { Meta } from '@storybook/react';
-import RelationRFPill from './relationpill';
+import { Meta, StoryObj } from '@storybook/react';
+import RelationPill from './relationpill';
 import { configureStore } from '@reduxjs/toolkit';
 import { Provider } from 'react-redux';
 import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme';
@@ -11,14 +11,15 @@ import {
   schemaSlice,
 } from '@graphpolaris/shared/lib/data-access/store';
 import { ReactFlowProvider } from 'reactflow';
+import { RelationData } from '../../../graph/reactflow/model';
 
-const Component: Meta<typeof RelationRFPill> = {
+const Component: Meta<typeof RelationPill> = {
   /* 👇 The title prop is optional.
    * See https://storybook.js.org/docs/react/configure/overview#configure-story-loading
    * to learn how to generate automatic titles
    */
-  title: 'Components/Pills/RelationRFPill',
-  component: RelationRFPill,
+  title: 'Querybuilder/Pills/RelationPill',
+  component: RelationPill,
   decorators: [
     (story) => (
       <Provider store={Mockstore}>
@@ -43,10 +44,13 @@ const Mockstore = configureStore({
 
 // const Template = (args: any) => <EntityRFPill {...args} />;
 
-export const Default = {
+export const Default: StoryObj<{ data: RelationData }> = {
   args: {
     data: {
       name: 'TestEntity',
+      collection: 'test',
+      depth: { min: 0, max: 1 },
+      fadeIn: false,
     },
   },
 };
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..b1de1902c48a34371115cf853e98de7fffaf27e2
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.tsx
@@ -0,0 +1,220 @@
+import React, { memo, useRef, useState } from 'react';
+
+import { useTheme } from '@mui/material';
+import { Handle, Position } from 'reactflow';
+
+import styles from './relationpill.module.scss';
+import { RelationNode } from '../../../graph/reactflow/model';
+import { Handles } from '../../../graph/reactflow/handles';
+
+// export type RelationRFPillProps = {
+//   data: {
+//     name: string;
+//     suggestedForConnection: any;
+//     isFromEntityConnected?: boolean;
+//     isToEntityConnected?: boolean;
+//   };
+// };
+
+/**
+ * Component to render a relation flow element
+ * @param { FlowElement<RelationData>} param0 The data of a relation flow element.
+ */
+export const RelationPill = memo(({ data }: RelationNode) => {
+  // export default function RelationRFPill({ data }: { data: any }) {
+  const theme = useTheme();
+  // console.log('RelationRFPill', data);
+
+  const minRef = useRef<HTMLInputElement>(null);
+  const maxRef = useRef<HTMLInputElement>(null);
+
+  const [readOnlyMin, setReadOnlyMin] = useState(true);
+  const [readOnlyMax, setReadOnlyMax] = useState(true);
+
+  const onDepthChanged = (depth: string) => {
+    // Don't allow depth above 99
+    const limit = 99;
+    if (data != undefined) {
+      data.depth.min = data.depth.min >= limit ? limit : data.depth.min;
+      data.depth.max = data.depth.max >= limit ? limit : data.depth.max;
+
+      // Check for for valid depth: min <= max
+      if (depth == 'min') {
+        if (data.depth.min > data.depth.max) data.depth.max = data.depth.min;
+        setReadOnlyMin(true);
+      } else if (depth == 'max') {
+        if (data.depth.max < data.depth.min) data.depth.min = data.depth.max;
+        setReadOnlyMax(true);
+      }
+
+      // Set to the correct width
+      if (maxRef.current)
+        maxRef.current.style.maxWidth = calcWidth(data.depth.max);
+      if (minRef.current)
+        minRef.current.style.maxWidth = calcWidth(data.depth.min);
+    }
+  };
+
+  const isNumber = (x: string) => {
+    {
+      if (typeof x != 'string') return false;
+      return !Number.isNaN(x) && !Number.isNaN(parseFloat(x));
+    }
+  };
+
+  const calcWidth = (data: number) => {
+    return data.toString().length + 0.5 + 'ch';
+  };
+
+  return (
+    <div
+      className={styles.relation}
+      style={{ backgroundColor: theme.palette.custom.elements.relation[0] }}
+    >
+      <div
+        className={styles.rightArrow}
+        style={{ borderLeftColor: theme.palette.custom.elements.relation[0] }}
+      ></div>
+      <div
+        className={styles.leftArrow}
+        style={{ borderRightColor: theme.palette.custom.elements.relation[0] }}
+      ></div>
+      {/* <span
+        className={styles.relationTop}
+        style={{ backgroundColor: theme.palette.custom.elements.relation[0] }}
+      ></span>
+      <span
+        className={styles.relationBottom}
+        style={{ backgroundColor: theme.palette.custom.elements.relation[0] }}
+      ></span> */}
+      <div className={styles.relationWrapper}>
+        <span
+          className={styles.relationHandleFiller}
+          // style={{ transform: 'translate(-100px,0)' }}
+        >
+          <Handle
+            id={Handles.RelationLeft}
+            type="target"
+            position={Position.Left}
+            className={
+              styles.relationHandleLeft +
+              ' ' +
+              (false ? styles.handleConnectedBorderLeft : '')
+            }
+          />
+        </span>
+        <span className={styles.relationHandleFiller}>
+          <Handle
+            id={Handles.ToAttribute}
+            type="target"
+            position={Position.Left}
+            className={
+              styles.relationHandleAttribute +
+              ' ' +
+              (false ? styles.handleConnectedFill : '')
+            }
+          />
+        </span>
+        <span className={styles.relationHandleFiller}>
+          <Handle
+            id={Handles.ReceiveFunction}
+            type="target"
+            position={Position.Left}
+            className={
+              styles.relationHandleFunction +
+              ' ' +
+              (false ? styles.handleConnectedFill : '')
+            }
+          />
+        </span>
+        <div className={styles.relationDataWrapper}>
+          <span className={styles.relationSpan}>{data?.name}</span>
+          <span className={styles.relationInputHolder}>
+            <span>[</span>
+            <input
+              className={
+                styles.relationInput +
+                ' ' +
+                (readOnlyMin ? styles.relationReadonly : '')
+              }
+              ref={minRef}
+              type="string"
+              min={0}
+              readOnly={readOnlyMin}
+              placeholder={'?'}
+              value={data?.depth.min}
+              onChange={(e) => {
+                if (data != undefined) {
+                  data.depth.min = isNumber(e.target.value)
+                    ? parseInt(e.target.value)
+                    : 0;
+                  e.target.style.maxWidth = calcWidth(data.depth.min);
+                }
+              }}
+              onDoubleClick={() => {
+                setReadOnlyMin(false);
+              }}
+              onBlur={(e) => {
+                onDepthChanged('min');
+              }}
+              onKeyDown={(e) => {
+                if (e.key === 'Enter') {
+                  onDepthChanged('min');
+                }
+              }}
+            ></input>
+            <span>..</span>
+            <input
+              className={
+                styles.relationInput +
+                ' ' +
+                (readOnlyMax ? styles.relationReadonly : '')
+              }
+              ref={maxRef}
+              type="string"
+              min={0}
+              readOnly={readOnlyMax}
+              placeholder={'?'}
+              value={data?.depth.max}
+              onChange={(e) => {
+                if (data != undefined) {
+                  data.depth.max = isNumber(e.target.value)
+                    ? parseInt(e.target.value)
+                    : 0;
+                  e.target.style.maxWidth = calcWidth(data.depth.max);
+                }
+              }}
+              onDoubleClick={() => {
+                setReadOnlyMax(false);
+              }}
+              onBlur={(e) => {
+                onDepthChanged('max');
+              }}
+              onKeyDown={(e) => {
+                if (e.key === 'Enter') {
+                  onDepthChanged('max');
+                }
+              }}
+            ></input>
+            <span>]</span>
+          </span>
+        </div>
+        <span className={styles.relationHandleFiller}>
+          <Handle
+            id={Handles.RelationRight}
+            type="target"
+            position={Position.Right}
+            className={
+              styles.relationHandleRight +
+              ' ' +
+              (false ? styles.handleConnectedBorderRight : '')
+            }
+          />
+        </span>
+      </div>
+    </div>
+  );
+});
+
+RelationPill.displayName = 'RelationPill';
+export default RelationPill;
diff --git a/libs/shared/lib/querybuilder/usecases/dragging/dragAttribute.ts b/libs/shared/lib/querybuilder/pills/dragging/dragAttribute.ts
similarity index 100%
rename from libs/shared/lib/querybuilder/usecases/dragging/dragAttribute.ts
rename to libs/shared/lib/querybuilder/pills/dragging/dragAttribute.ts
diff --git a/libs/shared/lib/querybuilder/usecases/dragging/dragAttributesAlong.ts b/libs/shared/lib/querybuilder/pills/dragging/dragAttributesAlong.ts
similarity index 100%
rename from libs/shared/lib/querybuilder/usecases/dragging/dragAttributesAlong.ts
rename to libs/shared/lib/querybuilder/pills/dragging/dragAttributesAlong.ts
diff --git a/libs/shared/lib/querybuilder/usecases/dragging/dragEntity.ts b/libs/shared/lib/querybuilder/pills/dragging/dragEntity.ts
similarity index 100%
rename from libs/shared/lib/querybuilder/usecases/dragging/dragEntity.ts
rename to libs/shared/lib/querybuilder/pills/dragging/dragEntity.ts
diff --git a/libs/shared/lib/querybuilder/usecases/dragging/dragPill.ts b/libs/shared/lib/querybuilder/pills/dragging/dragPill.ts
similarity index 95%
rename from libs/shared/lib/querybuilder/usecases/dragging/dragPill.ts
rename to libs/shared/lib/querybuilder/pills/dragging/dragPill.ts
index 1a7ae7dc97567751b86f69db05f1049712ed8d26..728c5f0e34473fa14fda287b9fa3728da6547936 100644
--- a/libs/shared/lib/querybuilder/usecases/dragging/dragPill.ts
+++ b/libs/shared/lib/querybuilder/pills/dragging/dragPill.ts
@@ -37,9 +37,9 @@ export function dragPillStarted(id: string, nodes: MultiGraph) {
  * @param nodes The graphology query builder nodes object
  * @param dx Delta x
  * @param dy Delta y
- * @param position The already updated positiong (dx dy are already applied)
+ * @param position The already updated positioning (dx dy are already applied)
  */
-export function dragPill(
+export function movePillTo(
   id: string,
   nodes: MultiGraph,
   dx: number,
diff --git a/libs/shared/lib/querybuilder/usecases/dragging/dragRelation.ts b/libs/shared/lib/querybuilder/pills/dragging/dragRelation.ts
similarity index 100%
rename from libs/shared/lib/querybuilder/usecases/dragging/dragRelation.ts
rename to libs/shared/lib/querybuilder/pills/dragging/dragRelation.ts
diff --git a/libs/shared/lib/querybuilder/usecases/dragging/getClosestPill.ts b/libs/shared/lib/querybuilder/pills/dragging/getClosestPill.ts
similarity index 100%
rename from libs/shared/lib/querybuilder/usecases/dragging/getClosestPill.ts
rename to libs/shared/lib/querybuilder/pills/dragging/getClosestPill.ts
diff --git a/libs/shared/lib/ui/pills/index.ts b/libs/shared/lib/querybuilder/pills/index.ts
similarity index 66%
rename from libs/shared/lib/ui/pills/index.ts
rename to libs/shared/lib/querybuilder/pills/index.ts
index 5f784740f5f732d8a2bcfdef058fb4a5e36be262..b37ce567ecf66be10946ef0072caa25307c36a5b 100644
--- a/libs/shared/lib/ui/pills/index.ts
+++ b/libs/shared/lib/querybuilder/pills/index.ts
@@ -1,3 +1,2 @@
-export * from './shared-ui-pills';
 export * from './customFlowLines';
 export * from './customFlowPills';
diff --git a/libs/shared/lib/querybuilder/pills/querypills.module.scss b/libs/shared/lib/querybuilder/pills/querypills.module.scss
new file mode 100644
index 0000000000000000000000000000000000000000..2cb3fedf0b75d41e546a59118070b9145a9ff215
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/querypills.module.scss
@@ -0,0 +1,63 @@
+.react-flow__node {
+  &.selected {
+    border: #000 solid 1px;
+  }
+}
+
+.entityWrapper {
+  &.hidden {
+    display: none;
+  }
+}
+
+.react-flow__edges {
+  zindex: '3';
+}
+.react-flow__nodes {
+}
+.react-flow__pane {
+}
+.react-flow__edge-default .selected {
+  stroke: 'gray !important';
+}
+
+// This is used to override the previous color of the handle, for that to work it has to be on the bottom of the file
+.handleConnectedFill {
+  &::before {
+    background: #181520;
+  }
+}
+.handleConnectedBorderRight {
+  &::before {
+    border-color: transparent transparent transparent #181520;
+  }
+}
+.handleConnectedBorderLeft {
+  &::before {
+    border-color: transparent #181520 transparent transparent;
+  }
+}
+
+// General style
+.handleFunction {
+  border: 0 !important;
+  border-radius: 50% !important;
+  left: 40 !important;
+  width: 6 !important;
+  height: 6 !important;
+  background: rgba(0, 0, 0, 0.3) !important;
+  margin-bottom: 16 !important;
+  &::before {
+    content: '' !important;
+    width: 4 !important;
+    height: 4 !important;
+    left: 1 !important;
+    bottom: 1 !important;
+    border: 0 !important;
+    border-radius: 50% !important;
+    background: rgba(255, 255, 255, 0.6) !important;
+    z-index: -1 !important;
+    display: inline-block !important;
+    position: fixed !important;
+  }
+}
diff --git a/libs/shared/lib/querybuilder/pills/querypills.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/querypills.module.scss.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a040b2068e5b80b1df7cfa195509c11c47e175ad
--- /dev/null
+++ b/libs/shared/lib/querybuilder/pills/querypills.module.scss.d.ts
@@ -0,0 +1,13 @@
+declare const classNames: {
+  readonly 'react-flow__node': 'react-flow__node';
+  readonly selected: 'selected';
+  readonly entityWrapper: 'entityWrapper';
+  readonly hidden: 'hidden';
+  readonly 'react-flow__edges': 'react-flow__edges';
+  readonly 'react-flow__edge-default': 'react-flow__edge-default';
+  readonly handleConnectedFill: 'handleConnectedFill';
+  readonly handleConnectedBorderRight: 'handleConnectedBorderRight';
+  readonly handleConnectedBorderLeft: 'handleConnectedBorderLeft';
+  readonly handleFunction: 'handleFunction';
+};
+export = classNames;
diff --git a/libs/shared/lib/querybuilder/usecases/addPill.ts b/libs/shared/lib/querybuilder/usecases/addPill.ts
deleted file mode 100644
index 4dc37e18d16bd55f0b405520704b97f174ef6fca..0000000000000000000000000000000000000000
--- a/libs/shared/lib/querybuilder/usecases/addPill.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import {
-  setQuerybuilderNodes,
-  store,
-} from '@graphpolaris/shared/lib/data-access/store';
-import Graph from 'graphology';
-import { Attributes } from 'graphology-types';
-
-/** monospace fontsize table */
-const widthPerFontsize = {
-  6: 3.6167,
-  7: 4.2167,
-  10: 6.0167,
-};
-
-/** Adds a query builder pill to the graphology nodes object. */
-export function addPill(
-  id: string,
-  attributes: Attributes,
-  nodes: Graph
-): boolean {
-  const { type, name } = attributes;
-  if (!type || !name) return false;
-  let { x, y } = attributes;
-
-  // Check if x and y are present, otherwise set them to 0
-  if (!x) x = 0;
-  if (!y) y = 0;
-
-  // Get the width and height of a node
-  const { w, h } = calcWidthHeightOfPill(attributes);
-
-  // Add a node to the graphology object
-  nodes.addNode(id, { ...attributes, x, y, w, h });
-
-  // Set the new nodes in the query builder slice
-  store.dispatch(setQuerybuilderNodes(nodes.export()));
-
-  return true;
-}
-
-/** Calculates the width and height of a query builder pill.
- * DEPENDS ON STYLING, if styling changed, change this.
- */
-function calcWidthHeightOfPill(attributes: Attributes): {
-  w: number;
-  h: number;
-} {
-  const { type, name } = attributes;
-
-  let w = 0;
-  let h = 0;
-  switch (type) {
-    case 'entity': {
-      // calculate width and height of entity pill
-      w = Math.min(name.length, 20) * widthPerFontsize[10]; // for fontsize 10px
-
-      const widthOfPillWithoutText = 42.1164; // WARNING: depends on styling
-      w += widthOfPillWithoutText;
-      h = 20;
-      break;
-    }
-    case 'relation': {
-      // calculate width and height of relation pill
-      w = Math.min(name.length, 20) * widthPerFontsize[10]; // for fontsize 10px
-
-      const widthOfPillWithoutText = 56.0666; // WARNING: depends on styling
-      w += widthOfPillWithoutText;
-      h = 20;
-      break;
-    }
-    case 'attribute': {
-      // calculate width and height of relation pill
-      const pixelsPerChar = widthPerFontsize[6]; // for fontsize 10px
-      w = name.length * pixelsPerChar;
-
-      const { datatype, operator } = attributes;
-      let value = attributes['value'];
-      if (!datatype || !operator) return { w: 0, h: 0 };
-      if (!value) value = '?';
-
-      // Add width of operator
-      w += operator.length * widthPerFontsize[7];
-      // use a max of 10, because max-width is set to 10ch;
-      w += Math.min(value.length, 10) * widthPerFontsize[6];
-
-      const widthOfPillWithoutText = 25.6666; // WARNING: depends on styling
-      w += widthOfPillWithoutText;
-      h = 12;
-      break;
-    }
-  }
-
-  return { w, h };
-}
diff --git a/libs/shared/lib/querybuilder/usecases/index.ts b/libs/shared/lib/querybuilder/usecases/index.ts
deleted file mode 100644
index 54e15f0b0d2ef473477ca7d09d970ef86eb63c29..0000000000000000000000000000000000000000
--- a/libs/shared/lib/querybuilder/usecases/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export * from './attribute/getAttributeBoolOperators';
-export * from './attribute/checkInput';
-export * from './createReactFlowElements';
-export * from './pillHandles';
-export * from './dragging/dragPill';
-export * from './addPill';
diff --git a/libs/shared/lib/querybuilder/usecases/querybuilder-usecases.spec.ts b/libs/shared/lib/querybuilder/usecases/querybuilder-usecases.spec.ts
deleted file mode 100644
index cb212e0e122658ec13e90e4c8b9e613c51b8b8d8..0000000000000000000000000000000000000000
--- a/libs/shared/lib/querybuilder/usecases/querybuilder-usecases.spec.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { querybuilderUsecases } from './querybuilder-usecases';
-import { assert, describe, expect, it } from "vitest";
-
-describe('querybuilderUsecases', () => {
-  it('should work', () => {
-    expect(querybuilderUsecases()).toEqual('querybuilder-usecases');
-  });
-});
diff --git a/libs/shared/lib/querybuilder/usecases/querybuilder-usecases.ts b/libs/shared/lib/querybuilder/usecases/querybuilder-usecases.ts
deleted file mode 100644
index 06d687eb90fbdd6d6e752c90417a12a854aff52b..0000000000000000000000000000000000000000
--- a/libs/shared/lib/querybuilder/usecases/querybuilder-usecases.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export function querybuilderUsecases(): string {
-  return 'querybuilder-usecases';
-}
diff --git a/libs/shared/lib/schema/panel/schema.tsx b/libs/shared/lib/schema/panel/schema.tsx
index 8dbd36ab16ba81f25cb4956419f1a13a7a11799f..68245392c939c6530a5cbd8c9ac808a4a17ca01f 100644
--- a/libs/shared/lib/schema/panel/schema.tsx
+++ b/libs/shared/lib/schema/panel/schema.tsx
@@ -1,4 +1,5 @@
 import {
+  AlgorithmToLayoutProvider,
   AllLayoutAlgorithms,
   LayoutFactory,
 } from '@graphpolaris/shared/lib/graph-layout';
@@ -7,12 +8,13 @@ import {
   schemaExpandRelation,
 } from '@graphpolaris/shared/lib/schema/schema-utils';
 import {
-  useSchema,
+  useSchemaGraph,
+  useSchemaGraphology,
   useSchemaLayout,
 } from '@graphpolaris/shared/lib/data-access/store';
 import { MultiGraph } from 'graphology';
 // import { AllLayoutAlgorithms, LayoutFactory } from '@graphpolaris/graph-layout';
-import { useEffect, useMemo, useState } from 'react';
+import { useEffect, useMemo, useRef, useState } from 'react';
 import ReactFlow, {
   ControlButton,
   Controls,
@@ -29,12 +31,12 @@ import 'reactflow/dist/style.css';
 import styles from './schema.module.scss';
 
 import {
-  EntityRFPill,
-  RelationRFPill,
-  AttributeRFPill,
+  EntityFlowElement,
+  RelationPill,
+  AttributePill,
   ConnectionDragLine,
   ConnectionLine,
-} from '@graphpolaris/shared/lib/ui/pills';
+} from '@graphpolaris/shared/lib/querybuilder/pills';
 import { EntityNode } from '../pills/nodes/entity/entity-node';
 import { RelationNode } from '../pills/nodes/relation/relation-node';
 import { NodeQualityEntityPopupNode } from '../pills/nodes/popup/node-quality-entity-popup';
@@ -73,40 +75,48 @@ export const Schema = (props: Props) => {
   const [nodes, setNodes, onNodeChanged] = useNodesState([] as Node[]);
   const [edges, setEdges, onEdgeChanged] = useEdgesState([] as Edge[]);
   // In case the schema is updated
-  const dbschema = useSchema();
-  // const [dbschema, setSchema] = useState(useSchema());
-  const [schemaLayout, setSchemaLayout] = useState(useSchemaLayout());
+  const schemaGraphology = useSchemaGraphology();
+  const schemaGraph = useSchemaGraph();
+  // const [schemaGraphology, setSchema] = useState(useSchema());
+  const schemaLayout = useSchemaLayout();
+  const layout = useRef<AlgorithmToLayoutProvider<AllLayoutAlgorithms>>();
 
-  console.log('dbSchema', dbschema.edges());
+  // console.log('dbSchema', schemaGraphology.edges());
   // useEffect(() => {
-  //   console.log('dbSchema', dbschema, dbschema.order);
-  // }, [dbschema]);
+  //   console.log('dbSchema', schemaGraphology, schemaGraphology.order);
+  // }, [schemaGraphology]);
 
   const toggleNodeQualityPopup = (id: string) => {};
   const toggleAttributeAnalyticsPopupMenu = (id: string) => {};
 
+  function updateLayout() {
+    const layoutFactory = new LayoutFactory();
+    layout.current = layoutFactory.createLayout(
+      schemaLayout as AllLayoutAlgorithms
+    ); // TODO: more layouts here
+  }
+
+  useEffect(() => {
+    updateLayout();
+  }, []);
+
   useEffect(() => {
-    if (dbschema == undefined || dbschema.order == 0) {
+    if (schemaGraphology == undefined || schemaGraphology.order == 0) {
       return;
     }
-    // console.log('dbSchema', dbschema.edges());
-
-    const layoutFactory = new LayoutFactory();
-    const layout = layoutFactory.createLayout(
-      schemaLayout as AllLayoutAlgorithms
-    );
+    console.log(schemaGraphology.export());
 
-    const expandedSchema = schemaExpandRelation(dbschema);
-    layout?.layout(expandedSchema); // TODO: more layouts here
+    const expandedSchema = schemaExpandRelation(schemaGraphology);
+    layout.current?.layout(expandedSchema);
 
     const schemaFlow = schemaGraphology2Reactflow(expandedSchema);
 
-    schemaFlow.nodes.forEach((n) => {
-      n.data.toggleNodeQualityPopup = toggleNodeQualityPopup;
-      n.data.toggleAttributeAnalyticsPopupMenu =
-        toggleAttributeAnalyticsPopupMenu;
-    });
-    console.log(edges);
+    // schemaFlow.nodes.forEach((n) => {
+    //   n.data.toggleNodeQualityPopup = toggleNodeQualityPopup;
+    //   n.data.toggleAttributeAnalyticsPopupMenu =
+    //     toggleAttributeAnalyticsPopupMenu;
+    // });
+    // console.log(edges);
 
     // console.log(
     //   'schema Layout',
@@ -119,11 +129,11 @@ export const Schema = (props: Props) => {
     setEdges(schemaFlow.edges);
     // console.log(
     //   'update schema useEffect',
-    //   dbschema,
-    //   dbschema.order,
+    //   schemaGraphology,
+    //   schemaGraphology.order,
     //   schemaFlow
     // );
-  }, [dbschema, schemaLayout]);
+  }, [schemaGraph, schemaLayout]);
 
   const graphStyles = { width: '100%', height: '500px' };
 
@@ -151,6 +161,7 @@ export const Schema = (props: Props) => {
           edges={edges}
           style={graphStyles}
           onInit={onInit}
+          panOnDrag={false}
           attributionPosition="top-right"
         >
           <Controls
diff --git a/libs/shared/lib/schema/panel/schemaOLD.tsx b/libs/shared/lib/schema/panel/schemaOLD.tsx
index e162b7869413f1a534e0acd3d79fcab42c001c40..f2d62bf1c65d224b203a2d34f2ebf84fd3a4e626 100644
--- a/libs/shared/lib/schema/panel/schemaOLD.tsx
+++ b/libs/shared/lib/schema/panel/schemaOLD.tsx
@@ -7,7 +7,7 @@ import {
   schemaExpandRelation,
 } from '@graphpolaris/shared/lib/schema/schema-utils';
 import {
-  useSchema,
+  useSchemaGraphology,
   useSchemaLayout,
 } from '@graphpolaris/shared/lib/data-access/store';
 import { MultiGraph } from 'graphology';
@@ -28,12 +28,12 @@ import 'reactflow/dist/style.css';
 import styles from './schema.module.scss';
 
 import {
-  EntityRFPill,
-  RelationRFPill,
-  AttributeRFPill,
+  EntityFlowElement,
+  RelationPill,
+  AttributePill,
   ConnectionDragLine,
   ConnectionLine,
-} from '@graphpolaris/shared/lib/ui/pills';
+} from '@graphpolaris/shared/lib/querybuilder/pills';
 
 interface Props {
   content?: string;
@@ -44,9 +44,9 @@ const onLoad = (reactFlowInstance: any) => {
 };
 
 const nodeTypes = {
-  entity: EntityRFPill,
-  relation: RelationRFPill,
-  attribute: AttributeRFPill,
+  entity: EntityFlowElement,
+  relation: RelationPill,
+  attribute: AttributePill,
 };
 const edgeTypes = {
   connection: ConnectionLine,
@@ -56,7 +56,7 @@ export const Schema = (props: Props) => {
   const [nodes, setNodes, onNodeChanged] = useNodesState([] as Node[]);
   const [edges, setEdges, onEdgeChanged] = useEdgesState([] as Edge[]);
   // In case the schema is updated
-  const dbschema = useSchema();
+  const dbschema = useSchemaGraphology();
   // const [dbschema, setSchema] = useState(useSchema());
   const [schemaLayout, setSchemaLayout] = useState(useSchemaLayout());
 
diff --git a/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx b/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx
index 9307bee9e25218c2f1198bf95f3273d297ce08e5..a33dcaceb8b31acfcbc944521a0cc7d416e67429 100644
--- a/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx
+++ b/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx
@@ -30,7 +30,7 @@ import {
  */
 export const EntityNode = React.memo(
   ({ id, data }: NodeProps<SchemaGraphNodeWithFunctions>) => {
-    console.log(data);
+    // console.log(data);
 
     const [hidden, setHidden] = useState<boolean>(true);
     const theme = useTheme();
diff --git a/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx b/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx
index 7217c67b31e66aa720922c61edb7e07d7bb32379..aa5e1c849973ed5a7d779da77ce281708ff3d015 100644
--- a/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx
+++ b/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx
@@ -33,7 +33,7 @@ export const RelationNode = React.memo(
   ({ id, data }: NodeProps<SchemaGraphRelationWithFunctions>) => {
     const [hidden, setHidden] = useState<boolean>(true);
     const theme = useTheme();
-    console.log(data);
+    // console.log(data);
 
     /**
      * Adds drag functionality in order to be able to drag the relationNode to the schema.
@@ -67,8 +67,6 @@ export const RelationNode = React.memo(
       data.toggleAttributeAnalyticsPopupMenu(data.collection);
     };
 
-    console.log(theme.palette.custom.nodesBase[0]);
-
     const widthExternalBoxes = data.attributes
       ? calcWidthRelationNodeBox(data.attributes.length, data.nodeCount)
       : 0;
diff --git a/libs/shared/lib/ui/pills/customFlowPills/attributepill/attributepill.module.scss b/libs/shared/lib/ui/pills/customFlowPills/attributepill/attributepill.module.scss
deleted file mode 100644
index 9ba5ba22c49c279617faef06e92d4256e49a36fb..0000000000000000000000000000000000000000
--- a/libs/shared/lib/ui/pills/customFlowPills/attributepill/attributepill.module.scss
+++ /dev/null
@@ -1,60 +0,0 @@
-@use './variables.module.scss';
-
-.attribute {
-  display: flex;
-  font-family: monospace;
-  font-weight: bold;
-  font-size: variables.$fontsize;
-  border-radius: 2px;
-}
-
-// .handle {
-//   border: 0px;
-//   border-radius: 10px;
-//   left: 12px;
-//   width: 7px;
-//   height: 7px;
-//   margin-bottom: 11px;
-//   background: rgba(255, 255, 255, 0.6);
-//   box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);
-//   transform-origin: center;
-// }
-
-.contentWrapper {
-  display: flex;
-  align-items: center;
-
-  .content {
-    padding: variables.$ypad 0 variables.$ypad 1ch;
-    max-width: 15ch;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    white-space: nowrap;
-  }
-}
-
-.attributeInput {
-  float: right;
-  padding: 0 1ch 0 0;
-  display: flex;
-  align-items: center;
-
-  input {
-    background-color: rgba(100, 100, 100, 0.1);
-    font-family: monospace;
-    font-size: variables.$fontsize;
-    border: 1px solid rgba(100, 100, 100, 0.3);
-    border-radius: 2px;
-    height: variables.$height;
-    outline: none;
-    transition: border 0.3s;
-    color: black;
-    &::placeholder {
-      color: black;
-    }
-
-    &:focus {
-      border: 1px solid rgba(0, 0, 0, 0.3);
-    }
-  }
-}
diff --git a/libs/shared/lib/ui/pills/customFlowPills/attributepill/attributepill.module.scss.d.ts b/libs/shared/lib/ui/pills/customFlowPills/attributepill/attributepill.module.scss.d.ts
deleted file mode 100644
index af1e5312f0c30b01086c1404e45089b601240243..0000000000000000000000000000000000000000
--- a/libs/shared/lib/ui/pills/customFlowPills/attributepill/attributepill.module.scss.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-declare const classNames: {
-  readonly attribute: 'attribute';
-  readonly contentWrapper: 'contentWrapper';
-  readonly content: 'content';
-  readonly attributeInput: 'attributeInput';
-};
-export = classNames;
diff --git a/libs/shared/lib/ui/pills/customFlowPills/attributepill/attributepill.tsx b/libs/shared/lib/ui/pills/customFlowPills/attributepill/attributepill.tsx
deleted file mode 100644
index e202d2988984b5c215736bde581aae3efee6f128..0000000000000000000000000000000000000000
--- a/libs/shared/lib/ui/pills/customFlowPills/attributepill/attributepill.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import {
-  CheckDatatypeConstraint,
-  GetAttributeBoolOperators,
-} from '@graphpolaris/shared/lib/querybuilder/usecases';
-import {
-  updateQBAttributeOperator,
-  updateQBAttributeValue,
-  useAppDispatch,
-} from '@graphpolaris/shared/lib/data-access/store';
-import { useTheme } from '@mui/material';
-import React, { useMemo, useState } from 'react';
-import styles from './attributepill.module.scss';
-import AttributeOperatorSelect from './operatorselect';
-import { NodeProps } from 'reactflow';
-
-/**
- * Component to render an attribute flow element
- * @param {FlowElement<EntityData>)} param0 The data of an entity flow element.
- */
-export const AttributeRFPill = React.memo(({ id, data }: NodeProps) => {
-  const theme = useTheme();
-  const dispatch = useAppDispatch();
-  const [value, setValue] = useState(data?.value || '');
-
-  const onChange = (e: any) => {
-    setValue(e.target.value);
-  };
-  const validateInput = () => {
-    const newValue = CheckDatatypeConstraint(data.datatype, value);
-    setValue(newValue);
-    dispatch(updateQBAttributeValue({ id, value: newValue }));
-  };
-
-  // Calculates the size of the input
-  const getInputWidth = () => {
-    if (value == '') return 1;
-    else if (value.length > 10) return 10;
-    return value.length;
-  };
-
-  const boolOperators = useMemo(
-    () => GetAttributeBoolOperators(data?.datatype),
-    [data?.datatype]
-  );
-
-  // Determine the backgroundcolor based on if the attribute is connected to a entity or relation
-  let bgcolor;
-  if (data?.attributeOfA == 'entity')
-    bgcolor = theme.palette.custom.queryBuilder.entity.lighterbg;
-  else if (data?.attributeOfA == 'relation')
-    bgcolor = theme.palette.custom.queryBuilder.relation.lighterbg;
-  else bgcolor = theme.palette.custom.queryBuilder.attribute.background;
-
-  return (
-    <div
-      className={styles.attribute}
-      style={{
-        background: bgcolor,
-        color: theme.palette.custom.queryBuilder.text,
-      }}
-    >
-      {/* <Handle
-        id={Handles.Attribute}
-        type="source"
-        position={Position.Bottom}
-        className={styles.handle}
-      /> */}
-      <div className={styles.contentWrapper}>
-        <span className={styles.content} title={data.name}>
-          {data.name}
-        </span>
-        <AttributeOperatorSelect
-          selected={data?.operator}
-          options={boolOperators}
-          changed={(o) =>
-            dispatch(updateQBAttributeOperator({ id, operator: o.value }))
-          }
-        />
-        <span className={styles.attributeInput}>
-          <input
-            style={{ maxWidth: `${getInputWidth()}ch` }}
-            type="string"
-            placeholder={'?'}
-            value={value}
-            onChange={onChange}
-            onBlur={validateInput}
-            onKeyDown={(e) => e.key == 'Enter' && validateInput()}
-          ></input>
-        </span>
-      </div>
-    </div>
-  );
-});
-AttributeRFPill.displayName = 'AttributeRFPill';
-
-export default AttributeRFPill;
diff --git a/libs/shared/lib/ui/pills/customFlowPills/entitypill/entitypill.module.scss b/libs/shared/lib/ui/pills/customFlowPills/entitypill/entitypill.module.scss
deleted file mode 100644
index 755d2b41d564abe3f9e4eb41f56865ef7d2432f4..0000000000000000000000000000000000000000
--- a/libs/shared/lib/ui/pills/customFlowPills/entitypill/entitypill.module.scss
+++ /dev/null
@@ -1,49 +0,0 @@
-.entity {
-  display: flex;
-  font-family: monospace;
-  font-weight: bold;
-  font-size: 10px;
-  padding: 4px 2ch;
-  border-radius: 3px;
-}
-
-.highlighted {
-  box-shadow: black 0 0 2px;
-}
-
-.handleLeft {
-  border: 0px;
-  border-radius: 0px;
-  left: 12px;
-  width: 7px;
-  height: 7px;
-  margin-bottom: 11px;
-  background: rgba(255, 255, 255, 0.6);
-  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);
-  transform-origin: center;
-}
-
-// .handleBottom {
-//   border: 0px;
-//   border-radius: 0px;
-//   width: 7px;
-//   height: 7px;
-//   left: 27.5px;
-//   margin-bottom: 11px;
-//   background: rgba(255, 255, 255, 0.6);
-//   box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);
-//   transform: rotate(-45deg);
-//   transform-origin: center;
-// }
-
-.contentWrapper {
-  margin-left: 3ch;
-
-  span {
-    max-width: 20ch;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    white-space: nowrap;
-    display: block;
-  }
-}
diff --git a/libs/shared/lib/ui/pills/customFlowPills/entitypill/entitypill.module.scss.d.ts b/libs/shared/lib/ui/pills/customFlowPills/entitypill/entitypill.module.scss.d.ts
deleted file mode 100644
index d397689047c7b475c20b89c9efe1de5e16da08d8..0000000000000000000000000000000000000000
--- a/libs/shared/lib/ui/pills/customFlowPills/entitypill/entitypill.module.scss.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-declare const classNames: {
-  readonly entity: 'entity';
-  readonly highlighted: 'highlighted';
-  readonly handleLeft: 'handleLeft';
-  readonly contentWrapper: 'contentWrapper';
-};
-export = classNames;
diff --git a/libs/shared/lib/ui/pills/customFlowPills/entitypill/entitypill.tsx b/libs/shared/lib/ui/pills/customFlowPills/entitypill/entitypill.tsx
deleted file mode 100644
index 3a3168c580ad4fe62fd4c7c8af07652785cdee39..0000000000000000000000000000000000000000
--- a/libs/shared/lib/ui/pills/customFlowPills/entitypill/entitypill.tsx
+++ /dev/null
@@ -1,74 +0,0 @@
-// import { handles } from '@graphpolaris/shared/lib/querybuilder/usecases';
-import { useTheme } from '@mui/material';
-import React, { useEffect } from 'react';
-import { ReactFlow, Handle, Position } from 'reactflow';
-import styles from './entitypill.module.scss';
-import cn from 'classnames';
-
-export const Handless = {
-  entity: {
-    attributes: 'attributesHandle',
-    relations: 'relationsHandle',
-  },
-};
-
-/** Links need handles to what they are connected to (and which side) */
-export enum Handles {
-  RelationLeft = 'leftEntityHandle', //target
-  RelationRight = 'rightEntityHandle', //target
-  ToAttributeHandle = 'attributesHandle', //target
-  ToRelation = 'relationsHandle', //source
-  Attribute = 'AttributeHandle', //source
-  ReceiveFunction = 'receiveFunctionHandle', //target
-  FunctionBase = 'functionHandle_', // + name from FunctionTypes args //source
-}
-
-/**
- * Component to render an entity flow element
- * @param {ReactFlow<EntityData>)} param0 The data of an entity flow element.
- */
-export const EntityRFPill = React.memo(({ data }: { data: any }) => {
-  const theme = useTheme();
-
-  console.log('EntityRFPill', data);
-  return (
-    <div
-      className={cn(styles['entity'], {
-        [styles['highlighted']]: data.suggestedForConnection,
-      })}
-      style={{
-        background: theme.palette.custom.queryBuilder.entity.background,
-        color: theme.palette.custom.queryBuilder.text,
-      }}
-    >
-      {/* <Handle
-        id={handles.entity.relation}
-        type="source"
-        position={Position.Bottom}
-        className={styles['handleLeft']}
-        style={data?.isConnected ? { backgroundColor: '#2e2e2e' } : {}}
-      /> */}
-      {/* <Handle
-      id={Handles.ToAttributeHandle}
-      type="target"
-      position={Position.Bottom}
-      className={styles.handleBottom}
-      /> */}
-      <Handle
-        type="target"
-        position={Position.Left}
-        isValidConnection={(connection) => connection.source === 'some-id'}
-        onConnect={(params) => console.log('handle onConnect', params)}
-        style={{ background: '#fff' }}
-      />
-      <div className={styles['contentWrapper']}>
-        <span title={data.name}>{data.name}</span>
-      </div>
-      FooBar
-    </div>
-  );
-});
-
-EntityRFPill.displayName = 'EntityRFPill';
-
-export default EntityRFPill;
diff --git a/libs/shared/lib/ui/pills/customFlowPills/relationpill/relationpill.module.scss b/libs/shared/lib/ui/pills/customFlowPills/relationpill/relationpill.module.scss
deleted file mode 100644
index fa564adf33da3132ca7873bfa700591df8e21246..0000000000000000000000000000000000000000
--- a/libs/shared/lib/ui/pills/customFlowPills/relationpill/relationpill.module.scss
+++ /dev/null
@@ -1,113 +0,0 @@
-.relation {
-  display: flex;
-  text-align: center;
-  font-family: monospace;
-  font-weight: bold;
-  font-size: 10px;
-  background-color: transparent;
-}
-
-.highlighted {
-  box-shadow: black 0 0 2px;
-}
-
-.contentWrapper {
-  display: flex;
-  align-items: center;
-
-  .handleLeft {
-    position: relative;
-    z-index: 3;
-
-    top: 25%;
-    border: 0px;
-    border-radius: 0px;
-
-    background: transparent;
-    transform-origin: center;
-
-    width: 0;
-    height: 0;
-    border-top: 5px solid transparent;
-    border-bottom: 5px solid transparent;
-    border-right: rgba(255, 255, 255, 0.7) 6px solid;
-
-    &::after {
-      content: '';
-      display: block;
-      position: absolute;
-      width: 0;
-      height: 0;
-      border-top: 7px solid transparent;
-      border-bottom: 7px solid transparent;
-      border-right: rgba(0, 0, 0, 0.1) 8px solid;
-      top: -7px;
-      right: -7px;
-    }
-  }
-  .highlighted {
-    z-index: -1;
-    box-shadow: 0 0 2px 1px gray;
-  }
-
-  .content {
-    margin: 0 2ch;
-    padding: 3px 0;
-    max-width: 20ch;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    white-space: nowrap;
-    // pointer-events: none;
-  }
-
-  .handleRight {
-    position: relative;
-    top: 25%;
-    border: 0px;
-    border-radius: 0px;
-
-    background: transparent;
-    transform-origin: center;
-
-    width: 0;
-    height: 0;
-    border-top: 5px solid transparent;
-    border-bottom: 5px solid transparent;
-    border-left: rgba(255, 255, 255, 0.7) 6px solid;
-
-    &::after {
-      content: '';
-      display: block;
-      position: absolute;
-      width: 0;
-      height: 0;
-      border-top: 7px solid transparent;
-      border-bottom: 7px solid transparent;
-      border-left: rgba(0, 0, 0, 0.1) 8px solid;
-      top: -7px;
-      left: -7px;
-    }
-  }
-}
-
-$height: 10px;
-.arrowLeft {
-  z-index: 2;
-  width: 0;
-  height: 0;
-  border-top: $height solid transparent;
-  border-bottom: $height solid transparent;
-  transform: scale(1.028) translate(0.3px, 0px);
-
-  border-right: $height solid;
-}
-
-.arrowRight {
-  width: 0;
-  height: 0;
-  border-top: $height solid transparent;
-  border-bottom: $height solid transparent;
-  transform: scale(1.02) translate(-0.3px, 0px);
-
-  border-left: $height solid;
-}
diff --git a/libs/shared/lib/ui/pills/customFlowPills/relationpill/relationpill.module.scss.d.ts b/libs/shared/lib/ui/pills/customFlowPills/relationpill/relationpill.module.scss.d.ts
deleted file mode 100644
index 68ba73f84e0f485df7403105d19c5b1eb2018f97..0000000000000000000000000000000000000000
--- a/libs/shared/lib/ui/pills/customFlowPills/relationpill/relationpill.module.scss.d.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-declare const classNames: {
-  readonly relation: 'relation';
-  readonly highlighted: 'highlighted';
-  readonly contentWrapper: 'contentWrapper';
-  readonly handleLeft: 'handleLeft';
-  readonly content: 'content';
-  readonly handleRight: 'handleRight';
-  readonly arrowLeft: 'arrowLeft';
-  readonly arrowRight: 'arrowRight';
-};
-export = classNames;
diff --git a/libs/shared/lib/ui/pills/customFlowPills/relationpill/relationpill.tsx b/libs/shared/lib/ui/pills/customFlowPills/relationpill/relationpill.tsx
deleted file mode 100644
index 7e81ade7c6a0de0669fe20804caeaa3f13974730..0000000000000000000000000000000000000000
--- a/libs/shared/lib/ui/pills/customFlowPills/relationpill/relationpill.tsx
+++ /dev/null
@@ -1,114 +0,0 @@
-import React, { memo } from 'react';
-
-import { handles } from '@graphpolaris/shared/lib/querybuilder/usecases';
-import { useTheme } from '@mui/material';
-import { Handle, Position } from 'reactflow';
-import cn from 'classnames';
-
-import styles from './relationpill.module.scss';
-
-export type RelationRFPillProps = {
-  data: {
-    name: string;
-    suggestedForConnection: any;
-    isFromEntityConnected?: boolean;
-    isToEntityConnected?: boolean;
-  };
-};
-
-/**
- * Component to render a relation flow element
- * @param { FlowElement<RelationData>} param0 The data of a relation flow element.
- */
-export const RelationRFPill = memo(({ data }: RelationRFPillProps) => {
-  // export default function RelationRFPill({ data }: { data: any }) {
-  const theme = useTheme();
-  console.log('RelationRFPill', data);
-
-  // const minRef = useRef<HTMLInputElement>(null);
-  // const maxRef = useRef<HTMLInputElement>(null);
-
-  // const [readOnlyMin, setReadOnlyMin] = useState(true);
-  // const [readOnlyMax, setReadOnlyMax] = useState(true);
-
-  // const onDepthChanged = (depth: string) => {
-  //   // Don't allow depth above 99
-  //   const limit = 99;
-  //   if (data != undefined) {
-  //     data.depth.min = data.depth.min >= limit ? limit : data.depth.min;
-  //     data.depth.max = data.depth.max >= limit ? limit : data.depth.max;
-
-  //     // Check for for valid depth: min <= max
-  //     if (depth == 'min') {
-  //       if (data.depth.min > data.depth.max) data.depth.max = data.depth.min;
-  //       setReadOnlyMin(true);
-  //     } else if (depth == 'max') {
-  //       if (data.depth.max < data.depth.min) data.depth.min = data.depth.max;
-  //       setReadOnlyMax(true);
-  //     }
-
-  //     // Set to the correct width
-  //     if (maxRef.current)
-  //       maxRef.current.style.maxWidth = calcWidth(data.depth.max);
-  //     if (minRef.current)
-  //       minRef.current.style.maxWidth = calcWidth(data.depth.min);
-  //   }
-  // };
-
-  // const calcWidth = (data: number) => {
-  //   return data.toString().length + 0.5 + 'ch';
-  // };
-
-  return (
-    <div className={styles['relation']}>
-      <div
-        className={styles['arrowLeft']}
-        style={{
-          borderRightColor:
-            theme.palette.custom.queryBuilder.relation.background,
-        }}
-      />
-      <div
-        className={cn(styles['contentWrapper'], {
-          [styles['highlighted']]: data.suggestedForConnection,
-        })}
-        style={{
-          color: theme.palette.custom.queryBuilder.text,
-          background: theme.palette.custom.queryBuilder.relation.background,
-        }}
-      >
-        <Handle
-          id={handles.relation.fromEntity}
-          type="target"
-          position={Position.Left}
-          className={styles['handleLeft']}
-          style={
-            data?.isFromEntityConnected ? { borderRightColor: '#2e2e2e' } : {} // TODO: this should be color from theme
-          }
-        />
-        <span className={styles['content']} title={data.name}>
-          {data.name}
-        </span>
-        <Handle
-          id={handles.relation.toEntity}
-          type="source"
-          position={Position.Right}
-          className={styles['handleRight']}
-          style={
-            data?.isToEntityConnected ? { borderLeftColor: '#2e2e2e' } : {}
-          }
-        />
-      </div>
-      <div
-        className={styles['arrowRight']}
-        style={{
-          borderLeftColor:
-            theme.palette.custom.queryBuilder.relation.background,
-        }}
-      />
-    </div>
-  );
-});
-
-RelationRFPill.displayName = 'RelationRFPill';
-export default RelationRFPill;
diff --git a/libs/shared/lib/ui/pills/shared-ui-pills.spec.tsx b/libs/shared/lib/ui/pills/shared-ui-pills.spec.tsx
deleted file mode 100644
index 11b5289db01a4cb302743b4238d3eeae76baca8f..0000000000000000000000000000000000000000
--- a/libs/shared/lib/ui/pills/shared-ui-pills.spec.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { render } from "@testing-library/react";
-import { assert, describe, expect, it } from "vitest";
-
-import SharedUiPills from "./shared-ui-pills";
-
-describe("SharedUiPills", () => {
-  it("should render successfully", () => {
-    const { baseElement } = render(<SharedUiPills />);
-    expect(baseElement).toBeTruthy();
-  });
-});
diff --git a/libs/shared/lib/ui/pills/shared-ui-pills.tsx b/libs/shared/lib/ui/pills/shared-ui-pills.tsx
deleted file mode 100644
index 6a804d611fbd303b2d569e6c44d76d7810116ca8..0000000000000000000000000000000000000000
--- a/libs/shared/lib/ui/pills/shared-ui-pills.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import './shared-ui-pills.module.scss';
-
-/* eslint-disable-next-line */
-export interface SharedUiPillsProps {}
-
-export function SharedUiPills(props: SharedUiPillsProps) {
-  return (
-    <div>
-      <h1>Welcome to SharedUiPills!</h1>
-    </div>
-  );
-}
-
-export default SharedUiPills;
diff --git a/libs/shared/package.json b/libs/shared/package.json
index f5d77dbee732734934bbf9c3d7f895e73a9abdaf..717ce13fa739af63f20a7c5a57a870df30cf00e2 100644
--- a/libs/shared/package.json
+++ b/libs/shared/package.json
@@ -43,7 +43,7 @@
     "react-grid-layout": "^1.3.4",
     "react-json-view": "^1.21.3",
     "react-router-dom": "^6.8.1",
-    "reactflow": "next",
+    "reactflow": "^11.7.0",
     "regenerator-runtime": "0.13.11",
     "sass": "^1.59.3",
     "scss": "^0.2.4",
diff --git a/libs/storybook/.storybook/main.ts b/libs/storybook/.storybook/main.ts
index f4ed50e661f460aca8ddbf3cf30d2588e394e0dd..e2b95a49acaf80b8c4bd6b9a599864697ee57f62 100644
--- a/libs/storybook/.storybook/main.ts
+++ b/libs/storybook/.storybook/main.ts
@@ -9,7 +9,8 @@ const config: StorybookConfig = {
     // "../src/**/*.stories.@(js|jsx|ts|tsx)",
     // "../node_modules/@graphpolaris/**/*.stories.@(js|jsx|ts|tsx)"
     "../node_modules/@graphpolaris/shared/lib/**/*.stories.@(js|jsx|ts|tsx)",
-    "../../../apps/web/src/**/*.stories.@(js|jsx|ts|tsx)",
+    // "../node_modules/web/src/**/*.stories.@(js|jsx|ts|tsx)",
+    // "../../../apps/web/src/**/*.stories.@(js|jsx|ts|tsx)",
   ],
   addons: [
     "@storybook/addon-links",
@@ -18,10 +19,10 @@ const config: StorybookConfig = {
     {
       name: '@storybook/addon-styling',
       options: {
-        sass: {
-          // Require your Sass preprocessor here
-          implementation: require('sass'),
-        },
+        // sass: {
+        // Require your Sass preprocessor here
+        // implementation: require('sass'),
+        // },
       },
     },
     {
diff --git a/libs/storybook/package.json b/libs/storybook/package.json
index 4ae25ae4255dedc0484cb2607ade11962348fc2f..30a556d7485f8639ca3dc720e1c0e84f1d5d823e 100644
--- a/libs/storybook/package.json
+++ b/libs/storybook/package.json
@@ -10,21 +10,21 @@
   },
   "dependencies": {
     "@graphpolaris/shared": "workspace:*",
+    "web": "workspace:*",
     "postcss-scss": "^4.0.6",
     "react": "^18.2.0",
-    "react-dom": "^18.2.0",
-    "ui": "workspace:*"
+    "react-dom": "^18.2.0"
   },
   "devDependencies": {
-    "@storybook/addon-essentials": "7.0.0-rc.5",
-    "@storybook/addon-interactions": "7.0.0-rc.5",
-    "@storybook/addon-links": "7.0.0-rc.5",
-    "@storybook/addon-styling": "^0.3.2",
-    "@storybook/blocks": "7.0.0-rc.5",
+    "@storybook/addon-essentials": "next",
+    "@storybook/addon-interactions": "next",
+    "@storybook/addon-links": "^7.0.7",
+    "@storybook/addon-styling": "^1.0.5",
+    "@storybook/blocks": "^7.0.7",
     "@storybook/preset-scss": "^1.0.3",
-    "@storybook/react": "7.0.0-rc.5",
-    "@storybook/react-vite": "7.0.0-rc.5",
-    "@storybook/testing-library": "0.0.14-next.1",
+    "@storybook/react": "^7.0.7",
+    "@storybook/react-vite": "^7.0.7",
+    "@storybook/testing-library": "0.1.0",
     "@types/node": "18.13.0",
     "@types/react": "^18.0.28",
     "@types/react-dom": "^18.0.11",
@@ -36,7 +36,7 @@
     "prop-types": "15.8.1",
     "sass": "^1.59.3",
     "sass-loader": "^13.2.2",
-    "storybook": "7.0.0-rc.5",
+    "storybook": "^7.0.7",
     "typescript": "^4.9.3",
     "vite": "^4.2.0",
     "vite-plugin-sass-dts": "^1.3.2",
diff --git a/libs/workspace/ui/Button.tsx b/libs/workspace/ui/Button.tsx
deleted file mode 100644
index 61e9000e045c2b74bea925ddb11f2ce061f51521..0000000000000000000000000000000000000000
--- a/libs/workspace/ui/Button.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-interface Props {
-  primary?: boolean;
-  size?: "small" | "large";
-  label?: string;
-}
-
-export const Button = ({
-  primary = false,
-  label = "Boop",
-  size = "small",
-}: Props) => {
-  return (
-    <button
-      style={{
-        backgroundColor: primary ? "red" : "blue",
-        fontSize: size === "large" ? "24px" : "14px",
-      }}
-    >
-      {label}
-    </button>
-  );
-};
diff --git a/libs/workspace/ui/index.tsx b/libs/workspace/ui/index.tsx
deleted file mode 100644
index 916730e8fa531cefbf8435583bd6d68670717a66..0000000000000000000000000000000000000000
--- a/libs/workspace/ui/index.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-import * as React from "react";
-export * from "./Button";
diff --git a/libs/workspace/ui/package.json b/libs/workspace/ui/package.json
deleted file mode 100644
index 17b3a320abe3fe6efa54c20ed8cfd429721c19dd..0000000000000000000000000000000000000000
--- a/libs/workspace/ui/package.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "name": "ui",
-  "version": "0.0.0",
-  "main": "./index.tsx",
-  "types": "./index.tsx",
-  "license": "MIT",
-  "scripts": {
-    "lint": "eslint *.ts*"
-  },
-  "devDependencies": {
-    "@types/react": "^18.0.17",
-    "@types/react-dom": "^18.0.6",
-    "eslint": "^7.32.0",
-    "eslint-config-custom": "workspace:*",
-    "react": "^18.2.0",
-    "tsconfig": "workspace:*",
-    "typescript": "^4.5.2"
-  }
-}
diff --git a/libs/workspace/ui/tsconfig.json b/libs/workspace/ui/tsconfig.json
deleted file mode 100644
index cd6c94d6e8b0c3b34c21ef652ef4d56c64b4a5df..0000000000000000000000000000000000000000
--- a/libs/workspace/ui/tsconfig.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "extends": "tsconfig/react-library.json",
-  "include": ["."],
-  "exclude": ["dist", "build", "node_modules"]
-}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2053e84891e1902b85e8c9bceb9cc1f130c683be..14b92d621f83e7320fbe089587bac34e31210e2b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -21,10 +21,10 @@ importers:
         version: 8.0.3
       prettier:
         specifier: latest
-        version: 2.8.7
+        version: 2.8.8
       turbo:
         specifier: latest
-        version: 1.8.8
+        version: 1.9.3
 
   apps/web:
     dependencies:
@@ -34,6 +34,9 @@ importers:
       '@mui/base':
         specifier: 5.0.0-alpha.118
         version: 5.0.0-alpha.118(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
+      '@mui/icons-material':
+        specifier: ^5.11.11
+        version: 5.11.11(@mui/material@5.11.13)(@types/react@18.0.28)(react@18.2.0)
       '@mui/material':
         specifier: ^5.11.13
         version: 5.11.13(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
@@ -83,6 +86,9 @@ importers:
       '@types/styled-components':
         specifier: ^5.1.26
         version: 5.1.26
+      '@vitejs/plugin-basic-ssl':
+        specifier: ^1.0.1
+        version: 1.0.1(vite@4.2.1)
       '@vitejs/plugin-react-swc':
         specifier: ^3.0.0
         version: 3.2.0(vite@4.2.1)
@@ -97,7 +103,10 @@ importers:
         version: 4.9.5
       vite:
         specifier: ^4.2.0
-        version: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+        version: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
+      vite-plugin-dts:
+        specifier: ^2.1.0
+        version: 2.1.0(@types/node@18.13.0)(vite@4.2.1)
       vitest:
         specifier: ^0.29.2
         version: 0.29.4(happy-dom@8.9.0)(jsdom@21.1.1)(sass@1.59.3)
@@ -189,8 +198,8 @@ importers:
         specifier: ^6.8.1
         version: 6.9.0(react-dom@18.2.0)(react@18.2.0)
       reactflow:
-        specifier: next
-        version: 11.4.0-next.1(react-dom@18.2.0)(react@18.2.0)
+        specifier: ^11.7.0
+        version: 11.7.0(react-dom@18.2.0)(react@18.2.0)
       regenerator-runtime:
         specifier: 0.13.11
         version: 0.13.11
@@ -212,7 +221,7 @@ importers:
     devDependencies:
       '@storybook/addon-styling':
         specifier: ^0.3.2
-        version: 0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.0-rc.5)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2)
+        version: 0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.7)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2)
       '@storybook/preset-scss':
         specifier: ^1.0.3
         version: 1.0.3(css-loader@6.7.3)(sass-loader@13.2.2)(style-loader@3.3.2)
@@ -353,7 +362,7 @@ importers:
         version: 4.1.1(webpack@5.77.0)
       vite:
         specifier: ^4.1.0
-        version: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+        version: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
       vite-plugin-dts:
         specifier: ^2.1.0
         version: 2.1.0(@types/node@18.13.0)(vite@4.2.1)
@@ -381,37 +390,37 @@ importers:
       react-dom:
         specifier: ^18.2.0
         version: 18.2.0(react@18.2.0)
-      ui:
+      web:
         specifier: workspace:*
-        version: link:../workspace/ui
+        version: link:../../apps/web
     devDependencies:
       '@storybook/addon-essentials':
-        specifier: 7.0.0-rc.5
+        specifier: next
         version: 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)
       '@storybook/addon-interactions':
-        specifier: 7.0.0-rc.5
+        specifier: next
         version: 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)
       '@storybook/addon-links':
-        specifier: 7.0.0-rc.5
-        version: 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)
+        specifier: ^7.0.7
+        version: 7.0.7(react-dom@18.2.0)(react@18.2.0)
       '@storybook/addon-styling':
-        specifier: ^0.3.2
-        version: 0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.0-rc.5)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2)
+        specifier: ^1.0.5
+        version: 1.0.5(less@4.1.3)(postcss@8.4.21)(react-dom@18.2.0)(react@18.2.0)(sass@1.59.3)(webpack@5.77.0)
       '@storybook/blocks':
-        specifier: 7.0.0-rc.5
-        version: 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)
+        specifier: ^7.0.7
+        version: 7.0.7(react-dom@18.2.0)(react@18.2.0)
       '@storybook/preset-scss':
         specifier: ^1.0.3
         version: 1.0.3(css-loader@6.7.3)(sass-loader@13.2.2)(style-loader@3.3.2)
       '@storybook/react':
-        specifier: 7.0.0-rc.5
-        version: 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)
+        specifier: ^7.0.7
+        version: 7.0.7(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)
       '@storybook/react-vite':
-        specifier: 7.0.0-rc.5
-        version: 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)(vite@4.2.1)
+        specifier: ^7.0.7
+        version: 7.0.7(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)(vite@4.2.1)
       '@storybook/testing-library':
-        specifier: 0.0.14-next.1
-        version: 0.0.14-next.1
+        specifier: 0.1.0
+        version: 0.1.0
       '@types/node':
         specifier: 18.13.0
         version: 18.13.0
@@ -446,17 +455,17 @@ importers:
         specifier: ^13.2.2
         version: 13.2.2(sass@1.59.3)(webpack@5.77.0)
       storybook:
-        specifier: 7.0.0-rc.5
-        version: 7.0.0-rc.5
+        specifier: ^7.0.7
+        version: 7.0.7
       typescript:
         specifier: ^4.9.3
         version: 4.9.5
       vite:
         specifier: ^4.2.0
-        version: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+        version: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
       vite-plugin-sass-dts:
         specifier: ^1.3.2
-        version: 1.3.2(postcss@8.4.21)(prettier@2.8.7)(sass@1.59.3)(vite@4.2.1)
+        version: 1.3.2(postcss@8.4.21)(prettier@2.8.8)(sass@1.59.3)(vite@4.2.1)
       vite-tsconfig-paths:
         specifier: ^4.0.7
         version: 4.0.7(typescript@4.9.5)(vite@4.2.1)
@@ -485,30 +494,6 @@ importers:
 
   libs/workspace/tsconfig: {}
 
-  libs/workspace/ui:
-    devDependencies:
-      '@types/react':
-        specifier: ^18.0.17
-        version: 18.0.28
-      '@types/react-dom':
-        specifier: ^18.0.6
-        version: 18.0.11
-      eslint:
-        specifier: ^7.32.0
-        version: 7.32.0
-      eslint-config-custom:
-        specifier: workspace:*
-        version: link:../eslint-config-custom
-      react:
-        specifier: ^18.2.0
-        version: 18.2.0
-      tsconfig:
-        specifier: workspace:*
-        version: link:../tsconfig
-      typescript:
-        specifier: ^4.5.2
-        version: 4.9.5
-
 packages:
 
   /@ampproject/remapping@2.2.0:
@@ -537,8 +522,8 @@ packages:
     dependencies:
       '@babel/highlight': 7.18.6
 
-  /@babel/compat-data@7.21.0:
-    resolution: {integrity: sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==}
+  /@babel/compat-data@7.21.4:
+    resolution: {integrity: sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==}
     engines: {node: '>=6.9.0'}
     dev: true
 
@@ -549,13 +534,13 @@ packages:
       '@ampproject/remapping': 2.2.0
       '@babel/code-frame': 7.18.6
       '@babel/generator': 7.21.3
-      '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.21.3)
+      '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.3)
       '@babel/helper-module-transforms': 7.21.2
       '@babel/helpers': 7.21.0
       '@babel/parser': 7.21.3
       '@babel/template': 7.20.7
       '@babel/traverse': 7.21.3(supports-color@5.5.0)
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
       convert-source-map: 1.9.0
       debug: 4.3.4(supports-color@5.5.0)
       gensync: 1.0.0-beta.2
@@ -569,7 +554,7 @@ packages:
     resolution: {integrity: sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
       '@jridgewell/gen-mapping': 0.3.2
       '@jridgewell/trace-mapping': 0.3.17
       jsesc: 2.5.2
@@ -578,23 +563,23 @@ packages:
     resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
 
   /@babel/helper-builder-binary-assignment-operator-visitor@7.18.9:
     resolution: {integrity: sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/helper-explode-assignable-expression': 7.18.6
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     dev: true
 
-  /@babel/helper-compilation-targets@7.20.7(@babel/core@7.21.3):
-    resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==}
+  /@babel/helper-compilation-targets@7.21.4(@babel/core@7.21.3):
+    resolution: {integrity: sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
     dependencies:
-      '@babel/compat-data': 7.21.0
+      '@babel/compat-data': 7.21.4
       '@babel/core': 7.21.3
       '@babel/helper-validator-option': 7.21.0
       browserslist: 4.21.5
@@ -638,7 +623,7 @@ packages:
       '@babel/core': ^7.4.0-0
     dependencies:
       '@babel/core': 7.21.3
-      '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.21.3)
+      '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.3)
       '@babel/helper-plugin-utils': 7.20.2
       debug: 4.3.4(supports-color@5.5.0)
       lodash.debounce: 4.0.8
@@ -656,7 +641,7 @@ packages:
     resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     dev: true
 
   /@babel/helper-function-name@7.21.0:
@@ -664,26 +649,26 @@ packages:
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/template': 7.20.7
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
 
   /@babel/helper-hoist-variables@7.18.6:
     resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
 
   /@babel/helper-member-expression-to-functions@7.21.0:
     resolution: {integrity: sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     dev: true
 
   /@babel/helper-module-imports@7.18.6:
     resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
 
   /@babel/helper-module-transforms@7.21.2:
     resolution: {integrity: sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==}
@@ -696,7 +681,7 @@ packages:
       '@babel/helper-validator-identifier': 7.19.1
       '@babel/template': 7.20.7
       '@babel/traverse': 7.21.3(supports-color@5.5.0)
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -705,7 +690,7 @@ packages:
     resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     dev: true
 
   /@babel/helper-plugin-utils@7.20.2:
@@ -723,7 +708,7 @@ packages:
       '@babel/helper-annotate-as-pure': 7.18.6
       '@babel/helper-environment-visitor': 7.18.9
       '@babel/helper-wrap-function': 7.20.5
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -737,7 +722,7 @@ packages:
       '@babel/helper-optimise-call-expression': 7.18.6
       '@babel/template': 7.20.7
       '@babel/traverse': 7.21.3(supports-color@5.5.0)
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -746,21 +731,21 @@ packages:
     resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     dev: true
 
   /@babel/helper-skip-transparent-expression-wrappers@7.20.0:
     resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     dev: true
 
   /@babel/helper-split-export-declaration@7.18.6:
     resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
 
   /@babel/helper-string-parser@7.19.4:
     resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==}
@@ -782,7 +767,7 @@ packages:
       '@babel/helper-function-name': 7.21.0
       '@babel/template': 7.20.7
       '@babel/traverse': 7.21.3(supports-color@5.5.0)
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -793,7 +778,7 @@ packages:
     dependencies:
       '@babel/template': 7.20.7
       '@babel/traverse': 7.21.3(supports-color@5.5.0)
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -811,7 +796,7 @@ packages:
     engines: {node: '>=6.0.0'}
     hasBin: true
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
 
   /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.18.6(@babel/core@7.21.3):
     resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==}
@@ -949,9 +934,9 @@ packages:
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/compat-data': 7.21.0
+      '@babel/compat-data': 7.21.4
       '@babel/core': 7.21.3
-      '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.21.3)
+      '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.3)
       '@babel/helper-plugin-utils': 7.20.2
       '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.21.3)
       '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.21.3)
@@ -1240,7 +1225,7 @@ packages:
     dependencies:
       '@babel/core': 7.21.3
       '@babel/helper-annotate-as-pure': 7.18.6
-      '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.21.3)
+      '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.3)
       '@babel/helper-environment-visitor': 7.18.9
       '@babel/helper-function-name': 7.21.0
       '@babel/helper-optimise-call-expression': 7.18.6
@@ -1333,7 +1318,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.21.3
-      '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.21.3)
+      '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.3)
       '@babel/helper-function-name': 7.21.0
       '@babel/helper-plugin-utils': 7.20.2
     dev: true
@@ -1498,7 +1483,7 @@ packages:
       '@babel/helper-module-imports': 7.18.6
       '@babel/helper-plugin-utils': 7.20.2
       '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.21.3)
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     dev: true
 
   /@babel/plugin-transform-regenerator@7.20.5(@babel/core@7.21.3):
@@ -1609,15 +1594,15 @@ packages:
       '@babel/helper-plugin-utils': 7.20.2
     dev: true
 
-  /@babel/preset-env@7.20.2(@babel/core@7.21.3):
-    resolution: {integrity: sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==}
+  /@babel/preset-env@7.21.4(@babel/core@7.21.3):
+    resolution: {integrity: sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/compat-data': 7.21.0
+      '@babel/compat-data': 7.21.4
       '@babel/core': 7.21.3
-      '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.21.3)
+      '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.3)
       '@babel/helper-plugin-utils': 7.20.2
       '@babel/helper-validator-option': 7.21.0
       '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6(@babel/core@7.21.3)
@@ -1685,7 +1670,7 @@ packages:
       '@babel/plugin-transform-unicode-escapes': 7.18.10(@babel/core@7.21.3)
       '@babel/plugin-transform-unicode-regex': 7.18.6(@babel/core@7.21.3)
       '@babel/preset-modules': 0.1.5(@babel/core@7.21.3)
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
       babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.21.3)
       babel-plugin-polyfill-corejs3: 0.6.0(@babel/core@7.21.3)
       babel-plugin-polyfill-regenerator: 0.4.1(@babel/core@7.21.3)
@@ -1716,7 +1701,7 @@ packages:
       '@babel/helper-plugin-utils': 7.20.2
       '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.21.3)
       '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.21.3)
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
       esutils: 2.0.3
     dev: true
 
@@ -1764,7 +1749,7 @@ packages:
     dependencies:
       '@babel/code-frame': 7.18.6
       '@babel/parser': 7.21.3
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
 
   /@babel/traverse@7.21.3(supports-color@5.5.0):
     resolution: {integrity: sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==}
@@ -1777,14 +1762,14 @@ packages:
       '@babel/helper-hoist-variables': 7.18.6
       '@babel/helper-split-export-declaration': 7.18.6
       '@babel/parser': 7.21.3
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
       debug: 4.3.4(supports-color@5.5.0)
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
 
-  /@babel/types@7.21.3:
-    resolution: {integrity: sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==}
+  /@babel/types@7.21.4:
+    resolution: {integrity: sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/helper-string-parser': 7.19.4
@@ -2642,7 +2627,7 @@ packages:
       magic-string: 0.27.0
       react-docgen-typescript: 2.2.2(typescript@4.9.5)
       typescript: 4.9.5
-      vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+      vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
     dev: true
 
   /@jridgewell/gen-mapping@0.1.1:
@@ -3349,6 +3334,21 @@ packages:
       - immer
     dev: false
 
+  /@reactflow/background@11.2.0(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-Fd8Few2JsLuE/2GaIM6fkxEBaAJvfzi2Lc106HKi/ddX+dZs8NUsSwMsJy1Ajs8b4GbiX8v8axfKpbK6qFMV8w==}
+    peerDependencies:
+      react: '>=17'
+      react-dom: '>=17'
+    dependencies:
+      '@reactflow/core': 11.7.0(react-dom@18.2.0)(react@18.2.0)
+      classcat: 5.0.4
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+      zustand: 4.3.6(react@18.2.0)
+    transitivePeerDependencies:
+      - immer
+    dev: false
+
   /@reactflow/controls@11.1.0-next.1(react-dom@18.2.0)(react@18.2.0):
     resolution: {integrity: sha512-jqvwxI9VFc4ZPBfZE98MigwE+UJbxLHBC47y0pt1bGqnxzK1XcAMocDVcvlTMbHWbDmouFmpk+cUoYSkQx5/cQ==}
     peerDependencies:
@@ -3364,6 +3364,20 @@ packages:
       - immer
     dev: false
 
+  /@reactflow/controls@11.1.11(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-g6WrsszhNkQjzkJ9HbVUBkGGoUy2z8dQVgH6CYQEjuoonD15cWAPGvjyg8vx8oGG7CuktUhWu5JPivL6qjECow==}
+    peerDependencies:
+      react: '>=17'
+      react-dom: '>=17'
+    dependencies:
+      '@reactflow/core': 11.7.0(react-dom@18.2.0)(react@18.2.0)
+      classcat: 5.0.4
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+    transitivePeerDependencies:
+      - immer
+    dev: false
+
   /@reactflow/core@11.4.0-next.1(react-dom@18.2.0)(react@18.2.0):
     resolution: {integrity: sha512-OgHMl9qs7ZMidoc+pUcZ4O1TxszrpW0jcb2tZQOfB5WpJL40HmwXrGYZdk9IhG1ANo4N0nwS5MBvho2Ddo7aSw==}
     peerDependencies:
@@ -3406,6 +3420,27 @@ packages:
       - immer
     dev: false
 
+  /@reactflow/core@11.7.0(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-UJcpbNRSupSSoMWh5UmRp6UUr0ug7xVKmMvadnkKKiNi9584q57nz4HMfkqwN3/ESbre7LD043yh2n678d/5FQ==}
+    peerDependencies:
+      react: '>=17'
+      react-dom: '>=17'
+    dependencies:
+      '@types/d3': 7.4.0
+      '@types/d3-drag': 3.0.2
+      '@types/d3-selection': 3.0.5
+      '@types/d3-zoom': 3.0.2
+      classcat: 5.0.4
+      d3-drag: 3.0.0
+      d3-selection: 3.0.0
+      d3-zoom: 3.0.0
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+      zustand: 4.3.6(react@18.2.0)
+    transitivePeerDependencies:
+      - immer
+    dev: false
+
   /@reactflow/minimap@11.3.0-next.1(react-dom@18.2.0)(react@18.2.0):
     resolution: {integrity: sha512-ZNo6oLTKSLHO/rdfribRO5pmBMWT8Y5Hbn5zKkzJgjPKmaa7sG6ZjuOJNBz4LuKy7GrP5Uu2wGSc8svxNvYogA==}
     peerDependencies:
@@ -3426,6 +3461,25 @@ packages:
       - immer
     dev: false
 
+  /@reactflow/minimap@11.5.0(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-n/3tlaknLpi3zaqCC+tDDPvUTOjd6jglto9V3RB1F2wlaUEbCwmuoR2GYTkiRyZMvuskKyAoQW8+0DX0+cWwsA==}
+    peerDependencies:
+      react: '>=17'
+      react-dom: '>=17'
+    dependencies:
+      '@reactflow/core': 11.7.0(react-dom@18.2.0)(react@18.2.0)
+      '@types/d3-selection': 3.0.5
+      '@types/d3-zoom': 3.0.2
+      classcat: 5.0.4
+      d3-selection: 3.0.0
+      d3-zoom: 3.0.0
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+      zustand: 4.3.6(react@18.2.0)
+    transitivePeerDependencies:
+      - immer
+    dev: false
+
   /@reactflow/node-resizer@2.1.0(react-dom@18.2.0)(react@18.2.0):
     resolution: {integrity: sha512-DVL8nnWsltP8/iANadAcTaDB4wsEkx2mOLlBEPNE3yc5loSm3u9l5m4enXRcBym61MiMuTtDPzZMyYYQUjuYIg==}
     peerDependencies:
@@ -3459,6 +3513,21 @@ packages:
       - immer
     dev: false
 
+  /@reactflow/node-toolbar@1.1.11(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-+hKtx+cvXwfCa9paGxE+G34rWRIIVEh68ZOqAtivClVmfqGzH/sEoGWtIOUyg9OEDNE1nEmZ1NrnpBGSmHHXFg==}
+    peerDependencies:
+      react: '>=17'
+      react-dom: '>=17'
+    dependencies:
+      '@reactflow/core': 11.7.0(react-dom@18.2.0)(react@18.2.0)
+      classcat: 5.0.4
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+      zustand: 4.3.6(react@18.2.0)
+    transitivePeerDependencies:
+      - immer
+    dev: false
+
   /@reduxjs/toolkit@1.9.3(react-redux@8.0.5)(react@18.2.0):
     resolution: {integrity: sha512-GU2TNBQVofL09VGmuSioNPQIu6Ml0YLf4EJhgj0AvBadRlCGzUWet8372LjvO4fqKZF2vH1xU0htAa7BrK9pZg==}
     peerDependencies:
@@ -3650,7 +3719,7 @@ packages:
       '@storybook/csf-plugin': 7.0.0-rc.5
       '@storybook/csf-tools': 7.0.0-rc.5
       '@storybook/global': 5.0.0
-      '@storybook/mdx2-csf': 1.0.0-next.6
+      '@storybook/mdx2-csf': 1.1.0-next.1
       '@storybook/node-logger': 7.0.0-rc.5
       '@storybook/postinstall': 7.0.0-rc.5
       '@storybook/preview-api': 7.0.0-rc.5
@@ -3732,8 +3801,8 @@ packages:
       - supports-color
     dev: true
 
-  /@storybook/addon-links@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0):
-    resolution: {integrity: sha512-MyfufFES3iNf/6fP/nTgB8op3v5jUWPvguo/L8mREUk2LfjB8KNmQuJolM4RzrKOl6cOcD6vZlqaVkuLiOSPYA==}
+  /@storybook/addon-links@7.0.7(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-DEjDxjHb3mT8Sdnx4In5Ev9gJ/XdjlHOq4iuy0wnMyrCV4wnzTQnIeSCx8nkrXFb314zc33JPnCcrb5pQoD5GQ==}
     peerDependencies:
       react: ^16.8.0 || ^17.0.0 || ^18.0.0
       react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -3743,14 +3812,14 @@ packages:
       react-dom:
         optional: true
     dependencies:
-      '@storybook/client-logger': 7.0.0-rc.5
-      '@storybook/core-events': 7.0.0-rc.5
-      '@storybook/csf': 0.0.2-next.11
+      '@storybook/client-logger': 7.0.7
+      '@storybook/core-events': 7.0.7
+      '@storybook/csf': 0.1.0
       '@storybook/global': 5.0.0
-      '@storybook/manager-api': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)
-      '@storybook/preview-api': 7.0.0-rc.5
-      '@storybook/router': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)
-      '@storybook/types': 7.0.0-rc.5
+      '@storybook/manager-api': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/preview-api': 7.0.7
+      '@storybook/router': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/types': 7.0.7
       prop-types: 15.8.1
       react: 18.2.0
       react-dom: 18.2.0(react@18.2.0)
@@ -3802,7 +3871,7 @@ packages:
       ts-dedent: 2.2.0
     dev: true
 
-  /@storybook/addon-styling@0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.0-rc.5)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2):
+  /@storybook/addon-styling@0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.7)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2):
     resolution: {integrity: sha512-ztKy9uU2yKBtvBp4/Km4LD1JCNNFHpXS33LjbeIfho0toRv100g8tUojrdnoRX1b2KVK6cqep5mJV0z2ak9hIQ==}
     peerDependencies:
       '@storybook/addons': ^6.5.8
@@ -3829,13 +3898,50 @@ packages:
       '@storybook/api': 6.5.16(react-dom@18.2.0)(react@18.2.0)
       '@storybook/components': 6.5.16(react-dom@18.2.0)(react@18.2.0)
       '@storybook/core-events': 6.5.16
-      '@storybook/manager-api': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/manager-api': 7.0.7(react-dom@18.2.0)(react@18.2.0)
       '@storybook/theming': 6.5.16(react-dom@18.2.0)(react@18.2.0)
       react: 18.2.0
       react-dom: 18.2.0(react@18.2.0)
       sass-loader: 13.2.2(sass@1.59.3)(webpack@5.77.0)
     dev: true
 
+  /@storybook/addon-styling@1.0.5(less@4.1.3)(postcss@8.4.21)(react-dom@18.2.0)(react@18.2.0)(sass@1.59.3)(webpack@5.77.0):
+    resolution: {integrity: sha512-Vh+kzYJnCZOd5FGAXZ4Z0t+c5UXEkSAI1BN0SGu6ps1579uDkH3byWVq+hTEVo2lh0YgSzjs5rppUIoEVQYAzw==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
+    dependencies:
+      '@storybook/api': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/components': 7.0.5(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/core-events': 7.0.7
+      '@storybook/manager-api': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/node-logger': 7.0.7
+      '@storybook/preview-api': 7.0.7
+      '@storybook/theming': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/types': 7.0.7
+      css-loader: 6.7.3(webpack@5.77.0)
+      less-loader: 11.1.0(less@4.1.3)(webpack@5.77.0)
+      postcss-loader: 7.3.0(postcss@8.4.21)(webpack@5.77.0)
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+      resolve-url-loader: 5.0.0
+      sass-loader: 13.2.2(sass@1.59.3)(webpack@5.77.0)
+      style-loader: 3.3.2(webpack@5.77.0)
+    transitivePeerDependencies:
+      - fibers
+      - less
+      - node-sass
+      - postcss
+      - sass
+      - sass-embedded
+      - webpack
+    dev: true
+
   /@storybook/addon-toolbars@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0):
     resolution: {integrity: sha512-GErLxEBVh3HaQEvUNmKlNDcNuEYpGNVT1Nr1Tsc4J8EKG1ivEfQfVu6/5fduPZE8Vt1IUAzrVEp9NYzSELH49Q==}
     peerDependencies:
@@ -3928,6 +4034,23 @@ packages:
       util-deprecate: 1.0.2
     dev: true
 
+  /@storybook/api@7.0.7(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-0++LcK6PX1Z2HsI9fyZyqvmeFrB5NDMcsbmIvJfA2NfK92UW8y7t6Ft2fq/2jUCJcWT8Jp3xpatUvYb28irfwg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
+    dependencies:
+      '@storybook/client-logger': 7.0.7
+      '@storybook/manager-api': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+    dev: true
+
   /@storybook/blocks@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0):
     resolution: {integrity: sha512-9ZGDExwA6DgR/BsFSk2aCe7p/AIIQAiCemV1W1Djp7lt6OOALWfLZ7r1sFUqY9ZgNkfD1N41JpmqJtPDLXejGQ==}
     peerDependencies:
@@ -3962,58 +4085,88 @@ packages:
       - supports-color
     dev: true
 
-  /@storybook/builder-manager@7.0.0-rc.5:
-    resolution: {integrity: sha512-VAtkM9HT9OUl06n/GHzdrcgr2zf1DULbzayy6jJ8HxDHQe8ONM2fe+v8gF0NAcmtEi0i9C381sS7P3pnNAK4Qw==}
+  /@storybook/blocks@7.0.7(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-ehR0hAFWNHHqmrmbwYPKhLpgbIBKtyMbeoGClTRSnrVBGONciYJdmxegkCTReUklCY+HBJjtlwNowT+7+5sSaw==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/channels': 7.0.7
+      '@storybook/client-logger': 7.0.7
+      '@storybook/components': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/core-events': 7.0.7
+      '@storybook/csf': 0.1.0
+      '@storybook/docs-tools': 7.0.7
+      '@storybook/global': 5.0.0
+      '@storybook/manager-api': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/preview-api': 7.0.7
+      '@storybook/theming': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/types': 7.0.7
+      '@types/lodash': 4.14.191
+      color-convert: 2.0.1
+      dequal: 2.0.3
+      lodash: 4.17.21
+      markdown-to-jsx: 7.2.0(react@18.2.0)
+      memoizerific: 1.11.3
+      polished: 4.2.2
+      react: 18.2.0
+      react-colorful: 5.6.1(react-dom@18.2.0)(react@18.2.0)
+      react-dom: 18.2.0(react@18.2.0)
+      telejson: 7.0.4
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@storybook/builder-manager@7.0.7:
+    resolution: {integrity: sha512-VI/0iEjAlzQDt1yKu8GXugNIz7t46IHIKgMNmltQ05KPypMgInUoMmbfP5AYOVddjLdSqjMLO7EK58pBLOInpw==}
     dependencies:
       '@fal-works/esbuild-plugin-global-externals': 2.1.2
-      '@storybook/core-common': 7.0.0-rc.5
-      '@storybook/manager': 7.0.0-rc.5
-      '@storybook/node-logger': 7.0.0-rc.5
+      '@storybook/core-common': 7.0.7
+      '@storybook/manager': 7.0.7
+      '@storybook/node-logger': 7.0.7
       '@types/ejs': 3.1.2
       '@types/find-cache-dir': 3.2.1
-      '@yarnpkg/esbuild-plugin-pnp': 3.0.0-rc.15(esbuild@0.16.17)
+      '@yarnpkg/esbuild-plugin-pnp': 3.0.0-rc.15(esbuild@0.17.12)
       browser-assert: 1.2.1
       ejs: 3.1.9
-      esbuild: 0.16.17
+      esbuild: 0.17.12
       esbuild-plugin-alias: 0.2.1
       express: 4.18.2
       find-cache-dir: 3.3.2
       fs-extra: 11.1.1
       process: 0.11.10
-      slash: 3.0.0
       util: 0.12.5
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@storybook/builder-vite@7.0.0-rc.5(typescript@4.9.5)(vite@4.2.1):
-    resolution: {integrity: sha512-TkT+KaUBHiyFyHQ31qeq3zFM1p5cwffu3orAJRcSWOCHkQy1hbu2H55ZApgZJRHBq9MGxtUZ1FTVYIb3OLv1jg==}
+  /@storybook/builder-vite@7.0.7(typescript@4.9.5)(vite@4.2.1):
+    resolution: {integrity: sha512-2wL6fsFWzij+R155urOLc7EjZtlVWf4FLfaSlLGAuZwRQU40N04YdMaHMp9tjd9Vdr5fxEDwTB51PnVWJMlsEw==}
     peerDependencies:
       '@preact/preset-vite': '*'
-      '@storybook/mdx1-csf': '>=1.0.0-next.1'
       typescript: '>= 4.3.x'
       vite: ^3.0.0 || ^4.0.0
       vite-plugin-glimmerx: '*'
     peerDependenciesMeta:
       '@preact/preset-vite':
         optional: true
-      '@storybook/mdx1-csf':
-        optional: true
       typescript:
         optional: true
       vite-plugin-glimmerx:
         optional: true
     dependencies:
-      '@storybook/channel-postmessage': 7.0.0-rc.5
-      '@storybook/channel-websocket': 7.0.0-rc.5
-      '@storybook/client-logger': 7.0.0-rc.5
-      '@storybook/core-common': 7.0.0-rc.5
-      '@storybook/csf-plugin': 7.0.0-rc.5
-      '@storybook/mdx2-csf': 1.0.0-next.6
-      '@storybook/node-logger': 7.0.0-rc.5
-      '@storybook/preview': 7.0.0-rc.5
-      '@storybook/preview-api': 7.0.0-rc.5
-      '@storybook/types': 7.0.0-rc.5
+      '@storybook/channel-postmessage': 7.0.7
+      '@storybook/channel-websocket': 7.0.7
+      '@storybook/client-logger': 7.0.7
+      '@storybook/core-common': 7.0.7
+      '@storybook/csf-plugin': 7.0.7
+      '@storybook/mdx2-csf': 1.0.0
+      '@storybook/node-logger': 7.0.7
+      '@storybook/preview': 7.0.7
+      '@storybook/preview-api': 7.0.7
+      '@storybook/types': 7.0.7
       browser-assert: 1.2.1
       es-module-lexer: 0.9.3
       express: 4.18.2
@@ -4021,41 +4174,42 @@ packages:
       glob: 8.1.0
       glob-promise: 6.0.2(glob@8.1.0)
       magic-string: 0.27.0
+      remark-external-links: 8.0.0
+      remark-slug: 6.1.0
       rollup: 3.20.0
-      slash: 3.0.0
       typescript: 4.9.5
-      vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+      vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@storybook/channel-postmessage@7.0.0:
-    resolution: {integrity: sha512-Sy3oHL/xDRjUiHnM0ncnkbOE5pK3O72MjOoiLJX4FCI90w03KM4+F/N0eU2cXl6yXHuCyI5eJisEzQxTNsaJiw==}
+  /@storybook/channel-postmessage@7.0.0-rc.5:
+    resolution: {integrity: sha512-NBnIKiACAnLpsVe7bf9B2XE4tH+4HgTJh8Mvj1Dpu1jxu2cJ3j20x3IGgELXCXSEicUbXCqr+O1Zc7CHBXYV+g==}
     dependencies:
-      '@storybook/channels': 7.0.0
-      '@storybook/client-logger': 7.0.0
-      '@storybook/core-events': 7.0.0
+      '@storybook/channels': 7.0.0-rc.5
+      '@storybook/client-logger': 7.0.0-rc.5
+      '@storybook/core-events': 7.0.0-rc.5
       '@storybook/global': 5.0.0
       qs: 6.11.1
       telejson: 7.0.4
     dev: true
 
-  /@storybook/channel-postmessage@7.0.0-rc.5:
-    resolution: {integrity: sha512-NBnIKiACAnLpsVe7bf9B2XE4tH+4HgTJh8Mvj1Dpu1jxu2cJ3j20x3IGgELXCXSEicUbXCqr+O1Zc7CHBXYV+g==}
+  /@storybook/channel-postmessage@7.0.7:
+    resolution: {integrity: sha512-XMtYfcaE0UoY/V7K1cTu9PcWETD4iyWb/Yswc4F9VrPw0Ui4UwGS1j4iaAu8DC06yyoJs4XvxYFBMlCQmKja6A==}
     dependencies:
-      '@storybook/channels': 7.0.0-rc.5
-      '@storybook/client-logger': 7.0.0-rc.5
-      '@storybook/core-events': 7.0.0-rc.5
+      '@storybook/channels': 7.0.7
+      '@storybook/client-logger': 7.0.7
+      '@storybook/core-events': 7.0.7
       '@storybook/global': 5.0.0
       qs: 6.11.1
       telejson: 7.0.4
     dev: true
 
-  /@storybook/channel-websocket@7.0.0-rc.5:
-    resolution: {integrity: sha512-n8oPrbxGS9FtSkNWYMpOtEZedeeVxnxJuiEwApGRkWt0q3eWIK9u24NElIbjCoSysaZl60CXrlK615W+Ml3ujQ==}
+  /@storybook/channel-websocket@7.0.7:
+    resolution: {integrity: sha512-KDbLiQts4/dCow3qk5WJSPA6SlaX3iP9RhF0Fjj03hoG2TRskrvo+AkUiJr8gF6dpkPndfuCYUCRsO2Ml8B+AA==}
     dependencies:
-      '@storybook/channels': 7.0.0-rc.5
-      '@storybook/client-logger': 7.0.0-rc.5
+      '@storybook/channels': 7.0.7
+      '@storybook/client-logger': 7.0.7
       '@storybook/global': 5.0.0
       telejson: 7.0.4
     dev: true
@@ -4068,28 +4222,32 @@ packages:
       util-deprecate: 1.0.2
     dev: true
 
-  /@storybook/channels@7.0.0:
-    resolution: {integrity: sha512-adPIkvL4q37dGTWCpSzV8ETLdkxsg7BAgzeT9pustZJjRIZqAHGUAm7krDtGT7jbV4dU0Zw0VpUrnmyfxIkOKQ==}
-    dev: true
-
   /@storybook/channels@7.0.0-rc.5:
     resolution: {integrity: sha512-/T4iJQsTj42bs+d2sG8aLyInKh1IjZeK0vPoJRK9gvy3YfxTj3yodZ60s2yywKJCgGjg5zJMFxYMWqSVmHIdnw==}
     dev: true
 
-  /@storybook/cli@7.0.0-rc.5:
-    resolution: {integrity: sha512-v0gCsKM2NtNBkhJJ4ZXQcNyasKj8zJxW0KRWpfrECe04ko7wuN8MCsJIZAE4AWQnmtx7OWWVYNrzfTFUEVTs6A==}
+  /@storybook/channels@7.0.5:
+    resolution: {integrity: sha512-WiSPXgOK63jAlDDmbTs1sVXoYe3r/4VjpfwhEcxSPU544YQVARF1ePtiGjlp8HVFhZh1Q7afbVGJ9w96++u98A==}
+    dev: true
+
+  /@storybook/channels@7.0.7:
+    resolution: {integrity: sha512-Om4ovBLNw8pVrBu83MpOKgAuGO9Dpr1Coh2qp8t64WRPkejX1mxOY9IgH723//zH3igx8LCkf9rvBvcrsyaScQ==}
+    dev: true
+
+  /@storybook/cli@7.0.7:
+    resolution: {integrity: sha512-koTkWr7wlaHF14T5moRP/tYM44+Jf4GEzQ/rqx/Jfn7EbNlVUOibdLJj4JnseMGRc7ZP6tKYku2n+B8g7hJX4w==}
     hasBin: true
     dependencies:
       '@babel/core': 7.21.3
-      '@babel/preset-env': 7.20.2(@babel/core@7.21.3)
+      '@babel/preset-env': 7.21.4(@babel/core@7.21.3)
       '@ndelangen/get-tarball': 3.0.7
-      '@storybook/codemod': 7.0.0-rc.5
-      '@storybook/core-common': 7.0.0-rc.5
-      '@storybook/core-server': 7.0.0-rc.5
-      '@storybook/csf-tools': 7.0.0-rc.5
-      '@storybook/node-logger': 7.0.0-rc.5
-      '@storybook/telemetry': 7.0.0-rc.5
-      '@storybook/types': 7.0.0-rc.5
+      '@storybook/codemod': 7.0.7
+      '@storybook/core-common': 7.0.7
+      '@storybook/core-server': 7.0.7
+      '@storybook/csf-tools': 7.0.7
+      '@storybook/node-logger': 7.0.7
+      '@storybook/telemetry': 7.0.7
+      '@storybook/types': 7.0.7
       '@types/semver': 7.3.13
       boxen: 5.1.2
       chalk: 4.1.2
@@ -4105,9 +4263,9 @@ packages:
       get-port: 5.1.1
       giget: 1.1.2
       globby: 11.1.0
-      jscodeshift: 0.14.0(@babel/preset-env@7.20.2)
+      jscodeshift: 0.14.0(@babel/preset-env@7.21.4)
       leven: 3.1.0
-      prettier: 2.8.7
+      prettier: 2.8.8
       prompts: 2.4.2
       puppeteer-core: 2.1.1
       read-pkg-up: 7.0.1
@@ -4132,33 +4290,39 @@ packages:
       global: 4.4.0
     dev: true
 
-  /@storybook/client-logger@7.0.0:
-    resolution: {integrity: sha512-wRZZiPta37DFc8SVZ8Q3ZqyTrs5qgO6bcCuVDRLQAcO0Oz4xKEVPEVfVVxSPZU/+p2ypqdBBCP2pdL/Jy86AJg==}
+  /@storybook/client-logger@7.0.0-rc.5:
+    resolution: {integrity: sha512-YkqjJb2jK6/jT4zm9cmdMVZeOyzoDxiyK3BedhoXKMRDMz+7+E7tcOZEXsuvTGekJe459TTnwYLfvUvObaXNKw==}
     dependencies:
       '@storybook/global': 5.0.0
     dev: true
 
-  /@storybook/client-logger@7.0.0-rc.5:
-    resolution: {integrity: sha512-YkqjJb2jK6/jT4zm9cmdMVZeOyzoDxiyK3BedhoXKMRDMz+7+E7tcOZEXsuvTGekJe459TTnwYLfvUvObaXNKw==}
+  /@storybook/client-logger@7.0.5:
+    resolution: {integrity: sha512-p8Vtb5G/l3gePNDbNjqgGsikthRqDfsPAqFEsAvBWJVZ3vq/ZSU4IsCWSLO/kdkyJyhTXMqQZnOpQ0pDXlOPcQ==}
+    dependencies:
+      '@storybook/global': 5.0.0
+    dev: true
+
+  /@storybook/client-logger@7.0.7:
+    resolution: {integrity: sha512-EclHjDs5HwHMKB4X2orn/KKA0DTIDmp4AXAUJGRfxb5ArpKEb7tXLHsgrRBlaoz1j5LAwKTmEyZOONh9G3etjg==}
     dependencies:
       '@storybook/global': 5.0.0
     dev: true
 
-  /@storybook/codemod@7.0.0-rc.5:
-    resolution: {integrity: sha512-aiW7PeU9rZE9wp6tNxLxloAsfVNzeG8pI0HJrj1JALhvaPzlCphdMP8Cf2UT0a4ADjpmYQSsGX301XFgMQYFKA==}
+  /@storybook/codemod@7.0.7:
+    resolution: {integrity: sha512-VlkDlkvfbzLe+NOmzs5zGrGb4jnaeAFZqpvIkXxevr6aGcOwgeelNv8gTmgBAcy+xbGW4Pp0XA2BlMweIvKEKA==}
     dependencies:
       '@babel/core': 7.21.3
-      '@babel/preset-env': 7.20.2(@babel/core@7.21.3)
-      '@babel/types': 7.21.3
-      '@storybook/csf': 0.0.2-next.11
-      '@storybook/csf-tools': 7.0.0-rc.5
-      '@storybook/node-logger': 7.0.0-rc.5
-      '@storybook/types': 7.0.0-rc.5
+      '@babel/preset-env': 7.21.4(@babel/core@7.21.3)
+      '@babel/types': 7.21.4
+      '@storybook/csf': 0.1.0
+      '@storybook/csf-tools': 7.0.7
+      '@storybook/node-logger': 7.0.7
+      '@storybook/types': 7.0.7
       cross-spawn: 7.0.3
       globby: 11.1.0
-      jscodeshift: 0.14.0(@babel/preset-env@7.20.2)
+      jscodeshift: 0.14.0(@babel/preset-env@7.21.4)
       lodash: 4.17.21
-      prettier: 2.8.7
+      prettier: 2.8.8
       recast: 0.23.1
     transitivePeerDependencies:
       - supports-color
@@ -4200,6 +4364,42 @@ packages:
       util-deprecate: 1.0.2
     dev: true
 
+  /@storybook/components@7.0.5(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-SHftxNH3FG3RZwJ5nbyBZwn5pkI3Ei2xjD7zDwxztI8bCp5hPnOTDwAnQZZCkeW7atSQUe7xFkYqlCgNmXR4PQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/client-logger': 7.0.5
+      '@storybook/csf': 0.1.0
+      '@storybook/global': 5.0.0
+      '@storybook/theming': 7.0.5(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/types': 7.0.5
+      memoizerific: 1.11.3
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+      use-resize-observer: 9.1.0(react-dom@18.2.0)(react@18.2.0)
+      util-deprecate: 1.0.2
+    dev: true
+
+  /@storybook/components@7.0.7(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-6PLs9LMkBuhH/w4bSJ72tYgICMbOOIHuoB/fQdVlzhsdnXL2fM/v4RVW2N7v+Oz3lYXp/JtV8V9Ub8h6eDQKXg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/client-logger': 7.0.7
+      '@storybook/csf': 0.1.0
+      '@storybook/global': 5.0.0
+      '@storybook/theming': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/types': 7.0.7
+      memoizerific: 1.11.3
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+      use-resize-observer: 9.1.0(react-dom@18.2.0)(react@18.2.0)
+      util-deprecate: 1.0.2
+    dev: true
+
   /@storybook/core-client@7.0.0-rc.5:
     resolution: {integrity: sha512-jBY4kJDL5sdVcnGzz+cpruzkF01Hi+DJ/c9mpNiL+CjiDSFewtCk28Qggwccm9tKne5eAlrFiJAu5MOlbIcM+g==}
     dependencies:
@@ -4207,6 +4407,13 @@ packages:
       '@storybook/preview-api': 7.0.0-rc.5
     dev: true
 
+  /@storybook/core-client@7.0.7:
+    resolution: {integrity: sha512-eydcpR28qV3A3BwR5V6wsixoI1BRLA0SzFiwH/1ajrgX13inv+gV97gHv47Ojf/+YAZ3HqdVaUKFsUfMKwKieA==}
+    dependencies:
+      '@storybook/client-logger': 7.0.7
+      '@storybook/preview-api': 7.0.7
+    dev: true
+
   /@storybook/core-common@7.0.0-rc.5:
     resolution: {integrity: sha512-YlkcTcDx8bkOq3/STAuBkQOBQB5i0zLj2Zb0LUPzIDDBPZlGb3mJEla0UyJoMbP/E/QCq1K8pA1l9vtTK+ROJQ==}
     dependencies:
@@ -4234,37 +4441,63 @@ packages:
       - supports-color
     dev: true
 
+  /@storybook/core-common@7.0.7:
+    resolution: {integrity: sha512-c8T24wex9bnCYdZVZFNX4VV+wfhrp47OLzVONZDqxMhq6G//Bgv5zH4Awcx5UfWf/05VcP7KGF1VKj8ebRyEEA==}
+    dependencies:
+      '@storybook/node-logger': 7.0.7
+      '@storybook/types': 7.0.7
+      '@types/node': 16.18.16
+      '@types/pretty-hrtime': 1.0.1
+      chalk: 4.1.2
+      esbuild: 0.17.12
+      esbuild-register: 3.4.2(esbuild@0.17.12)
+      file-system-cache: 2.0.2
+      find-up: 5.0.0
+      fs-extra: 11.1.1
+      glob: 8.1.0
+      glob-promise: 6.0.2(glob@8.1.0)
+      handlebars: 4.7.7
+      lazy-universal-dotenv: 4.0.0
+      picomatch: 2.3.1
+      pkg-dir: 5.0.0
+      pretty-hrtime: 1.0.3
+      resolve-from: 5.0.0
+      ts-dedent: 2.2.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@storybook/core-events@6.5.16:
     resolution: {integrity: sha512-qMZQwmvzpH5F2uwNUllTPg6eZXr2OaYZQRRN8VZJiuorZzDNdAFmiVWMWdkThwmyLEJuQKXxqCL8lMj/7PPM+g==}
     dependencies:
       core-js: 3.29.1
     dev: true
 
-  /@storybook/core-events@7.0.0:
-    resolution: {integrity: sha512-pxzNmgEI1p90bHyAYABHDDtB2XM5pffq6CqIHboK6aSCux7Cdc16IjOYq6BJIhCKaaI+qQHaFLR4JfaFAsxwQQ==}
-    dev: true
-
   /@storybook/core-events@7.0.0-rc.5:
     resolution: {integrity: sha512-n9+TqgrgkXN5V+mNdgdnojUVqhKOsyL3DNfOmAsbLEewhg5z6+QDYxOe/FBe1usGI2DV+ihwb/knMZzuYXN5ow==}
     dev: true
 
-  /@storybook/core-server@7.0.0-rc.5:
-    resolution: {integrity: sha512-rif4CTnaExe+GLNv2wWRkqJPNn1WN+1ZWv/YLjYUjR2zGeLQn26/XLUKVn5CCQ4DzHbqWwfMaxlPKhNAeZyodw==}
+  /@storybook/core-events@7.0.7:
+    resolution: {integrity: sha512-XNsR2RgaL2vBwuqsu+KA1DzGmB1UFfrAhpxhmyWTKDCniwtTLlaXgfKbqwcrOrPu/o1YswgIup/9UHepRHaf4A==}
+    dev: true
+
+  /@storybook/core-server@7.0.7:
+    resolution: {integrity: sha512-PB4zoClH7aKG4XeJhxx43iK9n/C9gctXubNN5DSN6thPm4UITOas+/q4N7AHbCPyRbcMyoW7M31KtpzZu4Fjew==}
     dependencies:
       '@aw-web-design/x-default-browser': 1.4.88
       '@discoveryjs/json-ext': 0.5.7
-      '@storybook/builder-manager': 7.0.0-rc.5
-      '@storybook/core-common': 7.0.0-rc.5
-      '@storybook/core-events': 7.0.0-rc.5
-      '@storybook/csf': 0.0.2-next.11
-      '@storybook/csf-tools': 7.0.0-rc.5
-      '@storybook/docs-mdx': 0.0.1-next.6
+      '@storybook/builder-manager': 7.0.7
+      '@storybook/core-common': 7.0.7
+      '@storybook/core-events': 7.0.7
+      '@storybook/csf': 0.1.0
+      '@storybook/csf-tools': 7.0.7
+      '@storybook/docs-mdx': 0.1.0
       '@storybook/global': 5.0.0
-      '@storybook/manager': 7.0.0-rc.5
-      '@storybook/node-logger': 7.0.0-rc.5
-      '@storybook/preview-api': 7.0.0-rc.5
-      '@storybook/telemetry': 7.0.0-rc.5
-      '@storybook/types': 7.0.0-rc.5
+      '@storybook/manager': 7.0.7
+      '@storybook/node-logger': 7.0.7
+      '@storybook/preview-api': 7.0.7
+      '@storybook/telemetry': 7.0.7
+      '@storybook/types': 7.0.7
       '@types/detect-port': 1.3.2
       '@types/node': 16.18.16
       '@types/node-fetch': 2.6.2
@@ -4288,7 +4521,6 @@ packages:
       read-pkg-up: 7.0.1
       semver: 7.3.8
       serve-favicon: 2.5.0
-      slash: 3.0.0
       telejson: 7.0.4
       ts-dedent: 2.2.0
       util-deprecate: 1.0.2
@@ -4310,13 +4542,22 @@ packages:
       - supports-color
     dev: true
 
+  /@storybook/csf-plugin@7.0.7:
+    resolution: {integrity: sha512-uhf2g077gXA6ZEMXIPQ0RnX+IoOTBJbj+6+VQfT7K5tvJeop1z0Fvk0FoknNXcUe7aUA0nzA/cUQ1v4vXqbY3Q==}
+    dependencies:
+      '@storybook/csf-tools': 7.0.7
+      unplugin: 0.10.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@storybook/csf-tools@7.0.0-rc.5:
     resolution: {integrity: sha512-DvcAygIZMZIL30j7WxMXeJ6a+A2/Y/FuatZItmW+3sNv0FK1J9wH2SKw7QjzEw75LsgjvO07lU2cgcsPDFhXoA==}
     dependencies:
       '@babel/generator': 7.21.3
       '@babel/parser': 7.21.3
       '@babel/traverse': 7.21.3(supports-color@5.5.0)
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
       '@storybook/csf': 0.0.2-next.11
       '@storybook/types': 7.0.0-rc.5
       fs-extra: 11.1.1
@@ -4326,6 +4567,22 @@ packages:
       - supports-color
     dev: true
 
+  /@storybook/csf-tools@7.0.7:
+    resolution: {integrity: sha512-KbO5K2RS0oFm94eR49bAPvoyXY3Q6+ozvBek/F05RP7iAV790icQc59Xci9YDM1ONgb3afS+gSJGFBsE0h4pmg==}
+    dependencies:
+      '@babel/generator': 7.21.3
+      '@babel/parser': 7.21.3
+      '@babel/traverse': 7.21.3(supports-color@5.5.0)
+      '@babel/types': 7.21.4
+      '@storybook/csf': 0.1.0
+      '@storybook/types': 7.0.7
+      fs-extra: 11.1.1
+      recast: 0.23.1
+      ts-dedent: 2.2.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@storybook/csf@0.0.2--canary.4566f4d.1:
     resolution: {integrity: sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ==}
     dependencies:
@@ -4338,8 +4595,14 @@ packages:
       type-fest: 2.19.0
     dev: true
 
-  /@storybook/docs-mdx@0.0.1-next.6:
-    resolution: {integrity: sha512-DjoSIXADmLJtdroXAjUotFiZlcZ2usWhqrS7aeOtZs0DVR0Ws5WQjnwtpDUXt8gryTSd+OZJ0cNsDcqg4JDEvQ==}
+  /@storybook/csf@0.1.0:
+    resolution: {integrity: sha512-uk+jMXCZ8t38jSTHk2o5btI+aV2Ksbvl6DoOv3r6VaCM1KZqeuMwtwywIQdflkA8/6q/dKT8z8L+g8hC4GC3VQ==}
+    dependencies:
+      type-fest: 2.19.0
+    dev: true
+
+  /@storybook/docs-mdx@0.1.0:
+    resolution: {integrity: sha512-JDaBR9lwVY4eSH5W8EGHrhODjygPd6QImRbwjAuJNEnY0Vw4ie3bPkeGfnacB3OBW6u/agqPv2aRlR46JcAQLg==}
     dev: true
 
   /@storybook/docs-tools@7.0.0-rc.5:
@@ -4356,18 +4619,22 @@ packages:
       - supports-color
     dev: true
 
-  /@storybook/global@5.0.0:
-    resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==}
+  /@storybook/docs-tools@7.0.7:
+    resolution: {integrity: sha512-VB4Qa33DYNxXALWcXyDid246r9Q6SGM+Q+pGWOuEJsxRxDmrUspXHaHG0CO1NIjMWfbqpOoz61vquZO0GZoAAg==}
+    dependencies:
+      '@babel/core': 7.21.3
+      '@storybook/core-common': 7.0.7
+      '@storybook/preview-api': 7.0.7
+      '@storybook/types': 7.0.7
+      '@types/doctrine': 0.0.3
+      doctrine: 3.0.0
+      lodash: 4.17.21
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@storybook/instrumenter@7.0.0:
-    resolution: {integrity: sha512-A7jBrV7VM3OxRgall8rpjagy3VC78A/OV1g1aYVVLpAF/+Odj+MeHHF179+fR6JBLnBgukNfsG7/ZHHGs0gL5Q==}
-    dependencies:
-      '@storybook/channels': 7.0.0
-      '@storybook/client-logger': 7.0.0
-      '@storybook/core-events': 7.0.0
-      '@storybook/global': 5.0.0
-      '@storybook/preview-api': 7.0.0
+  /@storybook/global@5.0.0:
+    resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==}
     dev: true
 
   /@storybook/instrumenter@7.0.0-rc.5:
@@ -4380,6 +4647,16 @@ packages:
       '@storybook/preview-api': 7.0.0-rc.5
     dev: true
 
+  /@storybook/instrumenter@7.0.7:
+    resolution: {integrity: sha512-0zE5lM3laKvCT4GW/XKKw8kakvI4catqK8PObZolRhfxbtGufW4VJZ2E8vXLtgA/+K3zikypjuWE6d45NLbh9w==}
+    dependencies:
+      '@storybook/channels': 7.0.7
+      '@storybook/client-logger': 7.0.7
+      '@storybook/core-events': 7.0.7
+      '@storybook/global': 5.0.0
+      '@storybook/preview-api': 7.0.7
+    dev: true
+
   /@storybook/manager-api@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0):
     resolution: {integrity: sha512-MsNj/cPIOlL7HJ8ReYahUvJVfvZDtNfacUYSFuQjQwdnp0u3pbC5mGZPd32tAGj7lLaLzcqqo1yR+NAgwpZUBw==}
     peerDependencies:
@@ -4405,12 +4682,41 @@ packages:
       ts-dedent: 2.2.0
     dev: true
 
-  /@storybook/manager@7.0.0-rc.5:
-    resolution: {integrity: sha512-VPTIYzcKguKaA+4HGFPAPRdDGTZ8fxKAKL71VgP+AOOJhNmdTWHCXs8Yu7GMg/2uyRZ2zSKiOeBESh+Qb8pRZg==}
+  /@storybook/manager-api@7.0.7(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-QTd/P72peAhofKqK+8yzIO9iWAEfPn8WUGGveV2KGaTlSlgbr87RLHEKilcXMZcYhBWC9izFRmjKum9ROdskrQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/channels': 7.0.7
+      '@storybook/client-logger': 7.0.7
+      '@storybook/core-events': 7.0.7
+      '@storybook/csf': 0.1.0
+      '@storybook/global': 5.0.0
+      '@storybook/router': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/theming': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/types': 7.0.7
+      dequal: 2.0.3
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+      semver: 7.3.8
+      store2: 2.14.2
+      telejson: 7.0.4
+      ts-dedent: 2.2.0
     dev: true
 
-  /@storybook/mdx2-csf@1.0.0-next.6:
-    resolution: {integrity: sha512-m6plojocU/rmrqWd26yvm8D+oHZPZ6PtSSFmZIgpNDEPVmc8s4fBD6LXOAB5MiPI5f8KLUr2HVhOMZ97o5pDTw==}
+  /@storybook/manager@7.0.7:
+    resolution: {integrity: sha512-FhquwUpUOHsjZROf6E6kzUnJ6EmMeJ9b+HYg6yYPyIMYVMjAhnkRKbIj0phGx2lhgKFlmxik+3pgchK5SLdcZA==}
+    dev: true
+
+  /@storybook/mdx2-csf@1.0.0:
+    resolution: {integrity: sha512-dBAnEL4HfxxJmv7LdEYUoZlQbWj9APZNIbOaq0tgF8XkxiIbzqvgB0jhL/9UOrysSDbQWBiCRTu2wOVxedGfmw==}
+    dev: true
+
+  /@storybook/mdx2-csf@1.1.0-next.1:
+    resolution: {integrity: sha512-ONvFBZySHsBIkUYGrUM8FCG2tDKf663TIErztPSOghOpmBGyFLjSsXJHkNWiRi4c740PoemLqJd2XZZVlXRVLQ==}
     dev: true
 
   /@storybook/node-logger@7.0.0-rc.5:
@@ -4422,6 +4728,15 @@ packages:
       pretty-hrtime: 1.0.3
     dev: true
 
+  /@storybook/node-logger@7.0.7:
+    resolution: {integrity: sha512-5Y4LLgKeCStq1ktCKZ5eNPzQQSQ+CYZAlkEdzQ3Pp//0KXaZvVxEvGtaYhAymP2HatLpI8Oneo4lHrJioRfgww==}
+    dependencies:
+      '@types/npmlog': 4.1.4
+      chalk: 4.1.2
+      npmlog: 5.0.1
+      pretty-hrtime: 1.0.3
+    dev: true
+
   /@storybook/postinstall@7.0.0-rc.5:
     resolution: {integrity: sha512-F23wxKEJ2XoVnHT7oAMjCXtANWvNq7M+FmIowgI98b3FT1dxt9fFPKKY+3Lcqp0Xa6Pzezd03KR9vAxXvvK/iQ==}
     dev: true
@@ -4438,53 +4753,63 @@ packages:
       style-loader: 3.3.2(webpack@5.77.0)
     dev: true
 
-  /@storybook/preview-api@7.0.0:
-    resolution: {integrity: sha512-Q0IYYH1gOmx42ClYlQfQPjuERBWM3Ey+3DFsLQaraKXDdgZ9wN7jPNuS7wxuUNylT0oa/3WjxT7qNfiGw8JtBw==}
+  /@storybook/preview-api@7.0.0-rc.5:
+    resolution: {integrity: sha512-cuyFIT/4MXfoqN6d5AK/KH7Yp0cifuOmcBj4+9xrmrPK47m4F8eHZ/mX6rXE6rVFNsWv65Al5An6WCM1CDImJg==}
     dependencies:
-      '@storybook/channel-postmessage': 7.0.0
-      '@storybook/channels': 7.0.0
-      '@storybook/client-logger': 7.0.0
-      '@storybook/core-events': 7.0.0
+      '@storybook/channel-postmessage': 7.0.0-rc.5
+      '@storybook/channels': 7.0.0-rc.5
+      '@storybook/client-logger': 7.0.0-rc.5
+      '@storybook/core-events': 7.0.0-rc.5
       '@storybook/csf': 0.0.2-next.11
       '@storybook/global': 5.0.0
-      '@storybook/types': 7.0.0
+      '@storybook/types': 7.0.0-rc.5
       '@types/qs': 6.9.7
       dequal: 2.0.3
       lodash: 4.17.21
       memoizerific: 1.11.3
       qs: 6.11.1
+      slash: 3.0.0
       synchronous-promise: 2.0.17
       ts-dedent: 2.2.0
       util-deprecate: 1.0.2
     dev: true
 
-  /@storybook/preview-api@7.0.0-rc.5:
-    resolution: {integrity: sha512-cuyFIT/4MXfoqN6d5AK/KH7Yp0cifuOmcBj4+9xrmrPK47m4F8eHZ/mX6rXE6rVFNsWv65Al5An6WCM1CDImJg==}
+  /@storybook/preview-api@7.0.7:
+    resolution: {integrity: sha512-R5pmGTodpu6hbwEg2RM2ulWtW3d426YzsisHrZJ+FT9lecWauN1y9xHCz7HdNzEFhT8r4YOa24L9ZS3mosZ7hA==}
     dependencies:
-      '@storybook/channel-postmessage': 7.0.0-rc.5
-      '@storybook/channels': 7.0.0-rc.5
-      '@storybook/client-logger': 7.0.0-rc.5
-      '@storybook/core-events': 7.0.0-rc.5
-      '@storybook/csf': 0.0.2-next.11
+      '@storybook/channel-postmessage': 7.0.7
+      '@storybook/channels': 7.0.7
+      '@storybook/client-logger': 7.0.7
+      '@storybook/core-events': 7.0.7
+      '@storybook/csf': 0.1.0
       '@storybook/global': 5.0.0
-      '@storybook/types': 7.0.0-rc.5
+      '@storybook/types': 7.0.7
       '@types/qs': 6.9.7
       dequal: 2.0.3
       lodash: 4.17.21
       memoizerific: 1.11.3
       qs: 6.11.1
-      slash: 3.0.0
       synchronous-promise: 2.0.17
       ts-dedent: 2.2.0
       util-deprecate: 1.0.2
     dev: true
 
-  /@storybook/preview@7.0.0-rc.5:
-    resolution: {integrity: sha512-AG6vg4dsHVjbNchC3eiDqwSKfUWyFXauYDLg+Ce4F47s98J5ly+mFAIY0Vo1mwao3CVHLk0SYt+vtuQZF52WAg==}
+  /@storybook/preview@7.0.7:
+    resolution: {integrity: sha512-uL3ZcFao6UvxiSxCIcXKFakxEr9Nn0lvu0zzC2yQCVepzA7a+GDr1cK5VbZ6Mez38CnOvBmb5pkCbgRqSf/oug==}
+    dev: true
+
+  /@storybook/react-dom-shim@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-Hyx8Px1LLc3+WjIUW5hNFEsbQspONnyThxBCU7w0kAivpJn7vy26HFCHp4QA1FPU6CnJUl5dVxckj6bosv/Gqg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
     dev: true
 
-  /@storybook/react-dom-shim@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0):
-    resolution: {integrity: sha512-Hyx8Px1LLc3+WjIUW5hNFEsbQspONnyThxBCU7w0kAivpJn7vy26HFCHp4QA1FPU6CnJUl5dVxckj6bosv/Gqg==}
+  /@storybook/react-dom-shim@7.0.7(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-INGwFeu9M+RzpvktSKuwy8Rk/70mXGqxxsb9lPtq7phmETvfpNX7GnLJqiVazTaQiB1DkB0iAPUsK2MNbBu+Kw==}
     peerDependencies:
       react: ^16.8.0 || ^17.0.0 || ^18.0.0
       react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -4493,8 +4818,8 @@ packages:
       react-dom: 18.2.0(react@18.2.0)
     dev: true
 
-  /@storybook/react-vite@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)(vite@4.2.1):
-    resolution: {integrity: sha512-IW2DYK6K115B7VKBvNMaSMVe3LWyFyFBgjby1N2/wfL5jkvrwRmYH4ag5+qn1e6HgxH6F+Wd9ryLhf8jaldgVQ==}
+  /@storybook/react-vite@7.0.7(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)(vite@4.2.1):
+    resolution: {integrity: sha512-RuWfP/kiLpuHdcF9dWUUp9SOGMmO0FJ0HGV5yAOhGmi8KmTzvc8zjC+hJjj+sSgn2n71BO8pG/zqGl16FwfwVQ==}
     engines: {node: '>=16'}
     peerDependencies:
       react: ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -4503,18 +4828,17 @@ packages:
     dependencies:
       '@joshwooding/vite-plugin-react-docgen-typescript': 0.2.1(typescript@4.9.5)(vite@4.2.1)
       '@rollup/pluginutils': 4.2.1
-      '@storybook/builder-vite': 7.0.0-rc.5(typescript@4.9.5)(vite@4.2.1)
-      '@storybook/react': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)
+      '@storybook/builder-vite': 7.0.7(typescript@4.9.5)(vite@4.2.1)
+      '@storybook/react': 7.0.7(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)
       '@vitejs/plugin-react': 3.1.0(vite@4.2.1)
       ast-types: 0.14.2
       magic-string: 0.27.0
       react: 18.2.0
       react-docgen: 6.0.0-alpha.3
       react-dom: 18.2.0(react@18.2.0)
-      vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+      vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
     transitivePeerDependencies:
       - '@preact/preset-vite'
-      - '@storybook/mdx1-csf'
       - supports-color
       - typescript
       - vite-plugin-glimmerx
@@ -4559,6 +4883,45 @@ packages:
       - supports-color
     dev: true
 
+  /@storybook/react@7.0.7(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5):
+    resolution: {integrity: sha512-eEsIfAGumzo7KRi/WKFpn/PGFhwLv72oiEM/8l5MMX/6poIkiekunqJLfx2BoL4cCtiS4g7OYzOdWjN01DwVCg==}
+    engines: {node: '>=16.0.0'}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@storybook/client-logger': 7.0.7
+      '@storybook/core-client': 7.0.7
+      '@storybook/docs-tools': 7.0.7
+      '@storybook/global': 5.0.0
+      '@storybook/preview-api': 7.0.7
+      '@storybook/react-dom-shim': 7.0.7(react-dom@18.2.0)(react@18.2.0)
+      '@storybook/types': 7.0.7
+      '@types/escodegen': 0.0.6
+      '@types/estree': 0.0.51
+      '@types/node': 16.18.16
+      acorn: 7.4.1
+      acorn-jsx: 5.3.2(acorn@7.4.1)
+      acorn-walk: 7.2.0
+      escodegen: 2.0.0
+      html-tags: 3.2.0
+      lodash: 4.17.21
+      prop-types: 15.8.1
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+      react-element-to-jsx-string: 15.0.0(react-dom@18.2.0)(react@18.2.0)
+      ts-dedent: 2.2.0
+      type-fest: 2.19.0
+      typescript: 4.9.5
+      util-deprecate: 1.0.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@storybook/router@6.5.16(react-dom@18.2.0)(react@18.2.0):
     resolution: {integrity: sha512-ZgeP8a5YV/iuKbv31V8DjPxlV4AzorRiR8OuSt/KqaiYXNXlOoQDz/qMmiNcrshrfLpmkzoq7fSo4T8lWo2UwQ==}
     peerDependencies:
@@ -4587,6 +4950,19 @@ packages:
       react-dom: 18.2.0(react@18.2.0)
     dev: true
 
+  /@storybook/router@7.0.7(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-/lM8/NHQKeshfnC3ayFuO8Y9TCSHnCAPRhIsVxvanBzcj+ILbCIyZ+TspvB3hT4MbX/Ez+JR8VrMbjXIGwmH8w==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/client-logger': 7.0.7
+      memoizerific: 1.11.3
+      qs: 6.11.1
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+    dev: true
+
   /@storybook/semver@7.3.2:
     resolution: {integrity: sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg==}
     engines: {node: '>=10'}
@@ -4596,11 +4972,11 @@ packages:
       find-up: 4.1.0
     dev: true
 
-  /@storybook/telemetry@7.0.0-rc.5:
-    resolution: {integrity: sha512-So3Tb+wanyM2KMT1lVv56Kt8VEaQqwt375lWOt3TLNj15L0NYLvCmMCBRsLhtaB4arLo+uwfR4lBs372Qu7w2A==}
+  /@storybook/telemetry@7.0.7:
+    resolution: {integrity: sha512-Ka6pwWr3sWs3A/6WQ0wsoSYzXx3Mhr7eByNZZKuuCu9jnw3I8AbIOqQX2iOVzaQBLZsvXEeqvYY8iZ+GuRbbGQ==}
     dependencies:
-      '@storybook/client-logger': 7.0.0-rc.5
-      '@storybook/core-common': 7.0.0-rc.5
+      '@storybook/client-logger': 7.0.7
+      '@storybook/core-common': 7.0.7
       chalk: 4.1.2
       detect-package-manager: 2.0.1
       fetch-retry: 5.0.4
@@ -4613,11 +4989,11 @@ packages:
       - supports-color
     dev: true
 
-  /@storybook/testing-library@0.0.14-next.1:
-    resolution: {integrity: sha512-1CAl40IKIhcPaCC4pYCG0b9IiYNymktfV/jTrX7ctquRY3akaN7f4A1SippVHosksft0M+rQTFE0ccfWW581fw==}
+  /@storybook/testing-library@0.1.0:
+    resolution: {integrity: sha512-g947f4LJZw3IluBhysMKLJXByAFiSxnGuooENqU+ZPt/GTrz1I9GDBlhmoTJahuFkVbwHvziAl/8riY2Re921g==}
     dependencies:
-      '@storybook/client-logger': 7.0.0
-      '@storybook/instrumenter': 7.0.0
+      '@storybook/client-logger': 7.0.7
+      '@storybook/instrumenter': 7.0.7
       '@testing-library/dom': 8.20.0
       '@testing-library/user-event': 13.5.0(@testing-library/dom@8.20.0)
       ts-dedent: 2.2.0
@@ -4651,13 +5027,32 @@ packages:
       react-dom: 18.2.0(react@18.2.0)
     dev: true
 
-  /@storybook/types@7.0.0:
-    resolution: {integrity: sha512-eCMW/xTVMswgD/58itibw8s8f2hZ7tciT3saRdGCymg9tPUhMC/9eGIIUSr/C+xfnCJEZm6J6DgEUo1xlifonw==}
+  /@storybook/theming@7.0.5(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-XgQXKktcVBOkJT5gXjqtjH7C2pjdreDy0BTVTaEmFzggyyw+cgFrkJ7tuB27oKwYe+svx26c/olVMSHYf+KqhA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
     dependencies:
-      '@storybook/channels': 7.0.0
-      '@types/babel__core': 7.20.0
-      '@types/express': 4.17.17
-      file-system-cache: 2.0.2
+      '@emotion/use-insertion-effect-with-fallbacks': 1.0.0(react@18.2.0)
+      '@storybook/client-logger': 7.0.5
+      '@storybook/global': 5.0.0
+      memoizerific: 1.11.3
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+    dev: true
+
+  /@storybook/theming@7.0.7(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-InTZe+Sgco1NsxgiG+cyUKWQe3GsjlIyU/o5qDdtOTXcZ64HzyBuAZlAequSddqfDeMDqxRFPc2w1J28MAUHxA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@emotion/use-insertion-effect-with-fallbacks': 1.0.0(react@18.2.0)
+      '@storybook/client-logger': 7.0.7
+      '@storybook/global': 5.0.0
+      memoizerific: 1.11.3
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
     dev: true
 
   /@storybook/types@7.0.0-rc.5:
@@ -4669,6 +5064,24 @@ packages:
       file-system-cache: 2.0.2
     dev: true
 
+  /@storybook/types@7.0.5:
+    resolution: {integrity: sha512-By+tF3B30QiCnzEJ+Z73M2usSCqBWEmX4OGT1KbiEzWekkrsfCfpZwfzeMw1WwdQGlB1gLKTzB8wZ1zZB8oPtQ==}
+    dependencies:
+      '@storybook/channels': 7.0.5
+      '@types/babel__core': 7.20.0
+      '@types/express': 4.17.17
+      file-system-cache: 2.0.2
+    dev: true
+
+  /@storybook/types@7.0.7:
+    resolution: {integrity: sha512-v9piuwp8FvTiHXIOOi5lEyTEJKhnbcbhVxgJ3VFhhXYFd0DTz6Bst0XIIgkgs21ITb3xhkfPbCRUueMcbXO1MA==}
+    dependencies:
+      '@storybook/channels': 7.0.7
+      '@types/babel__core': 7.20.0
+      '@types/express': 4.17.17
+      file-system-cache: 2.0.2
+    dev: true
+
   /@swc/core-darwin-arm64@1.3.42:
     resolution: {integrity: sha512-hM6RrZFyoCM9mX3cj/zM5oXwhAqjUdOCLXJx7KTQps7NIkv/Qjvobgvyf2gAb89j3ARNo9NdIoLjTjJ6oALtiA==}
     engines: {node: '>=10'}
@@ -4894,7 +5307,7 @@ packages:
     resolution: {integrity: sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==}
     dependencies:
       '@babel/parser': 7.21.3
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
       '@types/babel__generator': 7.6.4
       '@types/babel__template': 7.4.1
       '@types/babel__traverse': 7.18.3
@@ -4903,20 +5316,20 @@ packages:
   /@types/babel__generator@7.6.4:
     resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==}
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     dev: true
 
   /@types/babel__template@7.4.1:
     resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==}
     dependencies:
       '@babel/parser': 7.21.3
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     dev: true
 
   /@types/babel__traverse@7.18.3:
     resolution: {integrity: sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==}
     dependencies:
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
     dev: true
 
   /@types/body-parser@1.19.2:
@@ -5520,13 +5933,22 @@ packages:
       '@typescript-eslint/types': 5.52.0
       eslint-visitor-keys: 3.3.0
 
+  /@vitejs/plugin-basic-ssl@1.0.1(vite@4.2.1):
+    resolution: {integrity: sha512-pcub+YbFtFhaGRTo1832FQHQSHvMrlb43974e2eS8EKleR3p1cDdkJFPci1UhwkEf1J9Bz+wKBSzqpKp7nNj2A==}
+    engines: {node: '>=14.6.0'}
+    peerDependencies:
+      vite: ^3.0.0 || ^4.0.0
+    dependencies:
+      vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
+    dev: true
+
   /@vitejs/plugin-react-swc@3.2.0(vite@4.2.1):
     resolution: {integrity: sha512-IcBoXL/mcH7JdQr/nfDlDwTdIaH8Rg7LpfQDF4nAht+juHWIuv6WhpKPCSfY4+zztAaB07qdBoFz1XCZsgo3pQ==}
     peerDependencies:
       vite: ^4
     dependencies:
       '@swc/core': 1.3.42
-      vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+      vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
     dev: true
 
   /@vitejs/plugin-react@3.1.0(vite@4.2.1):
@@ -5540,7 +5962,7 @@ packages:
       '@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.21.3)
       magic-string: 0.27.0
       react-refresh: 0.14.0
-      vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+      vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -5690,13 +6112,13 @@ packages:
     resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
     dev: true
 
-  /@yarnpkg/esbuild-plugin-pnp@3.0.0-rc.15(esbuild@0.16.17):
+  /@yarnpkg/esbuild-plugin-pnp@3.0.0-rc.15(esbuild@0.17.12):
     resolution: {integrity: sha512-kYzDJO5CA9sy+on/s2aIW0411AklfCi8Ck/4QDivOqsMKpStZA2SsR+X27VTggGwpStWaLrjJcDcdDMowtG8MA==}
     engines: {node: '>=14.15.0'}
     peerDependencies:
       esbuild: '>=0.10.0'
     dependencies:
-      esbuild: 0.16.17
+      esbuild: 0.17.12
       tslib: 2.5.0
     dev: true
 
@@ -5776,6 +6198,14 @@ packages:
     engines: {node: '>= 10.0.0'}
     dev: true
 
+  /adjust-sourcemap-loader@4.0.0:
+    resolution: {integrity: sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==}
+    engines: {node: '>=8.9'}
+    dependencies:
+      loader-utils: 2.0.4
+      regex-parser: 2.2.11
+    dev: true
+
   /agent-base@5.1.1:
     resolution: {integrity: sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==}
     engines: {node: '>= 6.0.0'}
@@ -6072,7 +6502,7 @@ packages:
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/compat-data': 7.21.0
+      '@babel/compat-data': 7.21.4
       '@babel/core': 7.21.3
       '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.21.3)
       semver: 6.3.0
@@ -6617,7 +7047,7 @@ packages:
     dev: true
 
   /concat-map@0.0.1:
-    resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+    resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
 
   /concat-stream@1.6.2:
     resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
@@ -6696,6 +7126,12 @@ packages:
     engines: {node: '>= 0.6'}
     dev: true
 
+  /copy-anything@2.0.6:
+    resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==}
+    dependencies:
+      is-what: 3.14.1
+    dev: true
+
   /core-js-compat@3.29.1:
     resolution: {integrity: sha512-QmchCua884D8wWskMX8tW5ydINzd8oSJVx38lx/pVkFGqztxt73GYre3pm/hyYq8bPf+MW5In4I/uRShFDsbrA==}
     dependencies:
@@ -7545,6 +7981,15 @@ packages:
     hasBin: true
     dev: true
 
+  /errno@0.1.8:
+    resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
+    hasBin: true
+    requiresBuild: true
+    dependencies:
+      prr: 1.0.1
+    dev: true
+    optional: true
+
   /error-ex@1.3.2:
     resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
     dependencies:
@@ -7646,6 +8091,17 @@ packages:
       - supports-color
     dev: true
 
+  /esbuild-register@3.4.2(esbuild@0.17.12):
+    resolution: {integrity: sha512-kG/XyTDyz6+YDuyfB9ZoSIOOmgyFCH+xPRtsCa8W85HLRV5Csp+o3jWVbOSHgSLfyLc5DmP+KFDNwty4mEjC+Q==}
+    peerDependencies:
+      esbuild: '>=0.12 <1'
+    dependencies:
+      debug: 4.3.4(supports-color@5.5.0)
+      esbuild: 0.17.12
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /esbuild@0.16.17:
     resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==}
     engines: {node: '>=12'}
@@ -8045,7 +8501,7 @@ packages:
     engines: {node: '>=8.3.0'}
     dependencies:
       '@babel/traverse': 7.21.3(supports-color@5.5.0)
-      '@babel/types': 7.21.3
+      '@babel/types': 7.21.4
       c8: 7.13.0
     transitivePeerDependencies:
       - supports-color
@@ -8961,6 +9417,14 @@ packages:
     resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
     engines: {node: '>= 4'}
 
+  /image-size@0.5.5:
+    resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==}
+    engines: {node: '>=0.10.0'}
+    hasBin: true
+    requiresBuild: true
+    dev: true
+    optional: true
+
   /immer@9.0.19:
     resolution: {integrity: sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==}
     dev: false
@@ -9256,6 +9720,10 @@ packages:
       call-bind: 1.0.2
       get-intrinsic: 1.2.0
 
+  /is-what@3.14.1:
+    resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==}
+    dev: true
+
   /is-wsl@2.2.0:
     resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
     engines: {node: '>=8'}
@@ -9404,6 +9872,11 @@ packages:
       supports-color: 8.1.1
     dev: true
 
+  /jiti@1.18.2:
+    resolution: {integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==}
+    hasBin: true
+    dev: true
+
   /jju@1.4.0:
     resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
     dev: true
@@ -9425,7 +9898,7 @@ packages:
       argparse: 2.0.1
     dev: true
 
-  /jscodeshift@0.14.0(@babel/preset-env@7.20.2):
+  /jscodeshift@0.14.0(@babel/preset-env@7.21.4):
     resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==}
     hasBin: true
     peerDependencies:
@@ -9437,7 +9910,7 @@ packages:
       '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.21.3)
       '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.21.3)
       '@babel/plugin-transform-modules-commonjs': 7.21.2(@babel/core@7.21.3)
-      '@babel/preset-env': 7.20.2(@babel/core@7.21.3)
+      '@babel/preset-env': 7.21.4(@babel/core@7.21.3)
       '@babel/preset-flow': 7.18.6(@babel/core@7.21.3)
       '@babel/preset-typescript': 7.21.0(@babel/core@7.21.3)
       '@babel/register': 7.21.0(@babel/core@7.21.3)
@@ -9623,6 +10096,38 @@ packages:
       dotenv-expand: 10.0.0
     dev: true
 
+  /less-loader@11.1.0(less@4.1.3)(webpack@5.77.0):
+    resolution: {integrity: sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug==}
+    engines: {node: '>= 14.15.0'}
+    peerDependencies:
+      less: ^3.5.0 || ^4.0.0
+      webpack: ^5.0.0
+    dependencies:
+      klona: 2.0.6
+      less: 4.1.3
+      webpack: 5.77.0(esbuild@0.17.12)
+    dev: true
+
+  /less@4.1.3:
+    resolution: {integrity: sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==}
+    engines: {node: '>=6'}
+    hasBin: true
+    dependencies:
+      copy-anything: 2.0.6
+      parse-node-version: 1.0.1
+      tslib: 2.5.0
+    optionalDependencies:
+      errno: 0.1.8
+      graceful-fs: 4.2.11
+      image-size: 0.5.5
+      make-dir: 2.1.0
+      mime: 1.6.0
+      needle: 3.2.0
+      source-map: 0.6.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /leven@3.1.0:
     resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
     engines: {node: '>=6'}
@@ -10065,6 +10570,20 @@ packages:
   /natural-compare@1.4.0:
     resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
 
+  /needle@3.2.0:
+    resolution: {integrity: sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==}
+    engines: {node: '>= 4.4.x'}
+    hasBin: true
+    requiresBuild: true
+    dependencies:
+      debug: 3.2.7
+      iconv-lite: 0.6.3
+      sax: 1.2.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+    optional: true
+
   /negotiator@0.6.3:
     resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
     engines: {node: '>= 0.6'}
@@ -10376,6 +10895,11 @@ packages:
       json-parse-even-better-errors: 2.3.1
       lines-and-columns: 1.2.4
 
+  /parse-node-version@1.0.1:
+    resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==}
+    engines: {node: '>= 0.10'}
+    dev: true
+
   /parse5@7.1.2:
     resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
     dependencies:
@@ -10562,6 +11086,21 @@ packages:
       yaml: 2.2.1
     dev: true
 
+  /postcss-loader@7.3.0(postcss@8.4.21)(webpack@5.77.0):
+    resolution: {integrity: sha512-qLAFjvR2BFNz1H930P7mj1iuWJFjGey/nVhimfOAAQ1ZyPpcClAxP8+A55Sl8mBvM+K2a9Pjgdj10KpANWrNfw==}
+    engines: {node: '>= 14.15.0'}
+    peerDependencies:
+      postcss: ^7.0.0 || ^8.0.1
+      webpack: ^5.0.0
+    dependencies:
+      cosmiconfig: 8.1.3
+      jiti: 1.18.2
+      klona: 2.0.6
+      postcss: 8.4.21
+      semver: 7.3.8
+      webpack: 5.77.0(esbuild@0.17.12)
+    dev: true
+
   /postcss-modules-extract-imports@3.0.0(postcss@8.4.21):
     resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==}
     engines: {node: ^10 || ^12 || >= 14}
@@ -10671,8 +11210,8 @@ packages:
     hasBin: true
     dev: true
 
-  /prettier@2.8.7:
-    resolution: {integrity: sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==}
+  /prettier@2.8.8:
+    resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
     engines: {node: '>=10.13.0'}
     hasBin: true
     dev: true
@@ -10737,6 +11276,11 @@ packages:
     resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
     dev: true
 
+  /prr@1.0.1:
+    resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
+    dev: true
+    optional: true
+
   /psl@1.9.0:
     resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==}
     dev: true
@@ -11166,6 +11710,24 @@ packages:
       - immer
     dev: false
 
+  /reactflow@11.7.0(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-bjfJV1iQZ+VwIlvsnd4TbXNs6kuJ5ONscud6fNkF8RY/oU2VUZpdjA3q1zwmgnjmJcIhxuBiBI5VLGajYx/Ozg==}
+    peerDependencies:
+      react: '>=17'
+      react-dom: '>=17'
+    dependencies:
+      '@reactflow/background': 11.2.0(react-dom@18.2.0)(react@18.2.0)
+      '@reactflow/controls': 11.1.11(react-dom@18.2.0)(react@18.2.0)
+      '@reactflow/core': 11.7.0(react-dom@18.2.0)(react@18.2.0)
+      '@reactflow/minimap': 11.5.0(react-dom@18.2.0)(react@18.2.0)
+      '@reactflow/node-resizer': 2.1.0(react-dom@18.2.0)(react@18.2.0)
+      '@reactflow/node-toolbar': 1.1.11(react-dom@18.2.0)(react@18.2.0)
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+    transitivePeerDependencies:
+      - immer
+    dev: false
+
   /read-pkg-up@7.0.1:
     resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
     engines: {node: '>=8'}
@@ -11281,6 +11843,10 @@ packages:
       '@babel/runtime': 7.21.0
     dev: true
 
+  /regex-parser@2.2.11:
+    resolution: {integrity: sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==}
+    dev: true
+
   /regexp.prototype.flags@1.4.3:
     resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==}
     engines: {node: '>= 0.4'}
@@ -11363,6 +11929,17 @@ packages:
       global-dirs: 0.1.1
     dev: true
 
+  /resolve-url-loader@5.0.0:
+    resolution: {integrity: sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==}
+    engines: {node: '>=12'}
+    dependencies:
+      adjust-sourcemap-loader: 4.0.0
+      convert-source-map: 1.9.0
+      loader-utils: 2.0.4
+      postcss: 8.4.21
+      source-map: 0.6.1
+    dev: true
+
   /resolve@1.19.0:
     resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==}
     dependencies:
@@ -11493,6 +12070,11 @@ packages:
       immutable: 4.3.0
       source-map-js: 1.0.2
 
+  /sax@1.2.4:
+    resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==}
+    dev: true
+    optional: true
+
   /saxes@6.0.0:
     resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
     engines: {node: '>=v12.22.7'}
@@ -11784,11 +12366,11 @@ packages:
     resolution: {integrity: sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==}
     dev: true
 
-  /storybook@7.0.0-rc.5:
-    resolution: {integrity: sha512-zmp7E5O4AJoro99qrDYbOxloKaQED//5WlnjdIhZSndXxSJb82IyVl6VYZc7Ji6xUWC4EoqzrLcFbttfC4w5uQ==}
+  /storybook@7.0.7:
+    resolution: {integrity: sha512-MaFAhpPm/KsaoIQfGzapnRyXNh1VbS8l38BNZR5ZD97ejGkLukJ7TO4fFS87Hyy6whAXo6tTdtqeCByMQ9gRFA==}
     hasBin: true
     dependencies:
-      '@storybook/cli': 7.0.0-rc.5
+      '@storybook/cli': 7.0.7
     transitivePeerDependencies:
       - bufferutil
       - encoding
@@ -12094,6 +12676,31 @@ packages:
       webpack: 5.77.0(esbuild@0.16.17)
     dev: true
 
+  /terser-webpack-plugin@5.3.7(esbuild@0.17.12)(webpack@5.77.0):
+    resolution: {integrity: sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==}
+    engines: {node: '>= 10.13.0'}
+    peerDependencies:
+      '@swc/core': '*'
+      esbuild: '*'
+      uglify-js: '*'
+      webpack: ^5.1.0
+    peerDependenciesMeta:
+      '@swc/core':
+        optional: true
+      esbuild:
+        optional: true
+      uglify-js:
+        optional: true
+    dependencies:
+      '@jridgewell/trace-mapping': 0.3.17
+      esbuild: 0.17.12
+      jest-worker: 27.5.1
+      schema-utils: 3.1.1
+      serialize-javascript: 6.0.1
+      terser: 5.16.8
+      webpack: 5.77.0(esbuild@0.17.12)
+    dev: true
+
   /terser@5.16.8:
     resolution: {integrity: sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA==}
     engines: {node: '>=10'}
@@ -12283,65 +12890,65 @@ packages:
       tslib: 1.14.1
       typescript: 4.9.5
 
-  /turbo-darwin-64@1.8.8:
-    resolution: {integrity: sha512-18cSeIm7aeEvIxGyq7PVoFyEnPpWDM/0CpZvXKHpQ6qMTkfNt517qVqUTAwsIYqNS8xazcKAqkNbvU1V49n65Q==}
+  /turbo-darwin-64@1.9.3:
+    resolution: {integrity: sha512-0dFc2cWXl82kRE4Z+QqPHhbEFEpUZho1msHXHWbz5+PqLxn8FY0lEVOHkq5tgKNNEd5KnGyj33gC/bHhpZOk5g==}
     cpu: [x64]
     os: [darwin]
     requiresBuild: true
     dev: true
     optional: true
 
-  /turbo-darwin-arm64@1.8.8:
-    resolution: {integrity: sha512-ruGRI9nHxojIGLQv1TPgN7ud4HO4V8mFBwSgO6oDoZTNuk5ybWybItGR+yu6fni5vJoyMHXOYA2srnxvOc7hjQ==}
+  /turbo-darwin-arm64@1.9.3:
+    resolution: {integrity: sha512-1cYbjqLBA2zYE1nbf/qVnEkrHa4PkJJbLo7hnuMuGM0bPzh4+AnTNe98gELhqI1mkTWBu/XAEeF5u6dgz0jLNA==}
     cpu: [arm64]
     os: [darwin]
     requiresBuild: true
     dev: true
     optional: true
 
-  /turbo-linux-64@1.8.8:
-    resolution: {integrity: sha512-N/GkHTHeIQogXB1/6ZWfxHx+ubYeb8Jlq3b/3jnU4zLucpZzTQ8XkXIAfJG/TL3Q7ON7xQ8yGOyGLhHL7MpFRg==}
+  /turbo-linux-64@1.9.3:
+    resolution: {integrity: sha512-UuBPFefawEwpuxh5pM9Jqq3q4C8M0vYxVYlB3qea/nHQ80pxYq7ZcaLGEpb10SGnr3oMUUs1zZvkXWDNKCJb8Q==}
     cpu: [x64]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /turbo-linux-arm64@1.8.8:
-    resolution: {integrity: sha512-hKqLbBHgUkYf2Ww8uBL9UYdBFQ5677a7QXdsFhONXoACbDUPvpK4BKlz3NN7G4NZ+g9dGju+OJJjQP0VXRHb5w==}
+  /turbo-linux-arm64@1.9.3:
+    resolution: {integrity: sha512-vUrNGa3hyDtRh9W0MkO+l1dzP8Co2gKnOVmlJQW0hdpOlWlIh22nHNGGlICg+xFa2f9j4PbQlWTsc22c019s8Q==}
     cpu: [arm64]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /turbo-windows-64@1.8.8:
-    resolution: {integrity: sha512-2ndjDJyzkNslXxLt+PQuU21AHJWc8f6MnLypXy3KsN4EyX/uKKGZS0QJWz27PeHg0JS75PVvhfFV+L9t9i+Yyg==}
+  /turbo-windows-64@1.9.3:
+    resolution: {integrity: sha512-0BZ7YaHs6r+K4ksqWus1GKK3W45DuDqlmfjm/yuUbTEVc8szmMCs12vugU2Zi5GdrdJSYfoKfEJ/PeegSLIQGQ==}
     cpu: [x64]
     os: [win32]
     requiresBuild: true
     dev: true
     optional: true
 
-  /turbo-windows-arm64@1.8.8:
-    resolution: {integrity: sha512-xCA3oxgmW9OMqpI34AAmKfOVsfDljhD5YBwgs0ZDsn5h3kCHhC4x9W5dDk1oyQ4F5EXSH3xVym5/xl1J6WRpUg==}
+  /turbo-windows-arm64@1.9.3:
+    resolution: {integrity: sha512-QJUYLSsxdXOsR1TquiOmLdAgtYcQ/RuSRpScGvnZb1hY0oLc7JWU0llkYB81wVtWs469y8H9O0cxbKwCZGR4RQ==}
     cpu: [arm64]
     os: [win32]
     requiresBuild: true
     dev: true
     optional: true
 
-  /turbo@1.8.8:
-    resolution: {integrity: sha512-qYJ5NjoTX+591/x09KgsDOPVDUJfU9GoS+6jszQQlLp1AHrf1wRFA3Yps8U+/HTG03q0M4qouOfOLtRQP4QypA==}
+  /turbo@1.9.3:
+    resolution: {integrity: sha512-ID7mxmaLUPKG/hVkp+h0VuucB1U99RPCJD9cEuSEOdIPoSIuomcIClEJtKamUsdPLhLCud+BvapBNnhgh58Nzw==}
     hasBin: true
     requiresBuild: true
     optionalDependencies:
-      turbo-darwin-64: 1.8.8
-      turbo-darwin-arm64: 1.8.8
-      turbo-linux-64: 1.8.8
-      turbo-linux-arm64: 1.8.8
-      turbo-windows-64: 1.8.8
-      turbo-windows-arm64: 1.8.8
+      turbo-darwin-64: 1.9.3
+      turbo-darwin-arm64: 1.9.3
+      turbo-linux-64: 1.9.3
+      turbo-linux-arm64: 1.9.3
+      turbo-windows-64: 1.9.3
+      turbo-windows-arm64: 1.9.3
     dev: true
 
   /type-check@0.3.2:
@@ -12710,7 +13317,7 @@ packages:
       mlly: 1.2.0
       pathe: 1.1.0
       picocolors: 1.0.0
-      vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+      vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
     transitivePeerDependencies:
       - '@types/node'
       - less
@@ -12737,7 +13344,7 @@ packages:
       kolorist: 1.7.0
       magic-string: 0.29.0
       ts-morph: 17.0.1
-      vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+      vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
     transitivePeerDependencies:
       - '@types/node'
       - rollup
@@ -12757,10 +13364,10 @@ packages:
       postcss-js: 4.0.1(postcss@8.4.21)
       prettier: 2.8.5
       sass: 1.59.3
-      vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+      vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
     dev: true
 
-  /vite-plugin-sass-dts@1.3.2(postcss@8.4.21)(prettier@2.8.7)(sass@1.59.3)(vite@4.2.1):
+  /vite-plugin-sass-dts@1.3.2(postcss@8.4.21)(prettier@2.8.8)(sass@1.59.3)(vite@4.2.1):
     resolution: {integrity: sha512-zClOXVLQHKG//aZ+gsDXMnhLLVKJprrv3x+KQBf/8GD/dM4FHmlK4zMM5JcOr12oq3kTz+DUYCtCEYsFY8eDPQ==}
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
@@ -12771,9 +13378,9 @@ packages:
     dependencies:
       postcss: 8.4.21
       postcss-js: 4.0.1(postcss@8.4.21)
-      prettier: 2.8.7
+      prettier: 2.8.8
       sass: 1.59.3
-      vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+      vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
     dev: true
 
   /vite-tsconfig-paths@4.0.7(typescript@4.9.5)(vite@4.2.1):
@@ -12787,13 +13394,13 @@ packages:
       debug: 4.3.4(supports-color@5.5.0)
       globrex: 0.1.2
       tsconfck: 2.1.0(typescript@4.9.5)
-      vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+      vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
     transitivePeerDependencies:
       - supports-color
       - typescript
     dev: true
 
-  /vite@4.2.1(@types/node@18.13.0)(sass@1.59.3):
+  /vite@4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3):
     resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==}
     engines: {node: ^14.18.0 || >=16.0.0}
     hasBin: true
@@ -12820,6 +13427,7 @@ packages:
     dependencies:
       '@types/node': 18.13.0
       esbuild: 0.17.12
+      less: 4.1.3
       postcss: 8.4.21
       resolve: 1.22.1
       rollup: 3.20.0
@@ -12879,7 +13487,7 @@ packages:
       tinybench: 2.4.0
       tinypool: 0.4.0
       tinyspy: 1.1.1
-      vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3)
+      vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3)
       vite-node: 0.29.4(@types/node@18.13.0)(sass@1.59.3)
       why-is-node-running: 2.2.2
     transitivePeerDependencies:
@@ -12973,6 +13581,46 @@ packages:
       - uglify-js
     dev: true
 
+  /webpack@5.77.0(esbuild@0.17.12):
+    resolution: {integrity: sha512-sbGNjBr5Ya5ss91yzjeJTLKyfiwo5C628AFjEa6WSXcZa4E+F57om3Cc8xLb1Jh0b243AWuSYRf3dn7HVeFQ9Q==}
+    engines: {node: '>=10.13.0'}
+    hasBin: true
+    peerDependencies:
+      webpack-cli: '*'
+    peerDependenciesMeta:
+      webpack-cli:
+        optional: true
+    dependencies:
+      '@types/eslint-scope': 3.7.4
+      '@types/estree': 0.0.51
+      '@webassemblyjs/ast': 1.11.1
+      '@webassemblyjs/wasm-edit': 1.11.1
+      '@webassemblyjs/wasm-parser': 1.11.1
+      acorn: 8.8.2
+      acorn-import-assertions: 1.8.0(acorn@8.8.2)
+      browserslist: 4.21.5
+      chrome-trace-event: 1.0.3
+      enhanced-resolve: 5.12.0
+      es-module-lexer: 0.9.3
+      eslint-scope: 5.1.1
+      events: 3.3.0
+      glob-to-regexp: 0.4.1
+      graceful-fs: 4.2.11
+      json-parse-even-better-errors: 2.3.1
+      loader-runner: 4.3.0
+      mime-types: 2.1.35
+      neo-async: 2.6.2
+      schema-utils: 3.1.1
+      tapable: 2.2.1
+      terser-webpack-plugin: 5.3.7(esbuild@0.17.12)(webpack@5.77.0)
+      watchpack: 2.4.0
+      webpack-sources: 3.2.3
+    transitivePeerDependencies:
+      - '@swc/core'
+      - esbuild
+      - uglify-js
+    dev: true
+
   /whatwg-encoding@2.0.0:
     resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==}
     engines: {node: '>=12'}