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"