Skip to content
Snippets Groups Projects
Commit f9d97490 authored by Matthias Feyll's avatar Matthias Feyll
Browse files

wip before changing unsubscribe to category param

parent 6df3abc1
Branches
No related tags found
4 merge requests!1196[renovate] Update module golang.org/x/net to v0.32.0,!1195UI: implement add device functionality,!1167Ui refactor style,!1161Ui refactor style
import { PndServiceGetPndListApiArg, api } from "@api/api"
import { createAsyncThunk } from "@reduxjs/toolkit"
import { setPnds } from "../reducer/device.reducer"
export const fetchPnds = createAsyncThunk('device/fetchPnds', (_, thunkApi) => {
const payload: PndServiceGetPndListApiArg = {
timestamp: new Date().getTime().toString(),
}
const subscription = thunkApi.dispatch(api.endpoints.pndServiceGetPndList.initiate(payload))
subscription.unwrap().then((response) => {
thunkApi.dispatch(setPnds(response.pnd))
})
})
\ No newline at end of file
import { import {
api,
NetworkelementFlattenedManagedNetworkElement, NetworkelementFlattenedManagedNetworkElement,
NetworkelementManagedNetworkElement, NetworkelementManagedNetworkElement,
PndPrincipalNetworkDomain, PndPrincipalNetworkDomain
PndServiceGetPndListApiArg,
} from '@api/api' } from '@api/api'
import { DeviceViewTabValues } from '@component/devices/view/device.view.tabs' import { DeviceViewTabValues } from '@component/devices/view/device.view.tabs'
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit' import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { RootState } from 'src/stores' import { RootState } from 'src/stores'
import '../routines/index' import '../routines/index'
import { startListening } from '/src/stores/middleware/listener.middleware' import { startListening } from '/src/stores/middleware/listener.middleware'
...@@ -40,11 +38,11 @@ const deviceSlice = createSlice({ ...@@ -40,11 +38,11 @@ const deviceSlice = createSlice({
name: 'device', name: 'device',
initialState, initialState,
reducers: { reducers: {
setDevices: (state, action: PayloadAction<Device[]>) => { setDevices: (state, action: PayloadAction<Device[] | undefined>) => {
state.devices = action.payload state.devices = action.payload || []
}, },
setPnds: (state, action: PayloadAction<PndPrincipalNetworkDomain[]>) => { setPnds: (state, action: PayloadAction<PndPrincipalNetworkDomain[] | undefined>) => {
state.pnds = action.payload state.pnds = action.payload || []
}, },
setActiveTab: (state, action: PayloadAction<DeviceViewTabValues>) => { setActiveTab: (state, action: PayloadAction<DeviceViewTabValues>) => {
state.activeTab = action.payload state.activeTab = action.payload
...@@ -77,31 +75,23 @@ const deviceSlice = createSlice({ ...@@ -77,31 +75,23 @@ const deviceSlice = createSlice({
}, },
}) })
export const { setDevices, setActiveTab, setSelectedDevice, setSelectedMne, setSelectedJson } = export const { setDevices, setActiveTab, setSelectedDevice, setSelectedMne, setSelectedJson, setPnds } =
deviceSlice.actions deviceSlice.actions
const { setPnds } = deviceSlice.actions
export default deviceSlice.reducer export default deviceSlice.reducer
export const deviceReducerPath = deviceSlice.reducerPath export const deviceReducerPath = deviceSlice.reducerPath
export const fetchPnds = createAsyncThunk('device/fetchPnds', (_, thunkApi) => {
const payload: PndServiceGetPndListApiArg = {
timestamp: new Date().getTime().toString(),
}
const subscription = thunkApi.dispatch(api.endpoints.pndServiceGetPndList.initiate(payload))
subscription.unwrap().then((response) => {
thunkApi.dispatch(setPnds(response.pnd))
})
})
// add default selected device if no selected device is set // add default selected device if no selected device is set
startListening({ startListening({
predicate: (action) => setDevices.match(action), predicate: (action) => setDevices.match(action),
effect: async (action, listenerApi) => { effect: async (action, listenerApi) => {
const { device } = listenerApi.getOriginalState() as RootState const { device: state } = listenerApi.getOriginalState() as RootState
if (!device.selectedDevice && !!action.payload[0]) { if (state.selectedDevice) {
listenerApi.dispatch(setSelectedDevice(action.payload[0])) return
} }
// if there are no devices available do set null
const newDevices = action.payload?.[0] || null
listenerApi.dispatch(setSelectedDevice(newDevices))
}, },
}) })
...@@ -16,6 +16,7 @@ import { router } from './routes' ...@@ -16,6 +16,7 @@ import { router } from './routes'
import './shared/icons/icons' import './shared/icons/icons'
import { persistor, store } from './stores' import { persistor, store } from './stores'
window.env = window.location.hostname === 'localhost' ? 'development' : 'production';
ReactDOM.createRoot(document.getElementById("root")).render( ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode> <React.StrictMode>
......
import { createAsyncThunk } from "@reduxjs/toolkit"
import { setUser } from "@shared/reducer/user.reducer"
import { RootState } from "src/stores"
import { api, UserServiceGetUsersApiArg } from "./api"
export const fetchUser = createAsyncThunk('user/fetchUser', (_, thunkAPI) => {
const payload: UserServiceGetUsersApiArg = {}
thunkAPI.dispatch(api.endpoints.userServiceGetUsers.initiate(payload)).then((response) => {
if (response.error || !response.data?.user?.length) {
// TODO proper error handling
throw new Error('Fetching the pnd list after successful login failed')
}
const { user } = thunkAPI.getState() as RootState
const matchedUser = response.data.user.find((_user) => _user.name === user.username)
if (!matchedUser) {
// TODO proper error handling
throw new Error('No user found with the provided username')
}
thunkAPI.dispatch(setUser(matchedUser))
})
})
export const debugMessage = (message: string) => {
if (window?.env === 'development') {
console.warn("Debug: \n" + message)
}
}
\ No newline at end of file
import { fetchUser } from '@api/user.fetch';
import logo from '@assets/logo.svg'; import logo from '@assets/logo.svg';
import { fetchPnds } from '@component/devices/reducer/device.reducer'; import { fetchPnds } from '@component/devices/api/pnd.fetch';
import { faCircleUser, faRightFromBracket } from "@fortawesome/free-solid-svg-icons"; import { faCircleUser, faRightFromBracket } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { useAppDispatch, useAppSelector } from '@hooks'; import { useAppDispatch, useAppSelector } from '@hooks';
import { useAuth } from "@provider/auth.provider"; import { useAuth } from "@provider/auth.provider";
import { MenuProvider } from '@provider/menu/menu.provider'; import { MenuProvider } from '@provider/menu/menu.provider';
import { DEVICE_URL, LOGIN_URL } from '@routes'; import { DEVICE_URL, LOGIN_URL } from '@routes';
import { fetchUser } from '@shared/reducer/user.reducer';
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { Dropdown } from "react-bootstrap"; import { Dropdown } from "react-bootstrap";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
......
import { debugMessage } from '@helper/debug'
import { PayloadAction, createSlice } from '@reduxjs/toolkit' import { PayloadAction, createSlice } from '@reduxjs/toolkit'
import { RoutineManager } from '@utils/routine.manager' import { RoutineManager } from '@utils/routine.manager'
import { RootState } from '../../stores' import { RootState } from '../../stores'
import { startListening } from '../../stores/middleware/listener.middleware' import { startListening } from '../../stores/middleware/listener.middleware'
import { setToken } from './user.reducer' import { setToken } from './user.reducer'
// ---------------- thunk types ----------------
interface ThunkEntityDTO { interface ThunkEntityDTO {
thunk: any thunk: any
payload: Object payload: Object
/** /**
* Only one subscription per category is allowed. New subscription will unsubscribe and overwrite the old one * Only one subscription per category is allowed.
* New subscription will unsubscribe and overwrite the old one
*/ */
category: CATEGORIES category: CATEGORIES
} }
interface ThunkEntity extends ThunkEntityDTO { /**
* This Wrapper holds the actual thunk information
* as well as additional information
*/
interface ThunkWrapper extends ThunkEntityDTO {
id?: number id?: number
locked: boolean locked: boolean
} }
export interface ReducerState {
thunks: { [key in keyof typeof CATEGORIES]: ThunkEntity | null }
}
export enum CATEGORIES { export enum CATEGORIES {
TABLE, TABLE,
TAB, TAB,
} }
// ---------------- reducer types ----------------
export interface ReducerState {
thunks: { [key in keyof typeof CATEGORIES]: ThunkWrapper | null }
}
const initialState: ReducerState = { const initialState: ReducerState = {
thunks: { thunks: {
TABLE: null, TABLE: null,
...@@ -40,7 +50,11 @@ const RoutineSlice = createSlice({ ...@@ -40,7 +50,11 @@ const RoutineSlice = createSlice({
initialState, initialState,
reducers: { reducers: {
addRoutine: (state: any, { payload }: PayloadAction<ThunkEntityDTO>) => { addRoutine: (state: any, { payload }: PayloadAction<ThunkEntityDTO>) => {
const newThunk: ThunkEntity = { ...payload, locked: true } if (state.thunks[CATEGORIES[payload.category]]?.locked) {
}
const newThunk: ThunkWrapper = { ...payload, locked: true }
state.thunks[CATEGORIES[payload.category]] = newThunk state.thunks[CATEGORIES[payload.category]] = newThunk
}, },
...@@ -48,8 +62,8 @@ const RoutineSlice = createSlice({ ...@@ -48,8 +62,8 @@ const RoutineSlice = createSlice({
const thunk = state.thunks[CATEGORIES[payload.category] as any] const thunk = state.thunks[CATEGORIES[payload.category] as any]
if (!thunk) { if (!thunk) {
// TODO debugMessage("Desired thunk of category " + payload.category + " is not available")
throw new Error('Thunk not found') return
} }
state.thunks[CATEGORIES[payload.category] as any] = { ...thunk, id: payload.id, locked: false } state.thunks[CATEGORIES[payload.category] as any] = { ...thunk, id: payload.id, locked: false }
...@@ -89,11 +103,17 @@ startListening({ ...@@ -89,11 +103,17 @@ startListening({
// }, // },
// }) // })
// add new routine /**
* Add new routine
*
* This listener handles the connection between the RoutingManager that
* stores the non persistable thunk object and the peristable thunk information.
* The persistable information are stored in this reducer
*/
startListening({ startListening({
predicate: (action) => addRoutine.match(action), predicate: (action) => addRoutine.match(action),
effect: async (action, listenerApi) => { effect: async (action, listenerApi) => {
const { thunk } = action.payload as ThunkEntity const { thunk } = action.payload as ThunkWrapper
const subscription = await listenerApi.dispatch(thunk(action.payload.payload)) const subscription = await listenerApi.dispatch(thunk(action.payload.payload))
const thunkId = await RoutineManager.add(subscription.payload) const thunkId = await RoutineManager.add(subscription.payload)
listenerApi.dispatch( listenerApi.dispatch(
......
import { api, RbacUser, UserServiceGetUsersApiArg } from '@api/api' import { RbacUser } from '@api/api'
import { setCookieValue } from '@helper/coookie' import { setCookieValue } from '@helper/coookie'
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit' import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { RootState } from '..'
export interface UserSliceState { export interface UserSliceState {
// defined by the frontend user input. This value is getting compared with the backend response // defined by the frontend user input. This value is getting compared with the backend response
...@@ -34,27 +33,4 @@ export const { setToken } = userSlice.actions ...@@ -34,27 +33,4 @@ export const { setToken } = userSlice.actions
export const { setUser } = userSlice.actions export const { setUser } = userSlice.actions
export default userSlice.reducer export default userSlice.reducer
export const userReducerPath = userSlice.reducerPath export const userReducerPath = userSlice.reducerPath
\ No newline at end of file
export const fetchUser = createAsyncThunk('user/fetchUser', (_, thunkAPI) => {
const payload: UserServiceGetUsersApiArg = {}
thunkAPI.dispatch(api.endpoints.userServiceGetUsers.initiate(payload)).then((response) => {
if (response.error || !response.data?.user?.length) {
// TODO proper error handling
throw new Error('Fetching the pnd list after successful login failed')
}
const { user } = thunkAPI.getState() as RootState
// TODO ask if this is the correct approach
const matchedUser = response.data.user.find((_user) => _user.name === user.username)
if (!matchedUser) {
// TODO proper error handling
throw new Error('No user found with the provided username')
}
thunkAPI.dispatch(setUser(matchedUser))
})
})
...@@ -14,7 +14,7 @@ const initialState = { ...@@ -14,7 +14,7 @@ const initialState = {
/** /**
* Routine manager is a singleton that holds all running routines. * Routine manager is a singleton that holds all running routines.
* The redux store holds any persistable information about the routines. * The redux store holds any persistable information about the routines.
* The routines objects itself are stored in the RoutineManager. * The routine objects itself are stored in the RoutineManager.
*/ */
export const RoutineManager = (() => { export const RoutineManager = (() => {
const state = initialState const state = initialState
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment