Skip to content

Commit

Permalink
Merge pull request #41 from FAIMS/layout-of-fields-in-design-panel
Browse files Browse the repository at this point in the history
Improve layout of fields
  • Loading branch information
stevecassidy authored Dec 21, 2023
2 parents f5c1fdc + 8a18ac0 commit 18ee77b
Show file tree
Hide file tree
Showing 12 changed files with 571 additions and 524 deletions.
142 changes: 73 additions & 69 deletions src/components/Fields/BaseFieldEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,84 +97,88 @@ export const BaseFieldEditor = ({ fieldName, children }: Props) => {
return (
<Grid container spacing={2}>
<Grid item xs={12}>
<Card variant="outlined" sx={{ display: 'flex' }}>
<Grid item sm={6} xs={12} sx={{ mx: 1.5, my: 2 }}>
<TextField
name="label"
variant="outlined"
label="Label"
value={state.label}
onChange={(e) => updateProperty('label', e.target.value)}
helperText="Enter a label for the field."
/>
</Grid>

<Grid item sm={6} xs={12} sx={{ mx: 1.5, my: 2 }}>
<TextField
name="helperText"
variant="outlined"
label="Helper Text"
fullWidth
multiline={true}
rows={4}
value={state.helperText}
helperText="Help text shown along with the field (like this text)."
onChange={(e) => updateProperty('helperText', e.target.value)}
/>
</Grid>
</Card>
</Grid>

{children}

<Grid item xs={12}>
<Card variant="outlined" sx={{ display: 'flex ' }}>
<Grid item sm={4} sx={{ mx: 1.5, my: 2 }}>
<FormControlLabel required
control={<Checkbox
checked={state.required}
onChange={(e) => updateProperty('required', e.target.checked)}
/>} label="Required" />
</Grid>

<Grid item sm={4} sx={{ mx: 1.5, my: 2 }} container direction="column">
<FormControlLabel required
control={<Checkbox
checked={state.annotation}
onChange={(e) => updateProperty('annotation', e.target.checked)}
/>} label="Enable Annotation" />

{state.annotation &&
<Card variant="outlined">
<Grid container p={2} rowSpacing={3}>
<Grid item sm={6} xs={12} >
<TextField
name="label"
variant="outlined"
label="Label"
value={state.annotationLabel}
onChange={(e) => updateProperty('annotationLabel', e.target.value)}
helperText="Enter a label."
sx={{ mt: 1.5 }}
value={state.label}
onChange={(e) => updateProperty('label', e.target.value)}
helperText="Enter a label for the field."
/>
}
</Grid>

<Grid item sm={4} sx={{ mx: 1.5, my: 2 }} container direction="column">
<FormControlLabel required
control={<Checkbox
checked={state.uncertainty}
onChange={(e) => updateProperty('uncertainty', e.target.checked)}
/>} label="Enable Uncertainty" />
</Grid>

{state.uncertainty &&
<Grid item sm={6} xs={12} >
<TextField
name="label"
name="helperText"
variant="outlined"
label="Label"
value={state.uncertaintyLabel}
onChange={(e) => updateProperty('uncertaintyLabel', e.target.value)}
helperText="Enter a label."
sx={{ mt: 1.5 }}
label="Helper Text"
fullWidth
multiline={true}
rows={4}
value={state.helperText}
helperText="Help text shown along with the field (like this text)."
onChange={(e) => updateProperty('helperText', e.target.value)}
/>
}
</Grid>
</Grid>
</Card>
</Grid>

{children}

<Grid item xs={12}>
<Card variant="outlined">
<Grid container p={2} columnSpacing={1} rowSpacing={1}>
<Grid item xs={12} sm={4}>
<FormControlLabel required
control={<Checkbox
checked={state.required}
onChange={(e) => updateProperty('required', e.target.checked)}
/>} label="Required" />
</Grid>

<Grid item xs={12} sm={4} container direction="column" pr={1}>
<FormControlLabel required
control={<Checkbox
checked={state.annotation}
onChange={(e) => updateProperty('annotation', e.target.checked)}
/>} label="Enable Annotation" />

{state.annotation &&
<TextField
name="label"
variant="outlined"
label="Label"
value={state.annotationLabel}
onChange={(e) => updateProperty('annotationLabel', e.target.value)}
helperText="Enter a label."
sx={{ mt: 1.5 }}
/>
}
</Grid>

<Grid item xs={12} sm={4} container direction="column">
<FormControlLabel required
control={<Checkbox
checked={state.uncertainty}
onChange={(e) => updateProperty('uncertainty', e.target.checked)}
/>} label="Enable Uncertainty" />

{state.uncertainty &&
<TextField
name="label"
variant="outlined"
label="Label"
value={state.uncertaintyLabel}
onChange={(e) => updateProperty('uncertaintyLabel', e.target.value)}
helperText="Enter a label."
sx={{ mt: 1.5 }}
/>
}
</Grid>
</Grid>
</Card>
</Grid>
Expand Down
54 changes: 28 additions & 26 deletions src/components/Fields/MapFormFieldEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { useAppSelector, useAppDispatch } from "../../state/hooks";
import { BaseFieldEditor } from "./BaseFieldEditor";
import { FieldType, Notebook } from "../../state/initial";

export const MapFormFieldEditor = ({ fieldName }: {fieldName: string}) => {
export const MapFormFieldEditor = ({ fieldName }: { fieldName: string }) => {

const field = useAppSelector((state: Notebook) => state['ui-specification'].fields[fieldName]);
const dispatch = useAppDispatch();
Expand Down Expand Up @@ -55,31 +55,33 @@ export const MapFormFieldEditor = ({ fieldName }: {fieldName: string}) => {
<BaseFieldEditor fieldName={fieldName}>
<Grid item xs={12}>
<Card variant="outlined" sx={{ display: 'flex' }}>
<Grid item sm={6} xs={12} sx={{ mx: 1.5, my: 2 }}>
<TextField
variant="outlined"
label="Zoom Level"
type="number"
value={initZoom}
inputProps={{ min: 0 }}
onChange={(e) => updateProperty('zoom', parseFloat(e.target.value))}
/>
</Grid>
<Grid item sm={6} xs={12} sx={{ mx: 1.5, my: 2 }}>
<FormControl sx={{ minWidth: 150 }}>
<InputLabel id="featureType-label">Select Feature Type</InputLabel>
<Select
labelId="featureType-label"
label="Select Feature Type"
value={initFeatureType}
onChange={(e) => updateProperty('featureType', e.target.value)}
required
>
<MenuItem value="Polygon">Polygon</MenuItem>
<MenuItem value="Point">Point</MenuItem>
<MenuItem value="LineString">LineString</MenuItem>
</Select>
</FormControl>
<Grid container p={2} rowGap={2}>
<Grid item sm={6} xs={12}>
<TextField
variant="outlined"
label="Zoom Level"
type="number"
value={initZoom}
inputProps={{ min: 0 }}
onChange={(e) => updateProperty('zoom', parseFloat(e.target.value))}
/>
</Grid>
<Grid item sm={6} xs={12}>
<FormControl sx={{ minWidth: 150 }}>
<InputLabel id="featureType-label">Select Feature Type</InputLabel>
<Select
labelId="featureType-label"
label="Select Feature Type"
value={initFeatureType}
onChange={(e) => updateProperty('featureType', e.target.value)}
required
>
<MenuItem value="Polygon">Polygon</MenuItem>
<MenuItem value="Point">Point</MenuItem>
<MenuItem value="LineString">LineString</MenuItem>
</Select>
</FormControl>
</Grid>
</Grid>
</Card>
</Grid>
Expand Down
121 changes: 62 additions & 59 deletions src/components/Fields/OptionsEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { useAppSelector, useAppDispatch } from "../../state/hooks";
import { useState } from "react";
import { FieldType, Notebook } from "../../state/initial";

export const OptionsEditor = ({ fieldName }: {fieldName: string}) => {
export const OptionsEditor = ({ fieldName }: { fieldName: string }) => {

const field = useAppSelector((state: Notebook) => state['ui-specification'].fields[fieldName])
const dispatch = useAppDispatch()
Expand All @@ -34,7 +34,7 @@ export const OptionsEditor = ({ fieldName }: {fieldName: string}) => {
if (field['component-parameters'].ElementProps) {
options = field['component-parameters'].ElementProps.options;
if (options)
options = options.map((pair) => pair.label.trim())
options = options.map((pair) => pair.label.trim())
} else {
field['component-parameters'].ElementProps = { options: [] }
}
Expand All @@ -51,30 +51,31 @@ export const OptionsEditor = ({ fieldName }: {fieldName: string}) => {
const newField = JSON.parse(JSON.stringify(field)) as FieldType;
newField['component-parameters'].ElementProps = {
options: updatedOptions.map((o, index) => {
if (fieldName.includes('radio')) {
return {
RadioProps: {
id: 'radio-group-field-' + index
},
label: o,
value: o,
if (fieldName.includes('radio')) {
return {
RadioProps: {
id: 'radio-group-field-' + index
},
label: o,
value: o,
}
}
}
else {
return {
label: o,
value: o
else {
return {
label: o,
value: o
}
}
}

})};
})
};

dispatch({ type: 'ui-specification/fieldUpdated', payload: { fieldName, newField } })
}

const addOption = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()

const emptyOption: boolean = newOption.trim().length == 0
const duplicateOption: boolean = options.some((element: string) => {
// Making sure duplicate check is case insensitive.
Expand Down Expand Up @@ -106,49 +107,51 @@ export const OptionsEditor = ({ fieldName }: {fieldName: string}) => {
return (
<BaseFieldEditor fieldName={fieldName}>
<Grid item xs={12}>
<Card variant="outlined" sx={{ display: 'flex' }}>
<Grid item xs={6} sx={{ m: 1.5 }}>
<Alert severity="info">Add and remove options as needed.</Alert>
<form onSubmit={addOption}>
<Grid item alignItems="stretch" style={{ display: "flex" }}>
<TextField
label="Add Option"
value={newOption}
onChange={(e) => setNewOption(e.target.value)}
sx={{ my: 1.5 }} />
<Button
color="primary"
startIcon={<AddCircleIcon />}
variant="outlined"
type="submit"
sx={{ my: 1.5 }}
>
ADD{' '}
</Button>
</Grid>
</form>
{errorMessage && <Alert severity="error">{errorMessage}</Alert>}
</Grid>
<Grid item xs={6} sx={{ m: 1.5 }}>
<List>
{options.map((option: string) => {
return (
<ListItem
key={option}
secondaryAction={
<IconButton
edge="end"
aria-label="delete"
onClick={() => removeOption(option)}>
<DeleteIcon />
</IconButton>
}
<Card variant="outlined">
<Grid container p={2}>
<Grid item xs={12} sm={6}>
<Alert severity="info">Add and remove options as needed.</Alert>
<form onSubmit={addOption}>
<Grid item alignItems="stretch" style={{ display: "flex" }}>
<TextField
label="Add Option"
value={newOption}
onChange={(e) => setNewOption(e.target.value)}
sx={{ my: 1.5 }} />
<Button
color="primary"
startIcon={<AddCircleIcon />}
variant="outlined"
type="submit"
sx={{ my: 1.5 }}
>
<ListItemText primary={option} />
</ListItem>
)
})}
</List>
ADD{' '}
</Button>
</Grid>
</form>
{errorMessage && <Alert severity="error">{errorMessage}</Alert>}
</Grid>
<Grid item xs={12} sm={6}>
<List>
{options.map((option: string) => {
return (
<ListItem
key={option}
secondaryAction={
<IconButton
edge="end"
aria-label="delete"
onClick={() => removeOption(option)}>
<DeleteIcon />
</IconButton>
}
>
<ListItemText primary={option} />
</ListItem>
)
})}
</List>
</Grid>
</Grid>
</Card>
</Grid>
Expand Down
Loading

0 comments on commit 18ee77b

Please sign in to comment.