From f557dd0f392cf6cafbab0a199f7d1c138a1c6ff1 Mon Sep 17 00:00:00 2001 From: Jan-Gerke Salomon Date: Wed, 4 Oct 2023 12:57:19 +0200 Subject: [PATCH] fix(searchable single selects): add posibility to deselect --- .../CategoryComboSelect.tsx | 15 ++++++------ .../CategoryComboSelect/useOptionsQuery.ts | 6 ++++- .../ModelSingleSelect/ModelSingleSelect.tsx | 23 ++++++++++++------- .../ModelSingleSelect/index.ts | 2 +- .../OptionSetSelect/OptionSetSelect.tsx | 15 ++++++------ src/pages/dataElements/New.tsx | 1 - .../dataElements/form/CustomAttributes.tsx | 5 ++-- src/pages/dataElements/form/customFields.tsx | 1 + 8 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/components/metadataFormControls/CategoryComboSelect/CategoryComboSelect.tsx b/src/components/metadataFormControls/CategoryComboSelect/CategoryComboSelect.tsx index c2d1a050..869f7e2a 100644 --- a/src/components/metadataFormControls/CategoryComboSelect/CategoryComboSelect.tsx +++ b/src/components/metadataFormControls/CategoryComboSelect/CategoryComboSelect.tsx @@ -1,22 +1,20 @@ import i18n from '@dhis2/d2-i18n' import React, { forwardRef } from 'react' import { ModelSingleSelect } from '../ModelSingleSelect' +import type { ModelSingleSelectProps } from '../ModelSingleSelect' import { useInitialOptionQuery } from './useInitialOptionQuery' import { useOptionsQuery } from './useOptionsQuery' -interface CategoryComboSelectProps { - onChange: ({ selected }: { selected: string }) => void - placeholder?: string - selected?: string - showAllOption?: boolean - onBlur?: () => void - onFocus?: () => void -} +type CategoryComboSelectProps = Omit< + ModelSingleSelectProps, + 'useInitialOptionQuery' | 'useOptionsQuery' +> export const CategoryComboSelect = forwardRef(function CategoryComboSelect( { onChange, placeholder = i18n.t('Category combo'), + required, selected, showAllOption, onBlur, @@ -27,6 +25,7 @@ export const CategoryComboSelect = forwardRef(function CategoryComboSelect( return ( value === selected ) - if (selectedOption && !optionsContainSelected) { - return [...options, selectedOption] + const withSelectedOption = + selectedOption && !optionsContainSelected + ? [...options, selectedOption] + : options + + if (!required) { + return [{ value: '', label: i18n.t('None') }, ...withSelectedOption] } - return options + return withSelectedOption } type UseInitialOptionQuery = ({ @@ -44,8 +52,9 @@ type UseInitialOptionQuery = ({ selected?: string }) => QueryResponse -interface ModelSingleSelectProps { +export interface ModelSingleSelectProps { onChange: ({ selected }: { selected: string }) => void + required?: boolean placeholder?: string selected?: string showAllOption?: boolean @@ -55,14 +64,11 @@ interface ModelSingleSelectProps { useOptionsQuery: () => QueryResponse } -export interface ModelSingleSelectHandle { - refetch: () => void -} - export const ModelSingleSelect = forwardRef(function ModelSingleSelect( { onChange, placeholder = '', + required, selected, showAllOption, onBlur, @@ -134,6 +140,7 @@ export const ModelSingleSelect = forwardRef(function ModelSingleSelect( const displayOptions = computeDisplayOptions({ selected, selectedOption, + required, options: result, }) diff --git a/src/components/metadataFormControls/ModelSingleSelect/index.ts b/src/components/metadataFormControls/ModelSingleSelect/index.ts index 077b733f..d5dbc231 100644 --- a/src/components/metadataFormControls/ModelSingleSelect/index.ts +++ b/src/components/metadataFormControls/ModelSingleSelect/index.ts @@ -1 +1 @@ -export { ModelSingleSelect } from './ModelSingleSelect' +export * from './ModelSingleSelect' diff --git a/src/components/metadataFormControls/OptionSetSelect/OptionSetSelect.tsx b/src/components/metadataFormControls/OptionSetSelect/OptionSetSelect.tsx index a84bc158..4adbd951 100644 --- a/src/components/metadataFormControls/OptionSetSelect/OptionSetSelect.tsx +++ b/src/components/metadataFormControls/OptionSetSelect/OptionSetSelect.tsx @@ -1,22 +1,20 @@ import i18n from '@dhis2/d2-i18n' import React, { forwardRef } from 'react' import { ModelSingleSelect } from '../ModelSingleSelect' +import type { ModelSingleSelectProps } from '../ModelSingleSelect' import { useInitialOptionQuery } from './useInitialOptionQuery' import { useOptionsQuery } from './useOptionsQuery' -interface OptionSetSelectProps { - onChange: ({ selected }: { selected: string }) => void - placeholder?: string - selected?: string - showAllOption?: boolean - onBlur?: () => void - onFocus?: () => void -} +type OptionSetSelectProps = Omit< + ModelSingleSelectProps, + 'useInitialOptionQuery' | 'useOptionsQuery' +> export const OptionSetSelect = forwardRef(function OptionSetSelect( { onChange, placeholder = i18n.t('Option set'), + required, selected, showAllOption, onBlur, @@ -27,6 +25,7 @@ export const OptionSetSelect = forwardRef(function OptionSetSelect( return ( { variables: payload, }) } catch (e) { - console.log('> e', e) return { [FORM_ERROR]: (e as Error | string).toString() } } diff --git a/src/pages/dataElements/form/CustomAttributes.tsx b/src/pages/dataElements/form/CustomAttributes.tsx index 2eaf1bd9..ce0b0326 100644 --- a/src/pages/dataElements/form/CustomAttributes.tsx +++ b/src/pages/dataElements/form/CustomAttributes.tsx @@ -64,9 +64,8 @@ function CustomAttribute({ attribute, index }: CustomAttributeProps) { ) } - throw new Error( - `@TODO(CustomAttributes): Implement value type "${attribute.valueType}"!` - ) + // @TODO: Verify that all value types have been covered! + throw new Error(`Implement value type "${attribute.valueType}"!`) } export function CustomAttributes({ diff --git a/src/pages/dataElements/form/customFields.tsx b/src/pages/dataElements/form/customFields.tsx index 757850e2..2bce4ada 100644 --- a/src/pages/dataElements/form/customFields.tsx +++ b/src/pages/dataElements/form/customFields.tsx @@ -251,6 +251,7 @@ export function CategoryComboField() { validationText={meta.error} >