diff --git a/workspaces/frontend/config/webpack.common.js b/workspaces/frontend/config/webpack.common.js index 71c779c..a78bd03 100644 --- a/workspaces/frontend/config/webpack.common.js +++ b/workspaces/frontend/config/webpack.common.js @@ -5,6 +5,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const CopyPlugin = require('copy-webpack-plugin'); const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); const Dotenv = require('dotenv-webpack'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); const ASSET_PATH = process.env.ASSET_PATH || '/'; const IMAGES_DIRNAME = 'images'; const relativeDir = path.resolve(__dirname, '..'); @@ -18,7 +19,6 @@ module.exports = (env) => { { loader: 'ts-loader', options: { - transpileOnly: true, experimentalWatchApi: true, }, }, @@ -166,6 +166,7 @@ module.exports = (env) => { new CopyPlugin({ patterns: [{ from: './src/images', to: 'images' }], }), + new ForkTsCheckerWebpackPlugin(), ], resolve: { extensions: ['.js', '.ts', '.tsx', '.jsx'], diff --git a/workspaces/frontend/package-lock.json b/workspaces/frontend/package-lock.json index 552f018..ef81a76 100644 --- a/workspaces/frontend/package-lock.json +++ b/workspaces/frontend/package-lock.json @@ -51,6 +51,7 @@ "dotenv": "^16.4.5", "dotenv-webpack": "^8.1.0", "expect": "^29.7.0", + "fork-ts-checker-webpack-plugin": "^9.0.3", "html-webpack-plugin": "^5.6.0", "imagemin": "^8.0.1", "jest": "^29.7.0", @@ -9180,15 +9181,6 @@ "node": ">=10.13.0" } }, - "node_modules/enhanced-resolve/node_modules/tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "devOptional": true, - "engines": { - "node": ">=6" - } - }, "node_modules/enquirer": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", @@ -11054,6 +11046,184 @@ "node": "*" } }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.0.3.tgz", + "integrity": "sha512-zUE6ABwfybBbSH5TIsdAFiR2kfy0nm2yT0DEtujNM4vHbKhbrIsfoC5cPfJa4vqlmcSBPxqIED+EWVPWEw1hTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.7", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cosmiconfig": "^8.2.0", + "deepmerge": "^4.2.2", + "fs-extra": "^10.0.0", + "memfs": "^3.4.1", + "minimatch": "^3.0.4", + "node-abort-controller": "^3.0.1", + "schema-utils": "^3.1.1", + "semver": "^7.3.5", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "typescript": ">3.6.0", + "webpack": "^5.11.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -11698,15 +11868,6 @@ "strip-ansi": "^6.0.1" } }, - "node_modules/html-webpack-plugin/node_modules/tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/html-webpack-plugin/node_modules/terser": { "version": "5.26.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", @@ -12013,23 +12174,27 @@ "dev": true }, "node_modules/import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", - "optional": true, + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "devOptional": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/import-fresh/node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "optional": true, + "devOptional": true, "engines": { "node": ">=4" } @@ -15564,15 +15729,6 @@ "webpack": "^5.0.0" } }, - "node_modules/mini-css-extract-plugin/node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -16381,6 +16537,13 @@ "tslib": "^2.0.3" } }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "dev": true, + "license": "MIT" + }, "node_modules/node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -17144,7 +17307,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "optional": true, + "devOptional": true, "dependencies": { "callsites": "^3.0.0" }, @@ -20355,6 +20518,16 @@ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", "license": "MIT" }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/tcomb": { "version": "3.2.29", "resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz", @@ -21934,15 +22107,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/webpack/node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/webpack/node_modules/watchpack": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", diff --git a/workspaces/frontend/package.json b/workspaces/frontend/package.json index 05aac73..ffea910 100644 --- a/workspaces/frontend/package.json +++ b/workspaces/frontend/package.json @@ -62,6 +62,7 @@ "dotenv": "^16.4.5", "dotenv-webpack": "^8.1.0", "expect": "^29.7.0", + "fork-ts-checker-webpack-plugin": "^9.0.3", "html-webpack-plugin": "^5.6.0", "imagemin": "^8.0.1", "jest": "^29.7.0", diff --git a/workspaces/frontend/src/app/context/NotebookContext.tsx b/workspaces/frontend/src/app/context/NotebookContext.tsx index f187489..34787e4 100644 --- a/workspaces/frontend/src/app/context/NotebookContext.tsx +++ b/workspaces/frontend/src/app/context/NotebookContext.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { ReactNode } from 'react'; import { BFF_API_VERSION } from '~/app/const'; import useNotebookAPIState, { NotebookAPIState } from './useNotebookAPIState'; @@ -13,7 +14,11 @@ export const NotebookContext = React.createContext({ refreshAPIState: () => undefined, }); -export const NotebookContextProvider: React.FC = ({ children }) => { +interface NotebookContextProviderProps { + children: ReactNode; +} + +export const NotebookContextProvider: React.FC = ({ children }) => { const hostPath = `/api/${BFF_API_VERSION}`; const [apiState, refreshAPIState] = useNotebookAPIState(hostPath); diff --git a/workspaces/frontend/src/app/pages/Workspaces/Creation/WorkspaceCreation.tsx b/workspaces/frontend/src/app/pages/Workspaces/Creation/WorkspaceCreation.tsx index 1d024d8..271304c 100644 --- a/workspaces/frontend/src/app/pages/Workspaces/Creation/WorkspaceCreation.tsx +++ b/workspaces/frontend/src/app/pages/Workspaces/Creation/WorkspaceCreation.tsx @@ -29,9 +29,9 @@ const WorkspaceCreation: React.FunctionComponent = () => { const navigate = useNavigate(); const [currentStep, setCurrentStep] = useState(WorkspaceCreationSteps.KindSelection); - const [selectedKind, setSelectedKind] = useState(); - const [selectedImage, setSelectedImage] = useState(); - const [selectedPodConfig, setSelectedPodConfig] = useState(); + const [selectedKind, setSelectedKind] = useState(); + const [selectedImage, setSelectedImage] = useState(); + const [selectedPodConfig, setSelectedPodConfig] = useState(); const getStepVariant = useCallback( (step: WorkspaceCreationSteps) => { @@ -58,7 +58,7 @@ const WorkspaceCreation: React.FunctionComponent = () => { navigate('/workspaces'); }, [navigate]); - const onSelectWorkspaceKind = useCallback((newWorkspaceKind: WorkspaceKind) => { + const onSelectWorkspaceKind = useCallback((newWorkspaceKind: WorkspaceKind | undefined) => { setSelectedKind(newWorkspaceKind); setSelectedImage(undefined); setSelectedPodConfig(undefined); diff --git a/workspaces/frontend/src/app/pages/Workspaces/Creation/image/WorkspaceCreationImageList.tsx b/workspaces/frontend/src/app/pages/Workspaces/Creation/image/WorkspaceCreationImageList.tsx index dffae37..7b22b65 100644 --- a/workspaces/frontend/src/app/pages/Workspaces/Creation/image/WorkspaceCreationImageList.tsx +++ b/workspaces/frontend/src/app/pages/Workspaces/Creation/image/WorkspaceCreationImageList.tsx @@ -19,7 +19,7 @@ type WorkspaceCreationImageListProps = { images: WorkspaceImage[]; selectedLabels: Map>; selectedImage: WorkspaceImage | undefined; - onSelect: (workspaceImage: WorkspaceImage) => void; + onSelect: (workspaceImage: WorkspaceImage | undefined) => void; }; export const WorkspaceCreationImageList: React.FunctionComponent< @@ -41,7 +41,8 @@ export const WorkspaceCreationImageList: React.FunctionComponent< Object.keys(image.labels).reduce((accumulator, labelKey) => { const labelValue = image.labels[labelKey]; if (selectedLabels.has(labelKey)) { - return accumulator && selectedLabels.get(labelKey).has(labelValue); + const labelValues: Set | undefined = selectedLabels.get(labelKey); + return accumulator && labelValues !== undefined && labelValues.has(labelValue); } return accumulator; }, true), diff --git a/workspaces/frontend/src/app/pages/Workspaces/Creation/image/WorkspaceCreationImageSelection.tsx b/workspaces/frontend/src/app/pages/Workspaces/Creation/image/WorkspaceCreationImageSelection.tsx index 69222cf..cdfb1e9 100644 --- a/workspaces/frontend/src/app/pages/Workspaces/Creation/image/WorkspaceCreationImageSelection.tsx +++ b/workspaces/frontend/src/app/pages/Workspaces/Creation/image/WorkspaceCreationImageSelection.tsx @@ -9,7 +9,7 @@ import { FilterByLabels } from '~/app/pages/Workspaces/Creation/labelFilter/Filt interface WorkspaceCreationImageSelectionProps { images: WorkspaceImage[]; selectedImage: WorkspaceImage | undefined; - onSelect: (image: WorkspaceImage) => void; + onSelect: (image: WorkspaceImage | undefined) => void; } const WorkspaceCreationImageSelection: React.FunctionComponent< diff --git a/workspaces/frontend/src/app/pages/Workspaces/Creation/kind/WorkspaceCreationKindList.tsx b/workspaces/frontend/src/app/pages/Workspaces/Creation/kind/WorkspaceCreationKindList.tsx index 1de856c..23ef90f 100644 --- a/workspaces/frontend/src/app/pages/Workspaces/Creation/kind/WorkspaceCreationKindList.tsx +++ b/workspaces/frontend/src/app/pages/Workspaces/Creation/kind/WorkspaceCreationKindList.tsx @@ -18,7 +18,7 @@ import Filter, { FilteredColumn } from '~/shared/components/Filter'; type WorkspaceCreationKindListProps = { allWorkspaceKinds: WorkspaceKind[]; selectedKind: WorkspaceKind | undefined; - onSelect: (workspaceKind: WorkspaceKind) => void; + onSelect: (workspaceKind: WorkspaceKind | undefined) => void; }; export const WorkspaceCreationKindList: React.FunctionComponent = ({ diff --git a/workspaces/frontend/src/app/pages/Workspaces/Creation/kind/WorkspaceCreationKindSelection.tsx b/workspaces/frontend/src/app/pages/Workspaces/Creation/kind/WorkspaceCreationKindSelection.tsx index 5fe5b2c..ea9e376 100644 --- a/workspaces/frontend/src/app/pages/Workspaces/Creation/kind/WorkspaceCreationKindSelection.tsx +++ b/workspaces/frontend/src/app/pages/Workspaces/Creation/kind/WorkspaceCreationKindSelection.tsx @@ -7,7 +7,7 @@ import { WorkspaceCreationKindList } from '~/app/pages/Workspaces/Creation/kind/ interface WorkspaceCreationKindSelectionProps { selectedKind: WorkspaceKind | undefined; - onSelect: (kind: WorkspaceKind) => void; + onSelect: (kind: WorkspaceKind | undefined) => void; } const WorkspaceCreationKindSelection: React.FunctionComponent< diff --git a/workspaces/frontend/src/app/pages/Workspaces/Creation/labelFilter/FilterByLabels.tsx b/workspaces/frontend/src/app/pages/Workspaces/Creation/labelFilter/FilterByLabels.tsx index 32e1ae4..14051ac 100644 --- a/workspaces/frontend/src/app/pages/Workspaces/Creation/labelFilter/FilterByLabels.tsx +++ b/workspaces/frontend/src/app/pages/Workspaces/Creation/labelFilter/FilterByLabels.tsx @@ -7,7 +7,7 @@ import { import '@patternfly/react-catalog-view-extension/dist/css/react-catalog-view-extension.css'; type FilterByLabelsProps = { - labelledObjects: object[]; + labelledObjects: any[]; // eslint-disable-line @typescript-eslint/no-explicit-any selectedLabels: Map>; onSelect: (labels: Map>) => void; }; @@ -25,37 +25,36 @@ export const FilterByLabels: React.FunctionComponent = ({ if (!labelsMap.has(labelKey)) { labelsMap.set(labelKey, new Set()); } - labelsMap.get(labelKey).add(labelValue); + labelsMap.get(labelKey)?.add(labelValue); }); }); return labelsMap; }, [labelledObjects]); const isChecked = useCallback( - (label, labelValue) => selectedLabels.get(label)?.has(labelValue), + (label: string, labelValue: string) => selectedLabels.get(label)?.has(labelValue), [selectedLabels], ); const onChange = useCallback( - (labelKey, labelValue, event) => { - const { checked } = event.currentTarget; + (labelKey: string, labelValue: string, event: React.SyntheticEvent) => { + const { checked } = event.currentTarget as HTMLInputElement; const newSelectedLabels: Map> = new Map(selectedLabels); if (checked) { if (!newSelectedLabels.has(labelKey)) { newSelectedLabels.set(labelKey, new Set()); } - newSelectedLabels.get(labelKey).add(labelValue); + newSelectedLabels.get(labelKey)?.add(labelValue); } else { const labelValues = newSelectedLabels.get(labelKey); - labelValues.delete(labelValue); - if (labelValues.size === 0) { + labelValues?.delete(labelValue); + if (labelValues?.size === 0) { newSelectedLabels.delete(labelKey); } } onSelect(newSelectedLabels); - console.error(newSelectedLabels); }, [selectedLabels, onSelect], ); @@ -64,7 +63,7 @@ export const FilterByLabels: React.FunctionComponent = ({ {[...filterMap.keys()].map((label) => ( - {Array.from(filterMap.get(label).values()).map((labelValue) => ( + {Array.from(filterMap.get(label)?.values() ?? []).map((labelValue) => ( >; selectedPodConfig: WorkspacePodConfig | undefined; - onSelect: (workspacePodConfig: WorkspacePodConfig) => void; + onSelect: (workspacePodConfig: WorkspacePodConfig | undefined) => void; }; export const WorkspaceCreationPodConfigList: React.FunctionComponent< @@ -41,7 +41,8 @@ export const WorkspaceCreationPodConfigList: React.FunctionComponent< Object.keys(podConfig.labels).reduce((accumulator, labelKey) => { const labelValue = podConfig.labels[labelKey]; if (selectedLabels.has(labelKey)) { - return accumulator && selectedLabels.get(labelKey).has(labelValue); + const labelValues: Set | undefined = selectedLabels.get(labelKey); + return accumulator && labelValues !== undefined && labelValues.has(labelValue); } return accumulator; }, true), diff --git a/workspaces/frontend/src/app/pages/Workspaces/Creation/podConfig/WorkspaceCreationPodConfigSelection.tsx b/workspaces/frontend/src/app/pages/Workspaces/Creation/podConfig/WorkspaceCreationPodConfigSelection.tsx index 45ecd6a..6ac201a 100644 --- a/workspaces/frontend/src/app/pages/Workspaces/Creation/podConfig/WorkspaceCreationPodConfigSelection.tsx +++ b/workspaces/frontend/src/app/pages/Workspaces/Creation/podConfig/WorkspaceCreationPodConfigSelection.tsx @@ -9,7 +9,7 @@ import { FilterByLabels } from '~/app/pages/Workspaces/Creation/labelFilter/Filt interface WorkspaceCreationPodConfigSelectionProps { podConfigs: WorkspacePodConfig[]; selectedPodConfig: WorkspacePodConfig | undefined; - onSelect: (podConfig: WorkspacePodConfig) => void; + onSelect: (podConfig: WorkspacePodConfig | undefined) => void; } const WorkspaceCreationPodConfigSelection: React.FunctionComponent< diff --git a/workspaces/frontend/src/app/pages/Workspaces/ExpandedWorkspaceRow.tsx b/workspaces/frontend/src/app/pages/Workspaces/ExpandedWorkspaceRow.tsx index 7131f3d..8caa055 100644 --- a/workspaces/frontend/src/app/pages/Workspaces/ExpandedWorkspaceRow.tsx +++ b/workspaces/frontend/src/app/pages/Workspaces/ExpandedWorkspaceRow.tsx @@ -13,18 +13,18 @@ export const ExpandedWorkspaceRow: React.FC = ({ columnNames, }) => { const renderExpandedData = () => - Object.keys(columnNames).map((colName) => { + Object.keys(columnNames).map((colName, index) => { switch (colName) { case 'name': return ( - + ); default: - return ; + return ; } }); diff --git a/workspaces/frontend/src/app/pages/Workspaces/Workspaces.tsx b/workspaces/frontend/src/app/pages/Workspaces/Workspaces.tsx index bf78a76..e61217a 100644 --- a/workspaces/frontend/src/app/pages/Workspaces/Workspaces.tsx +++ b/workspaces/frontend/src/app/pages/Workspaces/Workspaces.tsx @@ -232,7 +232,7 @@ export const Workspaces: React.FunctionComponent = () => { const [activeActionType, setActiveActionType] = React.useState(null); const selectWorkspace = React.useCallback( - (newSelectedWorkspace) => { + (newSelectedWorkspace: Workspace | null) => { if (selectedWorkspace?.name === newSelectedWorkspace?.name) { setSelectedWorkspace(null); } else { @@ -567,7 +567,7 @@ export const Workspaces: React.FunctionComponent = () => { -
+ {Object.values(columnNames).map((columnName, index) => (