Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
@@ -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({
Comment thread
CarolineDenis marked this conversation as resolved.
type,
Expand All @@ -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}
<div>
<Select
disabled={handleChange === undefined}
value={formatter}
onValueChange={handleChange}
>
<option />
{availableFormatters.map(({ name, title }, index) => (
<option key={index} value={name}>
{title}
</option>
))}
</Select>
</div>
<Button.Small
Comment thread
CarolineDenis marked this conversation as resolved.
aria-controls={id('list')}
aria-label={queryText.chooseFormatter()}
className={`${
availableFormatters.find((selected) => 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}
</Button.Small>
{formatterSelectIsOpen && (
Comment thread
CarolineDenis marked this conversation as resolved.
<div>
<Select
Comment thread
CarolineDenis marked this conversation as resolved.
aria-label={queryText.chooseFormatter()}
className={`${customSelectElementBackground}`}
Comment thread
CarolineDenis marked this conversation as resolved.
disabled={handleChange === undefined}
id={id('list')}
value={formatter}
onValueChange={handleChange}
>
<option />
Comment thread
CarolineDenis marked this conversation as resolved.
{availableFormatters.map(({ name, title, isDefault }, index) => (
<option key={index} value={name}>
{title} {isDefault ? resourcesText.defaultInline() : ''}
Comment thread
CarolineDenis marked this conversation as resolved.
</option>
))}
</Select>
</div>
)}
</>
) : null;
}
19 changes: 19 additions & 0 deletions specifyweb/frontend/js_src/lib/components/QueryBuilder/Line.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -372,6 +373,24 @@ export function QueryLine({
mappingElementDivider
)
)}
{(fieldMeta.fieldType === 'formatter' ||
fieldMeta.fieldType === 'aggregator') &&
typeof fieldMeta.tableName === 'string' ? (
Comment thread
CarolineDenis marked this conversation as resolved.
<QueryFieldFormatter
formatter={field.dataObjFormatter}
tableName={fieldMeta.tableName}
type={fieldMeta.fieldType}
onChange={
handleChange === undefined
? undefined
: (dataObjectFormatter): void =>
handleChange({
...field,
dataObjFormatter: dataObjectFormatter,
})
}
/>
) : undefined}
</div>
{filtersVisible ? (
<div
Expand Down
3 changes: 3 additions & 0 deletions specifyweb/frontend/js_src/lib/localization/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -886,4 +886,7 @@ export const queryText = createDictionary({
'ru-ru': 'Просмотр записей',
'uk-ua': 'Переглянути записи',
},
chooseFormatter: {
'en-us': 'Choose formatter',
},
} as const);