Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,10 @@ export const SearchableSingleSelect = ({
>
{searchable && (
<div className={classes.searchField}>
<div className={classes.searchInput}>
<div
className={classes.searchInput}
id="single-select-search-input"
>
<Input
dense
initialFocus
Expand Down
5 changes: 4 additions & 1 deletion src/components/drawer/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ const DrawerContents = ({
delayInitialFocus: true,
allowOutsideClick: true,
clickOutsideDeactivates: () => {
return !!document.getElementById('expression-builder-modal')
return (
!!document.getElementById('expression-builder-modal') ||
!!document.getElementById('single-select-search-input')
)
},
}}
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/fields/date/DateFieldFF.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export function DateFieldFF({
format={'YYYY-MM-DD'}
onBlur={(_, e) => input.onBlur(e)}
clearable
label={required ? `${label} (required)` : label}
label={label}
{...resolvedValidation}
valid={resolvedValidation?.valid && input?.value !== ''}
{...calendarInputProps}
Expand Down
2 changes: 1 addition & 1 deletion src/components/form/fields/DateField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function DateField({
format={'YYYY-MM-DD'}
onBlur={(_, e) => input.onBlur(e)}
clearable
label={required ? `${label} (required)` : label}
label={label}
{...validation}
valid={validation?.valid && input?.value !== ''}
{...calendarInputProps}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ export function MessageTemplateField({
component={TextAreaFieldFF}
dataTest="formfields-message-template"
required
label={i18n.t('{{fieldLabel}} (required)', {
fieldLabel: i18n.t('Message'),
})}
label={i18n.t('Message')}
inputWidth="400px"
name="messageTemplate"
helpText={helpString}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/locales/form/CountryField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export function CountryField() {
<Field
name="country"
dataTest="formfields-country"
label={i18n.t('Country (required)')}
label={i18n.t('Country')}
required
error={touched && !!error}
validationText={(touched && error?.toString()) || ''}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/locales/form/LanguageField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function LanguageField() {
<Field
name="language"
dataTest="formfields-language"
label={i18n.t('Language (required)')}
label={i18n.t('Language')}
required
error={touched && !!error}
validationText={(touched && error?.toString()) || ''}
Expand Down
4 changes: 2 additions & 2 deletions src/pages/predictors/form/PredictorFormFields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ export const PredictorFormFields = () => {
<StandardFormField>
<NumberField
fieldName="sequentialSampleCount"
label={i18n.t('Sequential sample count (required)')}
label={i18n.t('Sequential sample count')}
required={true}
/>
</StandardFormField>
<StandardFormField>
<NumberField
fieldName="annualSampleCount"
label={i18n.t('Annual sample count (required)')}
label={i18n.t('Annual sample count')}
required={true}
/>
</StandardFormField>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,7 @@ export function ProgramRuleVariableNameField() {
dataTest="formfields-name"
required
inputWidth="400px"
label={i18n.t('{{fieldLabel}} (required)', {
fieldLabel: i18n.t('Name'),
})}
label={i18n.t('Name')}
helpText={i18n.t(
'Variable name cannot contain the words: and, or, not.'
)}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/programRuleVariables/fields/SourceTypeField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function SourceTypeField({

return (
<FieldGroup
label={i18n.t('Source type (required)')}
label={i18n.t('Source type')}
required
error={!!error}
validationText={error ? meta.error : undefined}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export const ProgramRuleVariableFormFields = () => {
inputWidth={FIELD_WIDTH}
dataTest="program-field"
name="program"
label={i18n.t('Program (required)')}
label={i18n.t('Program')}
query={{
resource: 'programs',
params: {
Expand Down
10 changes: 1 addition & 9 deletions src/pages/programRules/fields/ActionTextInputField.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import i18n from '@dhis2/d2-i18n'
import { Box, InputFieldFF } from '@dhis2/ui'
import React from 'react'
import { Field } from 'react-final-form'
Expand All @@ -19,14 +18,7 @@ export function ActionTextInputField({
<InputFieldFF
input={input}
meta={meta}
label={
required
? i18n.t('{{label}} (required)', {
label,
nsSeparator: '~:~',
})
: label
}
label={label}
required={required}
/>
</Box>
Expand Down
36 changes: 19 additions & 17 deletions src/pages/programRules/fields/DataElementField.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import i18n from '@dhis2/d2-i18n'
import { Box, Field as UIField } from '@dhis2/ui'
import { useQuery } from '@tanstack/react-query'
import React, { useMemo } from 'react'
import React, { useMemo, useState } from 'react'
import { Field, useFormState } from 'react-final-form'
import { useDebouncedCallback } from 'use-debounce'
import { BaseModelSingleSelect } from '../../../components/metadataFormControls/ModelSingleSelect/BaseModelSingleSelect'
import { useBoundResourceQueryFn } from '../../../lib'

Expand Down Expand Up @@ -31,6 +31,7 @@ export function DataElementField({
disableIfOtherFieldSet?: string
}>) {
const { values } = useFormState({ subscription: { values: true } })
const [filter, setFilter] = useState<string | undefined>(undefined)
const queryFn = useBoundResourceQueryFn()

const query = useMemo(
Expand All @@ -57,13 +58,24 @@ export function DataElementField({
(psde) => psde.dataElement
) ?? []
) ?? []
return [...new Map(list.map((de) => [de.id, de])).values()]
}, [data])
const allOptions = [...new Map(list.map((de) => [de.id, de])).values()]
return filter
? allOptions.filter((o) =>
o.displayName?.toLowerCase().includes(filter.toLowerCase())
)
: allOptions
}, [data, filter])

const disabled = disableIfOtherFieldSet
? !!values[disableIfOtherFieldSet]?.id
: false

const handleFilterChange = useDebouncedCallback(({ value }) => {
if (value != undefined) {
setFilter(value)
}
}, 250)

return (
<Field
name="dataElement"
Expand All @@ -72,14 +84,7 @@ export function DataElementField({
>
{({ input, meta }) => (
<UIField
label={
required
? i18n.t('{{label}} (required)', {
label,
nsSeparator: '~:~',
})
: label
}
label={label}
required={required}
disabled={disabled}
error={meta.invalid}
Expand All @@ -91,20 +96,17 @@ export function DataElementField({
<BaseModelSingleSelect
selected={input.value}
available={available}
clearable
onChange={(value) => {
input.onChange(value)
input.onBlur()
}}
showNoValueOption={{
value: '',
label: i18n.t('<No value>'),
}}
disabled={disabled}
invalid={meta.touched && !!meta.error}
onRetryClick={queryResult.refetch}
showEndLoader={false}
loading={queryResult.isLoading}
searchable={false}
onFilterChange={handleFilterChange}
/>
</Box>
</UIField>
Expand Down
28 changes: 19 additions & 9 deletions src/pages/programRules/fields/DataElementWithOptionSetField.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import i18n from '@dhis2/d2-i18n'
import { Box, Field as UIField } from '@dhis2/ui'
import { useQuery } from '@tanstack/react-query'
import React, { useMemo } from 'react'
import React, { useMemo, useState } from 'react'
import { Field, useForm, useFormState } from 'react-final-form'
import { useDebouncedCallback } from 'use-debounce'
import { BaseModelSingleSelect } from '../../../components/metadataFormControls/ModelSingleSelect/BaseModelSingleSelect'
import { useBoundResourceQueryFn, useClearFormFields } from '../../../lib'

Expand Down Expand Up @@ -31,6 +31,7 @@ export function DataElementWithOptionSetField({
label: string
}>) {
const form = useForm()
const [filter, setFilter] = useState<string | undefined>(undefined)
const clearDependentFields = useClearFormFields(
form,
'trackedEntityAttribute',
Expand Down Expand Up @@ -65,11 +66,23 @@ export function DataElementWithOptionSetField({
) ?? []
) ?? []
const withOptionSet = list.filter((de) => de.optionSet?.id)
return [...new Map(withOptionSet.map((de) => [de.id, de])).values()]
}, [data])
const allOptions = [
...new Map(withOptionSet.map((de) => [de.id, de])).values(),
]
return filter
? allOptions.filter((o) =>
o.displayName?.toLowerCase().includes(filter.toLowerCase())
)
: allOptions
}, [data, filter])

const formValues = values as { trackedEntityAttribute?: { id: string } }
const disabled = !!formValues.trackedEntityAttribute?.id
const handleFilterChange = useDebouncedCallback(({ value }) => {
if (value != undefined) {
setFilter(value)
}
}, 250)

return (
<Field
Expand Down Expand Up @@ -99,16 +112,13 @@ export function DataElementWithOptionSetField({
input.onChange(value)
input.onBlur()
}}
showNoValueOption={{
value: '',
label: i18n.t('<No value>'),
}}
clearable
disabled={disabled}
invalid={meta.touched && !!meta.error}
onRetryClick={queryResult.refetch}
showEndLoader={false}
loading={queryResult.isLoading}
searchable={false}
onFilterChange={handleFilterChange}
/>
</Box>
</UIField>
Expand Down
4 changes: 1 addition & 3 deletions src/pages/programRules/fields/ExpressionField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ export function ExpressionField({
<Box width="800px" minWidth="100px">
<PaddedContainer
title={
required
? i18n.t('Expression (required) *')
: i18n.t('Expression')
required ? i18n.t('Expression *') : i18n.t('Expression')
}
>
<ExpressionBuilderEntry
Expand Down
2 changes: 1 addition & 1 deletion src/pages/programRules/fields/LocationField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function LocationField({ required }: Readonly<{ required?: boolean }>) {

return (
<UIField
label={i18n.t('Display widget (required)')}
label={i18n.t('Display widget')}
required={required}
error={meta.invalid}
validationText={
Expand Down
7 changes: 2 additions & 5 deletions src/pages/programRules/fields/NotificationTemplateField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,7 @@ export function NotificationTemplateField({
content={i18n.t('Message template can not be edited after saving')}
>
<ModelSingleSelectField
label={
required
? i18n.t('Message template (required)')
: i18n.t('Message template')
}
label={i18n.t('Message template')}
required={required}
disabled={disabled}
query={{
Expand All @@ -64,6 +60,7 @@ export function NotificationTemplateField({
}}
input={input}
meta={meta}
searchable={false}
/>
</TooltipWrapper>
)
Expand Down
Loading
Loading