diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 189f7dbc9c..83e153cf37 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,71 +1,92 @@ module.exports = { root: true, - parser: "@typescript-eslint/parser", + parser: '@typescript-eslint/parser', plugins: [ - "react", - "react-hooks", - "testing-library", - "jest", - "jest-dom", - "@typescript-eslint", + 'react', + 'react-hooks', + 'testing-library', + 'jest', + 'jest-dom', + '@typescript-eslint', ], - ignorePatterns: ["apps/portals/src/tests/*"], + ignorePatterns: ['apps/portals/src/tests/*'], extends: [ - "eslint:recommended", - "plugin:react/recommended", - "plugin:jest/recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking", - "plugin:storybook/recommended", + 'eslint:recommended', + 'plugin:react/recommended', + 'plugin:jest/recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:storybook/recommended', + 'plugin:import/recommended', + 'plugin:import/typescript', ], parserOptions: { tsconfigRootDir: __dirname, project: [ - "./tsconfig.json", - "./packages/**/tsconfig.json", - "./apps/**/tsconfig.json", + './tsconfig.json', + './packages/**/tsconfig.json', + './apps/**/tsconfig.json', ], }, rules: { - "react/prop-types": [0], - "react/no-unstable-nested-components": "warn", - "react-hooks/rules-of-hooks": "error", - "react-hooks/exhaustive-deps": [ - "warn", + 'react/prop-types': [0], + 'react/no-unstable-nested-components': 'warn', + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': [ + 'warn', { - additionalHooks: "useDebouncedEffect", + additionalHooks: 'useDebouncedEffect', }, ], - "no-extra-semi": "off", - "prefer-const": "warn", - "jest/expect-expect": "off", - "@typescript-eslint/restrict-template-expressions": [ - "warn", + 'no-extra-semi': 'off', + 'prefer-const': 'warn', + 'jest/expect-expect': 'off', + '@typescript-eslint/restrict-template-expressions': [ + 'warn', { allowBoolean: true }, ], - "@typescript-eslint/unbound-method": "warn", - "@typescript-eslint/no-inferrable-types": "off", - "@typescript-eslint/ban-ts-comment": "warn", - "@typescript-eslint/no-empty-interface": "warn", - "@typescript-eslint/no-floating-promises": "off", - "@typescript-eslint/no-unsafe-argument": "warn", - "@typescript-eslint/no-unsafe-assignment": "warn", - "@typescript-eslint/no-unsafe-member-access": "warn", - "@typescript-eslint/no-unsafe-call": "warn", - "@typescript-eslint/no-unsafe-return": "warn", - "@typescript-eslint/no-unnecessary-type-assertion": "warn", - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/no-non-null-asserted-optional-chain": "off", - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-empty-function": "off", - "@typescript-eslint/no-extra-semi": "warn", + '@typescript-eslint/unbound-method': 'warn', + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/ban-ts-comment': 'warn', + '@typescript-eslint/no-empty-interface': 'warn', + '@typescript-eslint/no-floating-promises': 'off', + '@typescript-eslint/no-unsafe-argument': 'warn', + '@typescript-eslint/no-unsafe-assignment': 'warn', + '@typescript-eslint/no-unsafe-member-access': 'warn', + '@typescript-eslint/no-unsafe-call': 'warn', + '@typescript-eslint/no-unsafe-return': 'warn', + '@typescript-eslint/no-unnecessary-type-assertion': 'warn', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-extra-semi': 'warn', + 'import/order': [ + 'error', + { + groups: [ + 'builtin', + 'external', + 'internal', + 'parent', + 'sibling', + 'index', + 'object', + 'type', + ], + }, + ], }, settings: { react: { - version: "detect", + version: 'detect', + }, + 'import/resolver': { + typescript: true, + node: true, }, }, globals: { JSX: true, }, -}; +} diff --git a/apps/SageAccountWeb/package.json b/apps/SageAccountWeb/package.json index 5aac70cb52..040ab32db6 100644 --- a/apps/SageAccountWeb/package.json +++ b/apps/SageAccountWeb/package.json @@ -80,6 +80,7 @@ }, "scripts": { "clean": "rimraf build coverage", + "lint": "eslint src", "start": "vite", "build": "vite build", "test": "vitest", diff --git a/apps/SageAccountWeb/src/App.tsx b/apps/SageAccountWeb/src/App.tsx index a3a54b97db..c32a22a7e4 100644 --- a/apps/SageAccountWeb/src/App.tsx +++ b/apps/SageAccountWeb/src/App.tsx @@ -1,4 +1,14 @@ import { StyledEngineProvider } from '@mui/material/styles' +import React from 'react' +import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' +import { + ApplicationSessionManager, + SynapseClient, + SynapseToastContainer, + SynapseContextType, + SynapseContextConsumer, +} from 'synapse-react-client' +import { QueryClient, QueryClientProvider } from 'react-query' import { AppContextConsumer } from './AppContext' import { SageResourcesPage } from './components/SageResourcesPage' import { AccountCreatedPage } from './components/AccountCreatedPage' @@ -12,20 +22,10 @@ import { RegisterAccount1 } from './components/RegisterAccount1' import { RegisterAccount2 } from './components/RegisterAccount2' import { ResetPassword } from './components/ResetPassword' import { TermsOfUsePage } from './components/TermsOfUsePage' -import React from 'react' -import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' -import { - ApplicationSessionManager, - SynapseClient, - SynapseToastContainer, - SynapseContextType, - SynapseContextConsumer, -} from 'synapse-react-client' import { getSearchParam } from './URLUtils' import './App.scss' import AppInitializer from './AppInitializer' import LoginPage from './LoginPage' -import { QueryClient, QueryClientProvider } from 'react-query' import TwoFactorAuthEnrollmentPage from './components/TwoFactorAuth/TwoFactorAuthEnrollmentPage' import TwoFactorAuthBackupCodesPage from './components/TwoFactorAuth/TwoFactorAuthBackupCodesPage' import { PersonalAccessTokensPage } from './components/PersonalAccessTokensPage' diff --git a/apps/SageAccountWeb/src/AppInitializer.tsx b/apps/SageAccountWeb/src/AppInitializer.tsx index 71af84c9f8..db391ff2ff 100644 --- a/apps/SageAccountWeb/src/AppInitializer.tsx +++ b/apps/SageAccountWeb/src/AppInitializer.tsx @@ -1,11 +1,7 @@ import React, { useEffect, useState } from 'react' import { Redirect } from 'react-router-dom' -import { getSearchParam } from './URLUtils' -import useAnalytics from './useAnalytics' import { SignedTokenInterface } from '@sage-bionetworks/synapse-types' import { createTheme, ThemeProvider } from '@mui/material/styles' -import { useSourceApp } from './components/SourceApp.js' -import { sageAccountWebThemeOverrides } from './style/theme' import { Theme } from '@mui/material' import { useLastLoginInfoState, @@ -13,6 +9,10 @@ import { SynapseUtilityFunctions, useApplicationSessionContext, } from 'synapse-react-client' +import { getSearchParam } from './URLUtils' +import useAnalytics from './useAnalytics' +import { useSourceApp } from './components/SourceApp.js' +import { sageAccountWebThemeOverrides } from './style/theme' import { AppContextProvider } from './AppContext' function AppInitializer(props: { children?: React.ReactNode }) { diff --git a/apps/SageAccountWeb/src/components/AccountCreatedPage.tsx b/apps/SageAccountWeb/src/components/AccountCreatedPage.tsx index 5e9bcef8ab..0222c7e81c 100644 --- a/apps/SageAccountWeb/src/components/AccountCreatedPage.tsx +++ b/apps/SageAccountWeb/src/components/AccountCreatedPage.tsx @@ -1,14 +1,12 @@ import React from 'react' -import { SourceAppLogo, useSourceApp, useSourceAppConfigs } from './SourceApp' import { Button, Grid, Link, Typography } from '@mui/material' -import { AppContextConsumer } from '../AppContext' import { Link as RouterLink } from 'react-router-dom' -import { LeftRightPanel } from './LeftRightPanel' +import { AppContextConsumer } from '../AppContext' import useMembershipInvitationTokenHandler from '../hooks/useMembershipInvitationTokenHandler' +import { LeftRightPanel } from './LeftRightPanel' +import { SourceAppLogo, useSourceApp, useSourceAppConfigs } from './SourceApp' -export type AccountCreatedPageProps = {} - -export const AccountCreatedPage = (props: AccountCreatedPageProps) => { +export const AccountCreatedPage = () => { const membershipInvitation = useMembershipInvitationTokenHandler() const sourceApp = useSourceApp() const sourceAppConfigs = useSourceAppConfigs() diff --git a/apps/SageAccountWeb/src/components/AccountSettings.tsx b/apps/SageAccountWeb/src/components/AccountSettings.tsx index dcc249b1f3..d337eacda7 100644 --- a/apps/SageAccountWeb/src/components/AccountSettings.tsx +++ b/apps/SageAccountWeb/src/components/AccountSettings.tsx @@ -23,12 +23,12 @@ import { } from 'synapse-react-client' import { Link as RouterLink, useHistory, useLocation } from 'react-router-dom' import { Form } from 'react-bootstrap' +import UniversalCookies from 'universal-cookie' import { ChangePassword } from './ChangePassword' import { ORCiDButton } from './ProfileValidation/ORCiDButton' import AccountSettingsTopBar from './AccountSettingsTopBar' import { ConfigureEmail } from './ConfigureEmail' import { UnbindORCiDDialog } from './ProfileValidation/UnbindORCiD' -import UniversalCookies from 'universal-cookie' import { StyledFormControl } from './StyledComponents' import { ProfileAvatar } from './ProfileAvatar' import { useSourceAppConfigs } from './SourceApp' diff --git a/apps/SageAccountWeb/src/components/AccountSettingsTopBar.tsx b/apps/SageAccountWeb/src/components/AccountSettingsTopBar.tsx index 56ed56a71f..b0e789b613 100644 --- a/apps/SageAccountWeb/src/components/AccountSettingsTopBar.tsx +++ b/apps/SageAccountWeb/src/components/AccountSettingsTopBar.tsx @@ -1,12 +1,12 @@ import React from 'react' import { BadgeOutlined } from '@mui/icons-material' import { Box, Button, SxProps, Typography } from '@mui/material' -import { useSourceApp } from './SourceApp' -import { useAppContext } from '../AppContext' import { SynapseClient, useApplicationSessionContext, } from 'synapse-react-client' +import { useAppContext } from '../AppContext' +import { useSourceApp } from './SourceApp' const AccountSettingsTopBar: React.FunctionComponent = () => { const sourceApp = useSourceApp() diff --git a/apps/SageAccountWeb/src/components/ConfigureEmail.tsx b/apps/SageAccountWeb/src/components/ConfigureEmail.tsx index 1668bc18ed..86a22757ad 100644 --- a/apps/SageAccountWeb/src/components/ConfigureEmail.tsx +++ b/apps/SageAccountWeb/src/components/ConfigureEmail.tsx @@ -5,7 +5,6 @@ import { SynapseQueries, useSynapseContext, } from 'synapse-react-client' -import { getSearchParam, hexDecodeAndDeserialize } from '../URLUtils' import { Box, Button, @@ -20,6 +19,7 @@ import { } from '@mui/material' import DeleteIcon from '@mui/icons-material/DeleteTwoTone' import AddCircleTwoToneIcon from '@mui/icons-material/AddCircleTwoTone' +import { getSearchParam, hexDecodeAndDeserialize } from '../URLUtils' import { StyledFormControl } from './StyledComponents' export type ConfigureEmailProps = { @@ -158,13 +158,17 @@ export const ConfigureEmail = (props: ConfigureEmailProps) => { {email} deleteEmail(e, email)} + onClick={e => { + deleteEmail(e, email) + }} > @@ -202,7 +206,9 @@ export const ConfigureEmail = (props: ConfigureEmailProps) => { control={ updateEmailNotifications(!sendEmailNotifications)} + onChange={e => { + updateEmailNotifications(!sendEmailNotifications) + }} /> } label={ diff --git a/apps/SageAccountWeb/src/components/CropImage.ts b/apps/SageAccountWeb/src/components/CropImage.ts index e5ba6dd1c5..24893e8bab 100644 --- a/apps/SageAccountWeb/src/components/CropImage.ts +++ b/apps/SageAccountWeb/src/components/CropImage.ts @@ -1,4 +1,4 @@ -import { Area } from 'react-easy-crop/types' +import type { Area } from 'react-easy-crop/types' export const createImg = (url: string) => new Promise((res, rej) => { diff --git a/apps/SageAccountWeb/src/components/CurrentAffiliationPage.tsx b/apps/SageAccountWeb/src/components/CurrentAffiliationPage.tsx index 622015c25a..9791db189b 100644 --- a/apps/SageAccountWeb/src/components/CurrentAffiliationPage.tsx +++ b/apps/SageAccountWeb/src/components/CurrentAffiliationPage.tsx @@ -1,8 +1,5 @@ import React, { useEffect, useState } from 'react' -import { SourceAppLogo, useSourceApp } from './SourceApp' import { InputLabel, TextField, Typography } from '@mui/material' -import { LeftRightPanel } from './LeftRightPanel' -import { StyledFormControl } from './StyledComponents' import { displayToast, SynapseClient, @@ -10,6 +7,9 @@ import { useSynapseContext, } from 'synapse-react-client' import { Redirect } from 'react-router-dom' +import { SourceAppLogo, useSourceApp } from './SourceApp' +import { LeftRightPanel } from './LeftRightPanel' +import { StyledFormControl } from './StyledComponents' import { ContinueButton } from './ProfileValidation/ContinueButton' export const CurrentAffiliationPage = () => { diff --git a/apps/SageAccountWeb/src/components/EmailConfirmationPage.tsx b/apps/SageAccountWeb/src/components/EmailConfirmationPage.tsx index 64df6cc248..688885926f 100644 --- a/apps/SageAccountWeb/src/components/EmailConfirmationPage.tsx +++ b/apps/SageAccountWeb/src/components/EmailConfirmationPage.tsx @@ -36,7 +36,7 @@ export const EmailConfirmationPage: React.FunctionComponent<

Please check your email.

- We've sent an email to {email} + We've sent an email to {email}

Click the link in the message to verify your address, then continue @@ -49,7 +49,7 @@ export const EmailConfirmationPage: React.FunctionComponent< } target="_blank" > - I didn't receive an email + I didn't receive an email

)} diff --git a/apps/SageAccountWeb/src/components/ProfileValidation/ReturnToAppButton.tsx b/apps/SageAccountWeb/src/components/ProfileValidation/ReturnToAppButton.tsx index ce247457ad..9188b2c01d 100644 --- a/apps/SageAccountWeb/src/components/ProfileValidation/ReturnToAppButton.tsx +++ b/apps/SageAccountWeb/src/components/ProfileValidation/ReturnToAppButton.tsx @@ -11,9 +11,9 @@ import { useTheme, } from '@mui/material' import CloseIcon from '@mui/icons-material/Close' -import { useAppContext } from '../../AppContext' import React from 'react' import { NavLink } from 'react-router-dom' +import { useAppContext } from '../../AppContext' export const ReturnToAppButton: React.FC<{ children?: React.ReactNode }> = ({ children, @@ -52,9 +52,9 @@ export const ReturnToAppButton: React.FC<{ children?: React.ReactNode }> = ({ - If you cancel verification, you'll still be able to use portions of - the application which are available to registered users, but your - access will be restricted. + If you cancel verification, you'll still be able to use + portions of the application which are available to registered users, + but your access will be restricted. To resume your verification in the future, access the{' '} diff --git a/apps/SageAccountWeb/src/components/ProfileValidation/TermsAndConditionsSignature.tsx b/apps/SageAccountWeb/src/components/ProfileValidation/TermsAndConditionsSignature.tsx index f7e8dea079..a70d95878c 100644 --- a/apps/SageAccountWeb/src/components/ProfileValidation/TermsAndConditionsSignature.tsx +++ b/apps/SageAccountWeb/src/components/ProfileValidation/TermsAndConditionsSignature.tsx @@ -1,6 +1,6 @@ import { TextField, Typography } from '@mui/material' -import { StyledFormControl } from '../StyledComponents' import React from 'react' +import { StyledFormControl } from '../StyledComponents' export type TermsAndConditionsSignatureProps = { canSign: boolean diff --git a/apps/SageAccountWeb/src/components/ProfileValidation/TermsAndConditionsWrapped.tsx b/apps/SageAccountWeb/src/components/ProfileValidation/TermsAndConditionsWrapped.tsx index 3e5cb96e30..29e503b99a 100644 --- a/apps/SageAccountWeb/src/components/ProfileValidation/TermsAndConditionsWrapped.tsx +++ b/apps/SageAccountWeb/src/components/ProfileValidation/TermsAndConditionsWrapped.tsx @@ -1,10 +1,10 @@ import { Box } from '@mui/material' import { TermsAndConditions } from 'synapse-react-client' import React from 'react' -import { ContinueButton } from './ContinueButton' import { VerificationSubmission } from '@sage-bionetworks/synapse-types' -import { ReturnToAppButton } from './ReturnToAppButton' import { TermsAndConditionsLink } from '../TermsAndConditionsLink' +import { ContinueButton } from './ContinueButton' +import { ReturnToAppButton } from './ReturnToAppButton' // import { TermsAndConditionsSignature } from './TermsAndConditionsSignature' export type TermsAndConditionsWrappedProps = { diff --git a/apps/SageAccountWeb/src/components/ProfileValidation/ThankYou.tsx b/apps/SageAccountWeb/src/components/ProfileValidation/ThankYou.tsx index 607718cf08..81541835c6 100644 --- a/apps/SageAccountWeb/src/components/ProfileValidation/ThankYou.tsx +++ b/apps/SageAccountWeb/src/components/ProfileValidation/ThankYou.tsx @@ -29,14 +29,14 @@ const ThankYou: React.FC<{ children: React.ReactNode }> = ({ children }) => { - We're verifying your account. + We're verifying your account. - Here's what to expect next: + Here's what to expect next: Our Access and Compliance Team (ACT) will review your application. This diff --git a/apps/SageAccountWeb/src/components/ProfileValidation/UnbindORCiD.tsx b/apps/SageAccountWeb/src/components/ProfileValidation/UnbindORCiD.tsx index 45ac9e1c96..66f9e58d1f 100644 --- a/apps/SageAccountWeb/src/components/ProfileValidation/UnbindORCiD.tsx +++ b/apps/SageAccountWeb/src/components/ProfileValidation/UnbindORCiD.tsx @@ -58,7 +58,7 @@ export const UnbindORCiDDialog = (props: UnbindORCiDDialogProps) => { diff --git a/apps/SageAccountWeb/src/components/ProfileValidation/VerifyIdentify.tsx b/apps/SageAccountWeb/src/components/ProfileValidation/VerifyIdentify.tsx index 16b3106e0a..c1b41f24ee 100644 --- a/apps/SageAccountWeb/src/components/ProfileValidation/VerifyIdentify.tsx +++ b/apps/SageAccountWeb/src/components/ProfileValidation/VerifyIdentify.tsx @@ -1,10 +1,10 @@ -import { ORCiDButton } from './ORCiDButton' import React, { useEffect, useState } from 'react' import { VerificationSubmission } from '@sage-bionetworks/synapse-types' import CheckIcon from '@mui/icons-material/Check' //agendelTODO: mobe to sage account page //import { UnbindORCiDDialog } from 'components/ProfileValidation/UnbindORCiD' import { Box, Typography, useTheme } from '@mui/material' +import { ORCiDButton } from './ORCiDButton' import { ContinueButton } from './ContinueButton' import { ReturnToAppButton } from './ReturnToAppButton' diff --git a/apps/SageAccountWeb/src/components/RegisterAccount1.tsx b/apps/SageAccountWeb/src/components/RegisterAccount1.tsx index b76e9ec489..fd39e723a2 100644 --- a/apps/SageAccountWeb/src/components/RegisterAccount1.tsx +++ b/apps/SageAccountWeb/src/components/RegisterAccount1.tsx @@ -20,11 +20,11 @@ import { AliasType, isMembershipInvtnSignedToken, } from '@sage-bionetworks/synapse-types' -import { SourceAppLogo, useSourceApp } from './SourceApp' import { Link as RouterLink } from 'react-router-dom' -import { EmailConfirmationPage } from './EmailConfirmationPage' import GoogleLogo from '../assets/g-logo.png' import { useAppContext } from '../AppContext' +import { EmailConfirmationPage } from './EmailConfirmationPage' +import { SourceAppLogo, useSourceApp } from './SourceApp' import { BackButton } from './BackButton' import { StyledFormControl, @@ -256,7 +256,9 @@ export const RegisterAccount1 = () => {