mirror of
https://github.com/overleaf/overleaf.git
synced 2025-02-24 21:32:53 +00:00
Merge pull request #8074 from overleaf/ii-ts-strict-fixes-1
GitOrigin-RevId: b99c5c998de9cc36cffffaab5b318331b45e931d
This commit is contained in:
parent
16f3dc3abc
commit
5e08d5f505
11 changed files with 80 additions and 56 deletions
|
@ -39,16 +39,18 @@ function AccountInfoSection() {
|
|||
const { isLoading, isSuccess, isError, error, runAsync } = useAsync()
|
||||
const [isFormValid, setIsFormValid] = useState(true)
|
||||
|
||||
const handleEmailChange = event => {
|
||||
const handleEmailChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setEmail(event.target.value)
|
||||
setIsFormValid(event.target.validity.valid)
|
||||
}
|
||||
|
||||
const handleFirstNameChange = event => {
|
||||
const handleFirstNameChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
setFirstName(event.target.value)
|
||||
}
|
||||
|
||||
const handleLastNameChange = event => {
|
||||
const handleLastNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setLastName(event.target.value)
|
||||
}
|
||||
|
||||
|
@ -56,7 +58,7 @@ function AccountInfoSection() {
|
|||
!hasAffiliationsFeature && !isExternalAuthenticationSystemUsed
|
||||
const canUpdateNames = shouldAllowEditingDetails
|
||||
|
||||
const handleSubmit = event => {
|
||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault()
|
||||
if (!isFormValid) {
|
||||
return
|
||||
|
@ -151,11 +153,15 @@ function ReadOrWriteFormGroup({
|
|||
}: ReadOrWriteFormGroupProps) {
|
||||
const [validationMessage, setValidationMessage] = useState('')
|
||||
|
||||
const handleInvalid = event => {
|
||||
const handleInvalid = (
|
||||
event: React.InvalidEvent<HTMLInputElement & FormControl>
|
||||
) => {
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
const handleChangeAndValidity = event => {
|
||||
const handleChangeAndValidity = (
|
||||
event: React.ChangeEvent<HTMLInputElement & FormControl>
|
||||
) => {
|
||||
handleChange(event)
|
||||
setValidationMessage(event.target.validationMessage)
|
||||
}
|
||||
|
|
|
@ -70,20 +70,20 @@ function Input({ onChange, handleAddNewEmail }: InputProps) {
|
|||
(event: ChangeEvent<HTMLInputElement>) => {
|
||||
const hint = event.target.value
|
||||
setInputValue(hint)
|
||||
const match = matchLocalAndDomain(hint)
|
||||
if (!matchedDomain?.hostname.startsWith(match.domain)) {
|
||||
const { local, domain } = matchLocalAndDomain(hint)
|
||||
if (domain && !matchedDomain?.hostname.startsWith(domain)) {
|
||||
setSuggestion(null)
|
||||
}
|
||||
if (!match.domain) {
|
||||
if (!domain) {
|
||||
return
|
||||
}
|
||||
if (domainCache.has(match.domain)) {
|
||||
const cachedDomain = domainCache.get(match.domain)
|
||||
setSuggestion(`${match.local}@${cachedDomain.hostname}`)
|
||||
if (domainCache.has(domain)) {
|
||||
const cachedDomain = domainCache.get(domain) as DomainInfo
|
||||
setSuggestion(`${local}@${cachedDomain.hostname}`)
|
||||
setMatchedDomain(cachedDomain)
|
||||
return
|
||||
}
|
||||
const query = `?hostname=${match.domain}&limit=1`
|
||||
const query = `?hostname=${domain}&limit=1`
|
||||
getJSON<Nullable<DomainInfo[]>>(`/institutions/domains${query}`, {
|
||||
signal,
|
||||
})
|
||||
|
@ -96,8 +96,8 @@ function Input({ onChange, handleAddNewEmail }: InputProps) {
|
|||
}
|
||||
const hostname = data[0]?.hostname
|
||||
if (hostname) {
|
||||
domainCache.set(match.domain, data[0])
|
||||
setSuggestion(`${match.local}@${hostname}`)
|
||||
domainCache.set(domain, data[0])
|
||||
setSuggestion(`${local}@${hostname}`)
|
||||
setMatchedDomain(data[0])
|
||||
} else {
|
||||
setSuggestion(null)
|
||||
|
@ -142,7 +142,7 @@ function Input({ onChange, handleAddNewEmail }: InputProps) {
|
|||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (suggestion && !suggestion.startsWith(inputValue)) {
|
||||
if (suggestion && inputValue && !suggestion.startsWith(inputValue)) {
|
||||
setSuggestion(null)
|
||||
}
|
||||
}, [suggestion, inputValue])
|
||||
|
|
|
@ -35,24 +35,20 @@ export function SSOAlert() {
|
|||
const handleErrorClosed = () => setErrorClosed(true)
|
||||
|
||||
if (samlError) {
|
||||
return (
|
||||
!errorClosed && (
|
||||
<Alert bsStyle="danger" className="mb-0" onDismiss={handleErrorClosed}>
|
||||
<p className="text-center">
|
||||
<Icon
|
||||
type="exclamation-triangle"
|
||||
accessibilityLabel={t('generic_something_went_wrong')}
|
||||
/>{' '}
|
||||
{samlError.translatedMessage
|
||||
? samlError.translatedMessage
|
||||
: samlError.message}
|
||||
</p>
|
||||
{samlError.tryAgain && (
|
||||
<p className="text-center">{t('try_again')}</p>
|
||||
)}
|
||||
</Alert>
|
||||
)
|
||||
)
|
||||
return !errorClosed ? (
|
||||
<Alert bsStyle="danger" className="mb-0" onDismiss={handleErrorClosed}>
|
||||
<p className="text-center">
|
||||
<Icon
|
||||
type="exclamation-triangle"
|
||||
accessibilityLabel={t('generic_something_went_wrong')}
|
||||
/>{' '}
|
||||
{samlError.translatedMessage
|
||||
? samlError.translatedMessage
|
||||
: samlError.message}
|
||||
</p>
|
||||
{samlError.tryAgain && <p className="text-center">{t('try_again')}</p>}
|
||||
</Alert>
|
||||
) : null
|
||||
}
|
||||
|
||||
if (!institutionLinked) {
|
||||
|
|
|
@ -24,11 +24,15 @@ function LeaveModalForm({
|
|||
const [confirmation, setConfirmation] = useState(false)
|
||||
const [error, setError] = useState<FetchError | null>(null)
|
||||
|
||||
const handleEmailChange = event => {
|
||||
const handleEmailChange = (
|
||||
event: React.ChangeEvent<HTMLFormElement & FormControl>
|
||||
) => {
|
||||
setEmail(event.target.value)
|
||||
}
|
||||
|
||||
const handlePasswordChange = event => {
|
||||
const handlePasswordChange = (
|
||||
event: React.ChangeEvent<HTMLFormElement & FormControl>
|
||||
) => {
|
||||
setPassword(event.target.value)
|
||||
}
|
||||
|
||||
|
@ -36,7 +40,7 @@ function LeaveModalForm({
|
|||
setConfirmation(prev => !prev)
|
||||
}
|
||||
|
||||
const handleSubmit = event => {
|
||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault()
|
||||
if (!isFormValid) {
|
||||
return
|
||||
|
|
|
@ -13,12 +13,12 @@ function LinkingSection() {
|
|||
const projectSyncSuccessMessage = getMeta(
|
||||
'ol-projectSyncSuccessMessage'
|
||||
) as string
|
||||
const [integrationLinkingWidgets] = useState(
|
||||
const [integrationLinkingWidgets] = useState<any[]>(
|
||||
() =>
|
||||
getMeta('integrationLinkingWidgets') ||
|
||||
importOverleafModules('integrationLinkingWidgets')
|
||||
)
|
||||
const [referenceLinkingWidgets] = useState(
|
||||
const [referenceLinkingWidgets] = useState<any[]>(
|
||||
() =>
|
||||
getMeta('referenceLinkingWidgets') ||
|
||||
importOverleafModules('referenceLinkingWidgets')
|
||||
|
@ -139,7 +139,7 @@ function SSOLinkingWidgetContainer({
|
|||
const { t } = useTranslation()
|
||||
const { unlink } = useSSOContext()
|
||||
|
||||
let description = null
|
||||
let description = ''
|
||||
switch (subscription.providerId) {
|
||||
case 'collabratec':
|
||||
description = t('linked_collabratec_description')
|
||||
|
|
|
@ -141,7 +141,9 @@ function UnlinkConfirmationModal({
|
|||
}: UnlinkConfirmModalProps) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const handleCancel = event => {
|
||||
const handleCancel = (
|
||||
event: React.MouseEvent<HTMLButtonElement & Button>
|
||||
) => {
|
||||
event.preventDefault()
|
||||
handleHide()
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import GoogleLogo from '../../../../shared/svgs/google-logo'
|
|||
import OrcidLogo from '../../../../shared/svgs/orcid-logo'
|
||||
import LinkingStatus from './status'
|
||||
|
||||
const providerLogos = {
|
||||
const providerLogos: { readonly [p: string]: JSX.Element } = {
|
||||
collabratec: <IEEELogo />,
|
||||
google: <GoogleLogo />,
|
||||
orcid: <OrcidLogo />,
|
||||
|
@ -95,6 +95,7 @@ export function SSOLinkingWidget({
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
type ActionButtonProps = {
|
||||
unlinkRequestInflight: boolean
|
||||
accountIsLinked?: boolean
|
||||
|
|
|
@ -4,7 +4,7 @@ import Icon from '../../../../shared/components/icon'
|
|||
type Status = 'pending' | 'success' | 'error'
|
||||
|
||||
type LinkingStatusProps = {
|
||||
status?: Status
|
||||
status: Status
|
||||
description: string | ReactNode
|
||||
}
|
||||
|
||||
|
|
|
@ -72,16 +72,22 @@ function PasswordForm() {
|
|||
const [isNewPasswordValid, setIsNewPasswordValid] = useState(false)
|
||||
const [isFormValid, setIsFormValid] = useState(false)
|
||||
|
||||
const handleCurrentPasswordChange = event => {
|
||||
const handleCurrentPasswordChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
setCurrentPassword(event.target.value)
|
||||
}
|
||||
|
||||
const handleNewPassword1Change = event => {
|
||||
const handleNewPassword1Change = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
setNewPassword1(event.target.value)
|
||||
setIsNewPasswordValid(event.target.validity.valid)
|
||||
}
|
||||
|
||||
const handleNewPassword2Change = event => {
|
||||
const handleNewPassword2Change = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
setNewPassword2(event.target.value)
|
||||
}
|
||||
|
||||
|
@ -91,7 +97,7 @@ function PasswordForm() {
|
|||
)
|
||||
}, [currentPassword, newPassword1, newPassword2, isNewPasswordValid])
|
||||
|
||||
const handleSubmit = event => {
|
||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault()
|
||||
if (!isFormValid) {
|
||||
return
|
||||
|
@ -157,7 +163,7 @@ type PasswordFormGroupProps = {
|
|||
id: string
|
||||
label: string
|
||||
value: string
|
||||
handleChange: (event: any) => void
|
||||
handleChange: (event: React.ChangeEvent<HTMLInputElement>) => void
|
||||
minLength?: number
|
||||
validationMessage?: string
|
||||
}
|
||||
|
@ -173,11 +179,15 @@ function PasswordFormGroup({
|
|||
const [validationMessage, setValidationMessage] = useState('')
|
||||
const [hadInteraction, setHadInteraction] = useState(false)
|
||||
|
||||
const handleInvalid = event => {
|
||||
const handleInvalid = (
|
||||
event: React.InvalidEvent<HTMLInputElement & FormControl>
|
||||
) => {
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
const handleChangeAndValidity = event => {
|
||||
const handleChangeAndValidity = (
|
||||
event: React.ChangeEvent<HTMLInputElement & FormControl>
|
||||
) => {
|
||||
handleChange(event)
|
||||
setHadInteraction(true)
|
||||
setValidationMessage(event.target.validationMessage)
|
||||
|
|
|
@ -79,7 +79,9 @@ export class FetchError extends OError {
|
|||
getUserFacingMessage() {
|
||||
const statusCode = this.response?.status
|
||||
const defaultMessage = getErrorMessageForStatusCode(statusCode)
|
||||
const message = this.data?.message?.text || this.data?.message
|
||||
const message = (this.data?.message?.text || this.data?.message) as
|
||||
| string
|
||||
| undefined
|
||||
if (message && message !== defaultMessage) return message
|
||||
|
||||
const statusCodes: { readonly [K: number]: string } = {
|
||||
|
@ -208,11 +210,14 @@ async function parseResponseBody(response: Response) {
|
|||
return {}
|
||||
}
|
||||
|
||||
export function getUserFacingMessage(error: Error): string {
|
||||
export function getUserFacingMessage(error: Error | null) {
|
||||
if (!error) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (error instanceof FetchError) {
|
||||
return error.getUserFacingMessage()
|
||||
} else {
|
||||
// checking existence of `error` to prevent errors when called from Javascript
|
||||
return error?.message
|
||||
}
|
||||
|
||||
return error.message
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ function usePersistedState<T>(
|
|||
|
||||
useEffect(() => {
|
||||
if (listen) {
|
||||
const listener = event => {
|
||||
const listener = (event: StorageEvent) => {
|
||||
if (event.key === key) {
|
||||
// note: this value is read via getItem rather than from event.newValue
|
||||
// because getItem handles deserializing the JSON that's stored in localStorage.
|
||||
|
|
Loading…
Reference in a new issue