Skip to content

Commit

Permalink
EditDialog: use getFullFeatureWithMemberFeatures in MembersEditor and…
Browse files Browse the repository at this point in the history
… ParentsEditor
  • Loading branch information
zbycz committed Jan 7, 2025
1 parent 1b667fa commit f5a8f4a
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,46 @@ import { PresetSelect } from './PresetSelect';
import { MajorKeysEditor } from './MajorKeysEditor';
import { TagsEditor } from './TagsEditor/TagsEditor';
import React from 'react';
import { SingleFeatureEditContextProvider } from './SingleFeatureEditContext';
import {
SingleFeatureEditContextProvider,
useFeatureEditData,
} from './SingleFeatureEditContext';
import { MembersEditor } from '../MembersEditor';
import { ParentsEditor } from '../ParentsEditor';
import { Stack, Typography } from '@mui/material';
import { useEditContext } from '../../EditContext';

type Props = {
shortId: string;
};

const EditFeatureHeading = (props: { shortId: string }) => {
const { items } = useEditContext();
const { tags } = useFeatureEditData();

if (items.length <= 1) {
return null;
}

return (
<Stack
direction="row"
spacing={2}
justifyContent="space-between"
alignItems="center"
mb={2}
>
<Typography variant="h6">{tags.name || ' '}</Typography>
<Typography variant="caption" color="secondary">
{props.shortId}
</Typography>
</Stack>
);
};

export const FeatureEditSection = ({ shortId }: Props) => (
<SingleFeatureEditContextProvider shortId={shortId}>
<EditFeatureHeading shortId={shortId} />
<PresetSelect />
<MajorKeysEditor />
<TagsEditor />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,16 @@ import {
} from '@mui/material';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { FeatureRow } from './FeatureRow';
import { OsmId } from '../../../../services/types';
import { getApiId, getShortId } from '../../../../services/helpers';
import { fetchSchemaTranslations } from '../../../../services/tagging/translations';
import { fetchFeature } from '../../../../services/osmApi';
import { useEditContext } from '../EditContext';
import { t } from '../../../../services/intl';
import { useGetHandleClick } from './helpers';

export const MembersEditor = () => {
const { members } = useFeatureEditData();
const theme = useTheme();
const { addFeature, items, setCurrent } = useEditContext();
const handleClick = useGetHandleClick();

if (!members || members.length === 0) return null;

const handleClick = async (shortId) => {
const apiId: OsmId = getApiId(shortId);
await fetchSchemaTranslations();
const isNotInItems = !items.find((item) => item.shortId === shortId);
const feature = await fetchFeature(apiId);
if (isNotInItems) {
addFeature(feature);
}
setCurrent(getShortId(feature.osmMeta));
};

return (
<Accordion disableGutters elevation={0} square>
<AccordionSummary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@ import {
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { fetchParentFeatures } from '../../../../services/osmApi';
import { getApiId, getShortId } from '../../../../services/helpers';
import { fetchSchemaTranslations } from '../../../../services/tagging/translations';
import { useEditContext } from '../EditContext';
import { FeatureRow } from './FeatureRow';
import { t } from '../../../../services/intl';
import { useGetHandleClick } from './helpers';

export const ParentsEditor = () => {
const { shortId } = useFeatureEditData();
const [parents, setParents] = useState([]);
const theme = useTheme();
const { addFeature, setCurrent, items } = useEditContext();
const handleClick = useGetHandleClick();

useEffect(() => {
(async () => {
Expand Down Expand Up @@ -65,16 +64,7 @@ export const ParentsEditor = () => {
key={shortId}
shortId={shortId}
label={parent.tags.name}
onClick={() => {
const isNotInItems = !items.find(
(item) => item.shortId === shortId,
);
fetchSchemaTranslations();
if (isNotInItems) {
addFeature(parent);
}
setCurrent(shortId);
}}
onClick={() => handleClick(shortId)}
/>
);
})}
Expand Down
28 changes: 28 additions & 0 deletions src/components/FeaturePanel/EditDialog/EditContent/helpers.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import styled from '@emotion/styled';
import { Box, Stack } from '@mui/material';
import React from 'react';
import { EditDataItem } from '../useEditItems';
import { useEditContext } from '../EditContext';
import { getApiId, getShortId } from '../../../../services/helpers';
import { getFullFeatureWithMemberFeatures } from '../../../../services/osmApi';

const CharacterCountContainer = styled.div`
position: absolute;
Expand Down Expand Up @@ -49,3 +53,27 @@ export const getInputTypeForKey = (key: string) => {
}
return 'text';
};

const isInItems = (items: Array<EditDataItem>, shortId: string) =>
items.find((item) => item.shortId === shortId);

export const useGetHandleClick = () => {
const { addFeature, items, setCurrent } = useEditContext();

return async (shortId: string) => {
const apiId = getApiId(shortId);
if (apiId.id < 0) {
setCurrent(shortId);
return;
}

if (isInItems(items, shortId)) {
setCurrent(shortId);
return;
}

const feature = await getFullFeatureWithMemberFeatures(apiId);
addFeature(feature);
setCurrent(getShortId(feature.osmMeta));
};
};
71 changes: 46 additions & 25 deletions src/services/osmApi.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { resolveCountryCode } from 'next-codegrid';
import { FetchError, getShortId, getUrlOsmId, prod } from './helpers';
import { fetchJson } from './fetch';
import { Feature, LonLat, OsmId, Position, SuccessInfo } from './types';
import {
Feature,
LonLat,
OsmId,
Position,
RelationMember,
SuccessInfo,
} from './types';
import { removeFetchCache } from './fetchCache';
import { overpassAroundToSkeletons } from './overpassAroundToSkeletons';
import { isBrowser } from '../components/helpers';
Expand All @@ -20,30 +27,31 @@ import {
} from '../utils';
import { getOverpassUrl } from './overpassSearch';

type GetOsmUrl = (object: OsmId) => string;

const getOsmUrl: GetOsmUrl = ({ type, id }) =>
const getOsmUrl = ({ type, id }: OsmId) =>
`https://api.openstreetmap.org/api/0.6/${type}/${id}.json`;
const getOsmFullUrl: GetOsmUrl = ({ type, id }) =>
const getOsmFullUrl = ({ type, id }: OsmId) =>
`https://api.openstreetmap.org/api/0.6/${type}/${id}/full.json`;
const getOsmParentUrl: GetOsmUrl = ({ type, id }) =>
const getOsmParentUrl = ({ type, id }: OsmId) =>
`https://api.openstreetmap.org/api/0.6/${type}/${id}/relations.json`;
const getOsmHistoryUrl: GetOsmUrl = ({ type, id }) =>
const getOsmHistoryUrl = ({ type, id }: OsmId) =>
`https://api.openstreetmap.org/api/0.6/${type}/${id}/history.json`;

type OsmTypes = 'node' | 'way' | 'relation';
type OsmElement<T extends OsmTypes = 'node' | 'way' | 'relation'> = {
type: T;
id: number;
lat: number;
lon: number;
timestamp: string;
version: number;
changeset: number;
user: string;
uid: number;
tags: Record<string, string>;
members?: RelationMember[];
};
type OsmResponse = {
elements?: {
type: 'node' | 'way' | 'relation';
id: number;
lat: number;
lon: number;
timestamp: string;
version: number;
changeset: number;
user: string;
uid: number;
tags: Record<string, string>;
}[];
elements: OsmElement[];
};

const getOsmElement = async (apiId: OsmId) => {
Expand Down Expand Up @@ -196,8 +204,12 @@ export const fetchParentFeatures = async (apiId: OsmId) => {
return elements.map((element) => addSchemaToFeature(osmToFeature(element)));
};

const getItemsMap = (elements) => {
const map = { node: {}, way: {}, relation: {} };
const getItemsMap = (elements: OsmElement[]) => {
const map = {
node: {} as Record<number, OsmElement<'node'>>,
way: {} as Record<number, OsmElement<'way'>>,
relation: {} as Record<number, OsmElement<'relation'>>,
};
elements.forEach((element) => {
map[element.type][element.id] = element;
});
Expand Down Expand Up @@ -270,6 +282,17 @@ const addMemberFeaturesToArea = async (relation: Feature) => {
return { ...relation, memberFeatures };
};

export const getFullFeatureWithMemberFeatures = async (apiId: OsmId) => {
await fetchSchemaTranslations();
const full = await fetchJson<OsmResponse>(getOsmFullUrl(apiId));
const map = getItemsMap(full.elements);
const feature = addSchemaToFeature(osmToFeature(map[apiId.type][apiId.id]));
return {
...feature,
memberFeatures: getMemberFeatures(feature.members, map),
};
};

const addMemberFeaturesToRelation = async (relation: Feature) => {
const { tags, osmMeta: apiId } = relation;
if (apiId.type !== 'relation') {
Expand All @@ -280,12 +303,10 @@ const addMemberFeaturesToRelation = async (relation: Feature) => {
return await addMemberFeaturesToArea(relation);
}

const full = await fetchJson(getOsmFullUrl(apiId));
const map = getItemsMap(full.elements);

const full = await getFullFeatureWithMemberFeatures(apiId);
const out: Feature = {
...relation,
memberFeatures: getMemberFeatures(relation.members, map),
memberFeatures: full.memberFeatures,
};
mergeMemberImageDefs(out);
return out;
Expand Down
2 changes: 1 addition & 1 deletion src/services/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export type FeatureTags = {
[key: string]: string;
};

type RelationMember = {
export type RelationMember = {
type: OsmType;
ref: number;
role: string;
Expand Down

0 comments on commit f5a8f4a

Please sign in to comment.