diff --git a/react-ui/docs/README.md b/react-ui/docs/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..df992548adcb41a5a81426aed62508ccd7a5f37d
--- /dev/null
+++ b/react-ui/docs/README.md
@@ -0,0 +1,21 @@
+# goSDN - react ui
+The goSDN project is currently managed by a cli. With increased complexity it's getting harder and harder to manage, observe and debug this networks. This subproject provides an UI that keep large projects handable
+
+
+## Getting started
+Install all dependencies
+```
+yarn install
+yarn build::api
+```
+
+Run the local development server
+```
+yarn start
+```
+The ui is now accessible by `localhost:3000`
+
+
+
+## Development notes
+The ui can run independently from goSDN. But to actually get in touch with the ui, log in and start working with it you need a running goSDN instance on your local maschine. 
\ No newline at end of file
diff --git a/react-ui/package.json b/react-ui/package.json
index c178d3acbd186e6372802d3c1535bfe1e824fdc1..f1941701ca06ba93da67ce1f0552ae93a7042f13 100644
--- a/react-ui/package.json
+++ b/react-ui/package.json
@@ -3,6 +3,10 @@
     "version": "0.1.0",
     "private": true,
     "dependencies": {
+        "@fortawesome/fontawesome-svg-core": "^6.6.0",
+        "@fortawesome/free-regular-svg-icons": "^6.6.0",
+        "@fortawesome/free-solid-svg-icons": "^6.6.0",
+        "@fortawesome/react-fontawesome": "^0.2.2",
         "@reduxjs/toolkit": "^2.2.4",
         "@testing-library/jest-dom": "^6.4.8",
         "@testing-library/react": "^16.0.0",
diff --git a/react-ui/scripts/openapi-config.json b/react-ui/scripts/openapi-config.json
index f4246e54856af3088e263bf1670c647706844dcb..dbb9a84afe6e82a99fd944284fe5e080c88e11a4 100644
--- a/react-ui/scripts/openapi-config.json
+++ b/react-ui/scripts/openapi-config.json
@@ -6,5 +6,6 @@
   "exportName": "api",
   "hooks": true,
   "nullSafeAdditionalProps": true,
-  "withInterfaces": true
+  "withInterfaces": true,
+  "tag": true
 }
\ No newline at end of file
diff --git a/react-ui/src/components/view/login/login.tsx b/react-ui/src/components/view/login/login.tsx
index 919aa44018ea4b4089ec270ea2c1f8f459504e69..fe3b6369cb1d242834265f9b76b48f0f523f19c8 100644
--- a/react-ui/src/components/view/login/login.tsx
+++ b/react-ui/src/components/view/login/login.tsx
@@ -1,14 +1,14 @@
-import { Button, Col, Container, Form, Image, Row } from 'react-bootstrap'
+import { Alert, Button, Col, Container, Form, Image, Row, Spinner } from 'react-bootstrap'
 import { useTranslation } from 'react-i18next'
 import './login.scss'
 
 import logo from '@assets/logo.svg'
-import React, { useRef } from 'react'
 import useLoginViewModel from '@viewmodel/login.viewmodel'
+import React, { useRef } from 'react'
 
 const LoginPage = () => {
     const { t } = useTranslation('common')
-    const { valid, login, handleErrorMessageRendering } = useLoginViewModel();
+    const { login, handleErrorMessageRendering, displayFormFieldChecks, loginLoading } = useLoginViewModel();
 
 
     const usernameRef = useRef<HTMLInputElement>(null)
@@ -22,7 +22,9 @@ const LoginPage = () => {
         login(username, password);
     }
 
-    const invalidCredentials = (<div className="danger-box">{t('login.form.failed')}</div>)
+    const invalidForm = (<Alert variant="warning">{t('login.form.invalid')}</Alert>)
+    const invalidCredentials = (<Alert variant="danger">{t('login.form.failed')}</Alert>)
+
 
     return (
         <Container className="vh-100 d-flex flex-column justify-content-center login-container">
@@ -33,9 +35,9 @@ const LoginPage = () => {
                 <Col md={6} sm={10} className="c-box p-4">
                     <h1 className="text-center h2">goSDN - Web</h1>
 
-                    {handleErrorMessageRendering(invalidCredentials)}
+                    {handleErrorMessageRendering(invalidForm, invalidCredentials)}
 
-                    <Form className="mt-4" noValidate validated={valid} onSubmit={triggerLogin}>
+                    <Form className="mt-4" noValidate validated={displayFormFieldChecks()} onSubmit={triggerLogin}>
                         <Form.Group
                             className="mb-3"
                             controlId="loginForm.username"
@@ -65,8 +67,14 @@ const LoginPage = () => {
                             variant="primary"
                             type="submit"
                             className="w-100 mt-3"
+                            disabled={loginLoading}
                         >
                             {t('global.form.submit')}
+                            {loginLoading &&
+                                <Spinner animation="border" size="sm" role="status">
+                                    <span className="visually-hidden">Loading...</span>
+                                </Spinner>
+                            }
                         </Button>
                     </Form>
                 </Col>
diff --git a/react-ui/src/components/view_model/login.viewmodel.ts b/react-ui/src/components/view_model/login.viewmodel.ts
index 341c9933f39b7d42ef4d4864a6a41dd51d5ca8c0..110507a653dcc5da702f00fe10a9f8e28ae95d6f 100644
--- a/react-ui/src/components/view_model/login.viewmodel.ts
+++ b/react-ui/src/components/view_model/login.viewmodel.ts
@@ -1,21 +1,43 @@
 import { AuthServiceLoginApiArg, AuthServiceLoginApiResponse, useAuthServiceLoginMutation } from "@api/api";
-import { LoginFormFields, setLoginFormFields, test } from '@reducer/login.reducer';
 import { setToken } from "@reducer/user.reducer";
-import { useDispatch, useSelector } from "react-redux";
-import { AppDispatch, RootState } from "src/stores";
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
+import { useDispatch } from "react-redux";
+import { AppDispatch } from "src/stores";
+
+export interface PageLoginState {
+    submitted: boolean,
+    valid: boolean,
+}
 
 export default function useLoginViewModel() {
-    const { form, backendResponse } = useSelector((state: RootState) => state.loginPageReducer);
     const dispatch = useDispatch<AppDispatch>();
 
     const [
         sendLogin,
+        { data: loginResponse, error: loginError, isLoading: loginLoading, reset: resetLogin }
     ] = useAuthServiceLoginMutation()
 
 
-    const handleErrorMessageRendering = (renderError: JSX.Element): JSX.Element | null => {
-        if (form.valid && !backendResponse.valid) {
-            return renderError;
+    const [localFormState, updateLocalFormState] = useState({
+        submitted: false,
+        valid: false,
+    });
+
+
+    useEffect(() => {
+        console.log('loginREsponse:' + loginResponse);
+    }, [loginResponse])
+
+    const handleErrorMessageRendering = (formInvalidError: JSX.Element, backendResponseError: JSX.Element): JSX.Element | null => {
+        // backend response check
+        console.log('loginError:' + loginError);
+        if (!!loginError) {
+            return backendResponseError;
+        }
+
+        // form invalid check
+        if (localFormState.submitted && !localFormState.valid) {
+            return formInvalidError;
         }
 
         return null;
@@ -36,6 +58,10 @@ export default function useLoginViewModel() {
         return payload;
     }
 
+    const isFormValid = (username: string | undefined, password: string | undefined): boolean => {
+        return !!username && !!password;
+    }
+
     /**
      * Tries to `/login` by using the input fields.
      * 
@@ -43,15 +69,14 @@ export default function useLoginViewModel() {
      * @param event Submit event
      */
     const loginHandler = (username: string | undefined, password: string | undefined) => {
-        const loginFormFields: LoginFormFields = {
-            username: username,
-            password: password
-        }
+        resetLogin();
+        const valid = isFormValid(username, password);
         
-        dispatch(setLoginFormFields(loginFormFields));
+        updateLocalFormState({ ...localFormState, valid, submitted: true })
         
-        // don“t execute it here, execute it by subscribing to the store
-        //executeLogin(username!, password!);
+        if (valid) {
+            executeLogin(username!, password!);
+        }
     }
 
     const executeLogin = (username: string, password: string) => {
@@ -69,10 +94,15 @@ export default function useLoginViewModel() {
         });
     }
 
+    const displayFormFieldChecks = (): boolean => {
+        return localFormState.submitted && !loginError;
+    }
+
 
     return {
+        displayFormFieldChecks,
         login: loginHandler,
-        valid: backendResponse.valid,
-        handleErrorMessageRendering
+        handleErrorMessageRendering: handleErrorMessageRendering,
+        loginLoading,
     }
 }
diff --git a/react-ui/src/i18n/locales/en/translations.json b/react-ui/src/i18n/locales/en/translations.json
index d03dd572d76703a380138d8afa992fad00b34439..12ffef164243424f962e2a3ff718a984fe6b1c26 100644
--- a/react-ui/src/i18n/locales/en/translations.json
+++ b/react-ui/src/i18n/locales/en/translations.json
@@ -9,6 +9,7 @@
         "login": {
             "form": {
                 "failed": "The username or password is invalid",
+                "invalid": "Please type a username and password",
                 "username": {
                     "label": "Username"
                 },
diff --git a/react-ui/src/index.tsx b/react-ui/src/index.tsx
index 89858eea3fd2d89c8f88d732b242351ab4f7c77c..8441405d05e410c0c6d4d5a74794a54d027ff27a 100644
--- a/react-ui/src/index.tsx
+++ b/react-ui/src/index.tsx
@@ -1,3 +1,4 @@
+import './index.scss'
 import React from 'react'
 import ReactDOM, { Container } from 'react-dom/client'
 import {
@@ -7,7 +8,6 @@ import {
     createBrowserRouter,
     createRoutesFromElements,
 } from 'react-router-dom'
-import './index.scss'
 import Landingpage from './components/view/landingpage/landingpage'
 import LoginPage from './components/view/login/login'
 
@@ -18,6 +18,8 @@ import { Provider } from 'react-redux'
 import { persistor, store } from './stores'
 import { ToastContainer } from 'react-toastify'
 import { PersistGate } from 'redux-persist/integration/react'
+import './utils/icons/icons';
+
 
 const root = ReactDOM.createRoot(document.getElementById('root') as Container)
 
diff --git a/react-ui/src/stores/reducer/login.reducer.ts b/react-ui/src/stores/reducer/login.reducer.ts
index aba3865767634bdd82d237b381444a6457c37378..7016aa72335a6a2eda986706818438114687cee6 100644
--- a/react-ui/src/stores/reducer/login.reducer.ts
+++ b/react-ui/src/stores/reducer/login.reducer.ts
@@ -1,24 +1,8 @@
 import { PayloadAction, createSlice } from '@reduxjs/toolkit';
 import { startListening } from '../middleware/listener.middleware';
-import { useAuthServiceLoginMutation } from '@api/api';
+import { AuthServiceLoginApiArg, RbacUser, api, useAuthServiceLoginMutation } from '@api/api';
 
-export interface LoginFormFields {
-    username?: string,
-    password?: string
-}
-
-export interface PageLoginState {
-    form: {
-        valid: boolean,
-        fields: LoginFormFields
-    },
-    backendResponse: {
-        valid: boolean,
-        send: boolean
-    }
-}
-
-const initialState: PageLoginState = {
+const initialState = {
     backendResponse: {
         valid: false,
         send: false
@@ -37,28 +21,29 @@ const loginSlice = createSlice({
     initialState,
     reducers: {
         setLoginBackendCheck: (state, action: PayloadAction<boolean>) => { state.backendResponse.send = action.payload },
-        setLoginFormFields: (state, action: PayloadAction<LoginFormFields>) => {
-            const valid = !!action.payload.username && !!action.payload.password;
-            state.form.valid = valid;
 
-            if (valid) {
-                state.form.fields = action.payload
-            }
-        },
+        loginSuccess: (state, action: PayloadAction<string>) => {
+            state.backendResponse.valid = true;
+        }
     },
 })
 
 export const { setLoginBackendCheck } = loginSlice.actions
-export const { setLoginFormFields } = loginSlice.actions
 
 export default loginSlice.reducer
 
 
-startListening({
-    actionCreator: setLoginFormFields,
-
-    effect: async (action, listenerApi) => {
-        console.log('oh baby');
-
-      },
-})
\ No newline at end of file
+// startListening({
+//     actionCreator: setLoginFormFields,
+
+//     effect: async (action, listenerApi) => {
+//         const payload: AuthServiceLoginApiArg = {
+//             rbacLoginRequest: {
+//                 username: action.payload.username,
+//                 pwd: action.payload.password,
+//                 timestamp: new Date().getTime().toString(),
+//             },
+//         }
+//         listenerApi.dispatch(api.endpoints.authServiceLogin.initiate(payload));
+//       },
+// })
\ No newline at end of file
diff --git a/react-ui/src/stores/reducer/user.reducer.ts b/react-ui/src/stores/reducer/user.reducer.ts
index ef540c3342eb34f0978b8e1364176eba91219f61..d1a3c99cad3f033f1496ac6a8119f26fdcb52ced 100644
--- a/react-ui/src/stores/reducer/user.reducer.ts
+++ b/react-ui/src/stores/reducer/user.reducer.ts
@@ -1,12 +1,15 @@
 import { PayloadAction, createSlice } from '@reduxjs/toolkit';
+import { RbacUser } from '../../utils/api/api';
 
 export interface UserSliceState {
     token: string,
+    user: RbacUser | null,
 }
 
 
 const initialState: UserSliceState = {
-    token: ''
+    token: '',
+    user: null
 }
 
 
diff --git a/react-ui/src/style/box.scss b/react-ui/src/style/box.scss
index e705404c9e0c0d29b2e565366981a71889034bc5..e7a3ca7d39c2c5363d62b7379ae2358a5d0693a1 100644
--- a/react-ui/src/style/box.scss
+++ b/react-ui/src/style/box.scss
@@ -11,10 +11,16 @@ $border-radius: 10px;
     border-radius: $border-radius;
 }
 
-.danger-box {
-    background-color: map-get($theme-colors, 'danger') !important;
-    border-radius: calc($border-radius / 2);
-
+.abstract-box {
     padding: 16px $box-padding;
     font-size: .90em;
-}
\ No newline at end of file
+    border-radius: calc($border-radius / 2);
+}
+
+
+// @each $color, $value in $theme-colors {
+//     .#{$color}-box {
+//         @extend .abstract-box;
+//         background-color: $value !important;
+//     }
+// }
diff --git a/react-ui/src/style/colors.scss b/react-ui/src/style/colors.scss
index 1f11a48f3ae4842fc1a7f8da9127915f12cc4607..a10e9eafeacfd287625cdb17c389878782241185 100644
--- a/react-ui/src/style/colors.scss
+++ b/react-ui/src/style/colors.scss
@@ -2,6 +2,7 @@ $theme-colors: (
   'primary': #b350e0,
   'bg-primary': #E1E1E1,
   'danger': #ffdcdc,
+  'warning': #dbd116,
 );
   
 @import '/node_modules/bootstrap/scss/bootstrap';
diff --git a/react-ui/src/utils/api/api.ts b/react-ui/src/utils/api/api.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a5d1ebd6b6cd5d8dba8a5b00540f632e206e73ff
--- /dev/null
+++ b/react-ui/src/utils/api/api.ts
@@ -0,0 +1,1283 @@
+import { emptySplitApi as api } from '../../stores/api.store'
+export const addTagTypes = [
+    'AppService',
+    'ConfigurationManagementService',
+    'AuthService',
+    'NetworkElementService',
+    'PndService',
+    'RoleService',
+    'RoutingTableService',
+    'TopologyService',
+    'UserService',
+] as const
+const injectedRtkApi = api
+    .enhanceEndpoints({
+        addTagTypes,
+    })
+    .injectEndpoints({
+        endpoints: (build) => ({
+            appServiceDeregister: build.mutation<
+                AppServiceDeregisterApiResponse,
+                AppServiceDeregisterApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/deregister`,
+                    method: 'POST',
+                    body: queryArg.appAppDeregisterRequest,
+                }),
+                invalidatesTags: ['AppService'],
+            }),
+            configurationManagementServiceExportSdnConfig: build.query<
+                ConfigurationManagementServiceExportSdnConfigApiResponse,
+                ConfigurationManagementServiceExportSdnConfigApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/export/${queryArg.pid}`,
+                    params: { timestamp: queryArg.timestamp },
+                }),
+                providesTags: ['ConfigurationManagementService'],
+            }),
+            configurationManagementServiceImportSdnConfig: build.mutation<
+                ConfigurationManagementServiceImportSdnConfigApiResponse,
+                ConfigurationManagementServiceImportSdnConfigApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/import/${queryArg.pid}`,
+                    method: 'POST',
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        sdnConfigData: queryArg.sdnConfigData,
+                    },
+                }),
+                invalidatesTags: ['ConfigurationManagementService'],
+            }),
+            authServiceLogin: build.mutation<
+                AuthServiceLoginApiResponse,
+                AuthServiceLoginApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/login`,
+                    method: 'POST',
+                    body: queryArg.rbacLoginRequest,
+                }),
+                invalidatesTags: ['AuthService'],
+            }),
+            authServiceLogout: build.mutation<
+                AuthServiceLogoutApiResponse,
+                AuthServiceLogoutApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/logout/${queryArg.username}`,
+                    method: 'POST',
+                    params: { timestamp: queryArg.timestamp },
+                }),
+                invalidatesTags: ['AuthService'],
+            }),
+            networkElementServiceGetAllFlattened: build.query<
+                NetworkElementServiceGetAllFlattenedApiResponse,
+                NetworkElementServiceGetAllFlattenedApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/mnes`,
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        pid: queryArg.pid,
+                    },
+                }),
+                providesTags: ['NetworkElementService'],
+            }),
+            networkElementServiceAddList: build.mutation<
+                NetworkElementServiceAddListApiResponse,
+                NetworkElementServiceAddListApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/mnes`,
+                    method: 'POST',
+                    body: queryArg.networkelementAddListRequest,
+                }),
+                invalidatesTags: ['NetworkElementService'],
+            }),
+            networkElementServiceGetChangeList: build.query<
+                NetworkElementServiceGetChangeListApiResponse,
+                NetworkElementServiceGetChangeListApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/mnes/changes`,
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        pid: queryArg.pid,
+                    },
+                }),
+                providesTags: ['NetworkElementService'],
+            }),
+            networkElementServiceSetChangeList: build.mutation<
+                NetworkElementServiceSetChangeListApiResponse,
+                NetworkElementServiceSetChangeListApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/mnes/changes`,
+                    method: 'POST',
+                    body: queryArg.networkelementSetChangeListRequest,
+                }),
+                invalidatesTags: ['NetworkElementService'],
+            }),
+            networkElementServiceGetChange: build.query<
+                NetworkElementServiceGetChangeApiResponse,
+                NetworkElementServiceGetChangeApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/mnes/changes/${queryArg.cuid}`,
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        pid: queryArg.pid,
+                    },
+                }),
+                providesTags: ['NetworkElementService'],
+            }),
+            networkElementServiceSetPathList: build.mutation<
+                NetworkElementServiceSetPathListApiResponse,
+                NetworkElementServiceSetPathListApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/mnes/paths`,
+                    method: 'POST',
+                    body: queryArg.networkelementSetPathListRequest,
+                }),
+                invalidatesTags: ['NetworkElementService'],
+            }),
+            networkElementServiceGet: build.query<
+                NetworkElementServiceGetApiResponse,
+                NetworkElementServiceGetApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/mnes/${queryArg.mneid}`,
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        pid: queryArg.pid,
+                    },
+                }),
+                providesTags: ['NetworkElementService'],
+            }),
+            networkElementServiceDelete: build.mutation<
+                NetworkElementServiceDeleteApiResponse,
+                NetworkElementServiceDeleteApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/mnes/${queryArg.mneid}`,
+                    method: 'DELETE',
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        pid: queryArg.pid,
+                    },
+                }),
+                invalidatesTags: ['NetworkElementService'],
+            }),
+            networkElementServiceGetIntendedPath: build.query<
+                NetworkElementServiceGetIntendedPathApiResponse,
+                NetworkElementServiceGetIntendedPathApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/mnes/${queryArg.mneid}/intendedpaths/${queryArg.intendedPath}`,
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        pid: queryArg.pid,
+                    },
+                }),
+                providesTags: ['NetworkElementService'],
+            }),
+            networkElementServiceGetPath: build.query<
+                NetworkElementServiceGetPathApiResponse,
+                NetworkElementServiceGetPathApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/mnes/${queryArg.mneid}/paths/${queryArg.path}`,
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        pid: queryArg.pid,
+                    },
+                }),
+                providesTags: ['NetworkElementService'],
+            }),
+            networkElementServiceUpdate: build.mutation<
+                NetworkElementServiceUpdateApiResponse,
+                NetworkElementServiceUpdateApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/network-element/update`,
+                    method: 'POST',
+                    body: queryArg.networkelementUpdateNetworkElementRequest,
+                }),
+                invalidatesTags: ['NetworkElementService'],
+            }),
+            pndServiceGetPnd: build.query<
+                PndServiceGetPndApiResponse,
+                PndServiceGetPndApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/pnd/${queryArg.pid}`,
+                    params: { timestamp: queryArg.timestamp },
+                }),
+                providesTags: ['PndService'],
+            }),
+            pndServiceGetPndList: build.query<
+                PndServiceGetPndListApiResponse,
+                PndServiceGetPndListApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/pnds`,
+                    params: { timestamp: queryArg.timestamp },
+                }),
+                providesTags: ['PndService'],
+            }),
+            pndServiceCreatePndList: build.mutation<
+                PndServiceCreatePndListApiResponse,
+                PndServiceCreatePndListApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/pnds`,
+                    method: 'POST',
+                    body: queryArg.pndCreatePndListRequest,
+                }),
+                invalidatesTags: ['PndService'],
+            }),
+            pndServiceDeletePnd: build.mutation<
+                PndServiceDeletePndApiResponse,
+                PndServiceDeletePndApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/pnds/${queryArg.pid}`,
+                    method: 'DELETE',
+                    params: { timestamp: queryArg.timestamp },
+                }),
+                invalidatesTags: ['PndService'],
+            }),
+            appServiceRegister: build.mutation<
+                AppServiceRegisterApiResponse,
+                AppServiceRegisterApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/register`,
+                    method: 'POST',
+                    body: queryArg.appAppRegisterRequest,
+                }),
+                invalidatesTags: ['AppService'],
+            }),
+            roleServiceGetRoles: build.query<
+                RoleServiceGetRolesApiResponse,
+                RoleServiceGetRolesApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/roles`,
+                    params: { timestamp: queryArg.timestamp },
+                }),
+                providesTags: ['RoleService'],
+            }),
+            roleServiceCreateRoles: build.mutation<
+                RoleServiceCreateRolesApiResponse,
+                RoleServiceCreateRolesApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/roles/create`,
+                    method: 'POST',
+                    body: queryArg.rbacCreateRolesRequest,
+                }),
+                invalidatesTags: ['RoleService'],
+            }),
+            roleServiceDeleteRoles: build.mutation<
+                RoleServiceDeleteRolesApiResponse,
+                RoleServiceDeleteRolesApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/roles/delete`,
+                    method: 'DELETE',
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        roleName: queryArg.roleName,
+                    },
+                }),
+                invalidatesTags: ['RoleService'],
+            }),
+            roleServiceDeletePermissionsForRole: build.mutation<
+                RoleServiceDeletePermissionsForRoleApiResponse,
+                RoleServiceDeletePermissionsForRoleApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/roles/delete/permissions`,
+                    method: 'DELETE',
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        roleName: queryArg.roleName,
+                        permissionsToDelete: queryArg.permissionsToDelete,
+                    },
+                }),
+                invalidatesTags: ['RoleService'],
+            }),
+            roleServiceGetRole: build.query<
+                RoleServiceGetRoleApiResponse,
+                RoleServiceGetRoleApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/roles/get`,
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        roleName: queryArg.roleName,
+                        id: queryArg.id,
+                    },
+                }),
+                providesTags: ['RoleService'],
+            }),
+            roleServiceUpdateRoles: build.mutation<
+                RoleServiceUpdateRolesApiResponse,
+                RoleServiceUpdateRolesApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/roles/update`,
+                    method: 'POST',
+                    body: queryArg.rbacUpdateRolesRequest,
+                }),
+                invalidatesTags: ['RoleService'],
+            }),
+            routingTableServiceGetRoutes: build.query<
+                RoutingTableServiceGetRoutesApiResponse,
+                RoutingTableServiceGetRoutesApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/routing`,
+                    params: { timestamp: queryArg.timestamp },
+                }),
+                providesTags: ['RoutingTableService'],
+            }),
+            routingTableServiceAddRoutingTable: build.mutation<
+                RoutingTableServiceAddRoutingTableApiResponse,
+                RoutingTableServiceAddRoutingTableApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/routing/create`,
+                    method: 'POST',
+                    body: queryArg.topologyAddRoutingTableRequest,
+                }),
+                invalidatesTags: ['RoutingTableService'],
+            }),
+            routingTableServiceDeleteRoute: build.mutation<
+                RoutingTableServiceDeleteRouteApiResponse,
+                RoutingTableServiceDeleteRouteApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/routing/delete`,
+                    method: 'DELETE',
+                    params: { timestamp: queryArg.timestamp, id: queryArg.id },
+                }),
+                invalidatesTags: ['RoutingTableService'],
+            }),
+            topologyServiceGetTopology: build.query<
+                TopologyServiceGetTopologyApiResponse,
+                TopologyServiceGetTopologyApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/topology`,
+                    params: { timestamp: queryArg.timestamp },
+                }),
+                providesTags: ['TopologyService'],
+            }),
+            topologyServiceAddLink: build.mutation<
+                TopologyServiceAddLinkApiResponse,
+                TopologyServiceAddLinkApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/topology/create`,
+                    method: 'POST',
+                    body: queryArg.topologyAddLinkRequest,
+                }),
+                invalidatesTags: ['TopologyService'],
+            }),
+            topologyServiceDeleteLink: build.mutation<
+                TopologyServiceDeleteLinkApiResponse,
+                TopologyServiceDeleteLinkApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/topology/delete`,
+                    method: 'DELETE',
+                    params: { timestamp: queryArg.timestamp, id: queryArg.id },
+                }),
+                invalidatesTags: ['TopologyService'],
+            }),
+            topologyServiceUpdateLink: build.mutation<
+                TopologyServiceUpdateLinkApiResponse,
+                TopologyServiceUpdateLinkApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/topology/update`,
+                    method: 'POST',
+                    body: queryArg.topologyUpdateLinkRequest,
+                }),
+                invalidatesTags: ['TopologyService'],
+            }),
+            userServiceGetUsers: build.query<
+                UserServiceGetUsersApiResponse,
+                UserServiceGetUsersApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/users`,
+                    params: { timestamp: queryArg.timestamp },
+                }),
+                providesTags: ['UserService'],
+            }),
+            userServiceCreateUsers: build.mutation<
+                UserServiceCreateUsersApiResponse,
+                UserServiceCreateUsersApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/users/create`,
+                    method: 'POST',
+                    body: queryArg.rbacCreateUsersRequest,
+                }),
+                invalidatesTags: ['UserService'],
+            }),
+            userServiceDeleteUsers: build.mutation<
+                UserServiceDeleteUsersApiResponse,
+                UserServiceDeleteUsersApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/users/delete`,
+                    method: 'DELETE',
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        username: queryArg.username,
+                    },
+                }),
+                invalidatesTags: ['UserService'],
+            }),
+            userServiceGetUser: build.query<
+                UserServiceGetUserApiResponse,
+                UserServiceGetUserApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/users/get`,
+                    params: {
+                        timestamp: queryArg.timestamp,
+                        name: queryArg.name,
+                        id: queryArg.id,
+                    },
+                }),
+                providesTags: ['UserService'],
+            }),
+            userServiceUpdateUsers: build.mutation<
+                UserServiceUpdateUsersApiResponse,
+                UserServiceUpdateUsersApiArg
+            >({
+                query: (queryArg) => ({
+                    url: `/users/update`,
+                    method: 'POST',
+                    body: queryArg.rbacUpdateUsersRequest,
+                }),
+                invalidatesTags: ['UserService'],
+            }),
+        }),
+        overrideExisting: false,
+    })
+export { injectedRtkApi as api }
+export type AppServiceDeregisterApiResponse =
+    /** status 200 A successful response. */ AppAppDeregisterResponse
+export type AppServiceDeregisterApiArg = {
+    appAppDeregisterRequest: AppAppDeregisterRequest
+}
+export type ConfigurationManagementServiceExportSdnConfigApiResponse =
+    /** status 200 A successful response. */ ConfigurationmanagementExportSdnConfigResponse
+export type ConfigurationManagementServiceExportSdnConfigApiArg = {
+    pid: string
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+}
+export type ConfigurationManagementServiceImportSdnConfigApiResponse =
+    /** status 200 A successful response. */ ConfigurationmanagementImportSdnConfigResponse
+export type ConfigurationManagementServiceImportSdnConfigApiArg = {
+    pid: string
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    sdnConfigData?: string
+}
+export type AuthServiceLoginApiResponse =
+    /** status 200 A successful response. */ RbacLoginResponse
+export type AuthServiceLoginApiArg = {
+    rbacLoginRequest: Login
+}
+export type AuthServiceLogoutApiResponse =
+    /** status 200 A successful response. */ RbacLogoutResponse
+export type AuthServiceLogoutApiArg = {
+    username: string
+    timestamp?: string
+}
+export type NetworkElementServiceGetAllFlattenedApiResponse =
+    /** status 200 A successful response. */ NetworkelementGetAllFlattenedResponse
+export type NetworkElementServiceGetAllFlattenedApiArg = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pid?: string
+}
+export type NetworkElementServiceAddListApiResponse =
+    /** status 200 A successful response. */ NetworkelementAddListResponse
+export type NetworkElementServiceAddListApiArg = {
+    networkelementAddListRequest: NetworkelementAddListRequest
+}
+export type NetworkElementServiceGetChangeListApiResponse =
+    /** status 200 A successful response. */ NetworkelementGetChangeListResponse
+export type NetworkElementServiceGetChangeListApiArg = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pid?: string
+}
+export type NetworkElementServiceSetChangeListApiResponse =
+    /** status 200 A successful response. */ NetworkelementSetChangeListResponse
+export type NetworkElementServiceSetChangeListApiArg = {
+    networkelementSetChangeListRequest: NetworkelementSetChangeListRequest
+}
+export type NetworkElementServiceGetChangeApiResponse =
+    /** status 200 A successful response. */ NetworkelementGetChangeResponse
+export type NetworkElementServiceGetChangeApiArg = {
+    cuid: string[]
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pid?: string
+}
+export type NetworkElementServiceSetPathListApiResponse =
+    /** status 200 A successful response. */ NetworkelementSetPathListResponse
+export type NetworkElementServiceSetPathListApiArg = {
+    networkelementSetPathListRequest: NetworkelementSetPathListRequest
+}
+export type NetworkElementServiceGetApiResponse =
+    /** status 200 A successful response. */ GosdnnetworkelementGetResponse
+export type NetworkElementServiceGetApiArg = {
+    mneid: string
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pid?: string
+}
+export type NetworkElementServiceDeleteApiResponse =
+    /** status 200 A successful response. */ GosdnnetworkelementDeleteResponse
+export type NetworkElementServiceDeleteApiArg = {
+    mneid: string
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pid?: string
+}
+export type NetworkElementServiceGetIntendedPathApiResponse =
+    /** status 200 A successful response. */ NetworkelementGetIntendedPathResponse
+export type NetworkElementServiceGetIntendedPathApiArg = {
+    mneid: string
+    intendedPath: string
+    timestamp?: string
+    pid?: string
+}
+export type NetworkElementServiceGetPathApiResponse =
+    /** status 200 A successful response. */ NetworkelementGetPathResponse
+export type NetworkElementServiceGetPathApiArg = {
+    mneid: string
+    path: string
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pid?: string
+}
+export type NetworkElementServiceUpdateApiResponse =
+    /** status 200 A successful response. */ NetworkelementUpdateNetworkElementResponse
+export type NetworkElementServiceUpdateApiArg = {
+    networkelementUpdateNetworkElementRequest: TodoChangeNameToFitTheRest
+}
+export type PndServiceGetPndApiResponse =
+    /** status 200 A successful response. */ PndGetPndResponse
+export type PndServiceGetPndApiArg = {
+    pid: string
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+}
+export type PndServiceGetPndListApiResponse =
+    /** status 200 A successful response. */ PndGetPndListResponse
+export type PndServiceGetPndListApiArg = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+}
+export type PndServiceCreatePndListApiResponse =
+    /** status 200 A successful response. */ PndCreatePndListResponse
+export type PndServiceCreatePndListApiArg = {
+    pndCreatePndListRequest: PndCreatePndListRequest
+}
+export type PndServiceDeletePndApiResponse =
+    /** status 200 A successful response. */ PndDeletePndResponse
+export type PndServiceDeletePndApiArg = {
+    pid: string
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+}
+export type AppServiceRegisterApiResponse =
+    /** status 200 A successful response. */ AppAppRegisterResponse
+export type AppServiceRegisterApiArg = {
+    appAppRegisterRequest: AppAppRegisterRequest
+}
+export type RoleServiceGetRolesApiResponse =
+    /** status 200 A successful response. */ RbacGetRolesResponse
+export type RoleServiceGetRolesApiArg = {
+    timestamp?: string
+}
+export type RoleServiceCreateRolesApiResponse =
+    /** status 200 A successful response. */ RbacCreateRolesResponse
+export type RoleServiceCreateRolesApiArg = {
+    rbacCreateRolesRequest: CreateRoles
+}
+export type RoleServiceDeleteRolesApiResponse =
+    /** status 200 A successful response. */ RbacDeleteRolesResponse
+export type RoleServiceDeleteRolesApiArg = {
+    timestamp?: string
+    roleName?: string[]
+}
+export type RoleServiceDeletePermissionsForRoleApiResponse =
+    /** status 200 A successful response. */ RbacDeletePermissionsForRoleResponse
+export type RoleServiceDeletePermissionsForRoleApiArg = {
+    timestamp?: string
+    roleName?: string
+    permissionsToDelete?: string[]
+}
+export type RoleServiceGetRoleApiResponse =
+    /** status 200 A successful response. */ RbacGetRoleResponse
+export type RoleServiceGetRoleApiArg = {
+    timestamp?: string
+    roleName?: string
+    id?: string
+}
+export type RoleServiceUpdateRolesApiResponse =
+    /** status 200 A successful response. */ RbacUpdateRolesResponse
+export type RoleServiceUpdateRolesApiArg = {
+    rbacUpdateRolesRequest: UpdateRoles
+}
+export type RoutingTableServiceGetRoutesApiResponse =
+    /** status 200 A successful response. */ TopologyGetRoutesResponse
+export type RoutingTableServiceGetRoutesApiArg = {
+    timestamp?: string
+}
+export type RoutingTableServiceAddRoutingTableApiResponse =
+    /** status 200 A successful response. */ TopologyAddRoutingTableResponse
+export type RoutingTableServiceAddRoutingTableApiArg = {
+    topologyAddRoutingTableRequest: TopologyAddRoutingTableRequest
+}
+export type RoutingTableServiceDeleteRouteApiResponse =
+    /** status 200 A successful response. */ TopologyDeleteRoutesResponse
+export type RoutingTableServiceDeleteRouteApiArg = {
+    timestamp?: string
+    id?: string
+}
+export type TopologyServiceGetTopologyApiResponse =
+    /** status 200 A successful response. */ TopologyGetTopologyResponse
+export type TopologyServiceGetTopologyApiArg = {
+    timestamp?: string
+}
+export type TopologyServiceAddLinkApiResponse =
+    /** status 200 A successful response. */ TopologyAddLinkResponse
+export type TopologyServiceAddLinkApiArg = {
+    topologyAddLinkRequest: TopologyAddLinkRequest
+}
+export type TopologyServiceDeleteLinkApiResponse =
+    /** status 200 A successful response. */ TopologyDeleteLinkResponse
+export type TopologyServiceDeleteLinkApiArg = {
+    timestamp?: string
+    id?: string
+}
+export type TopologyServiceUpdateLinkApiResponse =
+    /** status 200 A successful response. */ TopologyUpdateLinkResponse
+export type TopologyServiceUpdateLinkApiArg = {
+    topologyUpdateLinkRequest: TopologyUpdateLinkRequest
+}
+export type UserServiceGetUsersApiResponse =
+    /** status 200 A successful response. */ RbacGetUsersResponse
+export type UserServiceGetUsersApiArg = {
+    timestamp?: string
+}
+export type UserServiceCreateUsersApiResponse =
+    /** status 200 A successful response. */ RbacCreateUsersResponse
+export type UserServiceCreateUsersApiArg = {
+    rbacCreateUsersRequest: CreateUsers
+}
+export type UserServiceDeleteUsersApiResponse =
+    /** status 200 A successful response. */ RbacDeleteUsersResponse
+export type UserServiceDeleteUsersApiArg = {
+    timestamp?: string
+    username?: string[]
+}
+export type UserServiceGetUserApiResponse =
+    /** status 200 A successful response. */ RbacGetUserResponse
+export type UserServiceGetUserApiArg = {
+    timestamp?: string
+    /** TODO(faseid): reconsider if this is necessary as required, but id is not? */
+    name?: string
+    id?: string
+}
+export type UserServiceUpdateUsersApiResponse =
+    /** status 200 A successful response. */ RbacUpdateUsersResponse
+export type UserServiceUpdateUsersApiArg = {
+    rbacUpdateUsersRequest: UpdateUsers
+}
+export type AppAppDeregisterResponse = {
+    timestamp?: string
+}
+export type ProtobufAny = {
+    /** A URL/resource name that uniquely identifies the type of the serialized
+    protocol buffer message. This string must contain at least
+    one "/" character. The last segment of the URL's path must represent
+    the fully qualified name of the type (as in
+    `path/google.protobuf.Duration`). The name should be in a canonical form
+    (e.g., leading "." is not accepted).
+    
+    In practice, teams usually precompile into the binary all types that they
+    expect it to use in the context of Any. However, for URLs which use the
+    scheme `http`, `https`, or no scheme, one can optionally set up a type
+    server that maps type URLs to message definitions as follows:
+    
+    * If no scheme is provided, `https` is assumed.
+    * An HTTP GET on the URL must yield a [google.protobuf.Type][]
+      value in binary format, or produce an error.
+    * Applications are allowed to cache lookup results based on the
+      URL, or have them precompiled into a binary to avoid any
+      lookup. Therefore, binary compatibility needs to be preserved
+      on changes to types. (Use versioned type names to manage
+      breaking changes.)
+    
+    Note: this functionality is not currently available in the official
+    protobuf release, and it is not used for type URLs beginning with
+    type.googleapis.com. As of May 2023, there are no widely used type server
+    implementations and no plans to implement one.
+    
+    Schemes other than `http`, `https` (or the empty scheme) might be
+    used with implementation specific semantics. */
+    '@type'?: string
+    [key: string]: any
+}
+export type GooglerpcStatus = {
+    code?: number
+    message?: string
+    details?: ProtobufAny[]
+}
+export type AppAppDeregisterRequest = {
+    timestamp?: string
+    appname?: string
+}
+export type ConfigurationmanagementExportSdnConfigResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    sdnConfigData?: string
+}
+export type ConfigurationmanagementImportSdnConfigResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+}
+export type RbacLoginResponse = {
+    timestamp?: string
+    token?: string
+}
+export type Login = {
+    timestamp?: string
+    username?: string
+    pwd?: string
+}
+export type RbacLogoutResponse = {
+    timestamp?: string
+}
+export type PndPrincipalNetworkDomain = {
+    id?: string
+    name?: string
+    description?: string
+}
+export type NetworkelementFlattenedManagedNetworkElement = {
+    id?: string
+    name?: string
+    pid?: string
+    pluginid?: string
+}
+export type NetworkelementGetAllFlattenedResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pnd?: PndPrincipalNetworkDomain
+    mne?: NetworkelementFlattenedManagedNetworkElement[]
+}
+export type GosdnnetworkelementSetResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    id?: string
+}
+export type NetworkelementAddListResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    responses?: GosdnnetworkelementSetResponse[]
+}
+export type EncodingDefinesTheValueEncodingFormatsThatAreSupportedByTheGNmiProtocolTheseEncodingsAreUsedByBothTheClientWhenSendingSetMessagesToModifyTheStateOfTheTargetAndTheTargetWhenSerializingDataToBeReturnedToTheClientInBothSubscribeAndGetRpCsReferenceGNmiSpecificationSection23 =
+    'JSON' | 'BYTES' | 'PROTO' | 'ASCII' | 'JSON_IETF'
+export type TransportGnmiTransportOption = {
+    compression?: string
+    grpcDialOptions?: {
+        [key: string]: string
+    }
+    token?: string
+    encoding?: EncodingDefinesTheValueEncodingFormatsThatAreSupportedByTheGNmiProtocolTheseEncodingsAreUsedByBothTheClientWhenSendingSetMessagesToModifyTheStateOfTheTargetAndTheTargetWhenSerializingDataToBeReturnedToTheClientInBothSubscribeAndGetRpCsReferenceGNmiSpecificationSection23
+}
+export type TransportRestconfTransportOption = object
+export type ChangedAccordingToStyleGuideHttpsDocsBufBuildBestPracticesStyleGuideEnums =
+
+        | 'TYPE_UNSPECIFIED'
+        | 'TYPE_OPENCONFIG'
+        | 'TYPE_CONTAINERISED'
+        | 'TYPE_PLUGIN'
+export type TransportTransportOption = {
+    address?: string
+    username?: string
+    password?: string
+    tls?: boolean
+    gnmiTransportOption?: TransportGnmiTransportOption
+    restconfTransportOption?: TransportRestconfTransportOption
+    type?: ChangedAccordingToStyleGuideHttpsDocsBufBuildBestPracticesStyleGuideEnums
+}
+export type NetworkelementSetMne = {
+    address?: string
+    pid?: string
+    pluginId?: string
+    mneName?: string
+    transportOption?: TransportTransportOption
+    gnmiSubscribePaths?: string[]
+    mneId?: string
+}
+export type NetworkelementAddListRequest = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    mne?: NetworkelementSetMne[]
+    pid?: string
+}
+export type NetworkelementChangeState =
+    | 'CHANGE_STATE_UNSPECIFIED'
+    | 'CHANGE_STATE_PENDING'
+    | 'CHANGE_STATE_COMMITTED'
+    | 'CHANGE_STATE_CONFIRMED'
+    | 'CHANGE_STATE_INCONSISTENT'
+export type GnmiPathElem = {
+    /** The name of the element in the path. */
+    name?: string
+    /** Map of key (attribute) name to value. */
+    key?: {
+        [key: string]: string
+    }
+}
+export type GnmiPath = {
+    /** Elements of the path are no longer encoded as a string, but rather within
+    the elem field as a PathElem message. */
+    element?: string[]
+    /** Label to disambiguate path. */
+    origin?: string
+    /** Elements of the path. */
+    elem?: GnmiPathElem[]
+    target?: string
+}
+export type GnmiValue = {
+    /** Value of the variable being transmitted. */
+    value?: string
+    type?: EncodingDefinesTheValueEncodingFormatsThatAreSupportedByTheGNmiProtocolTheseEncodingsAreUsedByBothTheClientWhenSendingSetMessagesToModifyTheStateOfTheTargetAndTheTargetWhenSerializingDataToBeReturnedToTheClientInBothSubscribeAndGetRpCsReferenceGNmiSpecificationSection23
+}
+export type GnmiDecimal64 = {
+    /** Set of digits. */
+    digits?: string
+    /** Number of digits following the decimal point. */
+    precision?: number
+}
+export type GnmiScalarArray = {
+    /** The set of elements within the array. Each TypedValue message should
+    specify only elements that have a field identifier of 1-7 (i.e., the
+    values are scalar values). */
+    element?: GnmiTypedValue[]
+}
+export type GnmiTypedValue = {
+    /** String value. */
+    stringVal?: string
+    /** Integer value. */
+    intVal?: string
+    /** Unsigned integer value. */
+    uintVal?: string
+    /** Bool value. */
+    boolVal?: boolean
+    /** Arbitrary byte sequence value. */
+    bytesVal?: string
+    /** Floating point value. */
+    floatVal?: number
+    decimalVal?: GnmiDecimal64
+    leaflistVal?: GnmiScalarArray
+    anyVal?: ProtobufAny
+    /** JSON-encoded text. */
+    jsonVal?: string
+    /** JSON-encoded text per RFC7951. */
+    jsonIetfVal?: string
+    /** Arbitrary ASCII text. */
+    asciiVal?: string
+    /** Protobuf binary encoded bytes. The message type is not included.
+    See the specification at
+    github.com/openconfig/reference/blob/master/rpc/gnmi/protobuf-vals.md
+    for a complete specification. */
+    protoBytes?: string
+}
+export type UpdateIsAReUsableMessageThatIsUsedToStoreAParticularPathValuePairReferenceGNmiSpecificationSection21 =
+    {
+        path?: GnmiPath
+        value?: GnmiValue
+        val?: GnmiTypedValue
+        /** Number of coalesced duplicates. */
+        duplicates?: number
+    }
+export type NotificationIsAReUsableMessageThatIsUsedToEncodeDataFromTheTargetToTheClientANotificationCarriesTwoTypesOfChangesToTheDataTreeDeletedValuesDeleteASetOfPathsThatHaveBeenRemovedFromTheDataTreeUpdatedValuesUpdateASetOfPathValuePairsIndicatingThePathWhoseValueHasChangedInTheDataTreeReferenceGNmiSpecificationSection21 =
+    {
+        /** Timestamp in nanoseconds since Epoch. */
+        timestamp?: string
+        prefix?: GnmiPath
+        alias?: string
+        /** Data elements that have changed values. */
+        update?: UpdateIsAReUsableMessageThatIsUsedToStoreAParticularPathValuePairReferenceGNmiSpecificationSection21[]
+        /** Data elements that have been deleted. */
+        delete?: GnmiPath[]
+        /** This notification contains a set of paths that are always updated together
+    referenced by a globally unique prefix. */
+        atomic?: boolean
+    }
+export type NetworkelementChange = {
+    id?: string
+    age?: string
+    state?: NetworkelementChangeState
+    diff?: NotificationIsAReUsableMessageThatIsUsedToEncodeDataFromTheTargetToTheClientANotificationCarriesTwoTypesOfChangesToTheDataTreeDeletedValuesDeleteASetOfPathsThatHaveBeenRemovedFromTheDataTreeUpdatedValuesUpdateASetOfPathValuePairsIndicatingThePathWhoseValueHasChangedInTheDataTreeReferenceGNmiSpecificationSection21
+}
+export type NetworkelementGetChangeListResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pnd?: PndPrincipalNetworkDomain
+    change?: NetworkelementChange[]
+}
+export type NetworkelementSetChangeListResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    responses?: GosdnnetworkelementSetResponse[]
+}
+export type GosdnnetworkelementOperation =
+    | 'OPERATION_UNSPECIFIED'
+    | 'OPERATION_CREATE'
+    | 'OPERATION_COMMIT'
+    | 'OPERATION_CONFIRM'
+export type NetworkelementSetChange = {
+    cuid?: string
+    op?: GosdnnetworkelementOperation
+}
+export type NetworkelementSetChangeListRequest = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    change?: NetworkelementSetChange[]
+    pid?: string
+}
+export type NetworkelementGetChangeResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pnd?: PndPrincipalNetworkDomain
+    change?: NetworkelementChange[]
+}
+export type NetworkelementSetPathListResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    responses?: GosdnnetworkelementSetResponse[]
+}
+export type NetworkelementApiOperation =
+    | 'API_OPERATION_UNSPECIFIED'
+    | 'API_OPERATION_UPDATE'
+    | 'API_OPERATION_REPLACE'
+    | 'API_OPERATION_DELETE'
+export type NetworkelementChangeRequest = {
+    mneid?: string
+    path?: GnmiPath
+    value?: GnmiTypedValue
+    apiOp?: NetworkelementApiOperation
+}
+export type NetworkelementSetPathListRequest = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    changeRequest?: NetworkelementChangeRequest[]
+    pid?: string
+}
+export type PluginRegistryManifest = {
+    name?: string
+    firmware?: string
+    author?: string
+    version?: string
+}
+export type PluginRegistryPlugin = {
+    id?: string
+    manifest?: PluginRegistryManifest
+}
+export type ConflictMetadata = {
+    resourceVersion?: string
+}
+export type NetworkelementManagedNetworkElement = {
+    id?: string
+    name?: string
+    model?: string
+    plugin?: PluginRegistryPlugin
+    mneNotification?: NotificationIsAReUsableMessageThatIsUsedToEncodeDataFromTheTargetToTheClientANotificationCarriesTwoTypesOfChangesToTheDataTreeDeletedValuesDeleteASetOfPathsThatHaveBeenRemovedFromTheDataTreeUpdatedValuesUpdateASetOfPathValuePairsIndicatingThePathWhoseValueHasChangedInTheDataTreeReferenceGNmiSpecificationSection21[]
+    transportAddress?: string
+    transportOption?: TransportTransportOption
+    metadata?: ConflictMetadata
+    associatedPnd?: string
+    gnmiSubscribePaths?: string[]
+}
+export type GosdnnetworkelementGetResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pnd?: PndPrincipalNetworkDomain
+    mne?: NetworkelementManagedNetworkElement
+}
+export type GosdnnetworkelementDeleteResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+}
+export type NetworkelementGetIntendedPathResponse = {
+    timestamp?: string
+    pnd?: PndPrincipalNetworkDomain
+    mneNotification?: NotificationIsAReUsableMessageThatIsUsedToEncodeDataFromTheTargetToTheClientANotificationCarriesTwoTypesOfChangesToTheDataTreeDeletedValuesDeleteASetOfPathsThatHaveBeenRemovedFromTheDataTreeUpdatedValuesUpdateASetOfPathValuePairsIndicatingThePathWhoseValueHasChangedInTheDataTreeReferenceGNmiSpecificationSection21[]
+}
+export type NetworkelementGetPathResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pnd?: PndPrincipalNetworkDomain
+    mneNotification?: NotificationIsAReUsableMessageThatIsUsedToEncodeDataFromTheTargetToTheClientANotificationCarriesTwoTypesOfChangesToTheDataTreeDeletedValuesDeleteASetOfPathsThatHaveBeenRemovedFromTheDataTreeUpdatedValuesUpdateASetOfPathValuePairsIndicatingThePathWhoseValueHasChangedInTheDataTreeReferenceGNmiSpecificationSection21[]
+}
+export type NetworkelementUpdateNetworkElementResponse = {
+    timestamp?: string
+}
+export type TodoChangeNameToFitTheRest = {
+    timestamp?: string
+    networkElement?: NetworkelementManagedNetworkElement
+}
+export type PndGetPndResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pnd?: PndPrincipalNetworkDomain
+}
+export type PndGetPndListResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pnd?: PndPrincipalNetworkDomain[]
+}
+export type PndCreatePndListResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+}
+export type PndPndCreateProperties = {
+    name?: string
+    description?: string
+}
+export type PndCreatePndListRequest = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+    pnd?: PndPndCreateProperties[]
+}
+export type PndDeletePndResponse = {
+    /** Timestamp in nanoseconds since Epoch. */
+    timestamp?: string
+}
+export type AppAppRegisterResponse = {
+    timestamp?: string
+    queueconnection?: string
+}
+export type AppAppRegisterRequest = {
+    timestamp?: string
+    appname?: string
+    token?: string
+}
+export type GosdnrbacRole = {
+    id?: string
+    name?: string
+    description?: string
+    permissions?: string[]
+}
+export type RbacGetRolesResponse = {
+    timestamp?: string
+    roles?: GosdnrbacRole[]
+}
+export type RbacCreateRolesResponse = {
+    timestamp?: string
+}
+export type CreateRoles = {
+    timestamp?: string
+    roles?: GosdnrbacRole[]
+}
+export type RbacDeleteRolesResponse = {
+    timestamp?: string
+}
+export type RbacDeletePermissionsForRoleResponse = {
+    timestamp?: string
+}
+export type RbacGetRoleResponse = {
+    timestamp?: string
+    role?: GosdnrbacRole
+}
+export type RbacUpdateRolesResponse = {
+    timestamp?: string
+}
+export type UpdateRoles = {
+    timestamp?: string
+    roles?: GosdnrbacRole[]
+}
+export type TopologyRoute = {
+    id?: string
+    targetIPRange?: string
+    nextHopIP?: string
+    portID?: string
+    metric?: string
+}
+export type TopologyRoutingTable = {
+    id?: string
+    nodeID?: string
+    routes?: TopologyRoute[]
+    metadata?: ConflictMetadata
+}
+export type TopologyGetRoutesResponse = {
+    timestamp?: string
+    routingTables?: TopologyRoutingTable[]
+}
+export type TopologyAddRoutingTableResponse = {
+    timestamp?: string
+}
+export type TopologyAddRoutingTableRequest = {
+    timestamp?: string
+    routingTable?: TopologyRoutingTable
+}
+export type TopologyDeleteRoutesResponse = {
+    timestamp?: string
+}
+export type TopologyNode = {
+    id?: string
+    name?: string
+    metadata?: ConflictMetadata
+}
+export type GosdntopologyConfiguration = {
+    ip?: string
+    prefixLength?: string
+}
+export type TopologyPort = {
+    id?: string
+    name?: string
+    configuration?: GosdntopologyConfiguration
+    metadata?: ConflictMetadata
+}
+export type TopologyLink = {
+    id?: string
+    name?: string
+    sourceNode?: TopologyNode
+    targetNode?: TopologyNode
+    sourcePort?: TopologyPort
+    targetPort?: TopologyPort
+    metadata?: ConflictMetadata
+}
+export type TopologyTopology = {
+    links?: TopologyLink[]
+}
+export type TopologyGetTopologyResponse = {
+    timestamp?: string
+    toplogy?: TopologyTopology
+}
+export type TopologyAddLinkResponse = {
+    timestamp?: string
+}
+export type TopologyAddLinkRequest = {
+    timestamp?: string
+    link?: TopologyLink
+}
+export type TopologyDeleteLinkResponse = {
+    timestamp?: string
+}
+export type TopologyUpdateLinkResponse = {
+    timestamp?: string
+}
+export type TopologyUpdateLinkRequest = {
+    timestamp?: string
+    link?: TopologyLink
+}
+export type RbacUser = {
+    id?: string
+    name?: string
+    roles?: {
+        [key: string]: string
+    }
+    password?: string
+    token?: string
+    metadata?: ConflictMetadata
+}
+export type RbacGetUsersResponse = {
+    timestamp?: string
+    user?: RbacUser[]
+}
+export type RbacCreateUsersResponse = {
+    timestamp?: string
+}
+export type CreateUsers = {
+    timestamp?: string
+    user?: RbacUser[]
+}
+export type RbacDeleteUsersResponse = {
+    timestamp?: string
+}
+export type RbacGetUserResponse = {
+    timestamp?: string
+    user?: RbacUser
+}
+export type RbacUpdateUsersResponse = {
+    timestamp?: string
+}
+export type RbacUpdateUser = {
+    id?: string
+    name?: string
+    roles?: {
+        [key: string]: string
+    }
+    password?: string
+    token?: string
+    metadata?: ConflictMetadata
+}
+export type UpdateUsers = {
+    timestamp?: string
+    user?: RbacUpdateUser[]
+}
+export const {
+    useAppServiceDeregisterMutation,
+    useConfigurationManagementServiceExportSdnConfigQuery,
+    useConfigurationManagementServiceImportSdnConfigMutation,
+    useAuthServiceLoginMutation,
+    useAuthServiceLogoutMutation,
+    useNetworkElementServiceGetAllFlattenedQuery,
+    useNetworkElementServiceAddListMutation,
+    useNetworkElementServiceGetChangeListQuery,
+    useNetworkElementServiceSetChangeListMutation,
+    useNetworkElementServiceGetChangeQuery,
+    useNetworkElementServiceSetPathListMutation,
+    useNetworkElementServiceGetQuery,
+    useNetworkElementServiceDeleteMutation,
+    useNetworkElementServiceGetIntendedPathQuery,
+    useNetworkElementServiceGetPathQuery,
+    useNetworkElementServiceUpdateMutation,
+    usePndServiceGetPndQuery,
+    usePndServiceGetPndListQuery,
+    usePndServiceCreatePndListMutation,
+    usePndServiceDeletePndMutation,
+    useAppServiceRegisterMutation,
+    useRoleServiceGetRolesQuery,
+    useRoleServiceCreateRolesMutation,
+    useRoleServiceDeleteRolesMutation,
+    useRoleServiceDeletePermissionsForRoleMutation,
+    useRoleServiceGetRoleQuery,
+    useRoleServiceUpdateRolesMutation,
+    useRoutingTableServiceGetRoutesQuery,
+    useRoutingTableServiceAddRoutingTableMutation,
+    useRoutingTableServiceDeleteRouteMutation,
+    useTopologyServiceGetTopologyQuery,
+    useTopologyServiceAddLinkMutation,
+    useTopologyServiceDeleteLinkMutation,
+    useTopologyServiceUpdateLinkMutation,
+    useUserServiceGetUsersQuery,
+    useUserServiceCreateUsersMutation,
+    useUserServiceDeleteUsersMutation,
+    useUserServiceGetUserQuery,
+    useUserServiceUpdateUsersMutation,
+} = injectedRtkApi
diff --git a/react-ui/src/utils/icons/icons.ts b/react-ui/src/utils/icons/icons.ts
new file mode 100644
index 0000000000000000000000000000000000000000..00021aa116faae88600fd06ab461aabd41aee9bb
--- /dev/null
+++ b/react-ui/src/utils/icons/icons.ts
@@ -0,0 +1,4 @@
+import { library } from '@fortawesome/fontawesome-svg-core'
+import { faSpinner, fas } from '@fortawesome/free-solid-svg-icons'
+
+library.add(fas, faSpinner)
\ No newline at end of file
diff --git a/react-ui/tsconfig.json b/react-ui/tsconfig.json
index 17feecac27b637293c8d8d28d4ad26cf1a4d9d0d..761bbe68320f8da3a7c3c84d4702286606ca92c5 100644
--- a/react-ui/tsconfig.json
+++ b/react-ui/tsconfig.json
@@ -23,7 +23,7 @@
       "baseUrl": ".",
       "paths": {
           "@assets/*": ["assets/*"],
-          "@api/*": ["src/api/*"],
+          "@api/*": ["src/utils/api/*"],
           "@viewmodel/*": ["src/components/view_model/*"],
           "@view/*": ["src/components/view/*"],
           "@reducer/*": ["src/stores/reducer/*"],
diff --git a/react-ui/vite.config.mjs b/react-ui/vite.config.mjs
index 0e2caf6fd97830bd7b477b6410c7692124de4f18..d5f7d6a210042f88c9946c6913a876c98bd97392 100644
--- a/react-ui/vite.config.mjs
+++ b/react-ui/vite.config.mjs
@@ -29,7 +29,7 @@ export default defineConfig({
   resolve: {
     alias: {
       '@assets': '/assets',
-      '@api': '/src/api',
+      '@api': '/src/utils/api',
       "@viewmodel": "/src/components/view_model",
       "@view": "/src/components/view",
       "@reducer": "/src/stores/reducer",
diff --git a/react-ui/yarn.lock b/react-ui/yarn.lock
index b08ab4c98c55c69d545343a573ef2947070305f1..307e7506296fdaf3fb56da27acf3771713513a96 100644
--- a/react-ui/yarn.lock
+++ b/react-ui/yarn.lock
@@ -1494,6 +1494,39 @@
   resolved "https://registry.yarnpkg.com/@exodus/schemasafe/-/schemasafe-1.3.0.tgz#731656abe21e8e769a7f70a4d833e6312fe59b7f"
   integrity sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==
 
+"@fortawesome/fontawesome-common-types@6.6.0":
+  version "6.6.0"
+  resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz#31ab07ca6a06358c5de4d295d4711b675006163f"
+  integrity sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw==
+
+"@fortawesome/fontawesome-svg-core@^6.6.0":
+  version "6.6.0"
+  resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz#2a24c32ef92136e98eae2ff334a27145188295ff"
+  integrity sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg==
+  dependencies:
+    "@fortawesome/fontawesome-common-types" "6.6.0"
+
+"@fortawesome/free-regular-svg-icons@^6.6.0":
+  version "6.6.0"
+  resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.6.0.tgz#fc49a947ac8dfd20403c9ea5f37f0919425bdf04"
+  integrity sha512-Yv9hDzL4aI73BEwSEh20clrY8q/uLxawaQ98lekBx6t9dQKDHcDzzV1p2YtBGTtolYtNqcWdniOnhzB+JPnQEQ==
+  dependencies:
+    "@fortawesome/fontawesome-common-types" "6.6.0"
+
+"@fortawesome/free-solid-svg-icons@^6.6.0":
+  version "6.6.0"
+  resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz#061751ca43be4c4d814f0adbda8f006164ec9f3b"
+  integrity sha512-IYv/2skhEDFc2WGUcqvFJkeK39Q+HyPf5GHUrT/l2pKbtgEIv1al1TKd6qStR5OIwQdN1GZP54ci3y4mroJWjA==
+  dependencies:
+    "@fortawesome/fontawesome-common-types" "6.6.0"
+
+"@fortawesome/react-fontawesome@^0.2.2":
+  version "0.2.2"
+  resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz#68b058f9132b46c8599875f6a636dad231af78d4"
+  integrity sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==
+  dependencies:
+    prop-types "^15.8.1"
+
 "@humanwhocodes/config-array@^0.11.14":
   version "0.11.14"
   resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b"