Skip to content

Commit 9b014a4

Browse files
TCA-645 #comment This commit performs some lint fixes as examples #time 1h
1 parent 11c431b commit 9b014a4

File tree

20 files changed

+416
-94
lines changed

20 files changed

+416
-94
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
"dependencies": {
2424
"@datadog/browser-logs": "^4.21.2",
2525
"@heroicons/react": "^1.0.6",
26+
"@stripe/react-stripe-js": "1.13.0",
27+
"@stripe/stripe-js": "1.41.0",
2628
"apexcharts": "^3.36.0",
2729
"axios": "^1.1.2",
2830
"browser-cookies": "^1.2.0",
@@ -78,8 +80,6 @@
7880
"@babel/preset-typescript": "^7.18.6",
7981
"@babel/runtime": "^7.19.4",
8082
"@cypress/code-coverage": "^3.10.0",
81-
"@stripe/react-stripe-js": "1.13.0",
82-
"@stripe/stripe-js": "1.41.0",
8383
"@testing-library/jest-dom": "^5.16.5",
8484
"@testing-library/react": "^13.4.0",
8585
"@testing-library/user-event": "^14.4.3",
@@ -144,6 +144,7 @@
144144
"start-server-and-test": "^1.14.0",
145145
"style-loader": "^3.3.1",
146146
"systemjs-webpack-interop": "^2.3.7",
147+
"typed-scss-modules": "^7.0.1",
147148
"webpack": "^4.41.2",
148149
"webpack-cli": "^4.10.0",
149150
"webpack-config-single-spa-react": "^4.0.3",

src-ts/declarations.d.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@ declare module '*.html' {
77

88
declare module '*.pdf'
99

10-
declare module '*.scss' {
11-
const scssFile: { [style: string]: any }
12-
export = scssFile
13-
}
14-
1510
declare module '*.svg' {
1611
import * as React from 'react'
1712

src-ts/header/utility-selectors/UtilitySelector/ProfileSelector/profile-not-logged-in/ProfileNotLoggedIn.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const ProfileNotLoggedIn: FC<{}> = () => {
3434
label='Sign Up'
3535
size='md'
3636
tabIndex={-1}
37-
onClick={signUp}
37+
onClick={() => signUp()}
3838
/>
3939
</>
4040
)

src-ts/lib/breadcrumb/breadcrumb-item/BreadcrumbItem.tsx

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,25 @@ interface BreadcrumbItemProps {
1010
item: BreadcrumbItemModel
1111
}
1212

13-
const BreadcrumbItem: FC<BreadcrumbItemProps> = (props: BreadcrumbItemProps) => (
14-
<li key={props.index} onClick={() => props.item.onClick?.(props.item)}>
15-
<Link className={props.item.isElipsis && styles.elipsis} to={props.item.url}>
16-
{props.item.name}
17-
</Link>
18-
</li>
19-
)
13+
const BreadcrumbItem: FC<BreadcrumbItemProps> = (props: BreadcrumbItemProps) => {
14+
15+
function onClick(): void {
16+
props.item.onClick?.(props.item)
17+
}
18+
19+
return (
20+
<li
21+
key={props.index}
22+
onClick={() => onClick()}
23+
>
24+
<Link
25+
className={props.item.isElipsis && styles.elipsis}
26+
to={props.item.url}
27+
>
28+
{props.item.name}
29+
</Link>
30+
</li>
31+
)
32+
}
2033

2134
export default BreadcrumbItem

src-ts/lib/button/Button.tsx

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const Button: FC<ButtonProps> = (props: ButtonProps) => {
4343
className={classes}
4444
href={props.url}
4545
onClick={clickHandler}
46-
rel={props.rel ?? props.target === '_blank' ? 'noreferrer' : ''}
46+
rel={props.rel || props.target === '_blank' ? 'noreferrer' : ''}
4747
role='button'
4848
tabIndex={props.tabIndex}
4949
title={props.title}
@@ -104,14 +104,20 @@ const Button: FC<ButtonProps> = (props: ButtonProps) => {
104104
)
105105
}
106106

107-
function getButtonClasses(props: ButtonProps): string {
107+
function getButtonClasses(
108+
className: string,
109+
buttonStyle: ButtonStyle,
110+
size: ButtonSize,
111+
disable?: boolean,
112+
hidden?: boolean,
113+
): string {
108114
const classes: string = classNames(
109115
'button',
110-
props.className,
111-
props.buttonStyle || 'primary',
112-
`button-${props.size || 'md'}`,
113-
!!props.disable ? 'disabled' : undefined,
114-
props.hidden ? 'hidden' : undefined,
116+
className,
117+
buttonStyle || 'primary',
118+
`button-${size || 'md'}`,
119+
{ disabled: disable },
120+
{ hidden },
115121
)
116122
return classes
117123
}

src-ts/lib/form/Form.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ import {
2323
formOnChange,
2424
formOnReset,
2525
formOnSubmitAsync,
26+
formValidateForm,
27+
FormValue,
2628
} from './form-functions'
27-
import { validateForm } from './form-functions/form.functions'
2829
import { FormGroups } from './form-groups'
2930
import styles from './Form.module.scss'
3031

@@ -41,8 +42,8 @@ interface FormProps<ValueType, RequestType> {
4142
readonly shouldDisableButton?: (isPrimaryGroup: boolean, index: number) => boolean
4243
}
4344

44-
const Form: <ValueType extends any, RequestType extends any>(props: FormProps<ValueType, RequestType>) => JSX.Element
45-
= <ValueType extends any, RequestType extends any>(props: FormProps<ValueType, RequestType>) => {
45+
const Form: <ValueType extends FormValue, RequestType extends FormValue>(props: FormProps<ValueType, RequestType>) => JSX.Element
46+
= <ValueType extends FormValue, RequestType extends FormValue>(props: FormProps<ValueType, RequestType>) => {
4647

4748
const [formDef, setFormDef]: [FormDefinition, Dispatch<SetStateAction<FormDefinition>>]
4849
= useState<FormDefinition>({ ...props.formDef })
@@ -65,7 +66,7 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va
6566
return
6667
}
6768

68-
validateForm(formRef.current?.elements, 'initial', inputs)
69+
formValidateForm(formRef.current?.elements, 'initial', inputs)
6970
checkIfFormIsValid(inputs)
7071
}, [
7172
formRef,
@@ -78,7 +79,7 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va
7879
}
7980

8081
// so we repeat the validation when formValues changes, to support the parent component's async data loading
81-
validateForm(formRef.current?.elements, 'change', inputs)
82+
formValidateForm(formRef.current?.elements, 'change', inputs)
8283
checkIfFormIsValid(inputs)
8384
}, [
8485
props.formValues,
@@ -90,6 +91,7 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va
9091
if (props.resetFormOnUnmount) {
9192
onReset()
9293
}
94+
// eslint-disable-next-line react-hooks/exhaustive-deps
9395
}, [])
9496

9597
function checkIfFormIsValid(formInputFields: Array<FormInputModel>): void {
@@ -167,7 +169,7 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va
167169
{...button}
168170
key={button.label || `button-${index}`}
169171
disable={disabled}
170-
tabIndex={button.notTabble ? -1 : index + (inputs ? inputs.length : 0) + (formDef.tabIndexStart || 0)}
172+
tabIndex={button.notTabble ? -1 : index + (inputs?.length || 0) + (formDef.tabIndexStart || 0)}
171173
/>
172174
)
173175
})
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { InputValue } from '../form-input.model'
2+
3+
export interface FormValue {
4+
[propertyName: string]: InputValue,
5+
}

src-ts/lib/form/form-functions/form.functions.ts

Lines changed: 67 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ import { toast } from 'react-toastify'
33

44
import { FormAction, FormDefinition } from '../form-definition.model'
55
import { FormGroup } from '../form-group.model'
6-
import { FormInputModel } from '../form-input.model'
6+
import { FormInputModel, InputValue } from '../form-input.model'
77

8-
export function getInputElement(formElements: HTMLFormControlsCollection, fieldName: string): HTMLInputElement {
8+
import { FormValue } from './form-value.model'
9+
10+
export type ValidationEvent = 'blur' | 'change' | 'submit' | 'initial'
11+
12+
export function getInputElement(formElements: HTMLFormControlsCollection, fieldName: string): HTMLInputElement | undefined {
913
return formElements.namedItem(fieldName) as HTMLInputElement
1014
}
1115

@@ -29,29 +33,42 @@ export function getInputModel(inputs: ReadonlyArray<FormInputModel>, fieldName:
2933
return formField
3034
}
3135

32-
export function initializeValues<T>(inputs: Array<FormInputModel>, formValues?: T): void {
33-
inputs
36+
export function initializeValues<T extends FormValue>(
37+
inputs: Array<FormInputModel>,
38+
formValues?: T,
39+
): void {
40+
41+
const filteredInputs: ReadonlyArray<FormInputModel> = inputs
3442
.filter(input => !input.dirty && !input.touched)
35-
.forEach(input => {
36-
if (input.type === 'checkbox') {
37-
input.value = input.checked || false
38-
} else {
39-
input.value = !!(formValues as any)?.hasOwnProperty(input.name)
40-
? (formValues as any)[input.name]
41-
: undefined
42-
}
43-
})
43+
44+
for (const input of filteredInputs) {
45+
if (input.type === 'checkbox') {
46+
input.value = input.checked || false
47+
} else {
48+
input.value = Object.prototype.hasOwnProperty.call(formValues, input.name)
49+
? (formValues as { [id: string]: InputValue })[input.name]
50+
: undefined
51+
}
52+
}
4453
}
4554

46-
export function onBlur<T>(event: FormEvent<HTMLInputElement | HTMLTextAreaElement>, inputs: ReadonlyArray<FormInputModel>, formValues?: T): void {
55+
export function onBlur<T extends FormValue>(
56+
event: FormEvent<HTMLInputElement | HTMLTextAreaElement>,
57+
inputs: ReadonlyArray<FormInputModel>,
58+
formValues?: T,
59+
): void {
4760
handleFieldEvent<T>(event.target as HTMLInputElement | HTMLTextAreaElement, inputs, 'blur', formValues)
4861
}
4962

50-
export function onChange<T>(event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>, inputs: ReadonlyArray<FormInputModel>, formValues?: T): void {
63+
export function onChange<T extends FormValue>(
64+
event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
65+
inputs: ReadonlyArray<FormInputModel>,
66+
formValues?: T,
67+
): void {
5168
handleFieldEvent<T>(event.target as HTMLInputElement | HTMLTextAreaElement, inputs, 'change', formValues)
5269
}
5370

54-
export function onReset(inputs: ReadonlyArray<FormInputModel>, formValue?: any): void {
71+
export function onReset<T extends FormValue>(inputs: ReadonlyArray<FormInputModel>, formValue?: T): void {
5572
inputs?.forEach(inputDef => {
5673
const typeCastedInput: FormInputModel = inputDef as FormInputModel
5774
typeCastedInput.dirty = false
@@ -61,7 +78,7 @@ export function onReset(inputs: ReadonlyArray<FormInputModel>, formValue?: any):
6178
})
6279
}
6380

64-
export async function onSubmitAsync<T>(
81+
export async function onSubmitAsync<T extends FormValue>(
6582
action: FormAction,
6683
event: FormEvent<HTMLFormElement>,
6784
formDef: FormDefinition,
@@ -93,13 +110,14 @@ export async function onSubmitAsync<T>(
93110
}
94111

95112
// set the properties for the updated T value
113+
const updatedValue: FormValue = { ...formValue }
96114
inputs
97115
.forEach(field => {
98-
(formValue as any)[field.name] = field.value
116+
updatedValue[field.name] = field.value
99117
})
100118

101119
// if there are no dirty fields, don't actually perform the save
102-
const savePromise: Promise<void> = !dirty ? Promise.resolve() : save(formValue)
120+
const savePromise: Promise<void> = !dirty ? Promise.resolve() : save(updatedValue as T)
103121

104122
return savePromise
105123
.then(() => {
@@ -109,13 +127,18 @@ export async function onSubmitAsync<T>(
109127
toast.success(safeSuccessMessage)
110128
onSuccess?.()
111129
})
112-
.catch(error => Promise.reject(error.response?.data?.result?.content || error.message || error))
130+
.catch(error => Promise.reject(error.response?.data?.result?.content ?? error.message ?? error))
113131
}
114132

115-
function handleFieldEvent<T>(input: HTMLInputElement | HTMLTextAreaElement, inputs: ReadonlyArray<FormInputModel>, event: 'blur' | 'change', formValues?: T): void {
133+
function handleFieldEvent<T extends FormValue>(
134+
input: HTMLInputElement | HTMLTextAreaElement,
135+
inputs: ReadonlyArray<FormInputModel>,
136+
event: 'blur' | 'change',
137+
formValues?: T,
138+
): void {
116139

117140
// set the dirty and touched flags on the field
118-
const originalValue: string | undefined = (formValues as any)?.[input.name]
141+
const originalValue: InputValue = formValues?.[input.name]
119142

120143
const inputDef: FormInputModel = getInputModel(inputs, input.name)
121144

@@ -153,7 +176,11 @@ function handleFieldEvent<T>(input: HTMLInputElement | HTMLTextAreaElement, inpu
153176
})
154177
}
155178

156-
function validateField(formInputDef: FormInputModel, formElements: HTMLFormControlsCollection, event: 'blur' | 'change' | 'submit' | 'initial'): void {
179+
function validateField(
180+
formInputDef: FormInputModel,
181+
formElements: HTMLFormControlsCollection,
182+
event: 'blur' | 'change' | 'submit' | 'initial',
183+
): void {
157184

158185
// this is the error the field had before the event took place
159186
const previousError: string | undefined = formInputDef.error
@@ -162,7 +189,11 @@ function validateField(formInputDef: FormInputModel, formElements: HTMLFormContr
162189
?.forEach(validatorFunction => {
163190

164191
// if the next error is the same as the previous error, then no need to do anything
165-
const nextError: string | undefined = validatorFunction.validator(formInputDef.value, formElements, validatorFunction.dependentField)
192+
const nextError: string | undefined = validatorFunction.validator(
193+
formInputDef.value,
194+
formElements,
195+
validatorFunction.dependentField,
196+
)
166197

167198
if (previousError === nextError) {
168199
return
@@ -186,13 +217,19 @@ function validateField(formInputDef: FormInputModel, formElements: HTMLFormContr
186217
})
187218
}
188219

189-
export type ValidationEvent = 'blur' | 'change' | 'submit' | 'initial'
220+
export function validateForm(
221+
formElements: HTMLFormControlsCollection,
222+
event: ValidationEvent,
223+
inputs: ReadonlyArray<FormInputModel>,
224+
): boolean {
225+
226+
let hasError: boolean = false
190227

191-
export function validateForm(formElements: HTMLFormControlsCollection, event: ValidationEvent, inputs: ReadonlyArray<FormInputModel>): boolean {
192-
const errors: ReadonlyArray<FormInputModel> = inputs?.filter(formInputDef => {
228+
for (const formInputDef of inputs) {
193229
formInputDef.dirty = formInputDef.dirty || event === 'submit'
194230
validateField(formInputDef, formElements, event)
195-
return !!formInputDef.error
196-
})
197-
return !errors.length
231+
hasError = hasError || !!formInputDef.error
232+
}
233+
234+
return !hasError
198235
}

src-ts/lib/form/form-functions/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ export {
77
onReset as formOnReset,
88
onSubmitAsync as formOnSubmitAsync,
99
getFormInputFields as formGetInputFields,
10+
validateForm as formValidateForm,
1011
} from './form.functions'
12+
export * from './form-value.model'

0 commit comments

Comments
 (0)