diff --git a/specifyweb/frontend/js_src/lib/components/QueryBuilder/Formatter.tsx b/specifyweb/frontend/js_src/lib/components/QueryBuilder/Formatter.tsx index 3e45ec9e844..606b6061823 100644 --- a/specifyweb/frontend/js_src/lib/components/QueryBuilder/Formatter.tsx +++ b/specifyweb/frontend/js_src/lib/components/QueryBuilder/Formatter.tsx @@ -1,11 +1,16 @@ import React from 'react'; import { usePromise } from '../../hooks/useAsyncState'; +import { useId } from '../../hooks/useId'; import { commonText } from '../../localization/common'; +import { queryText } from '../../localization/query'; +import { resourcesText } from '../../localization/resources'; +import { Button } from '../Atoms/Button'; import { Select } from '../Atoms/Form'; +import { icons } from '../Atoms/Icons'; import type { Tables } from '../DataModel/types'; import { fetchFormatters } from '../Formatters/formatters'; -import { mappingElementDivider } from '../WbPlanView/LineComponents'; +import { customSelectElementBackground } from '../WbPlanView/CustomSelectElement'; export function QueryFieldFormatter({ type, @@ -23,42 +28,73 @@ export function QueryFieldFormatter({ () => // Some code duplication, but required by TypeScript (type === 'formatter' - ? formatters?.formatters.map(({ table, name, title }) => ({ + ? formatters?.formatters.map(({ table, name, title, isDefault }) => ({ table, name, title, + isDefault, })) - : formatters?.aggregators.map(({ table, name, title }) => ({ + : formatters?.aggregators.map(({ table, name, title, isDefault }) => ({ table, name, title, + isDefault, })) ) ?.filter(({ table }) => table?.name === tableName) - .map(({ name, title = name }) => ({ name, title })), + .map(({ name, title = name, isDefault }) => ({ + name, + title, + isDefault, + })), [type, formatters, tableName] ); + + const [formatterSelectIsOpen, setFormatterSelect] = React.useState(false); + + const id = useId('formatters-selection'); + return availableFormatters === undefined ? ( typeof formatter === 'string' ? ( <>{commonText.loading()} ) : null ) : availableFormatters.length > 1 ? ( <> - {mappingElementDivider} -
- -
+ selected.name === formatter) + ?.isDefault || + formatter === undefined || + formatter === '' + ? 'bg-white dark:bg-neutral-600' + : 'bg-yellow-250 dark:bg-yellow-900 ' + }`} + title={queryText.chooseFormatter()} + onClick={() => setFormatterSelect(!formatterSelectIsOpen)} + > + {icons.cog} + + {formatterSelectIsOpen && ( +
+ +
+ )} ) : null; } diff --git a/specifyweb/frontend/js_src/lib/components/QueryBuilder/Line.tsx b/specifyweb/frontend/js_src/lib/components/QueryBuilder/Line.tsx index 13110bbd62b..8964345844e 100644 --- a/specifyweb/frontend/js_src/lib/components/QueryBuilder/Line.tsx +++ b/specifyweb/frontend/js_src/lib/components/QueryBuilder/Line.tsx @@ -47,6 +47,7 @@ import { } from './FieldFilter'; import type { DatePart } from './fieldSpec'; import { QueryFieldSpec } from './fieldSpec'; +import { QueryFieldFormatter } from './Formatter'; import type { QueryField } from './helpers'; import { QueryLineTools } from './QueryLineTools'; @@ -372,6 +373,24 @@ export function QueryLine({ mappingElementDivider ) )} + {(fieldMeta.fieldType === 'formatter' || + fieldMeta.fieldType === 'aggregator') && + typeof fieldMeta.tableName === 'string' ? ( + + handleChange({ + ...field, + dataObjFormatter: dataObjectFormatter, + }) + } + /> + ) : undefined} {filtersVisible ? (