Skip to content

Commit cdab141

Browse files
cdmh219Chanel Henleyflacoman91
authored
DATAP-1619 Upgraded to ESLint v9 for CCDB UI (#572)
* Initial upgrades and updates to config rules * updated with cypress-related config * converted main eslint config file to '.mjs' to distinguished it as a module, as opposed to making all js files modules by default in the package.json file * removed outdated comment per PR feedback * added eslint plugins for react-hooks and react-redux * Build updates * update dist * update dist --------- Co-authored-by: Chanel Henley <[email protected]> Co-authored-by: Richard Dinh <[email protected]>
1 parent 2c89b14 commit cdab141

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+973
-777
lines changed

.eslintignore

-2
This file was deleted.

.eslintrc.cjs

-80
This file was deleted.

cypress/.eslintrc.js

-3
This file was deleted.

dist/ccdb5.js

+42-42
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/ccdb5.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

eslint.config.mjs

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Run `npx @eslint/config-inspector` to inspect the config.
2+
3+
import globals from 'globals';
4+
import js from '@eslint/js';
5+
import importPlugin from 'eslint-plugin-import';
6+
import jsdoc from 'eslint-plugin-jsdoc';
7+
import jsxA11y from 'eslint-plugin-jsx-a11y';
8+
import reactPlugin from 'eslint-plugin-react';
9+
import reactHooksPlugin from 'eslint-plugin-react-hooks';
10+
import reactReduxPlugin from 'eslint-plugin-react-redux';
11+
import pluginCypress from 'eslint-plugin-cypress/flat';
12+
import eslintConfigPrettier from 'eslint-config-prettier';
13+
import babelParser from '@babel/eslint-parser';
14+
15+
export default [
16+
{
17+
ignores: ['\*_/**fixtures**/_.js', 'serviceWorker.js']
18+
},
19+
js.configs.recommended,
20+
importPlugin.flatConfigs.recommended,
21+
jsdoc.configs['flat/recommended'],
22+
jsxA11y.flatConfigs.recommended,
23+
reactPlugin.configs.flat.recommended,
24+
pluginCypress.configs.recommended,
25+
eslintConfigPrettier,
26+
{
27+
plugins: {
28+
'react-hooks': reactHooksPlugin,
29+
'react-redux': reactReduxPlugin
30+
}
31+
},
32+
{
33+
languageOptions: {
34+
ecmaVersion: 2023,
35+
parser: babelParser,
36+
parserOptions: {
37+
ecmaFeatures: {
38+
jsx: true,
39+
},
40+
},
41+
globals: {
42+
...globals.browser,
43+
...globals.node,
44+
...globals.jest,
45+
},
46+
},
47+
settings: {
48+
'import/resolver': {
49+
node: {
50+
paths: ['src'],
51+
extensions: ['.js', '.jsx', '.ts', '.d.ts', '.tsx']
52+
},
53+
},
54+
react: {
55+
version: 'detect',
56+
},
57+
},
58+
rules: {
59+
'id-length': ['error', { min: 2 }],
60+
'jsdoc/require-hyphen-before-param-description': ['warn', 'always'],
61+
'jsdoc/tag-lines': ['error', 'any', { startLines: 1 }],
62+
'no-console': ['warn'],
63+
'no-use-before-define': ['error','nofunc'],
64+
'no-unused-vars': [
65+
'error',
66+
{
67+
vars: 'all',
68+
args: 'after-used',
69+
ignoreRestSiblings: false,
70+
},
71+
],
72+
'no-var': ['error'],
73+
'prefer-const': ['error'],
74+
radix: ['error'],
75+
'react/jsx-no-leaked-render': [
76+
'error',
77+
{ validStrategies: ['coerce', 'ternary'] },
78+
],
79+
'react/no-multi-comp': ['error', { ignoreStateless: true }],
80+
'react/no-unstable-nested-components': ['error'],
81+
'react/self-closing-comp': ['error'],
82+
'react/boolean-prop-naming': ['error', { validateNested: true }],
83+
'react/default-props-match-prop-types': [
84+
'error',
85+
{ allowRequiredDefaults: true },
86+
],
87+
'react/jsx-curly-brace-presence': ['error'],
88+
'react/jsx-uses-react': 'off',
89+
'react/react-in-jsx-scope': 'off',
90+
...reactHooksPlugin.configs.recommended.rules,
91+
...reactReduxPlugin.configs.recommended.rules
92+
},
93+
},
94+
];

package.json

+13-8
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"devDependencies": {
3535
"@babel/cli": "^7.26.4",
3636
"@babel/core": "^7.24.7",
37-
"@babel/eslint-parser": "^7.24.7",
37+
"@babel/eslint-parser": "^7.26.5",
3838
"@babel/preset-react": "^7.26.3",
3939
"@babel/runtime": "^7.26.0",
4040
"@cfpb/browserslist-config": "0.0.3",
@@ -55,12 +55,17 @@
5555
"cypress": "^13.17.0",
5656
"d3": "^7.9.0",
5757
"dayjs": "^1.11.10",
58-
"eslint": "^8.57.0",
59-
"eslint-config-prettier": "^9.1.0",
58+
"eslint": "^9.18.0",
59+
"eslint-config-prettier": "^10.0.1",
6060
"eslint-config-react-app": "^7.0.1",
61-
"eslint-plugin-cypress": "^3.2.0",
62-
"eslint-plugin-jsdoc": "^48.2.5",
63-
"eslint-plugin-react-redux": "^4.1.0",
61+
"eslint-plugin-cypress": "^4.1.0",
62+
"eslint-plugin-import": "^2.31.0",
63+
"eslint-plugin-jsdoc": "^50.6.1",
64+
"eslint-plugin-jsx-a11y": "^6.10.2",
65+
"eslint-plugin-react": "^7.37.4",
66+
"eslint-plugin-react-hooks": "^5.1.0",
67+
"eslint-plugin-react-redux": "^4.2.0",
68+
"globals": "^15.14.0",
6469
"highcharts": "11.4.8",
6570
"history": "^5.3.0",
6671
"husky": "^9.1.7",
@@ -91,8 +96,8 @@
9196
"release-it": "^17.3.0",
9297
"sass": "^1.83.0",
9398
"string-replace-loader": "^3.1.0",
94-
"stylelint": "^16.12.0",
95-
"stylelint-config-standard": "^36.0.0",
99+
"stylelint": "^16.13.2",
100+
"stylelint-config-standard": "^37.0.0",
96101
"stylelint-config-standard-scss": "^14.0.0"
97102
},
98103
"lint-staged": {

src/App.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import './css/App.scss';
2+
import { ReactElement } from 'react';
23
import { Route, BrowserRouter as Router, Routes } from 'react-router-dom';
34
import { ComplaintDetail } from './components/ComplaintDetail/ComplaintDetail';
45
import { SearchComponents } from './components/Search/SearchComponents';
56

67
/**
7-
* Main App Component
88
*
9-
* @returns {JSX.Element} Main app
9+
* @returns {ReactElement} Main application component
1010
*/
1111
const App = () => {
1212
return (

src/actions/analytics.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const Analytics = {
5858
if (Analytics.tagManagerIsLoaded) {
5959
window.dataLayer.push(dataLayerOptions);
6060
} else if (callback && typeof callback === 'function') {
61-
callback(); // eslint-disable-line callback-return, no-inline-comments, max-len
61+
callback();
6262
}
6363
},
6464

src/actions/routes.js

-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ export function normalizeRouteParams(params) {
4242
* @returns {Function} a series of actions to execute
4343
*/
4444
export function changeRoute(path, params) {
45-
// eslint-disable-next-line complexity
4645
return function (dispatch, getState) {
4746
const store = getState();
4847
const normalized = normalizeRouteParams(params);

src/api/params/params.js

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable camelcase */
21
import { clamp, removeNullProperties } from '../../utils';
32
import { enforceValues } from '../../utils/reducers';
43
// ----------------------------------------------------------------------------

src/components/Charts/RowChart/RowChart.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export const RowChart = ({
4646
const wrapText = (text, width, viewMore) => {
4747
// ignore test coverage since this is code borrowed from d3 mbostock
4848
// text wrapping functions
49-
/* eslint-disable complexity */
49+
5050
/* istanbul ignore next */
5151
text.each(function () {
5252
const innerText = d3.select(this);
@@ -73,7 +73,6 @@ export const RowChart = ({
7373
.attr('y', y)
7474
.attr('dy', dy + 'em');
7575

76-
// eslint-disable-next-line no-cond-assign
7776
while ((word = words.pop())) {
7877
line.push(word);
7978
tspan.text(line.join(' '));
@@ -85,7 +84,7 @@ export const RowChart = ({
8584
.append('tspan')
8685
.attr('x', spanWidth)
8786
.attr('y', y)
88-
// eslint-disable-next-line no-mixed-operators
87+
8988
.attr('dy', ++lineNumber * lineHeight + dy + 'em')
9089
.text(word);
9190
wrapCount++;
@@ -97,12 +96,11 @@ export const RowChart = ({
9796
.select(innerText.node().parentNode)
9897
.select('.view-more-background');
9998
const oldHeight = viewMoreBackground.attr('height');
100-
// eslint-disable-next-line no-mixed-operators
99+
101100
const newHeight = parseFloat(oldHeight) + wrapCount * 12;
102101
viewMoreBackground.attr('height', newHeight);
103102
}
104103
});
105-
/* eslint-enable complexity */
106104
};
107105

108106
const collapseARow = (rowName) => {

src/components/Dialogs/DataExport/dataExportUtils.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function buildSomeResultsUri(format, size, state) {
2929

3030
params.size = size;
3131
params.format = format;
32-
// eslint-disable-next-line camelcase
32+
3333
params.no_aggs = true;
3434

3535
// Remove unnecessary pagination query params

src/components/Filters/Aggregation/AggregationBranch/AggregationBranch.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export const AggregationBranch = ({ fieldName, item, subitems }) => {
5353
disabled: item.isDisabled,
5454
key: slugify(item.key, sub.key),
5555
value: sub.key,
56-
// eslint-disable-next-line camelcase
56+
5757
doc_count: sub.doc_count,
5858
}));
5959

@@ -132,7 +132,6 @@ export const AggregationBranch = ({ fieldName, item, subitems }) => {
132132
AggregationBranch.propTypes = {
133133
fieldName: PropTypes.string.isRequired,
134134
item: PropTypes.shape({
135-
// eslint-disable-next-line camelcase
136135
doc_count: PropTypes.number.isRequired,
137136
key: PropTypes.string.isRequired,
138137
value: PropTypes.string,

src/components/Filters/Aggregation/AggregationItem/AggregationItem.js

-4
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,10 @@ const appliedFilters = ({ fieldName, item, aggs, filters }) => {
1717
// check the parent only, and uncheck the rest so that the fake check
1818
// will take affect
1919
const [parentFilter, childFilter] = item.key.split(SLUG_SEPARATOR);
20-
/* eslint-disable no-unexpected-multiline */
21-
// TODO: reformat to not need the unexpected multiline.
2220
const subItems = aggs
2321
.find((agg) => agg.key === parentFilter)
2422
['sub_' + fieldName + '.raw'].buckets.map((agg) => agg.key)
2523
.sort();
26-
/* eslint-enable no-unexpected-multiline */
2724

2825
const parentKey = parentFilter + SLUG_SEPARATOR;
2926
const selectedFilters = filters
@@ -121,7 +118,6 @@ export const AggregationItem = ({ fieldName, item }) => {
121118
AggregationItem.propTypes = {
122119
fieldName: PropTypes.string.isRequired,
123120
item: PropTypes.shape({
124-
// eslint-disable-next-line camelcase
125121
doc_count: PropTypes.number.isRequired,
126122
key: PropTypes.string.isRequired,
127123
value: PropTypes.string,

src/components/Filters/Date/CompanyReceivedFilter.spec.js

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { CompanyReceivedFilter } from './CompanyReceivedFilter';
2-
import React from 'react';
32
import { merge } from '../../../testUtils/functionHelpers';
43
import { queryState } from '../../../reducers/query/querySlice';
54
import * as filterActions from '../../../reducers/query/querySlice';

src/components/Filters/FilterPanel/FilterPanel.spec.js

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import React from 'react';
21
import { FilterPanel } from './FilterPanel';
32
import { merge } from '../../../testUtils/functionHelpers';
43
import { viewState } from '../../../reducers/view/viewSlice';

src/components/Filters/FilterSearch/FilterSearch.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { useGetAggregations } from '../../../api/hooks/useGetAggregations';
88
import { SLUG_SEPARATOR } from '../../../constants';
99
import { normalize } from '../../../utils';
1010
import { ClearButton } from '../../Typeahead/ClearButton/ClearButton';
11-
import HighlightingOption from '../../Typeahead/HighlightingOption/HighlightingOption';
11+
import { HighlightingOption } from '../../Typeahead/HighlightingOption/HighlightingOption';
1212
import getIcon from '../../Common/Icon/iconMap';
1313

1414
export const FilterSearch = ({ fieldName }) => {
@@ -22,6 +22,8 @@ export const FilterSearch = ({ fieldName }) => {
2222
const subaggName = `sub_${fieldName}.raw`.toLowerCase();
2323
const buckets = [];
2424

25+
const [inputText, setInputText] = useState('');
26+
2527
aggResults.forEach((option) => {
2628
if (buckets.findIndex((item) => item.key === option.key) === -1) {
2729
const parentAgg = { ...option };
@@ -57,15 +59,13 @@ export const FilterSearch = ({ fieldName }) => {
5759
}
5860
});
5961

62+
const [dropdownOptions, setDropdownOptions] = useState(buckets);
63+
6064
const handleClear = () => {
6165
ref.current.clear();
6266
setInputText('');
6367
};
6468

65-
const [inputText, setInputText] = useState('');
66-
67-
const [dropdownOptions, setDropdownOptions] = useState(buckets);
68-
6969
const handleInputChange = (value) => {
7070
setInputText(value);
7171
const rawValue = normalize(value);

0 commit comments

Comments
 (0)