From d1795158aea860f88125c5fe510c3204883fbc3d Mon Sep 17 00:00:00 2001 From: hodanoori <107242553+hodanoori@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:43:10 +0200 Subject: [PATCH] feat(heureka) : Refactor store implementation to implement filtering functionalities for diferent entities (#177) * Merge branch 'main' into renovate/npm-dependencies * feat(heureka): add filtering and search functionality for services tab * adjust store actions and update package-lock.json * CleanUp * CleanUp * add fetch filters value queries and change respective files * Automatic application of license header * fix (heureka): Update the package-lock.json (#164) * fix (heureka): Update the package-lock.json to be able to build it on mac * Update the version * feat(heureka): Substitute vulnerabilities with issues tab using the new issueMatch entity (#175) * fix(heureka): Add the left behind issueMatches.js file (#178) * fix(heureka): Fix merge conflicts in package-lock.json * Adjust relevant imports to use juno npm packages * Correct filter query * feat(heureka) : Add components view (#263) * feat(heureka) : add components view * Automatic application of license header * Install date-fns * feat(heureka): Add the total number of component versions and fix some errors * feat)heureka): Add pagination info to the components query * Using container and stack for styling and some cleanup * add componentInstances to componentVersion in the component query * Change the setting to put pagination on the right side of the page --------- Co-authored-by: License Bot * Add default filtering * feat(heureka): add filtering and search functionality for services tab * adjust store actions and update package-lock.json * Correct filter query * Automatic application of license header * feat(heureka): Add msg handling per tab and mem tabs to prevent unnecessary re-rendering (#281) * feat(heureka): Add error handling per tab and mem tabs to prevent unnecessary re-rendering * remove error considition to render Messages * move messages inside each tab and add resetMessages * remove unnecessary resetMessages and correct queries * feat(heureka): Refactor controllers and reduce redundencies (#295) * feat(heureka): Refactor controllers and reduce redundencies * Automatic application of license header --------- Co-authored-by: License Bot * Remove merge conflicts in utils * Remove not adjusted filter test * Resolve test errors * Refactoring store using slices * complete filtering for services tab * generalize filtering for all tabs * Activate the working filter select for services tab * Automatic application of license header * Adjust panel manager and services and issue details impl based on new store slices * CleanUp console.logs * Display search input only on issues tab for now * Display right icon on filter button * Cleanup and improvements based on code review inqueries * Add code comments and some wording and layouting improvements --------- Co-authored-by: License Bot --- heureka/ui/package-lock.json | 392 +----------------- heureka/ui/package.json | 3 +- heureka/ui/public/index.html | 14 +- heureka/ui/src/App.js | 18 +- heureka/ui/src/actions.js | 178 -------- heureka/ui/src/components/AsyncWorker.jsx | 1 - heureka/ui/src/components/StoreProvider.jsx | 29 -- .../components/components/ComponentsList.jsx | 27 +- .../components/ComponentsListController.jsx | 2 +- .../components/components/ComponentsTab.jsx | 7 +- .../ui/src/components/filters/FilterPills.jsx | 18 +- .../src/components/filters/FilterSelect.jsx | 98 ++--- heureka/ui/src/components/filters/Filters.jsx | 50 ++- .../src/components/issues/IssuesDetails.jsx | 11 +- .../ui/src/components/issues/IssuesList.jsx | 2 +- .../issues/IssuesListController.jsx | 2 +- .../src/components/issues/IssuesListItem.jsx | 16 +- .../ui/src/components/issues/IssuesTab.jsx | 7 +- .../components/services/ServicesDetail.jsx | 11 +- .../src/components/services/ServicesList.jsx | 28 +- .../services/ServicesListController.jsx | 2 +- .../components/services/ServicesListItem.jsx | 15 +- .../src/components/services/ServicesTab.jsx | 9 +- .../src/components/shared/ListController.jsx | 68 +-- .../ui/src/components/shared/PanelManager.jsx | 20 +- heureka/ui/src/components/tabs/TabContext.jsx | 12 +- heureka/ui/src/components/tabs/TabPanel.jsx | 4 +- heureka/ui/src/hooks/useAppStore.js | 101 +++++ heureka/ui/src/hooks/useCommunication.js | 77 ++-- heureka/ui/src/hooks/useQueryClientFn.js | 38 +- heureka/ui/src/hooks/useUrlState.js | 10 +- .../lib/queries/issueMatchesFilterValues.js | 52 +++ ...rviceFilters.js => serviceFilterValues.js} | 37 +- .../ui/src/lib/slices/createAuthDataSlice.js | 71 ++++ .../ui/src/lib/slices/createFiltersSlice.js | 145 +++++++ .../ui/src/lib/slices/createGlobalsSlice.js | 107 +++++ .../src/lib/slices/createUserActivitySlice.js | 26 ++ heureka/ui/src/lib/store.js | 94 ----- heureka/ui/src/lib/utils.js | 24 ++ heureka/ui/src/queries.js | 200 --------- 40 files changed, 891 insertions(+), 1135 deletions(-) delete mode 100644 heureka/ui/src/actions.js delete mode 100644 heureka/ui/src/components/StoreProvider.jsx create mode 100644 heureka/ui/src/hooks/useAppStore.js create mode 100644 heureka/ui/src/lib/queries/issueMatchesFilterValues.js rename heureka/ui/src/lib/queries/{serviceFilters.js => serviceFilterValues.js} (54%) create mode 100644 heureka/ui/src/lib/slices/createAuthDataSlice.js create mode 100644 heureka/ui/src/lib/slices/createFiltersSlice.js create mode 100644 heureka/ui/src/lib/slices/createGlobalsSlice.js create mode 100644 heureka/ui/src/lib/slices/createUserActivitySlice.js delete mode 100644 heureka/ui/src/lib/store.js create mode 100644 heureka/ui/src/lib/utils.js delete mode 100644 heureka/ui/src/queries.js diff --git a/heureka/ui/package-lock.json b/heureka/ui/package-lock.json index 696fa279..4b8114fb 100644 --- a/heureka/ui/package-lock.json +++ b/heureka/ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "heureka", - "version": "2.3.5", + "version": "2.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "heureka", - "version": "2.3.5", + "version": "2.4.0", "license": "Apache-2.0", "dependencies": { "@cloudoperators/juno-communicator": "^2.2.11", @@ -30,7 +30,6 @@ "babel-jest": "^29.3.1", "babel-plugin-transform-import-meta": "^2.2.0", "esbuild": "^0.19.4", - "graphql": "^16.8.2", "graphql-request": "^7.0.1", "immer": "^10.0.0", "jest": "^29.3.1", @@ -1899,18 +1898,18 @@ "dev": true }, "node_modules/@cloudoperators/juno-communicator": { - "version": "2.2.11", - "resolved": "https://registry.npmjs.org/@cloudoperators/juno-communicator/-/juno-communicator-2.2.11.tgz", - "integrity": "sha512-dDoqKw3nZuuNMkdmwYDG/l7Uw7a4rDF3RtteuEW9yUhMypocsGmbcgRhaZjUWpL21OPbFDVNi58r3+KO7IN2Ug==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@cloudoperators/juno-communicator/-/juno-communicator-2.2.12.tgz", + "integrity": "sha512-uwqFZFNmh/qipKOZsK1I35kVW6krrglu0spegGaJmPk5ZfEXw2y3i22/7IBdyLhXv+6IfE9lk7bXRJFtnY6++A==", "engines": { "node": ">=20.0.0 <21.0.0", "npm": ">=10.0.0 <11.0.0" } }, "node_modules/@cloudoperators/juno-messages-provider": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@cloudoperators/juno-messages-provider/-/juno-messages-provider-0.1.17.tgz", - "integrity": "sha512-ZECrpMVr3jx25YdcyayFUSXMHDRp9hjDLLbUSvQqcJLxtscpE14WEqGffelAMfr0Q6AqOi0DlEoSMVFlh7fYZw==", + "version": "0.1.18", + "resolved": "https://registry.npmjs.org/@cloudoperators/juno-messages-provider/-/juno-messages-provider-0.1.18.tgz", + "integrity": "sha512-3+81Xe9pOOa9uAUb4S4g74gkIVobv3iAH4Pvd2i63zA6qJ7waKy0T2WpVe1p7ZzY/Z9qoClq4Jd6neOJOi6DGA==", "dependencies": { "@cloudoperators/juno-ui-components": "*" }, @@ -1925,9 +1924,9 @@ } }, "node_modules/@cloudoperators/juno-ui-components": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/@cloudoperators/juno-ui-components/-/juno-ui-components-2.15.4.tgz", - "integrity": "sha512-lyziFGjtasxqiiZ86Yfn9EtJFtZ/72So1GmCsMdZCOt3WQnv/TcvQMnXCHe5Zg1fXZ/qNQWIac5rH6YbVS75yg==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@cloudoperators/juno-ui-components/-/juno-ui-components-2.16.0.tgz", + "integrity": "sha512-GyhK/edHg+Ez109B6QHLKUX1zcyP+IU0l3Z9uLs6RAVi6xcvQYY1xYiAT1OE4LkojfPqMwkL8PA5Ojy2V/deGA==", "engines": { "node": ">=20.0.0 <21.0.0", "npm": ">=10.0.0 <11.0.0" @@ -1946,261 +1945,13 @@ "juri": "^1.0.3" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", - "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", - "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", - "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", - "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", - "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", - "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", - "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", - "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", - "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", - "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", - "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", - "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", - "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", - "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", - "cpu": [ - "riscv64" - ], + "node_modules/@dprint/typescript": { + "version": "0.91.4", + "resolved": "https://registry.npmjs.org/@dprint/typescript/-/typescript-0.91.4.tgz", + "integrity": "sha512-je/T8JF07xehOVS7rx6Xo7T8Aa1Sd/p/+e/b/J2RE8yJHu09O+L0aHBSvec+usjR8/QwCu23AuDLl47zFSey5Q==", "dev": true, "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", - "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "peer": true }, "node_modules/@esbuild/linux-x64": { "version": "0.19.12", @@ -2218,102 +1969,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", - "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", - "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", - "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", - "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", - "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", - "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@graphql-typed-document-node/core": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", @@ -5456,20 +5111,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -5602,6 +5243,7 @@ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", "dev": true, + "peer": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } diff --git a/heureka/ui/package.json b/heureka/ui/package.json index d7f91062..01f0802e 100644 --- a/heureka/ui/package.json +++ b/heureka/ui/package.json @@ -1,6 +1,6 @@ { "name": "heureka", - "version": "2.3.5", + "version": "2.4.0", "author": "UI-Team", "contributors": [ "Hoda Noori, Arturo Reuschenbach Pucernau" @@ -26,7 +26,6 @@ "babel-jest": "^29.3.1", "babel-plugin-transform-import-meta": "^2.2.0", "esbuild": "^0.19.4", - "graphql": "^16.8.2", "graphql-request": "^7.0.1", "immer": "^10.0.0", "jest": "^29.3.1", diff --git a/heureka/ui/public/index.html b/heureka/ui/public/index.html index 3de8bd3d..a9b67f04 100644 --- a/heureka/ui/public/index.html +++ b/heureka/ui/public/index.html @@ -6,8 +6,8 @@ - - + + Heureka Dev
- \ No newline at end of file + diff --git a/heureka/ui/src/App.js b/heureka/ui/src/App.js index 109d5660..b2842364 100644 --- a/heureka/ui/src/App.js +++ b/heureka/ui/src/App.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { useEffect } from "react" +import React, { useLayoutEffect } from "react" import styles from "./styles.scss" import { AppShell, @@ -13,12 +13,19 @@ import { import { QueryClient, QueryClientProvider } from "@tanstack/react-query" import { MessagesProvider } from "@cloudoperators/juno-messages-provider" import AsyncWorker from "./components/AsyncWorker" -import StoreProvider, { useActions } from "./components/StoreProvider" import TabContext from "./components/tabs/TabContext" import { ErrorBoundary } from "react-error-boundary" +import { + useGlobalsActions, + useFilterActions, + StoreProvider, +} from "./hooks/useAppStore" import PanelManager from "./components/shared/PanelManager" -const App = (props) => { +function App(props = {}) { + const { setLabels, setPredefinedFilters, setActivePredefinedFilter } = + useFilterActions() + const { setEmbedded, setApiEndpoint } = useGlobalsActions() const preErrorClasses = ` custom-error-pre border-theme-error @@ -27,6 +34,11 @@ const App = (props) => { w-full ` + useLayoutEffect(() => { + setApiEndpoint(props.endpoint) + if (props.embedded === "true" || props.embedded === true) setEmbedded(true) + }, []) + const fallbackRender = ({ error }) => { return (
diff --git a/heureka/ui/src/actions.js b/heureka/ui/src/actions.js deleted file mode 100644 index a96a2502..00000000 --- a/heureka/ui/src/actions.js +++ /dev/null @@ -1,178 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -class HTTPError extends Error { - constructor(code, message) { - super(message || code) - this.name = "HTTPError" - this.statusCode = code - } -} - -export const encodeUrlParamsFromObject = (options) => { - if (!options) return "" - let encodedOptions = Object.keys(options) - .map((k) => { - if (typeof options[k] === "object") { - const childOption = options[k] - return Object.keys(childOption).map( - (childKey) => - `${encodeURIComponent(childKey)}=${encodeURIComponent( - childOption[childKey] - )}` - ) - } - return `${encodeURIComponent(k)}=${encodeURIComponent(options[k])}` - }) - .join("&") - return `&${encodedOptions}` -} - -const checkStatus = (response) => { - if (response.status < 400) { - return response - } else { - return response.text().then((message) => { - var error = new HTTPError(response.status, message || response.statusText) - error.statusCode = response.status - return Promise.reject(error) - }) - } -} - -// -// SERVICES -// - -export const services = ({ queryKey }) => { - const [_key, bearerToken, endpoint, options] = queryKey - return fetchFromAPI(bearerToken, endpoint, "/services", options) -} - -export const service = ({ queryKey }) => { - const [_key, bearerToken, endpoint, serviceId] = queryKey - return fetchFromAPI(bearerToken, endpoint, `/services/${serviceId}`) -} - -export const serviceFilters = ({ queryKey }) => { - const [_key, bearerToken, endpoint, options] = queryKey - return fetchFromAPI(bearerToken, endpoint, "/services/filters", options) -} - -// -// COMPONENTS -// - -export const components = ({ queryKey }) => { - const [_key, bearerToken, endpoint, options] = queryKey - return fetchFromAPI(bearerToken, endpoint, "/components", options) -} - -export const component = ({ queryKey }) => { - const [_key, bearerToken, endpoint, componentId] = queryKey - return fetchFromAPI(bearerToken, endpoint, `/components/${componentId}`) -} - -export const componentFilters = ({ queryKey }) => { - const [_key, bearerToken, endpoint, options] = queryKey - return fetchFromAPI(bearerToken, endpoint, "/components/filters", options) -} - -// -// ISSUES -// - -export const issues = ({ queryKey }) => { - const [_key, bearerToken, endpoint, options] = queryKey - return fetchFromAPI(bearerToken, endpoint, "/issues", options) -} - -export const issue = ({ queryKey }) => { - const [_key, bearerToken, endpoint, issueId] = queryKey - return fetchFromAPI(bearerToken, endpoint, `/issues/${issueId}`) -} - -export const issueFilters = ({ queryKey }) => { - const [_key, bearerToken, endpoint, options] = queryKey - return fetchFromAPI(bearerToken, endpoint, "/issues/filters", options) -} - -// -// USERS -// - -export const users = ({ queryKey }) => { - const [_key, bearerToken, endpoint, options] = queryKey - return fetchFromAPI(bearerToken, endpoint, "/users", options) -} - -export const user = ({ queryKey }) => { - const [_key, bearerToken, endpoint, userId] = queryKey - return fetchFromAPI(bearerToken, endpoint, `/users/${userId}`) -} - -export const userFilters = ({ queryKey }) => { - const [_key, bearerToken, endpoint, options] = queryKey - return fetchFromAPI(bearerToken, endpoint, "/users/filters", options) -} - -// -// COMMONS -// - -const fetchFromAPI = (bearerToken, endpoint, path, options) => { - const query = encodeUrlParamsFromObject(options) - return fetch(`${endpoint}${path}?${query}`, { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${bearerToken}`, - }, - }) - .then((response) => { - if (!response.ok) { - return response.json().then((errData) => { - const error = new HTTPError( - response.status, - errData.message || "Unknown error occurred" - ) - return Promise.reject(error) - }) - } - - let isJSON = response.headers - .get("content-type") - .includes("application/json") - - if (!isJSON) { - var error = new HTTPError( - 400, - "The response is not a valid JSON response" - ) - return Promise.reject(error) - } - - return response.json() - }) - .then((data) => { - if (data.errors && data.errors.length > 0) { - const graphQLError = data.errors[0] - const error = new HTTPError( - 400, - graphQLError.message || "GraphQL error occurred" - ) - return Promise.reject(error) - } - - return data - }) - .catch((error) => { - if (error instanceof HTTPError) { - throw error - } else { - throw new HTTPError(500, "An unexpected error occurred") - } - }) -} diff --git a/heureka/ui/src/components/AsyncWorker.jsx b/heureka/ui/src/components/AsyncWorker.jsx index 0282e3c0..0a06cdc2 100644 --- a/heureka/ui/src/components/AsyncWorker.jsx +++ b/heureka/ui/src/components/AsyncWorker.jsx @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React from "react" import useUrlState from "../hooks/useUrlState" import useQueryClientFn from "../hooks/useQueryClientFn" diff --git a/heureka/ui/src/components/StoreProvider.jsx b/heureka/ui/src/components/StoreProvider.jsx deleted file mode 100644 index 6cd2099d..00000000 --- a/heureka/ui/src/components/StoreProvider.jsx +++ /dev/null @@ -1,29 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import React, { createContext, useContext } from "react" -import { useStore as create } from "zustand" -import createStore from "../lib/store" - -const StoreContext = createContext() -const StoreProvider = ({ options, children }) => ( - - {children} - -) - -const useStore = (selector) => create(useContext(StoreContext), selector) - -export const useEndpoint = () => useStore((s) => s.endpoint) -export const useQueryClientFnReady = () => useStore((s) => s.queryClientFnReady) -export const useActiveTab = () => useStore((s) => s.activeTab) -export const useQueryOptions = (tab) => - useStore((s) => s.tabs[tab].queryOptions) -export const useShowPanel = () => useStore((s) => s.showPanel) -export const useShowServiceDetail = () => useStore((s) => s.showServiceDetail) -export const useShowIssueDetail = () => useStore((s) => s.showIssueDetail) -export const useActions = () => useStore((s) => s.actions) - -export default StoreProvider diff --git a/heureka/ui/src/components/components/ComponentsList.jsx b/heureka/ui/src/components/components/ComponentsList.jsx index ca0be285..7857ccba 100644 --- a/heureka/ui/src/components/components/ComponentsList.jsx +++ b/heureka/ui/src/components/components/ComponentsList.jsx @@ -9,21 +9,42 @@ import { DataGridRow, DataGridHeadCell, DataGridCell, + Tooltip, + TooltipTrigger, + TooltipContent, + Stack, } from "@cloudoperators/juno-ui-components" import HintNotFound from "../shared/HintNotFound" import HintLoading from "../shared/HintLoading" import ComponentsListItem from "./ComponentsListItem" const ComponentsList = ({ items, isLoading }) => { - console.log("components", items) return ( Name Type - Total Number of Versions + + + + Version Count + + Total Number of Component Versions + + + + - Total Number of Instances + + + + Instance Count + + Total Number of Component Instances + + + + {isLoading && !items ? ( diff --git a/heureka/ui/src/components/components/ComponentsListController.jsx b/heureka/ui/src/components/components/ComponentsListController.jsx index 6b9a607d..a53141a2 100644 --- a/heureka/ui/src/components/components/ComponentsListController.jsx +++ b/heureka/ui/src/components/components/ComponentsListController.jsx @@ -10,7 +10,7 @@ import ListController from "../shared/ListController" const ComponentsListController = () => { return ( diff --git a/heureka/ui/src/components/components/ComponentsTab.jsx b/heureka/ui/src/components/components/ComponentsTab.jsx index 38cf4559..c3aa2383 100644 --- a/heureka/ui/src/components/components/ComponentsTab.jsx +++ b/heureka/ui/src/components/components/ComponentsTab.jsx @@ -10,16 +10,13 @@ import { Messages, MessagesProvider, } from "@cloudoperators/juno-messages-provider" -import { Container } from "@cloudoperators/juno-ui-components" const ComponentsTab = () => { return ( <> - - - - + + {/* // Should be activated after BE respective implementation*/} diff --git a/heureka/ui/src/components/filters/FilterPills.jsx b/heureka/ui/src/components/filters/FilterPills.jsx index 8c0db7ce..bedfc1b2 100644 --- a/heureka/ui/src/components/filters/FilterPills.jsx +++ b/heureka/ui/src/components/filters/FilterPills.jsx @@ -4,27 +4,27 @@ */ import React from "react" - import { Pill, Stack } from "@cloudoperators/juno-ui-components" -// import { useActiveFilters, useFilterActions } from "../../hooks/useAppStore" +import { useActiveFilters, useFilterActions } from "../../hooks/useAppStore" +import { humanizeString } from "../../lib/utils" -const FilterPills = () => { - // const activeFilters = useActiveFilters() - // const { removeActiveFilter } = useFilterActions() +const FilterPills = ({ entityName }) => { + const activeFilters = useActiveFilters(entityName) + const { removeActiveFilter } = useFilterActions() return ( - {/* {Object.entries(activeFilters).map(([key, values]) => { + {Object.entries(activeFilters || {}).map(([key, values]) => { return values.map((value) => ( removeActiveFilter(key, value)} + onClose={() => removeActiveFilter(entityName, key, value)} key={`${key}:${value}`} /> )) - })} */} + })} ) } diff --git a/heureka/ui/src/components/filters/FilterSelect.jsx b/heureka/ui/src/components/filters/FilterSelect.jsx index d2a4a8d5..8430cf68 100644 --- a/heureka/ui/src/components/filters/FilterSelect.jsx +++ b/heureka/ui/src/components/filters/FilterSelect.jsx @@ -3,8 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { useMemo, useState } from "react" - +import React, { useState } from "react" import { Button, InputGroup, @@ -13,31 +12,37 @@ import { Stack, SearchInput, } from "@cloudoperators/juno-ui-components" -// import { humanizeString } from "../../lib/utils" +import { + useFilterLabels, + useFilterLabelValues, + useFilterActions, + useActiveFilters, + useSearchTerm, +} from "../../hooks/useAppStore" +import { humanizeString } from "../../lib/utils" -const FilterSelect = ({ filters }) => { +const FilterSelect = ({ entityName, isLoading }) => { const [filterLabel, setFilterLabel] = useState("") const [filterValue, setFilterValue] = useState("") - const [resetKey, setResetKey] = useState(Date.now()) - const filterLabels = useMemo(() => { - return filters?.map((filter) => filter?.label) - }, [filters]) + const { addActiveFilter, clearActiveFilters, setSearchTerm } = + useFilterActions() + + const filterLabels = useFilterLabels(entityName) + const filterLabelValues = useFilterLabelValues(entityName) + const activeFilters = useActiveFilters(entityName) + const searchTerm = useSearchTerm() const handleFilterAdd = (value) => { if (filterLabel && (filterValue || value)) { - // add active filter to store - addActiveFilter(filterLabel, filterValue || value) - - // reset filterValue - setFilterValue("") - } else { - // TODO: show error -> please select filter/value + // Add the active filter to the store + addActiveFilter(entityName, filterLabel, filterValue || value) + setFilterValue("") // Reset filter value after adding } } - const handleFilterLabelChange = (value) => { - setFilterLabel(value) + const handleFilterLabelChange = (label) => { + setFilterLabel(label) } const handleFilterValueChange = (value) => { @@ -46,21 +51,13 @@ const FilterSelect = ({ filters }) => { } const handleSearchChange = (value) => { - // debounce setSearchTerm to avoid unnecessary re-renders + // Debounce search term to avoid unnecessary re-renders const debouncedSearchTerm = setTimeout(() => { setSearchTerm(value.target.value) }, 500) - - // clear timeout if we have a new value return () => clearTimeout(debouncedSearchTerm) } - // const handleKeyDown = (event) => { - // if (event.key === "Enter") { - // handleFilterValueChange() - // } - // } - return ( @@ -68,58 +65,51 @@ const FilterSelect = ({ filters }) => { name="filter" className="filter-label-select w-64 mb-0" label="Filter" - value={filterLabel} + value={humanizeString(filterLabel)} onChange={(val) => handleFilterLabelChange(val)} + disabled={isLoading} > {filterLabels?.map((filter) => ( ))} - {/* -