diff --git a/app/client/.eslintrc.cjs b/app/client/.eslintrc.cjs index 0949c679..40f0b070 100644 --- a/app/client/.eslintrc.cjs +++ b/app/client/.eslintrc.cjs @@ -13,9 +13,14 @@ module.exports = { parser: "@typescript-eslint/parser", plugins: ["react-refresh"], rules: { + "no-extra-boolean-cast": "off", "react-refresh/only-export-components": [ "warn", - { allowConstantExport: true }, + { allowConstantExport: true }, // allow export const foo = 4 + ], + "@typescript-eslint/no-unused-vars": [ + "warn", + { argsIgnorePattern: "^_" }, // ignore unused args starting with _ ], }, }; diff --git a/app/client/src/components/providers.tsx b/app/client/src/components/providers.tsx index 495e4cc6..02d078ca 100644 --- a/app/client/src/components/providers.tsx +++ b/app/client/src/components/providers.tsx @@ -8,7 +8,7 @@ import { RebateYearProvider } from "@/contexts/rebateYear"; declare global { interface Window { - csb: any; + csb?: { toggleReactQueryDevtools: () => void }; } } @@ -22,11 +22,12 @@ export function Providers(props: { children: ReactNode }) { const { children } = props; const [queryClient] = useState(() => new QueryClient()); - const [devtoolsDisplayed, setDevtoolsDisplayed] = useState(false); + const [reactQueryDevtoolsShown, setReactQueryDevtoolsShown] = useState(false); useEffect(() => { - window.csb ??= {}; - window.csb.toggleDevtools = () => setDevtoolsDisplayed((value) => !value); + window.csb ??= { + toggleReactQueryDevtools: () => setReactQueryDevtoolsShown((val) => !val), + }; }); return ( @@ -37,7 +38,7 @@ export function Providers(props: { children: ReactNode }) { - {devtoolsDisplayed && ( + {reactQueryDevtoolsShown && ( diff --git a/app/client/src/contexts/dialog.tsx b/app/client/src/contexts/dialog.tsx index 20a59ad6..5cd25cb0 100644 --- a/app/client/src/contexts/dialog.tsx +++ b/app/client/src/contexts/dialog.tsx @@ -1,3 +1,5 @@ +/* eslint-disable react-refresh/only-export-components */ + import type { Dispatch, ReactNode } from "react"; import { createContext, useContext, useReducer } from "react"; diff --git a/app/client/src/contexts/notifications.tsx b/app/client/src/contexts/notifications.tsx index e1853627..6fc70863 100644 --- a/app/client/src/contexts/notifications.tsx +++ b/app/client/src/contexts/notifications.tsx @@ -1,3 +1,5 @@ +/* eslint-disable react-refresh/only-export-components */ + import type { Dispatch, ReactNode } from "react"; import { createContext, useContext, useReducer } from "react"; diff --git a/app/client/src/contexts/rebateYear.tsx b/app/client/src/contexts/rebateYear.tsx index d006e014..13f01636 100644 --- a/app/client/src/contexts/rebateYear.tsx +++ b/app/client/src/contexts/rebateYear.tsx @@ -1,3 +1,5 @@ +/* eslint-disable react-refresh/only-export-components */ + import type { Dispatch, ReactNode } from "react"; import { createContext, useContext, useReducer } from "react"; diff --git a/app/client/src/index.tsx b/app/client/src/index.tsx index f6636159..1e982891 100644 --- a/app/client/src/index.tsx +++ b/app/client/src/index.tsx @@ -18,7 +18,7 @@ import "@/styles.css"; const container = document.getElementById("root") as HTMLElement; -function Index() { +export default function Index() { return ( diff --git a/app/client/src/routes/crf2022.tsx b/app/client/src/routes/crf2022.tsx index 63da1ca5..86597dfe 100644 --- a/app/client/src/routes/crf2022.tsx +++ b/app/client/src/routes/crf2022.tsx @@ -63,7 +63,10 @@ function useFormioSubmissionQueryAndMutation(rebateId: string | undefined) { * https://github.com/formio/formio.js/blob/master/src/providers/storage/s3.js#L5 * https://github.com/formio/formio.js/blob/master/src/providers/storage/xhr.js#L90 */ - Formio.Providers.providers.storage.s3 = function (formio: any) { + Formio.Providers.providers.storage.s3 = function (formio: { + formUrl: string; + [field: string]: unknown; + }) { const s3Formio = cloneDeep(formio); s3Formio.formUrl = `${serverUrl}/api/formio/2022/s3/crf/${mongoId}/${comboKey}`; return s3(s3Formio); diff --git a/app/client/src/routes/frf2022.tsx b/app/client/src/routes/frf2022.tsx index 9053a539..1c72d84d 100644 --- a/app/client/src/routes/frf2022.tsx +++ b/app/client/src/routes/frf2022.tsx @@ -63,16 +63,25 @@ function useFormioSubmissionQueryAndMutation(mongoId: string | undefined) { * https://github.com/formio/formio.js/blob/master/src/providers/storage/s3.js#L5 * https://github.com/formio/formio.js/blob/master/src/providers/storage/xhr.js#L90 */ - Formio.Providers.providers.storage.s3 = function (formio: any) { + Formio.Providers.providers.storage.s3 = function (formio: { + formUrl: string; + [field: string]: unknown; + }) { const s3Formio = cloneDeep(formio); s3Formio.formUrl = `${serverUrl}/api/formio/2022/s3/frf/${mongoId}/${comboKey}`; return s3(s3Formio); }; - // remove `ncesDataSource` and `ncesDataLookup` fields const data = { ...res.submission?.data }; - if (data.hasOwnProperty("ncesDataSource")) delete data.ncesDataSource; - if (data.hasOwnProperty("ncesDataLookup")) delete data.ncesDataLookup; + + // remove `ncesDataSource` and `ncesDataLookup` fields + // (https://eslint.org/docs/latest/rules/no-prototype-builtins) + if (Object.prototype.hasOwnProperty.call(data, "ncesDataSource")) { + delete data.ncesDataSource; + } + if (Object.prototype.hasOwnProperty.call(data, "ncesDataLookup")) { + delete data.ncesDataLookup; + } return Promise.resolve({ ...res, @@ -423,8 +432,13 @@ function FundingRequestForm(props: { email: string }) { const data = { ...onSubmitSubmission.data }; // remove `ncesDataSource` and `ncesDataLookup` fields - if (data.hasOwnProperty("ncesDataSource")) delete data.ncesDataSource; // prettier-ignore - if (data.hasOwnProperty("ncesDataLookup")) delete data.ncesDataLookup; // prettier-ignore + // (https://eslint.org/docs/latest/rules/no-prototype-builtins) + if (Object.prototype.hasOwnProperty.call(data, "ncesDataSource")) { + delete data.ncesDataSource; + } + if (Object.prototype.hasOwnProperty.call(data, "ncesDataLookup")) { + delete data.ncesDataLookup; + } const updatedSubmission = { ...onSubmitSubmission, @@ -502,8 +516,13 @@ function FundingRequestForm(props: { email: string }) { const data = { ...onNextPageParam.submission.data }; // remove `ncesDataSource` and `ncesDataLookup` fields - if (data.hasOwnProperty("ncesDataSource")) delete data.ncesDataSource; // prettier-ignore - if (data.hasOwnProperty("ncesDataLookup")) delete data.ncesDataLookup; // prettier-ignore + // (https://eslint.org/docs/latest/rules/no-prototype-builtins) + if (Object.prototype.hasOwnProperty.call(data, "ncesDataSource")) { + delete data.ncesDataSource; + } + if (Object.prototype.hasOwnProperty.call(data, "ncesDataLookup")) { + delete data.ncesDataLookup; + } // "dirty check" – don't post an update if no changes have been made // to the form (ignoring current user fields) diff --git a/app/client/src/routes/frf2023.tsx b/app/client/src/routes/frf2023.tsx index fa13aca5..5226cbb8 100644 --- a/app/client/src/routes/frf2023.tsx +++ b/app/client/src/routes/frf2023.tsx @@ -62,7 +62,10 @@ function useFormioSubmissionQueryAndMutation(mongoId: string | undefined) { * https://github.com/formio/formio.js/blob/master/src/providers/storage/s3.js#L5 * https://github.com/formio/formio.js/blob/master/src/providers/storage/xhr.js#L90 */ - Formio.Providers.providers.storage.s3 = function (formio: any) { + Formio.Providers.providers.storage.s3 = function (formio: { + formUrl: string; + [field: string]: unknown; + }) { const s3Formio = cloneDeep(formio); s3Formio.formUrl = `${serverUrl}/api/formio/2023/s3/frf/${mongoId}/${comboKey}`; return s3(s3Formio); diff --git a/app/client/src/routes/prf2022.tsx b/app/client/src/routes/prf2022.tsx index c597142b..a7502314 100644 --- a/app/client/src/routes/prf2022.tsx +++ b/app/client/src/routes/prf2022.tsx @@ -63,7 +63,10 @@ function useFormioSubmissionQueryAndMutation(rebateId: string | undefined) { * https://github.com/formio/formio.js/blob/master/src/providers/storage/s3.js#L5 * https://github.com/formio/formio.js/blob/master/src/providers/storage/xhr.js#L90 */ - Formio.Providers.providers.storage.s3 = function (formio: any) { + Formio.Providers.providers.storage.s3 = function (formio: { + formUrl: string; + [field: string]: unknown; + }) { const s3Formio = cloneDeep(formio); s3Formio.formUrl = `${serverUrl}/api/formio/2022/s3/prf/${mongoId}/${comboKey}`; return s3(s3Formio); diff --git a/app/client/src/utilities.ts b/app/client/src/utilities.ts index c90058d9..6c7fa015 100644 --- a/app/client/src/utilities.ts +++ b/app/client/src/utilities.ts @@ -236,7 +236,7 @@ export type Rebate = }; }; -async function fetchData(url: string, options: RequestInit) { +async function fetchData(url: string, options: RequestInit) { try { const response = await fetch(url, options); const contentType = response.headers.get("content-type"); @@ -253,7 +253,7 @@ async function fetchData(url: string, options: RequestInit) { * Fetches data and returns a promise containing JSON fetched from a provided * web service URL or handles any other OK response returned from the server */ -export function getData(url: string) { +export function getData(url: string) { return fetchData(url, { method: "GET", credentials: "include" as const, @@ -264,7 +264,7 @@ export function getData(url: string) { * Posts JSON data and returns a promise containing JSON fetched from a provided * web service URL or handles any other OK response returned from the server */ -export function postData(url: string, data: object) { +export function postData(url: string, data: object) { return fetchData(url, { method: "POST", credentials: "include" as const,