Show error messages in labels modal

This commit is contained in:
Jackson Harper 2023-06-20 10:19:40 +08:00
parent d0140b33d9
commit 074efe3b43
2 changed files with 80 additions and 13 deletions

View file

@ -6,7 +6,13 @@ import { StyledText } from '../../elements/StyledText'
import { styled, theme } from '../../tokens/stitches.config'
import { Label } from '../../../lib/networking/fragments/labelFragment'
import { useGetLabelsQuery } from '../../../lib/networking/queries/useGetLabelsQuery'
import { Check, Circle, PencilSimple, Plus } from 'phosphor-react'
import {
Check,
Circle,
PencilSimple,
Plus,
WarningCircle,
} from 'phosphor-react'
import { createLabelMutation } from '../../../lib/networking/mutations/createLabelMutation'
import { showErrorToast, showSuccessToast } from '../../../lib/toastHelpers'
import { randomLabelColorHex } from '../../../utils/settings-page/labels/labelColorObjects'
@ -39,6 +45,8 @@ type SetLabelsControlProps = {
deleteLastLabel: () => void
selectOrCreateLabel: (value: string) => void
errorMessage?: string
}
type HeaderProps = {
@ -75,7 +83,8 @@ function Header(props: HeaderProps): JSX.Element {
<Box
css={{
width: '100%',
my: '14px',
mt: '10px',
mb: '5px',
px: '14px',
}}
>
@ -414,6 +423,28 @@ export function SetLabelsControl(props: SetLabelsControlProps): JSX.Element {
selectOrCreateLabel={props.selectOrCreateLabel}
clearInputState={props.clearInputState}
/>
<Box
css={{
width: '100%',
height: '15px',
color: '#FF3B30',
fontSize: '12px',
fontFamily: '$inter',
gap: '5px',
display: 'flex',
alignItems: 'center',
justifyContent: 'end',
paddingRight: '15px',
m: '0px',
}}
>
{props.errorMessage && (
<>
{props.errorMessage}
<WarningCircle color="#FF3B30" size={15} />
</>
)}
</Box>
<VStack
distribution="start"
alignment="start"

View file

@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from 'react'
import { useCallback, useEffect, useRef, useState } from 'react'
import { Label } from '../../../lib/networking/fragments/labelFragment'
import { SpanBox, VStack } from '../../elements/LayoutPrimitives'
import {
@ -27,6 +27,10 @@ export function SetLabelsModal(props: SetLabelsModalProps): JSX.Element {
const availableLabels = useGetLabelsQuery()
const [tabCount, setTabCount] = useState(-1)
const [tabStartValue, setTabStartValue] = useState('')
const [errorMessage, setErrorMessage] = useState<string | undefined>(
undefined
)
const errorTimeoutRef = useRef<NodeJS.Timeout | undefined>()
const [highlightLastLabel, setHighlightLastLabel] = useState(false)
const [selectedLabels, setSelectedLabels] = useState(
@ -47,9 +51,35 @@ export function SetLabelsModal(props: SetLabelsModalProps): JSX.Element {
[props, selectedLabels]
)
const showMessage = useCallback((msg: string) => {
console.log('showMessage: ', msg)
}, [])
const showMessage = useCallback(
(msg: string, timeout?: number) => {
if (errorTimeoutRef.current) {
clearTimeout(errorTimeoutRef.current)
errorTimeoutRef.current = undefined
}
setErrorMessage(msg)
if (timeout) {
errorTimeoutRef.current = setTimeout(() => {
setErrorMessage(undefined)
if (errorTimeoutRef.current) {
clearTimeout(errorTimeoutRef.current)
errorTimeoutRef.current = undefined
}
}, timeout)
}
},
[errorTimeoutRef]
)
useEffect(() => {
const maxLengthMessage = 'Max label length: 48 chars'
if (inputValue.length >= 48) {
showMessage(maxLengthMessage)
} else if (errorMessage === maxLengthMessage) {
setErrorMessage(undefined)
}
}, [inputValue, showMessage])
const clearInputState = useCallback(() => {
setTabCount(-1)
@ -59,15 +89,15 @@ export function SetLabelsModal(props: SetLabelsModalProps): JSX.Element {
}, [tabCount, tabStartValue, highlightLastLabel])
const createLabelAsync = useCallback(
(tempLabel: Label) => {
(newLabels: Label[], tempLabel: Label) => {
;(async () => {
const currentLabels = selectedLabels
const currentLabels = newLabels
const newLabel = await createLabelMutation(
tempLabel.name,
tempLabel.color
)
const idx = currentLabels.findIndex((l) => l.id === tempLabel.id)
if (newLabel) {
const idx = currentLabels.findIndex((l) => l.id === tempLabel.id)
showSuccessToast(`Created label ${newLabel.name}`, {
position: 'bottom-right',
})
@ -78,7 +108,11 @@ export function SetLabelsModal(props: SetLabelsModalProps): JSX.Element {
setSelectedLabels([...currentLabels, newLabel])
}
} else {
showMessage(`Error creating label ${tempLabel.name}`)
showMessage(`Error creating label ${tempLabel.name}`, 5000)
if (idx !== -1) {
currentLabels.splice(idx, 1)
setSelectedLabels([...currentLabels])
}
}
})()
},
@ -105,7 +139,7 @@ export function SetLabelsModal(props: SetLabelsModalProps): JSX.Element {
setSelectedLabels([...current, existing])
clearInputState()
} else {
showMessage(`label ${value} already added.`)
showMessage(`label ${value} already added.`, 5000)
}
} else {
const tempLabel = {
@ -116,10 +150,11 @@ export function SetLabelsModal(props: SetLabelsModalProps): JSX.Element {
createdAt: new Date(),
_temporary: true,
}
setSelectedLabels([...current, tempLabel])
const newLabels = [...current, tempLabel]
setSelectedLabels(newLabels)
clearInputState()
createLabelAsync(tempLabel)
createLabelAsync(newLabels, tempLabel)
}
},
[
@ -183,6 +218,7 @@ export function SetLabelsModal(props: SetLabelsModalProps): JSX.Element {
setHighlightLastLabel={setHighlightLastLabel}
deleteLastLabel={deleteLastLabel}
selectOrCreateLabel={selectOrCreateLabel}
errorMessage={errorMessage}
/>
</VStack>
</ModalContent>