Skip to content

Commit

Permalink
EditDialog: add iD style FieldsEditor
Browse files Browse the repository at this point in the history
  • Loading branch information
zbycz committed Oct 17, 2024
1 parent 359cfa4 commit 826e992
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import { OsmUserLogged } from './OsmUserLogged';
import { ContributionInfoBox } from './ContributionInfoBox';
import { OsmUserLoggedOut } from './OsmUserLoggedOut';
import { PresetSelect } from './PresetSelect';
import { FieldsEditor } from './FieldsEditor';

export const EditContent = () => (
<>
<DialogContent dividers>
<form autoComplete="off" onSubmit={(e) => e.preventDefault()}>
<OsmUserLoggedOut />
<PresetSelect />
<MajorKeysEditor />
<FieldsEditor />
{/*<MajorKeysEditor />*/}
<OptionsEditor />
<ContributionInfoBox />
<CommentField />
Expand Down
177 changes: 177 additions & 0 deletions src/components/FeaturePanel/EditDialog/EditContent/FieldsEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import { useEditContext } from '../EditContext';
import { getFields } from '../../../../services/tagging/fields';
import { getFieldTranslation } from '../../../../services/tagging/translations';
import {
Button,
Checkbox,
FormControl,
InputLabel,
MenuItem,
Select,
Stack,
TextField,
Typography,
} from '@mui/material';
import React, { useState } from 'react';
import { FeatureTags } from '../../../../services/types';
import { Field } from '../../../../services/tagging/types/Fields';
import { t } from '../../../../services/intl';
import { allPresets } from '../../../../services/tagging/data';
import { Preset } from '../../../../services/tagging/types/Presets';
import styled from '@emotion/styled';
import { OpeningHoursEditor } from './OpeningHoursEditor/OpeningHoursEditor';

const StyledFormControl = styled(FormControl)`
margin-top: 16px;
margin-bottom: 8px;
`;

const getInitialActiveFields = (
fields: Field[],
tags: FeatureTags,
): Field[] => {
const activeFields = [];
fields.forEach((field: Field) => {
if (tags[field.key]) {
activeFields.push(field);
}
});

return activeFields;
};

const FieldsEditorInner = ({ preset }: { preset: Preset }) => {
const { tags, setTag } = useEditContext().tags;

const { fields, moreFields, universalFields } = getFields(preset); // TODO
const [activeFields, setActiveFields] = useState(() =>
getInitialActiveFields(fields, tags),
);
const inactiveFields = fields.filter(
({ fieldKey }) => !activeFields.some((f) => f.fieldKey === fieldKey),
);

return (
<>
{activeFields.map((field) => {
const fieldKey = field.fieldKey;
const fieldTranslation = getFieldTranslation(field);
const label = `${fieldTranslation?.label ?? `[${fieldKey}]`} – fieldkey:${fieldKey} – type:${field.type}`;
const k = field.key ?? field.keys?.[0];

console.log({ k, label, field, fieldTranslation });

if (fieldKey === 'opening_hours') {
return <OpeningHoursEditor key={fieldKey} />;
}

if (field.type === 'combo') {
return (
<StyledFormControl key={fieldKey} fullWidth>
<InputLabel shrink>{label}</InputLabel>
<Select
label={label}
value={tags[k]}
onChange={(e) => setTag(k, e.target.value)}
displayEmpty
variant="outlined"
>
{Object.entries(fieldTranslation.options ?? {}).map(
([key, value]) => (
<MenuItem key={key} value={key}>
{value}
</MenuItem>
),
)}
</Select>
</StyledFormControl>
);
}

if (field.type === 'semiCombo') {
const values = tags[k]?.split(';') ?? [];
return (
<StyledFormControl key={fieldKey} fullWidth>
<InputLabel shrink>{label}</InputLabel>
<Select
label={label}
multiple
value={values}
onChange={(e) => setTag(k, e.target.value.join(';'))}
renderValue={(selected) => selected.join(';')}
displayEmpty
fullWidth
variant="outlined"
>
{field.options?.map((option) => (
<MenuItem key={option} value={option}>
<Checkbox checked={values.includes(option)} />
{option}
</MenuItem>
))}
</Select>
</StyledFormControl>
);
}

return (
<div key={fieldKey}>
<TextField
label={label}
value={tags[k]}
InputLabelProps={{ shrink: true }}
variant="outlined"
margin="normal"
name={k}
onChange={(e) => setTag(e.target.name, e.target.value)}
fullWidth
// autoFocus={focusTag === k}
/>
</div>
);
})}

{!!inactiveFields.length && (
<>
<Typography variant="body1" component="span" color="textSecondary">
{t('editdialog.add_major_tag')}:
</Typography>
{inactiveFields.map((field) => {
const fieldTranslation = getFieldTranslation(field);
const label = fieldTranslation?.label ?? `[${field.fieldKey}]`;

return (
<React.Fragment key={field.fieldKey}>
{' '}
<Button
size="small"
onClick={() => setActiveFields((arr) => [...arr, field])}
>
{label}
</Button>
</React.Fragment>
);
})}
</>
)}
<br />
<br />
</>
);
};

export const FieldsEditor = () => {
const { presetKey } = useEditContext();

// TODO remove condition
if (!presetKey) {
return null;
}

const preset = allPresets[presetKey];
if (!preset) {
return null;
}

return <FieldsEditorInner preset={preset} />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const LabelWrapper = styled.div`
const useMatchTags = (
feature: Feature,
tags: FeatureTags,
setPreset: Setter<string>,
setPresetKey: Setter<string>,
) => {
useEffect(() => {
(async () => {
Expand All @@ -76,9 +76,9 @@ const useMatchTags = (
const translatedPreset = (await getTranslatedPresets()).find(
(option) => option.presetKey === foundPreset.presetKey,
);
setPreset(translatedPreset?.presetKey ?? '');
setPresetKey(translatedPreset?.presetKey ?? '');
})();
}, [tags, feature, setPreset]);
}, [tags, feature, setPresetKey]);
};

const useOptions = () => {
Expand All @@ -90,11 +90,14 @@ const useOptions = () => {
};

export const PresetSelect = () => {
const { tags } = useEditContext().tags;
const [preset, setPreset] = useState('');
const {
tags: { tags },
presetKey,
setPresetKey,
} = useEditContext();
const { feature } = useFeatureContext();
const options = useOptions();
useMatchTags(feature, tags, setPreset);
useMatchTags(feature, tags, setPresetKey);

if (options.length === 0) {
return null;
Expand All @@ -108,7 +111,11 @@ export const PresetSelect = () => {
</Typography>
</LabelWrapper>

<PresetSearchBox value={preset} setValue={setPreset} options={options} />
<PresetSearchBox
value={presetKey}
setValue={setPresetKey}
options={options}
/>
</Row>
);
};
5 changes: 5 additions & 0 deletions src/components/FeaturePanel/EditDialog/EditContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ type EditContextType = {
setLocation: (s: string) => void;
comment: string;
setComment: (s: string) => void;
presetKey: string;
setPresetKey: Setter<string>;
tags: {
tagsEntries: TagsEntries;
setTagsEntries: Setter<TagsEntries>;
Expand Down Expand Up @@ -65,6 +67,7 @@ export const EditContextProvider = ({ feature, children }: Props) => {
const [location, setLocation] = useState('');
const [comment, setComment] = useState('');
const tags = useTagsState(feature.tags);
const [presetKey, setPresetKey] = useState(''); // only cache, real data in tags

const value: EditContextType = {
successInfo,
Expand All @@ -75,6 +78,8 @@ export const EditContextProvider = ({ feature, children }: Props) => {
setLocation,
comment,
setComment,
presetKey,
setPresetKey,
tags,
};

Expand Down

0 comments on commit 826e992

Please sign in to comment.