This is an automated email from the ASF dual-hosted git repository. cdutz pushed a commit to branch feature/new-ui-tool in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/feature/new-ui-tool by this push: new 765f3e859f chore: Continued working on getting redux to correctly handle the application state. 765f3e859f is described below commit 765f3e859fbfbb7fec4de79389c1758609c2fd45 Author: Christofer Dutz <cd...@apache.org> AuthorDate: Sun Jan 7 14:49:36 2024 +0100 chore: Continued working on getting redux to correctly handle the application state. --- plc4j/tools/ui/frontend/frontend/package.json | 4 +- plc4j/tools/ui/frontend/frontend/src/App.tsx | 12 +-- .../ui/frontend/frontend/src/pages/Inspect.tsx | 39 +++++--- .../tools/ui/frontend/frontend/src/store/index.ts | 109 ++++++++++----------- 4 files changed, 80 insertions(+), 84 deletions(-) diff --git a/plc4j/tools/ui/frontend/frontend/package.json b/plc4j/tools/ui/frontend/frontend/package.json index 6a22a39d0e..501de29ce4 100644 --- a/plc4j/tools/ui/frontend/frontend/package.json +++ b/plc4j/tools/ui/frontend/frontend/package.json @@ -16,6 +16,7 @@ "@mdi/react": "^1.6.1", "@mui/icons-material": "^5.14.19", "@mui/material": "^5.14.20", + "@reduxjs/toolkit": "^2.0.1", "axios": "^1.6.2", "primeflex": "^3.3.1", "primeicons": "^6.0.1", @@ -24,8 +25,7 @@ "react-dom": "^18.2.0", "react-redux": "^9.0.4", "react-router-dom": "^6.20.1", - "react-use-websocket": "^4.5.0", - "redux": "^5.0.1" + "react-use-websocket": "^4.5.0" }, "devDependencies": { "@types/react": "^18.2.37", diff --git a/plc4j/tools/ui/frontend/frontend/src/App.tsx b/plc4j/tools/ui/frontend/frontend/src/App.tsx index b524cafc5b..959914a261 100644 --- a/plc4j/tools/ui/frontend/frontend/src/App.tsx +++ b/plc4j/tools/ui/frontend/frontend/src/App.tsx @@ -29,7 +29,7 @@ import About from "./pages/About.tsx"; import useWebSocket from 'react-use-websocket'; import {useState} from "react"; import {RestApplicationClient} from "./generated/plc4j-tools-ui-frontend.ts"; -import store from "./store"; +import store, {InitializeConnectionsAction, initializeLists} from "./store"; axios.defaults.baseURL = 'http://localhost:8080'; const restClient = new RestApplicationClient(axios); @@ -64,14 +64,12 @@ function App() { // Load the initial list of drivers and connections and initialize the store with that. if(!initialized) { setInitialized(true); - + console.log("Initializing") restClient.getAllDrivers().then(driverList => { restClient.getAllDevices().then(deviceList => { - store.dispatch({ - type: 'initialize-lists', - driverList: driverList, - deviceList: deviceList - }) + console.log("Dispatching (Initialize-Lists)") + const action:InitializeConnectionsAction = {driverList:driverList.data, deviceList: deviceList.data} + store.dispatch(initializeLists(action)) }) }) } diff --git a/plc4j/tools/ui/frontend/frontend/src/pages/Inspect.tsx b/plc4j/tools/ui/frontend/frontend/src/pages/Inspect.tsx index f94959d29d..00dbed9809 100644 --- a/plc4j/tools/ui/frontend/frontend/src/pages/Inspect.tsx +++ b/plc4j/tools/ui/frontend/frontend/src/pages/Inspect.tsx @@ -22,36 +22,43 @@ import {ScrollPanel} from "primereact/scrollpanel"; import NavigationTree from "../components/NavigationTree.tsx"; import PlcConnection from "../components/PlcConnection.tsx"; import { useSelector } from "react-redux"; -import {ApplicationState} from "../store" import {Device, Driver} from "../generated/plc4j-tools-ui-frontend.ts"; import {TreeItemData} from "../model/TreeItemData.ts"; +import {RootState} from "../store"; - -function getByDriverTree(driverList: Driver[] | undefined, deviceList: Device[] | undefined):TreeItemData[] { - console.log('getByDriverTree') +function getByDriverTree(driverList: Driver[], deviceList: Device[]):TreeItemData[] { if(driverList && deviceList) { - console.log(driverList) - console.log(deviceList) + let result:TreeItemData[] = [] + driverList.forEach(value => { + result = [...result, { + id: value.code, + name: value.name, + type: "DRIVER", + supportsDiscovery: value.supportsDiscovery, + supportsBrowsing: false, + supportsReading: false, + supportsWriting: false, + supportsSubscribing: false, + supportsPublishing: false + }] + }) + // TODO: Now add each connection to the driver it belongs to. + return result } return [] } -function getByDeviceTree(driverList: Driver[] | undefined, deviceList: Device[] | undefined):TreeItemData[] { - console.log('getByDeviceTree') +function getByDeviceTree(driverList: Driver[], deviceList: Device[]):TreeItemData[] { if(driverList && deviceList) { - console.log(driverList) - console.log(deviceList) + // TODO: Do something ... } return [] } export default function Inspect() { - const lists = useSelector<ApplicationState>(state => { - state.driverList - state.deviceList - }) as ApplicationState - console.log("Test" + lists); - + const lists = useSelector((state: RootState) => { + return state.connections + }) return ( <Splitter className="h-full"> <SplitterPanel diff --git a/plc4j/tools/ui/frontend/frontend/src/store/index.ts b/plc4j/tools/ui/frontend/frontend/src/store/index.ts index bf095fce72..4433a9cbab 100644 --- a/plc4j/tools/ui/frontend/frontend/src/store/index.ts +++ b/plc4j/tools/ui/frontend/frontend/src/store/index.ts @@ -17,82 +17,73 @@ * under the License. */ -import {Action, createStore} from "redux"; +import {configureStore, createSlice, PayloadAction} from '@reduxjs/toolkit' import {Device, Driver} from "../generated/plc4j-tools-ui-frontend.ts"; +import {useDispatch} from "react-redux"; -export type ApplicationState = { - driverList?: Driver[] - deviceList?: Device[] -} - -type InitializeAction = { - type: string +export type InitializeConnectionsAction = { driverList: Driver[] deviceList: Device[] } type DeviceAction = { - type: string device: Device } -const storeReducer = (state: ApplicationState = {}, action: Action) => { - console.log(action); - if (action.type === 'initialize-lists') { - const initializeAction: InitializeAction = action as InitializeAction - return { - ...state, - deviceList: initializeAction.deviceList, - driverList: initializeAction.driverList - } - } else if (action.type === 'add-device') { - const deviceAction: DeviceAction = action as DeviceAction - if(state.deviceList) { - return { - ...state, - deviceList: [...state.deviceList, deviceAction.device] - } - } - return { - ...state, - deviceList: [deviceAction.device] - } - } else if (action.type === 'update-device') { - const deviceAction: DeviceAction = action as DeviceAction - if(state.deviceList) { - const device = state.deviceList.find(value => value.id == deviceAction.device.id); - if(device) { +export interface ConnectionsState { + driverList: Driver[] + deviceList: Device[] +} + +const connectionsInitialState: ConnectionsState = { + driverList: [] as Driver[], + deviceList: [] as Device[], +} + +const connectionsSlice = createSlice({ + name: 'connections', + initialState: connectionsInitialState, + reducers: { + initializeLists: (state, action: PayloadAction<InitializeConnectionsAction>) => { + state.driverList = action.payload.driverList + state.deviceList = action.payload.deviceList + console.log("updated driver and device lists") + }, + addDevice: (state, action: PayloadAction<DeviceAction>) => { + state.deviceList = [...state.deviceList, action.payload.device] + }, + updateDevice: (state, action: PayloadAction<DeviceAction>) => { + const device = state.deviceList.find(value => value.id == action.payload.device.id); + if (device) { const index = state.deviceList.indexOf(device); - if(index) { - const newList = state.deviceList; - newList.splice(index, 1, deviceAction.device) - return { - ...state, - newList - } + if (index) { + state.deviceList.splice(index, 1, action.payload.device); } } - } - } else if (action.type === 'delete-device') { - const deviceAction: DeviceAction = action as DeviceAction - if(state.deviceList) { - const device = state.deviceList.find(value => value.id == deviceAction.device.id); - if(device) { + }, + deleteDevice: (state, action: PayloadAction<DeviceAction>) => { + const device = state.deviceList.find(value => value.id == action.payload.device.id); + if (device) { const index = state.deviceList.indexOf(device); - if(index) { - const newList = state.deviceList; - newList.splice(index, 1) - return { - ...state, - newList - } + if (index) { + state.deviceList.splice(index, 1); } } } } - return state -} +}) -const store = createStore<ApplicationState, Action>(storeReducer) +export const { initializeLists, addDevice, updateDevice, deleteDevice } = connectionsSlice.actions + +const store = configureStore({ + reducer: { + connections: connectionsSlice.reducer + } +}) +export default store -export default store; +// Infer the `RootState` and `AppDispatch` types from the store itself +export type RootState = ReturnType<typeof store.getState> +// Inferred type: {connections: ConnectionsState} +export type AppDispatch = typeof store.dispatch +export const useAppDispatch: () => AppDispatch = useDispatch