From cbe02b3b9cb8f61b8d6d65560fdd18f2a68323ee Mon Sep 17 00:00:00 2001 From: Johannes Mey <johannes.mey@tu-dresden.de> Date: Mon, 11 Jul 2022 13:16:47 +0200 Subject: [PATCH] use redux --- dashboard/package-lock.json | 266 ++++++++++++++++++++++++++++++++++++ dashboard/package.json | 5 + dashboard/src/App.css | 4 - dashboard/src/App.js | 137 +++++++++---------- dashboard/src/index.js | 4 + dashboard/src/mgSlice.js | 23 ++++ dashboard/src/store.js | 8 ++ 7 files changed, 371 insertions(+), 76 deletions(-) create mode 100644 dashboard/src/mgSlice.js create mode 100644 dashboard/src/store.js diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index 2359a9d..2c3826c 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -8,6 +8,7 @@ "name": "dashboard", "version": "0.1.0", "dependencies": { + "@reduxjs/toolkit": "^1.8.3", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", "@testing-library/user-event": "^13.5.0", @@ -15,9 +16,13 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^4.4.0", + "react-redux": "^8.0.2", "react-scripts": "5.0.1", "react-vertical-timeline-component": "^3.5.2", "web-vitals": "^2.1.4" + }, + "devDependencies": { + "@redux-devtools/core": "^3.13.1" } }, "node_modules/@ampproject/remapping": { @@ -2984,6 +2989,60 @@ } } }, + "node_modules/@redux-devtools/core": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@redux-devtools/core/-/core-3.13.1.tgz", + "integrity": "sha512-VZbma4b28D7dLn6rKTxx4r1KJrgiT2EQNF4vjkpTlXTu0cQcHkEcAO9ixMBj6rZGrT/jinCHq8gBy2bWgnDvcA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@redux-devtools/instrument": "^2.1.0", + "@types/prop-types": "^15.7.5", + "lodash": "^4.17.21", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^0.14.9 || ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-redux": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "redux": "^3.5.2 || ^4.0.0" + } + }, + "node_modules/@redux-devtools/instrument": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/instrument/-/instrument-2.1.0.tgz", + "integrity": "sha512-e8fo88kuq/zWqfNf6S/GNfaQMjF4WSPpucmYfRhzZyyXHC3PCLd/xgz7zooPErDh9QwUXK6sTVYvrkq7hPbsFA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.7", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "redux": "^3.4.0 || ^4.0.0" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.8.3.tgz", + "integrity": "sha512-lU/LDIfORmjBbyDLaqFN2JB9YmAT1BElET9y0ZszwhSBa5Ef3t6o5CrHupw5J1iOXwd+o92QfQZ8OJpwXvsssg==", + "dependencies": { + "immer": "^9.0.7", + "redux": "^4.1.2", + "redux-thunk": "^2.4.1", + "reselect": "^4.1.5" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.0.2" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -3658,6 +3717,15 @@ "@types/node": "*" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", @@ -3968,6 +4036,11 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/@types/ws": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", @@ -8324,6 +8397,19 @@ "he": "bin/he" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -13798,6 +13884,49 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-redux": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.2.tgz", + "integrity": "sha512-nBwiscMw3NoP59NFCXFf02f8xdo+vSHT/uZ1ldDwF7XaTpzm+Phk97VT4urYBl5TYAPNVaFm12UHAEyzkpNzRA==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", @@ -13955,6 +14084,22 @@ "node": ">=8" } }, + "node_modules/redux": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", + "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-thunk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", + "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==", + "peerDependencies": { + "redux": "^4" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -14097,6 +14242,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "node_modules/reselect": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.6.tgz", + "integrity": "sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ==" + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -15606,6 +15756,14 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -18585,6 +18743,40 @@ "source-map": "^0.7.3" } }, + "@redux-devtools/core": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@redux-devtools/core/-/core-3.13.1.tgz", + "integrity": "sha512-VZbma4b28D7dLn6rKTxx4r1KJrgiT2EQNF4vjkpTlXTu0cQcHkEcAO9ixMBj6rZGrT/jinCHq8gBy2bWgnDvcA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.18.3", + "@redux-devtools/instrument": "^2.1.0", + "@types/prop-types": "^15.7.5", + "lodash": "^4.17.21", + "prop-types": "^15.8.1" + } + }, + "@redux-devtools/instrument": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/instrument/-/instrument-2.1.0.tgz", + "integrity": "sha512-e8fo88kuq/zWqfNf6S/GNfaQMjF4WSPpucmYfRhzZyyXHC3PCLd/xgz7zooPErDh9QwUXK6sTVYvrkq7hPbsFA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.16.7", + "lodash": "^4.17.21" + } + }, + "@reduxjs/toolkit": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.8.3.tgz", + "integrity": "sha512-lU/LDIfORmjBbyDLaqFN2JB9YmAT1BElET9y0ZszwhSBa5Ef3t6o5CrHupw5J1iOXwd+o92QfQZ8OJpwXvsssg==", + "requires": { + "immer": "^9.0.7", + "redux": "^4.1.2", + "redux-thunk": "^2.4.1", + "reselect": "^4.1.5" + } + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -19066,6 +19258,15 @@ "@types/node": "*" } }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", @@ -19338,6 +19539,11 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" }, + "@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "@types/ws": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", @@ -22491,6 +22697,21 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -26283,6 +26504,26 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "react-redux": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.2.tgz", + "integrity": "sha512-nBwiscMw3NoP59NFCXFf02f8xdo+vSHT/uZ1ldDwF7XaTpzm+Phk97VT4urYBl5TYAPNVaFm12UHAEyzkpNzRA==", + "requires": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, "react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", @@ -26406,6 +26647,20 @@ "strip-indent": "^3.0.0" } }, + "redux": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", + "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", + "requires": { + "@babel/runtime": "^7.9.2" + } + }, + "redux-thunk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", + "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==", + "requires": {} + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -26517,6 +26772,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "reselect": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.6.tgz", + "integrity": "sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ==" + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -27625,6 +27885,12 @@ "punycode": "^2.1.0" } }, + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "requires": {} + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/dashboard/package.json b/dashboard/package.json index a8dc7ea..f87a212 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@reduxjs/toolkit": "^1.8.3", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", "@testing-library/user-event": "^13.5.0", @@ -10,6 +11,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^4.4.0", + "react-redux": "^8.0.2", "react-scripts": "5.0.1", "react-vertical-timeline-component": "^3.5.2", "web-vitals": "^2.1.4" @@ -37,5 +39,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "@redux-devtools/core": "^3.13.1" } } diff --git a/dashboard/src/App.css b/dashboard/src/App.css index 8e651bb..67272f0 100644 --- a/dashboard/src/App.css +++ b/dashboard/src/App.css @@ -34,10 +34,6 @@ } -.ASTIcon { - transform: rotate(180deg); -} - .App-link { color: #61dafb; } diff --git a/dashboard/src/App.js b/dashboard/src/App.js index f8e80dc..3c4f84b 100644 --- a/dashboard/src/App.js +++ b/dashboard/src/App.js @@ -1,96 +1,89 @@ import './App.css'; -import React from 'react'; +import React, { useEffect, useRef } from 'react'; import './index.css'; import { VerticalTimeline, VerticalTimelineElement } from 'react-vertical-timeline-component'; import 'react-vertical-timeline-component/style.min.css'; import { GiFamilyTree } from "react-icons/gi"; +import { useSelector, useDispatch } from 'react-redux' +import { addAst, setAstList } from './mgSlice' -class App extends React.Component { - constructor(props) { - super(props); - this.state = { - asts: [], - contexts: {} - }; - } +function App() { - componentDidMount() { - fetch('http://localhost:7070/asts/') - .then(res => res.json()) - .then((asts) => { - this.setState({ - asts: asts.reverse(), - contexts: {} - }) - }) - .catch(console.log) + const ws = useRef(null); + const dispatch = useDispatch(); + const asts = useSelector(state => state.mg.asts); - const ws = new WebSocket("ws://localhost:7070/ast-events"); - - ws.onopen = (event) => { - ws.send("Web client connected!"); - }; - - ws.onmessage = (event) => { + useEffect(() => { + ws.current = new WebSocket("ws://localhost:7070/ast-events"); + ws.current.onopen = () => console.log("ws opened"); + ws.current.onclose = () => console.log("ws closed"); + ws.current.onmessage = (event) => { const json = JSON.parse(event.data); try { if ((json.event = "data")) { - var asts = this.state.asts.slice(); - const contexts = {}; - this.setState({ - asts: [event.data, ...asts], - contexts: contexts - }); + dispatch(addAst(event.data)); } } catch (err) { console.log(err); } }; - } - render() { + const wsCurrent = ws.current; - const astTimeline = this.state.asts.map(v => { - return ( - <VerticalTimelineElement - className="ast-timeline-event" - contentStyle={{ background: 'rgb(33, 150, 243)', color: '#fff' }} - contentArrowStyle={{ borderRight: '7px solid rgb(33, 150, 243)' }} - date={new Date(v.timestamp).toLocaleTimeString('en-us', { hour12: false })} - iconStyle={{ background: 'rgb(33, 150, 243)', color: '#fff', rotate: '180deg' }} - icon={<GiFamilyTree />} - key={v.timestamp} - position={'right'} - > - <h3 className="vertical-timeline-element-title">{v.parseRule}()</h3> - <p> - <img className="AstInTimeline" src={`data:image/svg+xml;utf8,${encodeURIComponent(v.diagram)}`} alt={v.parseRule} /> - </p> - </VerticalTimelineElement> + return () => { + wsCurrent.close(); + }; + }, [dispatch]); - ) - }) + useEffect(() => { + if (asts.length === 0) { + fetch('http://localhost:7070/asts/') + .then(res => res.json()) + .then((asts) => { + dispatch(setAstList(asts)) + }) + .catch(console.log) + } + }, [dispatch, asts.length]) - const lastImage = (this.state.asts.length > 0) ? (this.state.asts[0]) : ''; - return ( - <div className="App"> - <header className="App-header"> - <ControlPanel /> - </header> - <main> - <CurrentState - diagram={lastImage.diagram} - label={lastImage.parseRule} - /> - <VerticalTimeline - className='MG-Timeline'> - {astTimeline} - </VerticalTimeline> - </main> - </div> - ); - } + return ( + <div className="App"> + <header className="App-header"> + <ControlPanel /> + </header> + <main> + <CurrentState + diagram={asts[0] ? asts[0].diagram : ''} + label={asts[0] ? asts[0].parseRule : ''} + /> + <VerticalTimeline + className='MG-Timeline'> + {asts.map(v => { + console.log(v.parseRule) + return ( + <VerticalTimelineElement + className="ast-timeline-event" + contentStyle={{ background: 'rgb(33, 150, 243)', color: '#fff' }} + contentArrowStyle={{ borderRight: '7px solid rgb(33, 150, 243)' }} + date={new Date(v.timestamp).toLocaleTimeString('en-us', { hour12: false })} + iconStyle={{ background: 'rgb(33, 150, 243)', color: '#fff', rotate: '180deg' }} + icon={<GiFamilyTree />} + key={v.timestamp} + position={'right'} + > + <h3 className="vertical-timeline-element-title">{v.parseRule}()</h3> + <p> + <img className="AstInTimeline" src={`data:image/svg+xml;utf8,${encodeURIComponent(v.diagram)}`} alt={v.parseRule} /> + </p> + </VerticalTimelineElement> + + ) + })} + </VerticalTimeline> + </main> + </div> + ); } function CurrentState(props) { diff --git a/dashboard/src/index.js b/dashboard/src/index.js index d563c0f..634cced 100644 --- a/dashboard/src/index.js +++ b/dashboard/src/index.js @@ -3,11 +3,15 @@ import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; +import store from './store' +import { Provider } from 'react-redux' const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> + <Provider store={store}> <App /> + </Provider> </React.StrictMode> ); diff --git a/dashboard/src/mgSlice.js b/dashboard/src/mgSlice.js new file mode 100644 index 0000000..fbbef70 --- /dev/null +++ b/dashboard/src/mgSlice.js @@ -0,0 +1,23 @@ +import { createSlice } from '@reduxjs/toolkit' + +export const mgSlice = createSlice({ + name: 'mg', + initialState: { + asts: [], + contexts: {}, + }, + reducers: { + addAst: (state, action) => { + state.asts = [action.payload, ...state.asts]; + console.log("added ast, size is " + state.asts.length); + }, + setAstList: (state, action) => { + state.asts = action.payload.reverse(); + console.log("set AST list, size is " + state.asts.length); + } + } +}) + +export const { addAst, setAstList } = mgSlice.actions + +export default mgSlice.reducer \ No newline at end of file diff --git a/dashboard/src/store.js b/dashboard/src/store.js new file mode 100644 index 0000000..fd5cd81 --- /dev/null +++ b/dashboard/src/store.js @@ -0,0 +1,8 @@ +import { configureStore } from '@reduxjs/toolkit' +import mgReducer from './mgSlice' + +export default configureStore({ + reducer: { + mg: mgReducer + } +}) \ No newline at end of file -- GitLab