Skip to content

Commit

Permalink
Merge pull request #71 from sf-sahil-jassal/GH-70
Browse files Browse the repository at this point in the history
refactore(core): fix sonar smells related to any types and indices as keys
  • Loading branch information
yeshamavani authored Nov 23, 2023
2 parents c2f3b25 + 7402319 commit bf6db92
Show file tree
Hide file tree
Showing 66 changed files with 371 additions and 333 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"default-param-last": ["error"],
"no-console": ["warn", {"allow": ["warn", "error"]}],
"no-unused-vars": "off",
"no-restricted-imports": ["error", {"paths": ["import1", "import2"]}],
"@typescript-eslint/no-unused-vars": "error"
}
}
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"arrowParens": "avoid",
"bracketSpacing": false,
"singleQuote": true,
"printWidth": 120,
Expand Down
6 changes: 5 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@
"source.organizeImports": true,
"source.fixAll.eslint": true
},
"cSpell.words": ["reduxjs", "sfrefarch", "sigv"]
"cSpell.words": ["reduxjs", "sfrefarch", "sigv"],
"sonarlint.connectedMode.project": {
"connectionId": "SourceFuse",
"projectKey": "sourcefuse_react-boilerplate-ts-ui"
}
}
4 changes: 2 additions & 2 deletions src/Components/Breadcrumb/Breadcrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ export default function Breadcrumb(): JSX.Element {

return (
<MuiBreadcrumbs separator={<NavigateNextIcon fontSize="small" />} aria-label="breadcrumb" data-testid="breadcrumb">
{breadcrumbs.map(({match, breadcrumb}, index) => (
<Grid key={index}>
{breadcrumbs.map(({match, key, breadcrumb}, index) => (
<Grid key={key}>
{breadcrumbs.length - 1 === index ? (
<Grid
key={match?.pathname}
Expand Down
6 changes: 3 additions & 3 deletions src/Components/Checkbox/Checkbox.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {fireEvent, render, screen, within} from '@testing-library/react';
import React, {useState} from 'react';
import {useState} from 'react';
import Checkbox from './Checkbox';

const options = [
Expand All @@ -21,7 +21,7 @@ describe('Checkbox', () => {
describe('should work with useState', () => {
it('should be multi select by default', () => {
const MockCheckBox = () => {
const [value, setValue]: any = useState([]);
const [value, setValue] = useState<string | string[]>([]);
return <Checkbox id="test" value={value} onChange={setValue} label="test" options={options} />;
};
render(<MockCheckBox />);
Expand All @@ -42,7 +42,7 @@ describe('Checkbox', () => {
});
it('should be single select if singleSelect flag is passed', () => {
const MockCheckBox = () => {
const [value, setValue]: any = useState('');
const [value, setValue] = useState<string | string[]>('');
return <Checkbox id="test" value={value} onChange={setValue} label="test" options={options} singleSelect />;
};
render(<MockCheckBox />);
Expand Down
24 changes: 10 additions & 14 deletions src/Components/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,15 @@ import {
import InputLabel from 'Components/InputLabel';
import React, {memo, useCallback} from 'react';

export interface CheckboxOption {
label: string;
value: any;
}

export interface CheckboxProps extends MuiCheckboxProps {
export interface CheckboxProps extends Omit<MuiCheckboxProps, 'onChange'> {
label?: string;
helperText?: string;
errorMessage?: string | Array<any>;
errorMessage?: string;
value?: string | string[];
row?: boolean;
singleSelect?: boolean;
options: CheckboxOption[];
onChange?: (val: any) => void;
options: Array<{label: string; value: string}>;
onChange?: (val: string | string[]) => void;
}

const Checkbox: React.FC<CheckboxProps> = ({
Expand All @@ -46,7 +42,7 @@ const Checkbox: React.FC<CheckboxProps> = ({
const val = value === e?.target?.name ? '' : e.target.name;
onChange(val);
} else if (Array.isArray(value)) {
const index = value.findIndex((val) => val === e?.target?.value);
const index = value.findIndex(val => val === e?.target?.value);
const newValue = [...value];
if (index === -1) {
newValue.push(e.target.value);
Expand All @@ -63,19 +59,19 @@ const Checkbox: React.FC<CheckboxProps> = ({
<FormControl disabled={disabled} data-testid="checkboxFormControl">
{label && <InputLabel>{label}</InputLabel>}
<FormGroup row={row}>
{options.map((option: CheckboxOption) => (
{options.map((option: {label: string; value: string}) => (
<FormControlLabel
key={option.label}
control={
<MuiCheckbox
checked={
singleSelect
? value?.toString() === option?.value.toString()
: Array.isArray(value) && value.some((val) => val === option.value)
? value === option?.value
: Array.isArray(value) && value.some(val => val === option.value)
}
onChange={handleChange}
value={option.value}
name={singleSelect ? option?.value.toString() : id}
name={singleSelect ? option?.value : id}
{...rest}
/>
}
Expand Down
6 changes: 3 additions & 3 deletions src/Components/ComponentPaper.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import MuiPaper from '@mui/material/Paper';
import {styled} from '@mui/material/styles';
import {styled, Theme as MUITheme} from '@mui/material/styles';
import {memo, ReactNode} from 'react';

const Paper = styled(
MuiPaper,
{},
)(({theme}: any) => ({
)(({theme}: {theme: MUITheme}) => ({
padding: theme.spacing(2),
marginTop: theme.spacing(2),
border: '1px solid',
borderColor: theme?.palette?.border?.main,
borderColor: theme?.palette?.secondary?.main,
}));

const ComponentPaper = ({children}: {children: ReactNode}) => <Paper elevation={0}>{children}</Paper>;
Expand Down
4 changes: 2 additions & 2 deletions src/Components/DatePicker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ export interface DatePickerProps {
}

interface Props extends DatePickerProps {
value?: any;
value?: Date | null;
}

const DatePicker: React.FC<Props & PartialBy<MuiDatePickerProps<any, Date>, 'renderInput'>> = ({
const DatePicker: React.FC<Props & PartialBy<MuiDatePickerProps<Date | null, Date>, 'renderInput'>> = ({
id,
label,
value,
Expand Down
4 changes: 2 additions & 2 deletions src/Components/DateTimePicker/DateTimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ export interface DateTimePickerProps {
}

interface Props extends DateTimePickerProps {
value?: any;
value?: Date | null;
}

const DateTimePicker: React.FC<Props & PartialBy<MuiDateTimePickerProps<any, Date>, 'renderInput'>> = ({
const DateTimePicker: React.FC<Props & PartialBy<MuiDateTimePickerProps<Date | null, Date>, 'renderInput'>> = ({
id,
label,
value,
Expand Down
6 changes: 3 additions & 3 deletions src/Components/Dropdown/Dropdown.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {fireEvent, render, screen, within} from '@testing-library/react';
import {useState} from 'react';
import Dropdown from './Dropdown';
import Dropdown, {AutocompleteValueType, DropdownProps} from './Dropdown';
import userEvent from '@testing-library/user-event';

const options = [
Expand All @@ -9,8 +9,8 @@ const options = [
{label: 'Devops', value: 'devops'},
];

const MockDropdown = ({initialValue = [], ...props}: any) => {
const [value, setValue] = useState(initialValue);
const MockDropdown = (props: Omit<DropdownProps, 'id' | 'options'> & {initialValue?: AutocompleteValueType}) => {
const [value, setValue] = useState(props.initialValue);
return <Dropdown id="test" value={value} onChange={setValue} label="test" options={options} {...props} />;
};

Expand Down
63 changes: 41 additions & 22 deletions src/Components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,31 @@ import TextField from '@mui/material/TextField';
import InputLabel from 'Components/InputLabel';
import React from 'react';

export type AutocompleteValueType =
| NonNullable<string | {label: string; value: string}>
| (string | {label: string; value: string})[];

export interface DropdownProps
extends Omit<AutocompleteProps<{value: any; label: string}, boolean, boolean, boolean>, 'renderInput' | 'options'> {
extends Omit<
AutocompleteProps<{label: string; value: string}, boolean, boolean, boolean>,
'renderInput' | 'options' | 'value' | 'onChange'
> {
id: string;
label?: string;
disabled?: boolean;
enableAutoComplete?: boolean;
multiple?: boolean;
helperText?: string;
errorMessage?: any;
options: Array<{value: any; label: string}>;
onChange?: any;
errorMessage?: string;
options: Array<{value: string; label: string}>;
onChange?: (val: AutocompleteValueType) => void;
width?: number;
disableBorder?: boolean;
isLoading?: boolean;
}

interface Props extends DropdownProps {
value?: any;
value?: AutocompleteValueType;
}

const Dropdown: React.FC<Props> = ({
Expand All @@ -49,6 +56,29 @@ const Dropdown: React.FC<Props> = ({
const newId = enableAutoComplete ? id : `${id}-${Date.now()}`;
if (enableAutoComplete) multiple = false;

let displayValue = '';

if (Array.isArray(value)) {
displayValue = '';
} else if (typeof value === 'string') {
displayValue = value;
} else {
displayValue = value?.label || '';
}

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (enableAutoComplete && !multiple) {
let val: AutocompleteValueType;
if (e.target.value && onChange) {
val = {
label: e.target.value,
value: e.target.value,
};
onChange(val);
}
}
};

return (
<FormControl sx={{width: width ?? 1}} data-testid="dropdownFormControl" error={isError}>
{label && <InputLabel htmlFor={id}>{label}</InputLabel>}
Expand All @@ -60,7 +90,7 @@ const Dropdown: React.FC<Props> = ({
freeSolo={enableAutoComplete}
disableClearable={!enableAutoComplete}
isOptionEqualToValue={(option, val) => option?.value === val?.value}
getOptionLabel={(option) => {
getOptionLabel={option => {
if (typeof option !== 'string') {
return option?.label || '';
}
Expand Down Expand Up @@ -97,33 +127,22 @@ const Dropdown: React.FC<Props> = ({
marginTop: 2,
}}
disabled={disabled}
onChange={(e, val) => {
onChange(val);
onChange={(_, val) => {
if (onChange && val) onChange(val);
}}
renderInput={(params) => (
renderInput={params => (
<TextField
error={!!isError}
{...params}
onChange={(e) => {
if (enableAutoComplete && !multiple) {
let val: any = null;
if (e.target.value) {
val = {
label: e.target.value,
value: e.target.value,
};
}
onChange(val);
}
}}
onChange={handleInputChange}
inputProps={{
...params.inputProps,
readOnly: !enableAutoComplete,
sx: {
caretColor: !enableAutoComplete && 'transparent',
cursor: !enableAutoComplete && 'pointer !important',
},
...(enableAutoComplete && !multiple && {value: value?.label || ''}),
...(enableAutoComplete && !multiple && {value: displayValue}),
}}
/>
)}
Expand Down
14 changes: 9 additions & 5 deletions src/Components/Forms/Form/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import {Form as FormikForm, Formik} from 'formik';
import {forwardRef, ReactNode} from 'react';
import {ForwardedRef, forwardRef, ReactNode} from 'react';
import * as yup from 'yup';

type Props = {
interface Props {
initialValues: any;
onSubmit: any;
validationSchema?: any;
validationSchema?: ReturnType<typeof yup.object>;
id?: string;
enableReinitialize?: boolean;
children?: ReactNode;
};
}

const Form = forwardRef(
({initialValues, onSubmit, validationSchema, children, id, enableReinitialize = false}: Props, ref: any) => {
(
{initialValues, onSubmit, validationSchema, children, id, enableReinitialize = false}: Props,
ref: ForwardedRef<HTMLFormElement>,
) => {
return (
<Formik
enableReinitialize={enableReinitialize}
Expand Down
5 changes: 3 additions & 2 deletions src/Components/Forms/FormCheckbox/FormCheckbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import {useFormikContext} from 'formik';
import React, {useCallback} from 'react';

type Formik = {
[x: string]: string;
// singleselect | normal
[x: string]: string | string[];
};

const FormCheckbox: React.FC<CheckboxProps> = ({id, disabled, ...rest}) => {
const {setFieldValue, errors, touched, values} = useFormikContext<Formik>();
const isError = !!errors[id!] && touched[id!] && !disabled;
const handleOnChangeEvent = useCallback(
(val: any) => {
(val: string | string[]) => {
setFieldValue(id!, val);
},
[id, setFieldValue],
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Forms/FormDatePicker/FormDatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {useFormikContext} from 'formik';
import React, {useCallback} from 'react';

type Formik = {
[x: string]: string;
[x: string]: Date | null;
};

const FormDatePicker: React.FC<DatePickerProps> = ({id, disabled, ...rest}) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {useFormikContext} from 'formik';
import React, {useCallback} from 'react';

type Formik = {
[x: string]: string;
[x: string]: Date | null;
};

const FormDateTimePicker: React.FC<DateTimePickerProps> = ({id, disabled, ...rest}) => {
Expand Down
6 changes: 3 additions & 3 deletions src/Components/Forms/FormDropdown/FormDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import Dropdown, {DropdownProps} from 'Components/Dropdown/Dropdown';
import Dropdown, {AutocompleteValueType, DropdownProps} from 'Components/Dropdown/Dropdown';
import {useFormikContext} from 'formik';
import React, {useCallback} from 'react';

type Formik = {
[x: string]: string;
[x: string]: AutocompleteValueType;
};

const FormDropdown: React.FC<DropdownProps> = ({id, disabled, ...rest}) => {
const {setFieldValue, errors, touched, values} = useFormikContext<Formik>();
const isError = !!errors[id] && touched[id] && !disabled;
const handleChange = useCallback((val: any) => setFieldValue(id, val), [id, setFieldValue]);
const handleChange = useCallback((val: AutocompleteValueType) => setFieldValue(id, val), [id, setFieldValue]);

return (
<Dropdown
Expand Down
8 changes: 2 additions & 6 deletions src/Components/Forms/FormInput/FormInput.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import Input, {InputProps} from 'Components/Input/Input';
import {useFormikContext} from 'formik';
import {FormikValues, useFormikContext} from 'formik';
import {getValue} from 'Helpers/utils';
import React, {useCallback} from 'react';

type Formik = {
[x: string]: string;
};

const FormInput: React.FC<InputProps> = ({id, disabled, ...rest}) => {
const {setFieldValue, errors, touched, values} = useFormikContext<Formik>();
const {setFieldValue, errors, touched, values} = useFormikContext<FormikValues>();
const isError = !!getValue(errors, id) && getValue(touched, id) && !disabled;
const handleChangeEvent = useCallback((val: string) => setFieldValue(id, val), [id, setFieldValue]);

Expand Down
Loading

0 comments on commit bf6db92

Please sign in to comment.