diff options
Diffstat (limited to 'client/js')
-rw-r--r-- | client/js/app/src/app/pages/querybuilder/query-filters/QueryInput.jsx | 85 | ||||
-rw-r--r-- | client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx | 135 |
2 files changed, 128 insertions, 92 deletions
diff --git a/client/js/app/src/app/pages/querybuilder/query-filters/QueryInput.jsx b/client/js/app/src/app/pages/querybuilder/query-filters/QueryInput.jsx deleted file mode 100644 index 9a44d26ed49..00000000000 --- a/client/js/app/src/app/pages/querybuilder/query-filters/QueryInput.jsx +++ /dev/null @@ -1,85 +0,0 @@ -import React from 'react'; -import { Select, TextInput, ActionIcon, Button } from '@mantine/core'; -import { - ACTION, - dispatch, - useQueryBuilderContext, -} from 'app/pages/querybuilder/context/query-builder-provider'; -import { Container, Icon } from 'app/components'; - -export default function QueryInput() { - const { children, type } = useQueryBuilderContext('query'); - return <Inputs type={type.children} inputs={children} />; -} - -function Inputs({ id, type, inputs }) { - const usedTypes = inputs.map(({ type }) => type.name); - const remainingTypes = Object.fromEntries( - Object.entries(type).filter(([name]) => !usedTypes.includes(name)) - ); - const firstRemaining = Object.keys(remainingTypes)[0]; - return ( - <Container sx={{ backgroundColor: 'gold', rowGap: '5px' }}> - {inputs.map(({ id, input, type, children }) => ( - <Input - key={id} - types={remainingTypes} - {...{ id, input, type, children }} - /> - ))} - {firstRemaining && ( - <Button - leftIcon={<Icon name="plus" />} - onClick={() => - dispatch(ACTION.INPUT_ADD, { id, type: firstRemaining }) - } - > - Add property - </Button> - )} - </Container> - ); -} - -function Input({ id, input, types, type, children }) { - const options = { [type.name]: type, ...types }; - return ( - <> - <Container sx={{ display: 'flex' }}> - <Select - sx={{ flex: 1 }} - data={Object.values(options).map(({ name }) => name)} - onChange={(value) => - dispatch(ACTION.INPUT_UPDATE, { - id, - type: types[value], - }) - } - value={type.name} - searchable - /> - {!children && ( - <TextInput - sx={{ flex: 1 }} - onChange={(event) => - dispatch(ACTION.INPUT_UPDATE, { - id, - input: event.currentTarget.value, - }) - } - placeholder={type.type} - value={input} - /> - )} - <ActionIcon onClick={() => dispatch(ACTION.INPUT_REMOVE, id)}> - <Icon name="circle-minus" /> - </ActionIcon> - </Container> - {children && ( - <div style={{ marginLeft: '10%' }}> - <Inputs id={id} type={type.children} inputs={children} /> - </div> - )} - </> - ); -} diff --git a/client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx b/client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx index 0ad1eba7a16..19f3a728387 100644 --- a/client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx +++ b/client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx @@ -1,13 +1,134 @@ import React from 'react'; -import QueryInput from 'app/pages/querybuilder/query-filters/QueryInput'; -import PasteJSONButton from 'app/pages/querybuilder/query-filters/PasteJSONButton'; -import { Container } from 'app/components'; +import { + Select, + TextInput, + ActionIcon, + Button, + Box, + Stack, + Badge, +} from '@mantine/core'; +import { Container, Content, Icon } from 'app/components'; +import { + ACTION, + dispatch, + useQueryBuilderContext, +} from 'app/pages/querybuilder/context/query-builder-provider'; +import { SHADE } from 'app/styles/theme/colors'; -export function QueryFilters() { +function AddProperty(props) { + return ( + <Button leftIcon={<Icon name="plus" />} {...props}> + Add property + </Button> + ); +} + +function Input({ id, input, types, type, children }) { + const options = { [type.name]: type, ...types }; return ( - <Container sx={{ alignContent: 'start' }}> - <QueryInput /> - <PasteJSONButton /> + <> + <Box sx={{ display: 'flex', alignItems: 'center', gap: '5px' }}> + <Select + sx={{ flex: 1 }} + data={Object.values(options).map(({ name }) => name)} + onChange={(value) => + dispatch(ACTION.INPUT_UPDATE, { + id, + type: types[value], + }) + } + value={type.name} + searchable + /> + {!children && ( + <TextInput + sx={{ flex: 1 }} + onChange={(event) => + dispatch(ACTION.INPUT_UPDATE, { + id, + input: event.currentTarget.value, + }) + } + placeholder={type.type} + value={input} + /> + )} + <ActionIcon onClick={() => dispatch(ACTION.INPUT_REMOVE, id)}> + <Icon name="circle-minus" /> + </ActionIcon> + </Box> + {children && ( + <Box + py={8} + sx={(theme) => ({ + borderLeft: `1px dashed ${theme.fn.themeColor( + 'gray', + SHADE.UI_ELEMENT_BORDER_AND_FOCUS + )}`, + marginLeft: '13px', + paddingLeft: '13px', + })} + > + <Inputs id={id} type={type.children} inputs={children} /> + </Box> + )} + </> + ); +} + +function Inputs({ id, type, inputs }) { + const usedTypes = inputs.map(({ type }) => type.name); + const remainingTypes = Object.fromEntries( + Object.entries(type).filter(([name]) => !usedTypes.includes(name)) + ); + const firstRemaining = Object.keys(remainingTypes)[0]; + return ( + <Container sx={{ rowGap: '5px' }}> + {inputs.map(({ id, input, type, children }) => ( + <Input + key={id} + types={remainingTypes} + {...{ id, input, type, children }} + /> + ))} + {firstRemaining && ( + <> + {id != null ? ( + <Container sx={{ justifyContent: 'start' }}> + <AddProperty + onClick={() => + dispatch(ACTION.INPUT_ADD, { id, type: firstRemaining }) + } + variant="subtle" + size="xs" + compact + /> + </Container> + ) : ( + <AddProperty + onClick={() => + dispatch(ACTION.INPUT_ADD, { id, type: firstRemaining }) + } + mt={13} + /> + )} + </> + )} </Container> ); } + +export function QueryFilters() { + const { children, type } = useQueryBuilderContext('query'); + return ( + <Stack align="flex-start"> + <Badge variant="filled">Query filters</Badge> + <Container sx={{ alignContent: 'start' }}> + <Content> + <Inputs type={type.children} inputs={children} /> + </Content> + </Container> + </Stack> + ); +} |