Upgrade frontend dependencies (#3818)

Signed-off-by: Cintia Sanchez Garcia <cynthiasg@icloud.com>
This commit is contained in:
Cintia Sánchez García 2024-05-16 13:40:06 +02:00 committed by GitHub
parent c78611569b
commit 86145920bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
310 changed files with 2618 additions and 1822 deletions

39
web/eslint.config.js Normal file
View File

@ -0,0 +1,39 @@
// eslint.config.js
import js from '@eslint/js';
import reactHooks from 'eslint-plugin-react-hooks';
import simpleImportSort from 'eslint-plugin-simple-import-sort';
import tseslint from 'typescript-eslint';
import globals from "globals";
const config = [
js.configs.recommended,
...tseslint.configs.recommended,
{
linterOptions: {
reportUnusedDisableDirectives: 'error',
},
plugins: {
'@typescript-eslint': tseslint.plugin,
'react-hooks': reactHooks,
'simple-import-sort': simpleImportSort,
},
ignores: ['analytics.ts', 'jsonschema.ts'],
rules: {
'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error',
},
languageOptions: {
parser: tseslint.parser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
globals: {
...globals.browser,
},
},
},
];
export default config;

View File

@ -2,10 +2,11 @@
"name": "hub",
"version": "1.18.0",
"private": true,
"type": "module",
"dependencies": {
"@analytics/google-analytics-v3": "^0.6.1",
"analytics": "^0.8.11",
"apexcharts": "^3.48.0",
"apexcharts": "^3.49.1",
"bootstrap": "^5.3.3",
"classnames": "^2.5.1",
"codemirror": "^5.65.15",
@ -16,17 +17,17 @@
"json-schema-merge-allof": "^0.8.1",
"lodash": "^4.17.21",
"moment": "^2.30.1",
"nanoid": "^4.0.2",
"react": "^18.1.0",
"nanoid": "^5.0.7",
"react": "^18.3.1",
"react-apexcharts": "^1.4.1",
"react-codemirror2": "^7.3.0",
"react-color": "^2.19.3",
"react-diff-view": "3.0.2",
"react-dom": "^18.1.0",
"react-icons": "^5.1.0",
"react-image-crop": "^10.1.8",
"react-dom": "^18.3.1",
"react-icons": "^5.2.0",
"react-image-crop": "^11.0.5",
"react-markdown": "^8.0.7",
"react-router-dom": "^6.22.3",
"react-router-dom": "^6.23.1",
"react-syntax-highlighter": "^15.5.0",
"regexify-string": "^1.0.17",
"remark-gfm": "^3.0.1",
@ -37,12 +38,13 @@
"tinycolor2": "^1.6.0",
"ua-parser-js": "^1.0.37",
"unified": "^10.1.2",
"yaml": "^2.4.1"
"yaml": "^2.4.2"
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "14.2.1",
"@eslint/js": "^9.2.0",
"@testing-library/jest-dom": "^6.4.5",
"@testing-library/react": "^15.0.7",
"@testing-library/react-hooks": "^8.0.0",
"@testing-library/user-event": "^14.5.2",
"@types/bootstrap": "^5.2.10",
@ -50,34 +52,38 @@
"@types/jest": "^29.5.12",
"@types/json-schema": "^7.0.14",
"@types/json-schema-merge-allof": "^0.6.5",
"@types/lodash": "^4.17.0",
"@types/node": "^20.12.7",
"@types/react": "^18.2.78",
"@types/lodash": "^4.17.1",
"@types/node": "^20.12.12",
"@types/react": "^18.3.2",
"@types/react-color": "^3.0.12",
"@types/react-dom": "^18.2.25",
"@types/react-syntax-highlighter": "^15.5.11",
"@types/react-dom": "^18.3.0",
"@types/react-syntax-highlighter": "^15.5.13",
"@types/semver": "^7.5.8",
"eslint": "^9.2.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-simple-import-sort": "^12.1.0",
"globals": "^15.2.0",
"jest-fetch-mock": "^3.0.3",
"jest-mock": "^29.7.0",
"prettier": "^3.2.5",
"react-scripts": "^5.0.1",
"sass": "^1.75.0",
"sass": "^1.77.1",
"shx": "^0.3.4",
"typescript": "^5.4.5"
"typescript": "^5.4.5",
"typescript-eslint": "^7.9.0"
},
"proxy": "http://localhost:8000",
"scripts": {
"copy:static": "shx rm -rf src/static && shx mkdir src/static && shx cp -r public/static/* src/static",
"start": "yarn copy:static && DANGEROUSLY_DISABLE_HOST_CHECK=true react-scripts start",
"build": "yarn copy:static && INLINE_RUNTIME_CHUNK=false IMAGE_INLINE_SIZE_LIMIT=0 react-scripts build",
"start": "yarn copy:static && DANGEROUSLY_DISABLE_HOST_CHECK=true DISABLE_ESLINT_PLUGIN=true react-scripts start",
"build": "yarn copy:static && INLINE_RUNTIME_CHUNK=false IMAGE_INLINE_SIZE_LIMIT=0 DISABLE_ESLINT_PLUGIN=true react-scripts build",
"test": "sed -i -e 's/const FORCE_EXIT_DELAY = 500;/const FORCE_EXIT_DELAY = 1000;/g' ./node_modules/jest-worker/build/base/BaseWorkerPool.js && TZ=UTC react-scripts test # See https://github.com/facebook/jest/issues/11354",
"test:coverage": "TZ=UTC react-scripts test --coverage --watchAll=false",
"eject": "react-scripts eject",
"lint": "eslint --ext .js,.jsx,.ts,.tsx src --color",
"lint:fix": "eslint --ext .js,.jsx,.ts,.tsx src --fix",
"lint": "eslint src --max-warnings 0",
"lint:fix": "eslint src --max-warnings 0 --fix",
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
"format:diff": "prettier --list-different \"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
"isready": "yarn format && yarn lint && yarn test --watchAll=false --passWithNoTests --verbose && yarn build"

View File

@ -1,12 +1,12 @@
// @ts-ignore
// @ts-expect-error no d.ts file for this package
import googleAnalyticsV3 from '@analytics/google-analytics-v3';
import Analytics, { AnalyticsPlugin } from 'analytics';
import { isNull } from 'lodash';
import isNull from 'lodash/isNull';
import getMetaTag from '../utils/getMetaTag';
const getPlugins = (): AnalyticsPlugin[] => {
let plugins: AnalyticsPlugin[] = [];
const plugins: AnalyticsPlugin[] = [];
const analyticsConfig: string | null = getMetaTag('gaTrackingID');
if (!isNull(analyticsConfig) && analyticsConfig !== '' && analyticsConfig !== '{{ .gaTrackingID }}') {

View File

@ -35,7 +35,9 @@ import renameKeysInObject from '../utils/renameKeysInObject';
import API from './index';
enableFetchMocks();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const getData = (fixtureId: string): any => {
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-explicit-any
return require(`./__fixtures__/index/${fixtureId}.json`) as any;
};

View File

@ -1,6 +1,6 @@
import { isNull } from 'lodash';
import camelCase from 'lodash/camelCase';
import isArray from 'lodash/isArray';
import isNull from 'lodash/isNull';
import isObject from 'lodash/isObject';
import isUndefined from 'lodash/isUndefined';
@ -59,6 +59,7 @@ interface TransferRepositoryRequest {
}
interface Result {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
}
@ -67,6 +68,7 @@ interface FetchOptions {
headers?: {
[key: string]: string;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
body?: any;
}
@ -102,6 +104,7 @@ class API_CLASS {
private csrfToken: string | null = null;
private API_BASE_URL = '/api/v1';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public toCamelCase(r: any): any {
if (isArray(r)) {
return r.map((v) => this.toCamelCase(v));
@ -116,16 +119,18 @@ class API_CLASS {
return r;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private async handleErrors(res: any) {
if (!res.ok) {
let error: Error;
let tmpError;
switch (res.status) {
case 401:
try {
let text = await res.json();
tmpError = await res.json();
error = {
kind: ErrorKind.Unauthorized,
message: text.message !== '' ? text.message : undefined,
message: tmpError.message !== '' ? tmpError.message : undefined,
};
} catch {
error = {
@ -141,8 +146,8 @@ class API_CLASS {
break;
case 403:
try {
const er = await res.text();
if (er.includes('CSRF token invalid')) {
tmpError = await res.text();
if (tmpError.includes('CSRF token invalid')) {
this.csrfToken = null;
error = {
kind: ErrorKind.InvalidCSRF,
@ -165,10 +170,10 @@ class API_CLASS {
break;
default:
try {
let text = await res.json();
tmpError = await res.json();
error = {
kind: ErrorKind.Other,
message: text.message !== '' ? text.message : undefined,
message: tmpError.message !== '' ? tmpError.message : undefined,
};
} catch {
error = {
@ -181,6 +186,7 @@ class API_CLASS {
return res;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private checkIfApprovedSession(res: any) {
if (res.headers.has(this.HEADERS.sessionApproved)) {
const isApproved = res.headers.get(this.HEADERS.sessionApproved);
@ -197,9 +203,11 @@ class API_CLASS {
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private getHeadersValue(res: any, params?: string[]): any {
if (!isUndefined(params) && params.length > 0) {
let headers: any = {};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const headers: any = {};
params.forEach((param: string) => {
if (res.headers.has(param)) {
headers[param] = res.headers.get(param);
@ -211,6 +219,7 @@ class API_CLASS {
}
private async handleContent(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
res: any,
skipCamelConversion?: boolean,
checkApprovedSession?: boolean,
@ -220,6 +229,8 @@ class API_CLASS {
if (!isUndefined(checkApprovedSession) && checkApprovedSession) {
response = this.checkIfApprovedSession(res);
}
let content;
let tmpHeaders;
switch (response.headers.get('Content-Type')) {
case 'text/plain; charset=utf-8':
@ -227,25 +238,27 @@ class API_CLASS {
case 'application/yaml':
case 'text/yaml; charset=UTF-8':
case 'text/yaml':
const text = await response.text();
return text;
content = await response.text();
return content;
case 'application/json':
let json = await response.json();
const tmpHeaders = this.getHeadersValue(res, headers);
content = await response.json();
tmpHeaders = this.getHeadersValue(res, headers);
if (!isNull(tmpHeaders)) {
if (isArray(json)) {
json = { items: json };
if (isArray(content)) {
content = { items: content };
}
json = { ...json, ...tmpHeaders };
content = { ...content, ...tmpHeaders };
}
return skipCamelConversion ? json : this.toCamelCase(json);
return skipCamelConversion ? content : this.toCamelCase(content);
default:
return response;
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private async processFetchOptions(opts?: FetchOptions): Promise<FetchOptions | any> {
let options: FetchOptions | any = opts || {};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const options: FetchOptions | any = opts || {};
// Use CSRF token only when methods are DELETE, POST and PUT
if (opts && ['DELETE', 'POST', 'PUT'].includes(opts.method)) {
if (isNull(this.csrfToken)) {
@ -268,7 +281,9 @@ class API_CLASS {
return options;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private async apiFetch(props: APIFetchProps): Promise<any> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const csrfRetry = (func: () => Promise<any>) => {
return func().catch((error: Error) => {
if (error.kind === ErrorKind.InvalidCSRF) {
@ -280,7 +295,8 @@ class API_CLASS {
};
return csrfRetry(async () => {
let options: FetchOptions | any = await this.processFetchOptions(props.opts);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const options: FetchOptions | any = await this.processFetchOptions(props.opts);
return fetch(props.url, options)
.then(this.handleErrors)
@ -501,20 +517,23 @@ class API_CLASS {
}
public async checkAvailability(props: CheckAvailabilityProps): Promise<boolean> {
return fetch(`${this.API_BASE_URL}/check-availability/${props.resourceKind}?v=${encodeURIComponent(props.value)}`, {
method: 'HEAD',
})
.then((res: any) => {
switch (res.status) {
case 404:
return Promise.resolve(false);
default:
return Promise.resolve(true);
}
return (
fetch(`${this.API_BASE_URL}/check-availability/${props.resourceKind}?v=${encodeURIComponent(props.value)}`, {
method: 'HEAD',
})
.catch(() => {
return Promise.resolve(true);
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.then((res: any) => {
switch (res.status) {
case 404:
return Promise.resolve(false);
default:
return Promise.resolve(true);
}
})
.catch(() => {
return Promise.resolve(true);
})
);
}
public getUserOrganizations(query: SearchQuery): Promise<{ items: Organization[]; paginationTotalCount: string }> {
@ -896,7 +915,8 @@ class API_CLASS {
newFormatReport[item] = {
Results: report[item] as SecurityReportResult[],
};
} else if (isObject(report[item]) && report[item].hasOwnProperty('Results')) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} else if (isObject(report[item]) && !isUndefined((report[item] as any).Results)) {
newFormatReport[item] = report[item] as { Results: SecurityReportResult[] };
}
});
@ -1087,9 +1107,10 @@ class API_CLASS {
return this.getAllItems(`${this.API_BASE_URL}/subscriptions/opt-out`) as Promise<OptOutItem[]>;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private getAllItems(url: string): Promise<any[]> {
const MAX_LIMIT = 60;
let formattedUrl = `${url}?limit=${MAX_LIMIT}`;
const formattedUrl = `${url}?limit=${MAX_LIMIT}`;
return this.apiFetch({ url: `${formattedUrl}&offset=0`, headers: [this.HEADERS.pagination] }).then(
async (result) => {
@ -1101,6 +1122,7 @@ class API_CLASS {
await Promise.all([
...pagesList.map((page: number) => this.apiFetch({ url: `${formattedUrl}&offset=${page * MAX_LIMIT}` })),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
]).then((res) => res.forEach((list: any[]) => (items = [...items, ...list])));
return items;
} else {
@ -1149,12 +1171,14 @@ class API_CLASS {
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public getBannersInfo(url: string): Promise<any> {
return this.apiFetch({
url: url,
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public getSchemaDef(url: string): Promise<any> {
return this.apiFetch({
url: url,

View File

@ -1,4 +1,4 @@
import { isNull } from 'lodash';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { createContext, Dispatch, useContext, useEffect, useReducer, useState } from 'react';
@ -41,6 +41,7 @@ type Action =
export const AppCtx = createContext<{
ctx: AppState;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
dispatch: Dispatch<any>;
}>({
ctx: initialState,
@ -83,6 +84,7 @@ export function addNewDisplayedNotification(id: string) {
return { type: 'addNewDisplayedNotification', id };
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export async function refreshUserProfile(dispatch: Dispatch<any>, redirectUrl?: string | null) {
try {
const profile: Profile = await API.getUserProfile();
@ -102,6 +104,7 @@ export async function refreshUserProfile(dispatch: Dispatch<any>, redirectUrl?:
});
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
dispatch({ type: 'signOut' });
if (err.message === 'invalid session' && history.navigate && history.location) {
@ -156,10 +159,13 @@ function getCurrentSystemActiveTheme(prefs: ThemePrefs): ThemePrefs {
export function appReducer(state: AppState, action: Action) {
let prefs;
let userPrefs;
let guestPrefs;
let effective;
switch (action.type) {
case 'signIn':
prefs = lsStorage.getPrefs(action.profile.alias);
const userPrefs = { ...prefs, theme: getCurrentSystemActiveTheme(prefs.theme) };
userPrefs = { ...prefs, theme: getCurrentSystemActiveTheme(prefs.theme) };
updateActiveStyleSheet(userPrefs.theme.effective);
lsStorage.setPrefs(userPrefs, action.profile.alias);
lsStorage.setActiveProfile(action.profile.alias);
@ -179,7 +185,7 @@ export function appReducer(state: AppState, action: Action) {
case 'signOut':
prefs = lsStorage.getPrefs();
const guestPrefs = { ...prefs, theme: getCurrentSystemActiveTheme(prefs.theme) };
guestPrefs = { ...prefs, theme: getCurrentSystemActiveTheme(prefs.theme) };
lsStorage.setPrefs(guestPrefs);
lsStorage.setActiveProfile();
updateActiveStyleSheet(guestPrefs.theme.effective);
@ -211,7 +217,7 @@ export function appReducer(state: AppState, action: Action) {
};
case 'updateTheme':
const effective = action.theme === 'automatic' ? detectActiveThemeMode() : action.theme;
effective = action.theme === 'automatic' ? detectActiveThemeMode() : action.theme;
prefs = {
...state.prefs,
theme: {
@ -304,7 +310,7 @@ function AppCtxProvider(props: Props) {
updateActiveStyleSheet(theme);
setActiveInitialTheme(theme);
refreshUserProfile(dispatch);
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
useSystemThemeMode(ctx.prefs.theme.configured === 'automatic', dispatch);

View File

@ -1,4 +1,4 @@
import { throttle } from 'lodash';
import throttle from 'lodash/throttle';
import { useEffect, useState } from 'react';
const getDeviceConfig = (width: number) => {

View File

@ -1,6 +1,7 @@
import { useEffect } from 'react';
import { useLocation } from 'react-router';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const useOnLocationChange = (handleLocationChange: any) => {
const location = useLocation();
useEffect(() => handleLocationChange(location), [location, handleLocationChange]);

View File

@ -1,4 +1,4 @@
import { isNull } from 'lodash';
import isNull from 'lodash/isNull';
import { RefObject, useCallback, useEffect, useState } from 'react';
export default function useOutsideClick(

View File

@ -1,4 +1,4 @@
import { throttle } from 'lodash';
import throttle from 'lodash/throttle';
import { MutableRefObject, useEffect, useLayoutEffect, useState } from 'react';
const useOverflowWrapper = (
@ -28,15 +28,15 @@ const useOverflowWrapper = (
useEffect(() => {
window.addEventListener('resize', throttle(handleOverflow, 200));
return () => window.removeEventListener('resize', handleOverflow);
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
useLayoutEffect(() => {
handleOverflow();
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
useEffect(() => {
handleOverflow();
}, [itemsLength]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [itemsLength]);
return overflowContainer;
};

View File

@ -1,8 +1,9 @@
import { isNull } from 'lodash';
import isNull from 'lodash/isNull';
import { Dispatch, useCallback, useEffect, useState } from 'react';
import detectActiveThemeMode from '../utils/detectActiveThemeMode';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default function useSystemThemeMode(enabled: boolean, dispatch: Dispatch<any>) {
const [mediaQuery, setMediaQuery] = useState<MediaQueryList | null>(null);
const themeDarkModeFn = useCallback(() => {
@ -44,5 +45,5 @@ export default function useSystemThemeMode(enabled: boolean, dispatch: Dispatch<
removeListener();
}
};
}, [enabled]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [enabled]);
}

View File

@ -243,6 +243,7 @@ export interface JSONSchema4 {
/**
* @see https://tools.ietf.org/html/draft-zyp-json-schema-04#section-5.6
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[k: string]: any;
format?: string | undefined;

View File

@ -1,5 +1,6 @@
import classnames from 'classnames';
import { isNull, isUndefined } from 'lodash';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { ElementType, useEffect, useRef, useState } from 'react';
import styles from './Alert.module.css';
@ -39,7 +40,7 @@ const Alert: ElementType = (props: Props) => {
clearTimeout(timeout);
}
};
}, [props.message]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [props.message]);
return (
<div

View File

@ -1,4 +1,5 @@
import { isObject, isString } from 'lodash';
import isObject from 'lodash/isObject';
import isString from 'lodash/isString';
import isUndefined from 'lodash/isUndefined';
import { ElementType, MouseEvent as ReactMouseEvent } from 'react';
import { GoLink } from 'react-icons/go';
@ -19,10 +20,12 @@ const AnchorHeader: ElementType = (props: Props) => {
const location = useLocation();
let value = props.title;
if (isUndefined(value) && props.children && props.children.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const allContentValues = props.children.map((n: any) => {
if (isString(n)) {
return [n];
} else if (isObject(n)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return String((n as any).props.children);
} else {
return '';

View File

@ -1,4 +1,4 @@
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import { BiCloudDownload } from 'react-icons/bi';
import styles from './BlockCodeButtons.module.css';

View File

@ -53,6 +53,7 @@ describe('ButtonCopyToClipboard', () => {
});
it('renders tooltip after clicking button when navidator.clipboard is undefined', async () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(navigator as any).clipboard = null;
render(<ButtonCopyToClipboard text="Text to copy" />);
expect(screen.queryByRole('tooltip')).toBeNull();

View File

@ -1,5 +1,5 @@
import classnames from 'classnames';
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import { MouseEvent as ReactMouseEvent, useEffect, useState } from 'react';
import { FiCopy } from 'react-icons/fi';

View File

@ -6,7 +6,7 @@ import 'codemirror/mode/go/go';
import 'codemirror-rego/mode';
import classnames from 'classnames';
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import { ElementType, useContext } from 'react';
import { Controlled as CodeMirror } from 'react-codemirror2';
@ -46,6 +46,7 @@ const CodeEditor: ElementType = (props: Props) => {
editorDidMount={(editor) => {
editor.setSize('', '100%');
}}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onBeforeChange={(editor: any, data: any, value: string) => {
props.onChange(value);
}}

View File

@ -5,6 +5,7 @@ import { BrowserRouter as Router } from 'react-router-dom';
import { ContentDefaultModalKind } from '../../types';
import ContentDefaultModal from './ContentDefaultModal';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const isVisibleItemInContainer = require('../../utils/isVisibleItemInContainer');
jest.mock('../../utils/isVisibleItemInContainer', () => jest.fn());
@ -12,7 +13,7 @@ jest.mock('../../utils/isVisibleItemInContainer', () => jest.fn());
const mockUseNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as {}),
...(jest.requireActual('react-router-dom') as object),
useNavigate: () => mockUseNavigate,
useLocation: () => ({
state: null,

View File

@ -1,5 +1,6 @@
import classnames from 'classnames';
import { isNull, isUndefined } from 'lodash';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { ChangeEvent, useEffect, useLayoutEffect, useRef, useState } from 'react';
import { FaSearch } from 'react-icons/fa';
import { useLocation, useNavigate } from 'react-router-dom';
@ -24,6 +25,7 @@ interface Props {
btnModalContent: JSX.Element;
normalizedName: string;
title: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
files?: any[];
}
@ -52,13 +54,16 @@ const ContentDefaultModal = (props: Props) => {
const location = useLocation();
const anchor = useRef<HTMLDivElement>(null);
const [openStatus, setOpenStatus] = useState<boolean>(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const [selectedItem, setSelectedItem] = useState<any | null>(null);
const [isChangingSelectedItem, setIsChangingSelectedItem] = useState<boolean>(false);
const [code, setCode] = useState<string | undefined>(undefined);
const [inputValue, setInputValue] = useState<string>('');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const [visibleFiles, setVisibleFiles] = useState<any[]>(props.files || []);
const [currentPkgId, setCurrentPkgId] = useState<string>(props.packageId);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const onItemChange = (file: any | null) => {
setIsChangingSelectedItem(true);
setSelectedItem(file);
@ -102,18 +107,22 @@ const ContentDefaultModal = (props: Props) => {
};
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const getVisibleFiles = (): any[] => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return props.files!.filter((file: any) => {
const term = `${file.name} ${file.kind || ''}`.toLowerCase();
return term.includes(inputValue.toLowerCase());
});
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const reviewActiveFile = (currentFilteredFiles: any[][]) => {
if (currentFilteredFiles.length === 0 && !isUndefined(selectedItem)) {
onItemChange(null);
} else {
if (selectedItem) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const activeFile = currentFilteredFiles.find((file: any) => file === selectedItem);
if (isUndefined(activeFile)) {
onItemChange(currentFilteredFiles[0]);
@ -136,7 +145,7 @@ const ContentDefaultModal = (props: Props) => {
setVisibleFiles(filteredFiles);
}
}
}, [inputValue]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [inputValue]);
const updateUrl = (fileName?: string) => {
navigate(
@ -162,7 +171,7 @@ const ContentDefaultModal = (props: Props) => {
if (props.visibleModal && !openStatus && props.files && props.files.length > 0) {
onOpenModal();
}
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
useEffect(() => {
if (props.packageId !== currentPkgId) {
@ -173,7 +182,7 @@ const ContentDefaultModal = (props: Props) => {
onOpenModal();
}
}
}, [props.packageId]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [props.packageId]);
// Display active file in list
useLayoutEffect(() => {
@ -207,6 +216,7 @@ const ContentDefaultModal = (props: Props) => {
setVisibleFiles(props.files);
let currentActiveFile = props.files[0];
if (props.visibleFile) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const visibleFile = props.files.find((file: any) => file.name.toLowerCase() === props.visibleFile);
if (visibleFile) {
currentActiveFile = visibleFile;
@ -289,6 +299,7 @@ const ContentDefaultModal = (props: Props) => {
</div>
) : (
<div className="pe-2">
{/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
{visibleFiles.map((file: any, index: number) => {
const isActive = selectedItem === file;
return (
@ -308,9 +319,10 @@ const ContentDefaultModal = (props: Props) => {
>
<div className="d-flex flex-column align-self-center">
{(() => {
let resource: CustomResourcesDefinition;
switch (props.kind) {
case ContentDefaultModalKind.CustomResourcesDefinition:
const resource = file as CustomResourcesDefinition;
resource = file as CustomResourcesDefinition;
return (
<>
<div className="d-flex flex-row align-items-baseline my-1">

View File

@ -65,7 +65,7 @@ const ElementWithTooltip = (props: Props) => {
clearTimeout(timeout);
}
};
}, [onLabelHover, visibleTooltipStatus, tooltipWidth]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [onLabelHover, visibleTooltipStatus, tooltipWidth]);
useLayoutEffect(() => {
if (wrapper && wrapper.current) {

View File

@ -19,7 +19,7 @@ class ErrorBoundary extends Component<Props, State> {
this.state = { hasError: false };
}
static getDerivedStateFromError(error: any) {
static getDerivedStateFromError() {
return { hasError: true };
}

View File

@ -1,4 +1,4 @@
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import { useEffect, useState } from 'react';
import { FaCaretDown, FaCaretUp } from 'react-icons/fa';
@ -28,13 +28,13 @@ const ExpandableList = (props: Props) => {
if (!isUndefined(props.open) && open !== props.open) {
setOpenStatus(props.open);
}
}, [props.open]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [props.open]);
useEffect(() => {
if (props.forceCollapseList && open) {
setOpenStatus(!open);
}
}, [props.forceCollapseList]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [props.forceCollapseList]);
return (
<>

View File

@ -38,7 +38,7 @@ const FullScreenModal = (props: Props) => {
return () => {
window.removeEventListener('keydown', handleEsc);
};
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
if (!openStatus) return null;

View File

@ -1,6 +1,6 @@
import classnames from 'classnames';
import { isUndefined } from 'lodash';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { useRef, useState } from 'react';
import { RepositoryKind } from '../../types';

View File

@ -93,8 +93,6 @@ const InputField = forwardRef((props: Props, ref: Ref<RefInputField>) => {
errorTxt = props.invalidText.tooShort;
} else if (validityState.patternMismatch && !isUndefined(props.invalidText.patternMismatch)) {
errorTxt = props.invalidText.patternMismatch;
} else if (validityState.typeMismatch && !isUndefined(props.invalidText.typeMismatch)) {
errorTxt = props.invalidText.typeMismatch;
} else if (validityState.rangeUnderflow && !isUndefined(props.invalidText.rangeUnderflow)) {
errorTxt = props.invalidText.rangeUnderflow;
} else if (validityState.rangeOverflow && !isUndefined(props.invalidText.rangeOverflow)) {
@ -151,6 +149,7 @@ const InputField = forwardRef((props: Props, ref: Ref<RefInputField>) => {
input.current!.setCustomValidity('');
setPwdStrengthError(null);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
if (!isNull(input.current) && e.message) {
setPwdStrengthError(e.message);
@ -208,7 +207,7 @@ const InputField = forwardRef((props: Props, ref: Ref<RefInputField>) => {
clearTimeout(validateTimeout);
}
};
}, [inputValue]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [inputValue]);
return (
<div className={`${props.smallBottomMargin ? 'mb-3' : 'mb-4'} position-relative ${props.className}`}>

View File

@ -6,7 +6,7 @@ import isUndefined from 'lodash/isUndefined';
import { useCallback, useEffect, useRef, useState } from 'react';
import { BiCrop, BiImageAlt } from 'react-icons/bi';
import { MdAddAPhoto } from 'react-icons/md';
import ReactCrop, { centerCrop, Crop, makeAspectCrop, PercentCrop, PixelCrop } from 'react-image-crop';
import ReactCrop, { centerCrop, Crop, makeAspectCrop, PixelCrop } from 'react-image-crop';
import API from '../../api';
import { ErrorKind, LogoImage } from '../../types';
@ -37,6 +37,7 @@ const InputFileField = (props: Props) => {
const fileInput = useRef<HTMLInputElement | null>(null);
const [isSending, setIsSending] = useState<boolean>(false);
const [openStatus, setOpenStatus] = useState<boolean>(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const [image, setImage] = useState<any>(null);
async function saveImage(data: string | ArrayBuffer) {
@ -46,6 +47,7 @@ const InputFileField = (props: Props) => {
if (!isUndefined(props.onImageChange)) {
props.onImageChange(logo.imageId);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsSending(false);
if (err.kind !== ErrorKind.Unauthorized) {
@ -70,6 +72,7 @@ const InputFileField = (props: Props) => {
setImage(null);
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const saveOriginal = (file: any) => {
setIsSending(true);
const reader = new FileReader();
@ -81,6 +84,7 @@ const InputFileField = (props: Props) => {
reader.readAsArrayBuffer(file);
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const saveCroppedImage = (canvas: any, crop: any) => {
if (!crop || !canvas) {
alertDispatcher.postAlert({
@ -92,6 +96,7 @@ const InputFileField = (props: Props) => {
setIsSending(true);
canvas.toBlob(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(blob: any) => {
saveImage(blob);
onClose();
@ -133,6 +138,7 @@ const InputFileField = (props: Props) => {
}
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const onImageLoad = useCallback((e: any) => {
const { width, height } = e.currentTarget;
@ -158,10 +164,13 @@ const InputFileField = (props: Props) => {
useEffect(() => {
if (!isNull(completedCrop) && openStatus) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const img: any = imgRef.current;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const canvas: any = previewCanvasRef.current;
if (!isNull(canvas) && !isNull(img)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const tmpCrop: any = completedCrop;
const scaleX = img.naturalWidth / img.width;
@ -188,7 +197,7 @@ const InputFileField = (props: Props) => {
);
}
}
}, [completedCrop]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [completedCrop]);
const onClick = () => {
if (!isNull(fileInput) && !isNull(fileInput.current)) {
@ -290,8 +299,8 @@ const InputFileField = (props: Props) => {
crop={crop}
aspect={1}
circularCrop={props.circularCrop}
onChange={(c, percentCrop) => setCrop(c)}
onComplete={(c: PixelCrop, percentCrop: PercentCrop) => setCompletedCrop(c)}
onChange={(c) => setCrop(c)}
onComplete={(c: PixelCrop) => setCompletedCrop(c)}
>
<img alt={props.label} src={upImg as string} onLoad={onImageLoad} />
</ReactCrop>

View File

@ -1,5 +1,9 @@
import classnames from 'classnames';
import { compact, escapeRegExp, isNull, isUndefined, orderBy } from 'lodash';
import compact from 'lodash/compact';
import escapeRegExp from 'lodash/escapeRegExp';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import orderBy from 'lodash/orderBy';
import {
ChangeEvent,
forwardRef,
@ -59,6 +63,7 @@ const InputTypeahead = forwardRef((props: Props, ref: Ref<RefInputTypeaheadField
const getVisibleItems = useCallback((): Option[] | null => {
let filteredItems: Option[] = [];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let elements: any[] | null = null;
if (!isNull(highlightedItem)) {
@ -71,7 +76,7 @@ const InputTypeahead = forwardRef((props: Props, ref: Ref<RefInputTypeaheadField
filteredItems,
[
(item: Option) =>
props.selected.hasOwnProperty(item.filterKey) && props.selected[item.filterKey].includes(item.id.toString())
!isUndefined(props.selected[item.filterKey]) && props.selected[item.filterKey].includes(item.id.toString())
? -1
: 1,
'total',
@ -88,7 +93,7 @@ const InputTypeahead = forwardRef((props: Props, ref: Ref<RefInputTypeaheadField
}, [highlightedItem, props.displayItemsInValueLength, props.options, props.selected, inputValue]);
const getSelectedItems = useCallback((): Option[] => {
let selectedItems: Option[] = [];
const selectedItems: Option[] = [];
Object.keys(props.selected).forEach((fKey: string) => {
props.selected[fKey].forEach((item: string) => {
const selected = props.options.find((opt: Option) => opt.id.toString() === item && opt.filterKey === fKey);
@ -139,7 +144,7 @@ const InputTypeahead = forwardRef((props: Props, ref: Ref<RefInputTypeaheadField
useEffect(() => {
setVisibleItems(getVisibleItems());
}, [inputValue, props.options]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [inputValue, props.options]);
useEffect(() => {
setSelectedItems(getSelectedItems());
@ -176,8 +181,7 @@ const InputTypeahead = forwardRef((props: Props, ref: Ref<RefInputTypeaheadField
if (!isNull(highlightedItem) && visibleItems) {
const item = visibleItems[highlightedItem];
const isSelected =
props.selected.hasOwnProperty(item.filterKey) &&
props.selected[item.filterKey].includes(item.id.toString());
!isUndefined(props.selected[item.filterKey]) && props.selected[item.filterKey].includes(item.id.toString());
onSelect(item.filterKey, item.id.toString(), isSelected);
}
return;
@ -274,7 +278,7 @@ const InputTypeahead = forwardRef((props: Props, ref: Ref<RefInputTypeaheadField
<div className={`${styles.itemsList} ${props.listClassName}`} ref={itemsWrapper}>
{visibleItems.map((opt: Option, index: number) => {
const isSelected =
props.selected.hasOwnProperty(opt.filterKey) &&
!isUndefined(props.selected[opt.filterKey]) &&
props.selected[opt.filterKey].includes(opt.id.toString());
const name = getOptionName(opt.name);

View File

@ -1,5 +1,5 @@
import classnames from 'classnames';
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import styles from './Label.module.css';

View File

@ -1,5 +1,5 @@
import classnames from 'classnames';
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import styles from './Loading.module.css';

View File

@ -3,6 +3,7 @@ import userEvent from '@testing-library/user-event';
import Modal from './Modal';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
jest.mock('./Alert', () => (props: any) => <div>{props.message}</div>);
const onCloseMock = jest.fn();

View File

@ -1,5 +1,5 @@
import classnames from 'classnames';
import { isNull } from 'lodash';
import isNull from 'lodash/isNull';
import isString from 'lodash/isString';
import isUndefined from 'lodash/isUndefined';
import { MouseEvent, MutableRefObject, useEffect, useRef, useState } from 'react';

View File

@ -18,11 +18,12 @@ const user = userEvent.setup({ delay: null });
const mockUseNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as {}),
...(jest.requireActual('react-router-dom') as object),
useNavigate: () => mockUseNavigate,
}));
const getMockOrganization = (fixtureId: string): Organization => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
return require(`./__fixtures__/OrganizationInfo/${fixtureId}.json`) as Organization;
};

View File

@ -37,7 +37,7 @@ const OrganizationInfo = (props: Props) => {
async function fetchOrganization() {
try {
setOrganization(await API.getOrganization(props.organizationName));
} catch (err: any) {
} catch {
setOrganization(null);
}
}
@ -78,7 +78,7 @@ const OrganizationInfo = (props: Props) => {
}
cleanFetchTimeout();
};
}, [onLinkHover, onDropdownHover, organization, openStatus]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [onLinkHover, onDropdownHover, organization, openStatus]);
return (
<div className={props.className}>

View File

@ -9,13 +9,14 @@ import PackageCard from './PackageCard';
jest.mock('../../utils/calculateDiffInYears');
const getMockPackage = (fixtureId: string): Package => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
return require(`./__fixtures__/PackageCard/${fixtureId}.json`) as Package;
};
const mockUseNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as {}),
...(jest.requireActual('react-router-dom') as object),
useNavigate: () => mockUseNavigate,
}));

View File

@ -1,5 +1,5 @@
import { throttle } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import throttle from 'lodash/throttle';
import moment from 'moment';
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
import { FaUser } from 'react-icons/fa';
@ -102,11 +102,11 @@ const PackageCard = (props: Props) => {
useLayoutEffect(() => {
saveInfoWidth();
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
useEffect(() => {
checkPkgInfo();
}, [fullInfoWidth]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [fullInfoWidth]);
useEffect(() => {
window.addEventListener('resize', throttle(saveInfoWidth, 200));
@ -115,7 +115,7 @@ const PackageCard = (props: Props) => {
}
return () => window.removeEventListener('resize', saveInfoWidth);
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
return (
<div className={`py-sm-3 py-2 ${styles.cardWrapper} ${props.cardWrapperClassName}`} role="listitem">

View File

@ -1,4 +1,4 @@
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import { MdOutlineCategory } from 'react-icons/md';
import { useNavigate } from 'react-router-dom';

View File

@ -1,6 +1,6 @@
import classnames from 'classnames';
import { isString } from 'lodash';
import isNumber from 'lodash/isNumber';
import isString from 'lodash/isString';
import { useEffect, useState } from 'react';
import { FaCaretLeft, FaCaretRight } from 'react-icons/fa';
@ -25,7 +25,7 @@ interface ButtonProps {
const getPaginationOptions = (currentPage: number, pageCount: number): (string | number)[] => {
const delta = 1;
let range = [];
const range = [];
for (let i = Math.max(2, currentPage - delta); i <= Math.min(pageCount - 1, currentPage + delta); i++) {
range.push(i);
}

View File

@ -8,7 +8,7 @@ import RepositoryIconLabel from './RepositoryIconLabel';
const mockUseNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as {}),
...(jest.requireActual('react-router-dom') as object),
useNavigate: () => mockUseNavigate,
}));

View File

@ -1,5 +1,5 @@
import classnames from 'classnames';
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import { useNavigate } from 'react-router-dom';
import { RepositoryKind } from '../../types';

View File

@ -7,7 +7,7 @@ import RepositoryInfo from './RepositoryInfo';
const mockUseNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as {}),
...(jest.requireActual('react-router-dom') as object),
useNavigate: () => mockUseNavigate,
}));

View File

@ -96,12 +96,7 @@ const mockQueries = [
},
];
jest.mock('lodash', () => ({
...(jest.requireActual('lodash') as {}),
sampleSize: () => {
return mockQueries;
},
}));
jest.mock('lodash/sampleSize', () => () => mockQueries);
describe('SampleQueries', () => {
afterEach(() => {

View File

@ -1,4 +1,5 @@
import { isUndefined, sampleSize } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import sampleSize from 'lodash/sampleSize';
import { Fragment, memo } from 'react';
import { Link } from 'react-router-dom';

View File

@ -12,11 +12,12 @@ jest.mock('../../api');
const mockUseNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as {}),
...(jest.requireActual('react-router-dom') as object),
useNavigate: () => mockUseNavigate,
}));
const getMockSearch = (fixtureId: string): SearchResults => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
return require(`./__fixtures__/SearchBar/${fixtureId}.json`) as SearchResults;
};

View File

@ -189,7 +189,7 @@ const SearchBar = (props: Props) => {
} else {
cleanSearch();
}
} catch (err: any) {
} catch {
cleanSearch();
}
}
@ -216,7 +216,7 @@ const SearchBar = (props: Props) => {
clearTimeout(dropdownTimeout);
}
};
}, [value]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [value]);
return (
<>

View File

@ -10,6 +10,7 @@ jest.mock('../../api');
jest.mock('../../utils/alertDispatcher');
const getMockSearch = (fixtureId: string): SearchResults => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
return require(`./__fixtures__/SearchPackages/${fixtureId}.json`) as SearchResults;
};

View File

@ -49,7 +49,7 @@ const SearchPackages = (props: Props) => {
);
setPackages(searchResults.packages);
setIsSearching(false);
} catch (err: any) {
} catch {
setPackages(null);
alertDispatcher.postAlert({
type: 'danger',
@ -167,7 +167,7 @@ const SearchPackages = (props: Props) => {
clearTimeout(dropdownTimeout);
}
};
}, [searchQuery]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [searchQuery]);
return (
<div className="position-relative">

View File

@ -1,6 +1,7 @@
import classnames from 'classnames';
import { escapeRegExp, isUndefined } from 'lodash';
import escapeRegExp from 'lodash/escapeRegExp';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { ChangeEvent, KeyboardEvent, useEffect, useRef, useState } from 'react';
import { FaUser } from 'react-icons/fa';
import { FiSearch } from 'react-icons/fi';
@ -65,6 +66,7 @@ const SearchRepositories = (props: Props) => {
const data = await API.searchRepositories(query);
setRepositories(data.items);
setIsSearching(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
if (err.kind !== ErrorKind.Unauthorized) {
alertDispatcher.postAlert({
@ -202,7 +204,7 @@ const SearchRepositories = (props: Props) => {
clearTimeout(dropdownTimeout);
}
};
}, [searchName]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [searchName]);
return (
<div className="position-relative">

View File

@ -7,7 +7,7 @@ import SectionPanel from './SectionPanel';
const mockUseNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as {}),
...(jest.requireActual('react-router-dom') as object),
useNavigate: () => mockUseNavigate,
}));

View File

@ -1,4 +1,5 @@
import { isNull, isUndefined } from 'lodash';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
@ -28,7 +29,8 @@ const SecurityRating = (props: Props) => {
let rating = SEVERITY_RATING.default!;
for (const key in VulnerabilitySeverity) {
const sev = key.toLowerCase();
if (props.summary && props.summary.hasOwnProperty(sev) && (props.summary as any)[sev] > 0) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (props.summary && !isUndefined((props.summary as any)[sev]) && (props.summary as any)[sev] > 0) {
rating = SEVERITY_RATING[sev as VulnerabilitySeverity]!;
break;
}

View File

@ -1,5 +1,5 @@
import classNames from 'classnames';
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import { useEffect, useState } from 'react';
import { HiPlusCircle } from 'react-icons/hi';
@ -47,7 +47,7 @@ const SeeAllModal = (props: Props) => {
setOpenStatus(!openStatus);
}
setVisibleItems(getFirstItems());
}, [props.packageId, props.version, props.items]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [props.packageId, props.version, props.items]);
return (
<>

View File

@ -1,11 +1,13 @@
import classnames from 'classnames';
import { isNumber, isUndefined } from 'lodash';
import isNumber from 'lodash/isNumber';
import isUndefined from 'lodash/isUndefined';
import { FaStar } from 'react-icons/fa';
import prettifyNumber from '../../utils/prettifyNumber';
import styles from './StarBadge.module.css';
interface Props {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
starsNumber?: number | any;
className?: string;
size?: 'xs' | 'sm';

View File

@ -1,4 +1,4 @@
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import { useEffect, useRef, useState } from 'react';
import useOutsideClick from '../../hooks/useOutsideClick';
@ -42,7 +42,7 @@ const ValuesSearch = (props: Props) => {
if (isUndefined(opts) && !isUndefined(props.paths)) {
setOpts(props.paths.map((path: string) => ({ id: path, name: path, filterKey: 'path' })));
}
}, [props.paths]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [props.paths]);
if (isUndefined(opts)) return null;

View File

@ -1,6 +1,6 @@
import classNames from 'classnames';
import classnames from 'classnames';
import { isNull } from 'lodash';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { useEffect, useRef, useState } from 'react';
import { MdClose } from 'react-icons/md';

View File

@ -1,4 +1,4 @@
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import Badge from './Badge';
import styles from './Badge.module.css';

View File

@ -1,4 +1,5 @@
import { isNull, isUndefined } from 'lodash';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { MdStars } from 'react-icons/md';
import ExternalLink from '../ExternalLink';

View File

@ -1,5 +1,5 @@
import { isNull, isUndefined } from 'lodash';
import { Fragment } from 'react';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { FaFileSignature } from 'react-icons/fa';
import { HelmChartSignKey, RepositoryKind, Signature } from '../../../types';

View File

@ -1,4 +1,5 @@
import { isNull, isUndefined } from 'lodash';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { CgListTree } from 'react-icons/cg';
import Badge from './Badge';

View File

@ -1,4 +1,5 @@
import { isNull, isUndefined } from 'lodash';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { MdVerified } from 'react-icons/md';
import ExternalLink from '../ExternalLink';

View File

@ -1,5 +1,6 @@
import classnames from 'classnames';
import { isNull, isUndefined } from 'lodash';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { ElementType, useContext, useEffect, useState } from 'react';
import ReactMarkdown from 'react-markdown';
@ -69,13 +70,13 @@ const UserNotificationsController: ElementType = () => {
return () => {
notificationsDispatcher.close();
};
}, [ctx.user]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [ctx.user]);
useEffect(() => {
if (!isUndefined(ctx.user)) {
notificationsDispatcher.updateSettings(ctx.prefs.notifications);
}
}, [ctx.prefs.notifications]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [ctx.prefs.notifications]);
useEffect(() => {
return () => {

View File

@ -1,6 +1,5 @@
import { render, screen } from '@testing-library/react';
import { act, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { act } from 'react-dom/test-utils';
import { AppCtx } from '../../context/AppCtx';
import { AuthorizerAction, AuthorizerInput } from '../../types';

View File

@ -1,5 +1,5 @@
import classnames from 'classnames';
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import { forwardRef, MouseEvent, Ref, useContext, useEffect, useImperativeHandle, useState } from 'react';
import { AppCtx } from '../../context/AppCtx';
@ -61,13 +61,13 @@ const ActionBtn = forwardRef((props: Props, ref: Ref<RefActionBtn>) => {
})
);
}
}, [activeOrg, updateView]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [activeOrg, updateView]);
useEffect(() => {
if (activeOrg !== ctx.prefs.controlPanel.selectedOrg) {
setActiveOrg(ctx.prefs.controlPanel.selectedOrg);
}
}, [ctx.prefs.controlPanel.selectedOrg]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [ctx.prefs.controlPanel.selectedOrg]);
return (
<span

View File

@ -51,6 +51,7 @@ const UserContext = () => {
}
setOrganizations(confirmedOrganizations);
setIsLoading(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsLoading(false);
if (err.kind !== ErrorKind.Unauthorized) {
@ -62,7 +63,7 @@ const UserContext = () => {
useEffect(() => {
fetchOrganizations();
authorizer.init(ctx.prefs.controlPanel.selectedOrg);
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
return (
<div className={`position-relative ${styles.ctxWrapper}`}>

View File

@ -11,7 +11,7 @@ jest.mock('./repositories', () => () => <div />);
const mockUseNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as {}),
...(jest.requireActual('react-router-dom') as object),
useSearchParams: () => jest.fn(),
useParams: jest.fn(),
useNavigate: () => mockUseNavigate,
@ -62,6 +62,7 @@ describe('ControlPanelView', () => {
return null;
},
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
] as any);
});
@ -149,6 +150,7 @@ describe('ControlPanelView', () => {
}
},
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
] as any);
mocked(API).searchRepositories.mockResolvedValue({ items: [], paginationTotalCount: '0' });
@ -180,6 +182,7 @@ describe('ControlPanelView', () => {
}
},
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
] as any);
mocked(API).searchRepositories.mockResolvedValue({ items: [], paginationTotalCount: '0' });
render(
@ -210,6 +213,7 @@ describe('ControlPanelView', () => {
}
},
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
] as any);
mocked(API).searchRepositories.mockResolvedValue({ items: [], paginationTotalCount: '0' });
render(
@ -242,6 +246,7 @@ describe('ControlPanelView', () => {
}
},
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
] as any);
mocked(API).searchRepositories.mockResolvedValue({ items: [], paginationTotalCount: '0' });
render(
@ -270,6 +275,7 @@ describe('ControlPanelView', () => {
}
},
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
] as any);
mocked(API).searchRepositories.mockResolvedValue({ items: [], paginationTotalCount: '0' });
render(

View File

@ -104,7 +104,7 @@ const ControlPanelView = () => {
setContext(context);
}
}
}, [ctx]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [ctx]);
useEffect(() => {
if (ctx.user && !isNull(context)) {
@ -125,7 +125,7 @@ const ControlPanelView = () => {
}
}
}
}, [section, subsection, context]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [section, subsection, context]);
if (!isUndefined(ctx.user) && isNull(ctx.user)) {
navigate('/');

View File

@ -44,6 +44,7 @@ const MemberCard = (props: Props) => {
} else {
props.onSuccess();
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsDeletingMember(false);
if (err.kind !== ErrorKind.Unauthorized) {

View File

@ -51,6 +51,7 @@ const MemberModal = (props: Props) => {
}
setIsSending(false);
onCloseModal();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsSending(false);
if (err.kind !== ErrorKind.Unauthorized) {

View File

@ -1,4 +1,4 @@
import { isNull } from 'lodash';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import { useEffect, useState } from 'react';
import { MdClose, MdDone } from 'react-icons/md';
@ -27,6 +27,7 @@ const UserInvitation = (props: Props) => {
try {
await API.confirmOrganizationMembership(orgToConfirm!);
setValidInvitation(true);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
let error = !isUndefined(err.message)
? err.message
@ -52,7 +53,7 @@ const UserInvitation = (props: Props) => {
);
confirmOrganizationMembership();
}
}, [orgToConfirm]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [orgToConfirm]);
if (isUndefined(orgToConfirm) || isNull(props.orgToConfirm)) return null;

View File

@ -80,6 +80,7 @@ const MembersSection = (props: Props) => {
updatePageNumber();
setApiError(null);
setIsGettingMembers(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsGettingMembers(false);
if (err.kind !== ErrorKind.Unauthorized) {
@ -95,7 +96,7 @@ const MembersSection = (props: Props) => {
if (props.activePage && activePage !== parseInt(props.activePage)) {
fetchMembers();
}
}, [activePage]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [activePage]);
useEffect(() => {
if (!isUndefined(members)) {
@ -107,17 +108,17 @@ const MembersSection = (props: Props) => {
onPageNumberChange(1);
}
}
}, [activeOrg]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [activeOrg]);
useEffect(() => {
if (activeOrg !== ctx.prefs.controlPanel.selectedOrg) {
setActiveOrg(ctx.prefs.controlPanel.selectedOrg);
}
}, [ctx.prefs.controlPanel.selectedOrg]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [ctx.prefs.controlPanel.selectedOrg]);
useEffect(() => {
fetchMembers();
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
return (
<main

View File

@ -53,6 +53,7 @@ const OrganizationCard = (props: Props) => {
) {
dispatch(unselectOrg());
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsLeaving(false);
if (err.kind !== ErrorKind.Unauthorized) {

View File

@ -60,6 +60,7 @@ const OrganizationForm = forwardRef<HTMLFormElement, Props>((props, ref) => {
}
}
props.setIsSending(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
props.setIsSending(false);
if (err.kind !== ErrorKind.Unauthorized) {

View File

@ -69,6 +69,7 @@ const OrganizationsSection = (props: Props) => {
updatePageNumber();
setApiError(null);
setIsLoading(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsLoading(false);
if (err.kind !== ErrorKind.Unauthorized) {
@ -82,13 +83,13 @@ const OrganizationsSection = (props: Props) => {
useEffect(() => {
fetchOrganizations();
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
useEffect(() => {
if (props.activePage && activePage !== parseInt(props.activePage)) {
fetchOrganizations();
}
}, [activePage]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [activePage]);
return (
<main

View File

@ -13,7 +13,7 @@ jest.mock('./TransferModal', () => () => <div>Transfer repository</div>);
const mockUseNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as {}),
...(jest.requireActual('react-router-dom') as object),
useNavigate: () => mockUseNavigate,
}));

View File

@ -82,7 +82,7 @@ const RepositoryCard = (props: Props) => {
}
navigate('', { replace: true });
}
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
const getLastTracking = (): JSX.Element => {
const nextCheckTime: number = minutesToNearestInterval(30);

View File

@ -80,6 +80,7 @@ const ClaimRepositoryOwnerShipModal = (props: Props) => {
}
setIsSending(false);
onCloseModal();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsSending(false);
if (err.kind !== ErrorKind.Unauthorized) {
@ -126,6 +127,7 @@ const ClaimRepositoryOwnerShipModal = (props: Props) => {
setOrganizations(confirmedOrganizations);
setApiOrgsError(null);
setIsFetchingOrgs(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsFetchingOrgs(false);
if (err.kind !== ErrorKind.Unauthorized) {

View File

@ -1,4 +1,4 @@
import { isUndefined } from 'lodash';
import isUndefined from 'lodash/isUndefined';
import { ChangeEvent, SetStateAction, useState } from 'react';
import { FaTrashAlt } from 'react-icons/fa';
import { IoMdCloseCircle } from 'react-icons/io';
@ -32,6 +32,7 @@ const DeletionModal = (props: Props) => {
await API.deleteRepository(props.repository.name, props.organizationName);
setIsDeleting(false);
props.onSuccess();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsDeleting(false);
if (err.kind === ErrorKind.Unauthorized) {

View File

@ -67,6 +67,7 @@ const mockCtx = {
describe('Repository Modal - repositories section', () => {
afterEach(() => {
jest.resetAllMocks();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (window as any).config;
});

View File

@ -1,8 +1,10 @@
import classnames from 'classnames';
import { compact, isEmpty, uniq } from 'lodash';
import compact from 'lodash/compact';
import every from 'lodash/every';
import isEmpty from 'lodash/isEmpty';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import uniq from 'lodash/uniq';
import { nanoid } from 'nanoid';
import { ChangeEvent, KeyboardEvent, useContext, useRef, useState } from 'react';
import { FaPencilAlt } from 'react-icons/fa';
@ -124,6 +126,7 @@ const RepositoryModal = (props: Props) => {
}
setIsSending(false);
onCloseModal();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsSending(false);
if (err.kind !== ErrorKind.Unauthorized) {
@ -978,6 +981,7 @@ const RepositoryModal = (props: Props) => {
<label className={`form-label fw-bold ${styles.label}`}>Versioning</label>
<div className="d-flex flex-row mb-2">
{/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
{Object.entries(VersioningOption).map((opt: any) => {
return (
<div className="form-check me-4 mb-2" key={`versioning_${opt[1]}`}>

View File

@ -1,4 +1,4 @@
import { isEmpty } from 'lodash';
import isEmpty from 'lodash/isEmpty';
import { nanoid } from 'nanoid';
import { ChangeEvent, Dispatch, MouseEvent as ReactMouseEvent, SetStateAction, useEffect } from 'react';
import { HiPlus } from 'react-icons/hi';
@ -26,7 +26,7 @@ const TagsList = (props: Props) => {
const deleteTag = (index: number) => {
cleanRepeatedError();
let updatedTags = [...props.tags];
const updatedTags = [...props.tags];
updatedTags.splice(index, 1);
props.setContainerTags(updatedTags);
};
@ -37,13 +37,13 @@ const TagsList = (props: Props) => {
const onUpdateTag = (index: number, field: 'name' | 'mutable', value?: string) => {
cleanRepeatedError();
let tagToUpdate: ContainerTag = props.tags[index];
const tagToUpdate: ContainerTag = props.tags[index];
if (field === 'name') {
tagToUpdate[field] = value as string;
} else {
tagToUpdate[field] = !tagToUpdate.mutable;
}
let updatedTags = [...props.tags];
const updatedTags = [...props.tags];
updatedTags[index] = tagToUpdate;
props.setContainerTags(updatedTags);
};
@ -52,7 +52,7 @@ const TagsList = (props: Props) => {
if (isEmpty(props.tags)) {
props.setContainerTags([{ ...EMPTY_TAG, id: nanoid() }]);
}
}, [props.tags]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [props.tags]);
return (
<div className="mb-4">

View File

@ -61,6 +61,7 @@ const TransferRepositoryModal = (props: Props) => {
}
setIsSending(false);
onCloseModal();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsSending(false);
if (err.kind !== ErrorKind.Unauthorized) {
@ -101,6 +102,7 @@ const TransferRepositoryModal = (props: Props) => {
setOrganizations(orgs);
setApiError(null);
setIsFetchingOrgs(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsFetchingOrgs(false);
if (err.kind !== ErrorKind.Unauthorized) {

View File

@ -25,7 +25,7 @@ const defaultProps = {
const mockUseNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as {}),
...(jest.requireActual('react-router-dom') as object),
useNavigate: () => mockUseNavigate,
}));

View File

@ -72,13 +72,13 @@ const RepositoriesSection = (props: Props) => {
async function fetchRepositories() {
try {
setIsLoading(true);
let filters: { [key: string]: string[] } = {};
const filters: { [key: string]: string[] } = {};
if (activeOrg) {
filters.org = [activeOrg];
} else {
filters.user = [ctx.user!.alias];
}
let query: SearchQuery = {
const query: SearchQuery = {
offset: offset,
limit: DEFAULT_LIMIT,
filters: filters,
@ -105,6 +105,7 @@ const RepositoriesSection = (props: Props) => {
}
setApiError(null);
setIsLoading(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsLoading(false);
if (err.kind !== ErrorKind.Unauthorized) {
@ -120,13 +121,13 @@ const RepositoriesSection = (props: Props) => {
if (isUndefined(props.activePage) || isNull(props.activePage)) {
updatePageNumber();
}
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
useEffect(() => {
if (props.activePage && activePage !== parseInt(props.activePage)) {
fetchRepositories();
}
}, [activePage]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [activePage]);
useEffect(() => {
if (!isUndefined(repositories)) {
@ -138,17 +139,17 @@ const RepositoriesSection = (props: Props) => {
onPageNumberChange(1);
}
}
}, [activeOrg]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [activeOrg]);
useEffect(() => {
if (activeOrg !== ctx.prefs.controlPanel.selectedOrg) {
setActiveOrg(ctx.prefs.controlPanel.selectedOrg);
}
}, [ctx.prefs.controlPanel.selectedOrg]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [ctx.prefs.controlPanel.selectedOrg]);
useEffect(() => {
fetchRepositories();
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
return (
<main

View File

@ -10,6 +10,7 @@ import alertDispatcher from '../../../../../utils/alertDispatcher';
import AuthorizationSection from './index';
jest.mock('../../../../../utils/alertDispatcher');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
jest.mock('../../../../common/Alert', () => (props: any) => <div>{props.message}</div>);
jest.mock('../../../../common/CodeEditor', () => () => <div />);
@ -23,6 +24,7 @@ jest.mock('../../../../../utils/authorizer', () => ({
}));
const getMockAuthz = (fixtureId: string): OrganizationPolicy => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
return require(`./__fixtures__/index/${fixtureId}.json`) as OrganizationPolicy;
};

View File

@ -1,4 +1,6 @@
import { isNull, isUndefined, trim } from 'lodash';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import trim from 'lodash/trim';
import { ChangeEvent, MouseEvent as ReactMouseEvent, useContext, useEffect, useRef, useState } from 'react';
import { FaPencilAlt } from 'react-icons/fa';
import { RiTestTubeFill } from 'react-icons/ri';
@ -175,7 +177,7 @@ const AuthorizationSection = (props: Props) => {
});
}
setIsTesting(false);
} catch (err: any) {
} catch {
setIsTesting(false);
alertDispatcher.postAlert({
type: 'danger',
@ -205,6 +207,7 @@ const AuthorizationSection = (props: Props) => {
})
);
setIsLoading(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsLoading(false);
if (err.kind === ErrorKind.Unauthorized) {
@ -231,6 +234,7 @@ const AuthorizationSection = (props: Props) => {
// Update allowed actions and re-render button
authorizer.getAllowedActionsList(() => updateActionBtn.current!.reRender());
setIsSaving(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsSaving(false);
if (err.kind !== ErrorKind.Unauthorized) {
@ -263,7 +267,7 @@ const AuthorizationSection = (props: Props) => {
try {
const membersList: Member[] = await API.getAllOrganizationMembers(ctx.prefs.controlPanel.selectedOrg!);
setMembers(membersList.map((member: Member) => member.alias));
} catch (err: any) {
} catch {
setMembers(undefined);
}
}
@ -345,7 +349,7 @@ const AuthorizationSection = (props: Props) => {
getAuthorizationPolicy();
fetchMembers();
}
}, [selectedOrg]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [selectedOrg]);
useEffect(() => {
if (ctx.prefs.controlPanel.selectedOrg) {
@ -364,7 +368,7 @@ const AuthorizationSection = (props: Props) => {
}
}
}
}, [ctx.prefs.controlPanel.selectedOrg]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [ctx.prefs.controlPanel.selectedOrg]);
const onBeforeUnload = (e: BeforeUnloadEvent) => {
e.preventDefault();
@ -383,7 +387,7 @@ const AuthorizationSection = (props: Props) => {
return () => {
window.removeEventListener('beforeunload', onBeforeUnload);
};
}, [orgPolicy]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [orgPolicy]);
usePrompt({
when: !isNull(orgPolicy) && !isUndefined(orgPolicy) && !notGetPolicyAllowed && checkIfUnsavedChanges(),

View File

@ -2,6 +2,7 @@ import { render, screen } from '@testing-library/react';
import OrganizationSettingsSection from './index';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
jest.mock('../../../common/SectionPanel', () => (props: any) => <div>{props.defaultSection}</div>);
const defaultProps = {

View File

@ -34,6 +34,7 @@ const DeleteOrganization = (props: Props) => {
dispatch(unselectOrg());
scrollToTop(); // Scroll to top when org is deleted
setIsDeleting(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsDeleting(false);
if (err.kind === ErrorKind.Unauthorized) {

View File

@ -5,6 +5,7 @@ import UpdateOrg from './UpdateOrg';
jest.mock('../../../../../api');
const getMockOrganization = (fixtureId: string): Organization => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
return require(`./__fixtures__/UpdateOrg/${fixtureId}.json`) as Organization;
};

View File

@ -9,6 +9,7 @@ import ProfileOrgSection from './index';
jest.mock('../../../../../api');
const getMockOrganization = (fixtureId: string): Organization => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
return require(`./__fixtures__/index/${fixtureId}.json`) as Organization;
};

View File

@ -34,6 +34,7 @@ const ProfileSection = (props: Props) => {
setApiError(null);
}
setIsLoading(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsLoading(false);
if (err.kind !== ErrorKind.Unauthorized) {
@ -56,7 +57,7 @@ const ProfileSection = (props: Props) => {
) {
fetchOrganization();
}
}, [selectedOrg]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [selectedOrg]);
return (
<main role="main" className="p-0">

View File

@ -9,7 +9,7 @@ import Card from './Card';
jest.mock('../../../../../api');
jest.mock('../../../../../utils/alertDispatcher');
jest.mock('moment', () => ({
...(jest.requireActual('moment') as {}),
...(jest.requireActual('moment') as object),
unix: () => ({
format: () => '2020/06/18 16:35:39 (+00:00)',
}),

View File

@ -43,6 +43,7 @@ const APIKeyCard = (props: Props) => {
await API.deleteAPIKey(props.apiKey.apiKeyId!);
setIsDeleting(false);
props.onSuccess();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsDeleting(false);
if (err.kind === ErrorKind.Unauthorized) {

View File

@ -69,6 +69,7 @@ const APIKeyModal = (props: Props) => {
if (props.apiKey) {
onCloseModal();
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsSending(false);
if (err.kind !== ErrorKind.Unauthorized) {
@ -123,6 +124,7 @@ const APIKeyModal = (props: Props) => {
const currentAPIKey = await API.getAPIKey(props.apiKey!.apiKeyId!);
setApiKey(currentAPIKey);
nameInput.current!.updateValue(currentAPIKey.name);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
if (err.kind === ErrorKind.Unauthorized) {
props.onAuthError();

View File

@ -7,7 +7,10 @@ import API from '../../../../../api';
import { ErrorKind } from '../../../../../types';
import APIKeysSection from './index';
jest.mock('../../../../../api');
jest.mock('moment', () => ({ ...(jest.requireActual('moment') as {}), format: () => '2020/06/18 16:35:39 (+00:00)' }));
jest.mock('moment', () => ({
...(jest.requireActual('moment') as object),
format: () => '2020/06/18 16:35:39 (+00:00)',
}));
const getMockAPIKeys = (fixtureId: string) => {
return require(`./__fixtures__/index/${fixtureId}.json`);

View File

@ -68,6 +68,7 @@ const APIKeysSection = (props: Props) => {
updatePageNumber();
setApiError(null);
setIsLoading(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsLoading(false);
if (err.kind !== ErrorKind.Unauthorized) {
@ -81,13 +82,13 @@ const APIKeysSection = (props: Props) => {
useEffect(() => {
getAPIKeys();
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
useEffect(() => {
if (props.activePage && activePage !== parseInt(props.activePage)) {
getAPIKeys();
}
}, [activePage]); /* eslint-disable-line react-hooks/exhaustive-deps */
}, [activePage]);
return (
<div className="d-flex flex-column flex-grow-1">

View File

@ -2,6 +2,7 @@ import { render, screen } from '@testing-library/react';
import UserSettingsSection from './index';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
jest.mock('../../../common/SectionPanel', () => (props: any) => <div>{props.defaultSection}</div>);
const defaultProps = {

View File

@ -38,6 +38,7 @@ const DeleteAccount = (props: Props) => {
await API.registerDeleteUserCode();
setIsDeleting(false);
setDeleteSuccess(true);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsDeleting(false);
if (err.kind === ErrorKind.Unauthorized) {

View File

@ -40,10 +40,11 @@ const UpdatePassword = () => {
cleanForm();
setIsSending(false);
setIsValidated(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsSending(false);
if (err.kind !== ErrorKind.Unauthorized) {
let error = compoundErrorMessage(err, 'An error occurred updating your password');
const error = compoundErrorMessage(err, 'An error occurred updating your password');
alertDispatcher.postAlert({
type: 'danger',
message: error,

View File

@ -52,10 +52,11 @@ const UpdateProfile = (props: Props) => {
await API.updateUserProfile(user);
dispatch(updateUser(formattedUser));
setIsSending(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
setIsSending(false);
if (err.kind !== ErrorKind.Unauthorized) {
let error = compoundErrorMessage(err, 'An error occurred updating your profile');
const error = compoundErrorMessage(err, 'An error occurred updating your profile');
alertDispatcher.postAlert({
type: 'danger',
message: error,

View File

@ -9,6 +9,7 @@ import UserSettings from './index';
jest.mock('../../../../../api');
const getMockProfile = (fixtureId: string): Profile => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
return require(`./__fixtures__/index/${fixtureId}.json`) as Profile;
};

View File

@ -20,6 +20,7 @@ const ProfileSection = (props: Props) => {
async function fetchProfile() {
try {
setProfile(await API.getUserProfile());
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
if (err.kind !== ErrorKind.Unauthorized) {
setProfile(null);
@ -31,7 +32,7 @@ const ProfileSection = (props: Props) => {
useEffect(() => {
fetchProfile();
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
}, []);
return (
<main role="main" className="p-0">

Some files were not shown because too many files have changed in this diff Show More