From 7a46666efe5e8e0eb3f79f572110e24e67f5e18a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Gr=C3=A4=C3=9Fl?= Date: Mon, 15 Feb 2021 10:36:24 +0100 Subject: [PATCH] chore: Add react hooks linter (#977) --- .eslintrc.yml | 1 + package-lock.json | 6 ++++++ package.json | 3 ++- src/App.js | 3 ++- .../CompliancePolicies/CompliancePolicies.js | 2 +- .../CreatePolicy/EditPolicyRules.js | 2 +- .../CreatePolicy/EditPolicySystems.js | 2 +- src/SmartComponents/EditPolicy/EditPolicy.js | 4 ++-- .../PolicyDetails/PolicyDetails.js | 2 +- src/SmartComponents/Reports/Reports.js | 2 +- src/Utilities/hooks/useDocumentTitle.js | 2 +- src/Utilities/hooks/useFeature.js | 18 ++++++++---------- 12 files changed, 27 insertions(+), 20 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index e7d95ede5..adb2548b6 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -10,6 +10,7 @@ extends: - 'eslint:recommended' - 'prettier' - 'plugin:react/recommended' + - 'plugin:react-hooks/recommended' parserOptions: ecmaVersion: 7 sourceType: module diff --git a/package-lock.json b/package-lock.json index 6dadd9615..84c558c31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6566,6 +6566,12 @@ } } }, + "eslint-plugin-react-hooks": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", + "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", + "dev": true + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", diff --git a/package.json b/package.json index 321d3ec95..6a29fd75c 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "@babel/preset-flow": "^7.10.4", "@babel/preset-react": "^7.12.10", "@redhat-cloud-services/frontend-components-config": "^4.0.1", + "@wojtekmaj/enzyme-adapter-react-17": "^0.4.1", "babel-core": "^6.26.3", "babel-eslint": "^10.1.0", "babel-loader": "^8.2.2", @@ -102,12 +103,12 @@ "codecov": "^3.7.2", "css-loader": "^3.5.3", "enzyme": "^3.11.0", - "@wojtekmaj/enzyme-adapter-react-17": "^0.4.1", "enzyme-to-json": "^3.6.1", "eslint": "^7.17.0", "eslint-config-prettier": "^6.15.0", "eslint-loader": "^4.0.2", "eslint-plugin-react": "^7.21.2", + "eslint-plugin-react-hooks": "^4.2.0", "file-loader": "^6.2.0", "good-guy-http": "^1.13.0", "identity-obj-proxy": "^3.0.0", diff --git a/src/App.js b/src/App.js index 6bc0b3f04..96fe17cf7 100644 --- a/src/App.js +++ b/src/App.js @@ -4,6 +4,7 @@ import routerParams from '@redhat-cloud-services/frontend-components-utilities/R import { Routes } from './Routes'; import NotificationsPortal from '@redhat-cloud-services/frontend-components-notifications/NotificationPortal'; import './App.scss'; +import { useSetFlagsFromUrl } from 'Utilities/hooks/useFeature'; const appNavClick = { reports(redirect) { insights.chrome.appNavClick({ id: 'reports', redirect }); }, @@ -12,7 +13,7 @@ const appNavClick = { }; const App = (props) => { - + useSetFlagsFromUrl(); useEffect(() => { insights.chrome.init(); insights.chrome?.hideGlobalFilter?.(); diff --git a/src/SmartComponents/CompliancePolicies/CompliancePolicies.js b/src/SmartComponents/CompliancePolicies/CompliancePolicies.js index 649d82ba7..5f35370c4 100644 --- a/src/SmartComponents/CompliancePolicies/CompliancePolicies.js +++ b/src/SmartComponents/CompliancePolicies/CompliancePolicies.js @@ -59,7 +59,7 @@ export const CompliancePolicies = () => { ; let { data, error, loading, refetch } = useQuery(QUERY); - useEffect(() => { refetch(); }, [location]); + useEffect(() => { refetch(); }, [location, refetch]); let policies; if (data) { diff --git a/src/SmartComponents/CreatePolicy/EditPolicyRules.js b/src/SmartComponents/CreatePolicy/EditPolicyRules.js index db268de45..28bc6ee16 100644 --- a/src/SmartComponents/CreatePolicy/EditPolicyRules.js +++ b/src/SmartComponents/CreatePolicy/EditPolicyRules.js @@ -66,7 +66,7 @@ export const EditPolicyRules = ({ profileId, benchmarkId, selectedRuleRefIds, ch change('selectedRuleRefIds', ruleIds); } } - }, [data]); + }, [data, change, selectedRuleRefIds]); return diff --git a/src/SmartComponents/CreatePolicy/EditPolicySystems.js b/src/SmartComponents/CreatePolicy/EditPolicySystems.js index f9c27f224..84b5c87b7 100644 --- a/src/SmartComponents/CreatePolicy/EditPolicySystems.js +++ b/src/SmartComponents/CreatePolicy/EditPolicySystems.js @@ -34,7 +34,7 @@ const EditPolicySystems = ({ change, selectedSystemIds }) => { if (selectedSystemIds) { change('systems', selectedSystemIds); } - }, [selectedSystemIds]); + }, [selectedSystemIds, change]); const InvCmp = newInventory ? InventoryTable : SystemsTable; diff --git a/src/SmartComponents/EditPolicy/EditPolicy.js b/src/SmartComponents/EditPolicy/EditPolicy.js index 229f2893f..e434bd7b4 100644 --- a/src/SmartComponents/EditPolicy/EditPolicy.js +++ b/src/SmartComponents/EditPolicy/EditPolicy.js @@ -56,7 +56,7 @@ export const EditPolicy = ({ route }) => { ...updatedPolicy, hosts: selectedEntities ? selectedEntities : [] }); - }, [selectedEntities]); + }, [selectedEntities, updatedPolicy]); useEffect(() => { const complianceThresholdValid = @@ -69,7 +69,7 @@ export const EditPolicy = ({ route }) => { type: 'SELECT_ENTITIES', payload: { ids: policy?.hosts?.map(({ id }) => ({ id })) || [] } }); - }, [policy]); + }, [policy, dispatch]); const InvCmp = newInventory ? InventoryTable : SystemsTable; useTitleEntity(route, policy?.name); diff --git a/src/SmartComponents/PolicyDetails/PolicyDetails.js b/src/SmartComponents/PolicyDetails/PolicyDetails.js index 4c7b338ac..30b737522 100644 --- a/src/SmartComponents/PolicyDetails/PolicyDetails.js +++ b/src/SmartComponents/PolicyDetails/PolicyDetails.js @@ -131,7 +131,7 @@ export const PolicyDetails = ({ route }) => { useEffect(() => { refetch(); - }, [location]); + }, [location, refetch]); useTitleEntity(route, policy?.name); diff --git a/src/SmartComponents/Reports/Reports.js b/src/SmartComponents/Reports/Reports.js index d4262ec95..c02fd39f3 100644 --- a/src/SmartComponents/Reports/Reports.js +++ b/src/SmartComponents/Reports/Reports.js @@ -100,7 +100,7 @@ export const Reports = () => { useEffect(() => { refetch(); - }, [location]); + }, [location, refetch]); if (data) { profiles = profilesFromEdges(data); diff --git a/src/Utilities/hooks/useDocumentTitle.js b/src/Utilities/hooks/useDocumentTitle.js index 4ce5a4530..2ab69bc66 100644 --- a/src/Utilities/hooks/useDocumentTitle.js +++ b/src/Utilities/hooks/useDocumentTitle.js @@ -14,7 +14,7 @@ export const useTitleEntity = (route, entityTitle) => { const title = entityTitle ? route.title.replace('$entityTitle', entityTitle) : route.defaultTitle; route.setTitle(title); - }, [entityTitle, location]); + }, [entityTitle, location, route]); }; const useDocumentTitle = () => ( diff --git a/src/Utilities/hooks/useFeature.js b/src/Utilities/hooks/useFeature.js index d1df613e8..881fdc4b7 100644 --- a/src/Utilities/hooks/useFeature.js +++ b/src/Utilities/hooks/useFeature.js @@ -15,7 +15,7 @@ const setFeatureFlag = (featureValue, feature) => { }; // Allows setting feature flag values via ?feature|(enable/disable) -const setFlagsFromUrl = () => { +export const useSetFlagsFromUrl = () => { const { search, pathName: path } = useLocation(); const history = useHistory(); if (!search) { @@ -28,22 +28,20 @@ const setFlagsFromUrl = () => { history.push(path); }; -// Queries the local storage for feature flag values -const getLocatStateFlag = (feature) => ( - !!localStorage.getItem(`${LOCAL_STORE_FEATURE_PREFIX}:${feature}`) -); +const getFlagValue = (feature) => { + const defaultValue = features[feature]; + const storedValue = !!localStorage.getItem(`${LOCAL_STORE_FEATURE_PREFIX}:${feature}`); + + return storedValue || defaultValue; +}; // A hook to query feature values const useFeature = (feature) => { - const featureDefault = features[feature]; if (!feature) { return; } - setFlagsFromUrl(); - - const localStoreValue = getLocatStateFlag(feature); - const featureEnabled = localStoreValue || featureDefault; + const featureEnabled = getFlagValue(feature); console.log(`Feature ${feature} is set to ${featureEnabled}`); return featureEnabled;