mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-03-27 19:12:05 -04:00
Fix options in multiple languages and filter language mismatch
This commit is contained in:
@@ -23,7 +23,7 @@ export const MultiCheckbox = (props: {
|
||||
addPlaceholder?: string
|
||||
translationPrefix?: string
|
||||
}) => {
|
||||
const { choices, selected, onChange, className, addOption, addPlaceholder, translationPrefix } = props
|
||||
const {choices, selected, onChange, className, addOption, addPlaceholder, translationPrefix} = props
|
||||
|
||||
// Keep a local merged copy to allow optimistic adds while remaining in sync with props
|
||||
const [localChoices, setLocalChoices] = useState<{ [key: string]: string }>(choices)
|
||||
@@ -31,7 +31,7 @@ export const MultiCheckbox = (props: {
|
||||
setLocalChoices((prev) => {
|
||||
// If incoming choices changed, merge them with any locally added that still don't collide
|
||||
// Props should be source of truth on conflicts
|
||||
return { ...prev, ...choices }
|
||||
return {...prev, ...choices}
|
||||
})
|
||||
}, [choices])
|
||||
|
||||
@@ -44,12 +44,18 @@ export const MultiCheckbox = (props: {
|
||||
|
||||
const t = useT()
|
||||
|
||||
const translateOption = (key: string, value: string) => {
|
||||
if (!translationPrefix) return key
|
||||
return t(`${translationPrefix}.${toKey(value)}`, key)
|
||||
}
|
||||
|
||||
// Filter visible options while typing a new option (case-insensitive label match)
|
||||
const filteredEntries = useMemo(() => {
|
||||
if (!addOption) return entries
|
||||
const q = newLabel.trim().toLowerCase()
|
||||
let q = newLabel.trim()
|
||||
q = translateOption(q, q).toLowerCase()
|
||||
if (!q) return entries
|
||||
return entries.filter(([key]) => key.toLowerCase().includes(q))
|
||||
return entries.filter(([key, value]) => translateOption(key, value).toLowerCase().includes(q))
|
||||
}, [addOption, entries, newLabel])
|
||||
|
||||
const submitAdd = async () => {
|
||||
@@ -57,33 +63,37 @@ export const MultiCheckbox = (props: {
|
||||
const label = newLabel.trim()
|
||||
setError(null)
|
||||
if (!label) {
|
||||
setError('Please enter a value.')
|
||||
setError(t('multi-checkbox.enter_value', 'Please enter a value.'))
|
||||
return
|
||||
}
|
||||
// prevent duplicate by label or by value already selected
|
||||
const lowerCaseChoices = Object.keys(localChoices).map((k: string) => k.toLowerCase())
|
||||
if (lowerCaseChoices.includes(label.toLowerCase())) {
|
||||
setError('That option already exists.')
|
||||
// const key = Object.keys(lowerCaseChoices).find((k) => k.toLowerCase() === label.toLowerCase())
|
||||
// if (!key) return
|
||||
// setProfile('interests', [...(profile['interests'] ?? []), key])
|
||||
const existingEntry = Object.entries(localChoices).find(([key, value]) =>
|
||||
translateOption(key, value).toLowerCase() === translateOption(label, label).toLowerCase()
|
||||
)
|
||||
|
||||
if (existingEntry) {
|
||||
const [_, existingValue] = existingEntry
|
||||
if (!selected.includes(existingValue)) {
|
||||
onChange([...selected, existingValue])
|
||||
}
|
||||
setNewLabel('')
|
||||
return
|
||||
}
|
||||
setAdding(true)
|
||||
try {
|
||||
const result = addOption(label)
|
||||
if (!result) {
|
||||
setError('Could not add option.')
|
||||
setError(t('multi-checkbox.could_not_add', 'Could not add option.'))
|
||||
setAdding(false)
|
||||
return
|
||||
}
|
||||
const { key, value } = typeof result === 'string' ? { key: label, value: result } : result
|
||||
setLocalChoices((prev) => ({ ...prev, [key]: value }))
|
||||
const {key, value} = typeof result === 'string' ? {key: label, value: result} : result
|
||||
setLocalChoices((prev) => ({...prev, [key]: value}))
|
||||
// auto-select newly added option if not already selected
|
||||
if (!selected.includes(value)) onChange([...selected, value])
|
||||
setNewLabel('')
|
||||
} catch (e) {
|
||||
setError('Failed to add option.')
|
||||
setError(t('multi-checkbox.add_failed', 'Failed to add option.'))
|
||||
} finally {
|
||||
setAdding(false)
|
||||
}
|
||||
@@ -119,7 +129,7 @@ export const MultiCheckbox = (props: {
|
||||
{filteredEntries.map(([key, value]) => (
|
||||
<Checkbox
|
||||
key={key}
|
||||
label={translationPrefix ? t(`${translationPrefix}.${toKey(value)}`, key) : key}
|
||||
label={translateOption(key, value)}
|
||||
checked={selected.includes(value)}
|
||||
toggle={(checked: boolean) => {
|
||||
if (checked) {
|
||||
@@ -132,7 +142,9 @@ export const MultiCheckbox = (props: {
|
||||
))}
|
||||
</Row>
|
||||
{addOption && newLabel.trim() && filteredEntries.length === 0 && (
|
||||
<div className="px-2 text-sm text-ink-500">No matching options, feel free to add it.</div>
|
||||
<div className="px-2 text-sm text-ink-500">
|
||||
{t('multi-checkbox.no_matching_options', 'No matching options, feel free to add it.')}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -283,7 +283,11 @@
|
||||
"messages.toast.muting_forever.success": "Benachrichtigungen dauerhaft stummgeschaltet",
|
||||
"messages.toast.send_failed": "Senden der Nachricht fehlgeschlagen. Bitte versuchen Sie es später erneut oder kontaktieren Sie den Support, wenn das Problem weiterhin besteht.",
|
||||
"messages.you_prefix": "Sie: ",
|
||||
"multi-checkbox.enter_value": "Bitte geben Sie einen Wert ein.",
|
||||
"multi-checkbox.could_not_add": "Option konnte nicht hinzugefügt werden.",
|
||||
"multi-checkbox.add_failed": "Hinzufügen der Option fehlgeschlagen.",
|
||||
"multi-checkbox.search_or_add": "Suchen oder hinzufügen",
|
||||
"multi-checkbox.no_matching_options": "Keine passenden Optionen, Sie können gerne eine hinzufügen.",
|
||||
"nav.about": "Über uns",
|
||||
"nav.contact": "Kontakt",
|
||||
"nav.faq": "FAQ",
|
||||
@@ -734,6 +738,7 @@
|
||||
"register.error.all_fields_required": "Alle Felder sind erforderlich",
|
||||
"register.error.email_in_use": "Diese E-Mail ist bereits registriert",
|
||||
"register.error.unknown": "Registrierung fehlgeschlagen",
|
||||
"error.option_exists": "Diese Option existiert bereits",
|
||||
"register.get_started": "Loslegen",
|
||||
"register.link_signin": "Anmelden",
|
||||
"register.or_sign_up_with": "Oder registrieren mit",
|
||||
|
||||
@@ -283,7 +283,11 @@
|
||||
"messages.toast.muting_forever.success": "Notifs coupées définitivement",
|
||||
"messages.toast.send_failed": "Échec de l'envoi du message. Veuillez réessayer plus tard ou contacter le support si le problème persiste.",
|
||||
"messages.you_prefix": "Vous : ",
|
||||
"multi-checkbox.search_or_add": "Chercher ou ajouter",
|
||||
"multi-checkbox.enter_value": "Veuillez saisir une valeur.",
|
||||
"multi-checkbox.could_not_add": "Impossible d'ajouter l'option.",
|
||||
"multi-checkbox.add_failed": "Échec de l'ajout de l'option.",
|
||||
"multi-checkbox.search_or_add": "Rechercher ou ajouter",
|
||||
"multi-checkbox.no_matching_options": "Aucune option correspondante, n'hésitez pas à l'ajouter.",
|
||||
"nav.about": "À propos",
|
||||
"nav.contact": "Contact",
|
||||
"nav.faq": "FAQ",
|
||||
@@ -734,6 +738,7 @@
|
||||
"register.error.all_fields_required": "Tous les champs sont requis",
|
||||
"register.error.email_in_use": "Cet e‑mail est déjà enregistré",
|
||||
"register.error.unknown": "Échec de l'inscription",
|
||||
"error.option_exists": "Cette option existe déjà",
|
||||
"register.get_started": "Commencer",
|
||||
"register.link_signin": "Se connecter",
|
||||
"register.or_sign_up_with": "Ou inscrivez-vous avec",
|
||||
|
||||
Reference in New Issue
Block a user