Reimplementing a dialog to edit waypoints

This commit is contained in:
Eric van der Vlist 2023-01-16 20:59:00 +01:00
parent 3153ee308d
commit bdb11a52bb
4 changed files with 128 additions and 81 deletions

View File

@ -1,13 +1,9 @@
import { Component, createEffect, createSignal, onCleanup } from 'solid-js'; import { Component, createEffect, onCleanup } from 'solid-js';
import dispatch, { cancelDispatch } from '../../workers/dispatcher-main';
import VectorSource from 'ol/source/Vector'; import VectorSource from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON'; import GeoJSON from 'ol/format/GeoJSON';
import { useI18n } from '@solid-primitives/i18n'; import { useI18n } from '@solid-primitives/i18n';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import Dialog from '../dialog';
import { Box, Button, Stack, TextField } from '@suid/material';
import wpt from '.';
import { import {
createCachedSignal, createCachedSignal,
destroyCachedSignal, destroyCachedSignal,
@ -19,11 +15,6 @@ interface Props {
context: any; context: any;
} }
enum Mode {
CLOSED,
EDIT,
}
export const Wpt: Component<Props> = ({ export const Wpt: Component<Props> = ({
vectorSource, vectorSource,
wptId: wptId, wptId: wptId,
@ -48,8 +39,6 @@ export const Wpt: Component<Props> = ({
destroyCachedSignal(params); destroyCachedSignal(params);
}); });
const [editedWpt, setEditedWpt] = createSignal<Wpt>();
const getTitle = () => { const getTitle = () => {
if (wpt()?.name) { if (wpt()?.name) {
return `${wpt()?.name} (${t('wpt')})`; return `${wpt()?.name} (${t('wpt')})`;
@ -57,13 +46,6 @@ export const Wpt: Component<Props> = ({
return t('wpt'); return t('wpt');
}; };
const [mode, setMode] = createSignal<Mode>(Mode.CLOSED);
const edit = () => {
setMode(Mode.EDIT);
setEditedWpt(cloneDeep(wpt()));
};
createEffect(() => { createEffect(() => {
console.log({ caller: 'Wpt', vectorSource, wptId, wpt: cloneDeep(wpt()) }); console.log({ caller: 'Wpt', vectorSource, wptId, wpt: cloneDeep(wpt()) });
@ -86,7 +68,6 @@ export const Wpt: Component<Props> = ({
...wpt(), ...wpt(),
id: wptId, id: wptId,
getTitle, getTitle,
edit,
context: { ...context, wpt, wptId }, context: { ...context, wpt, wptId },
}, },
id: wptId, id: wptId,
@ -104,66 +85,7 @@ export const Wpt: Component<Props> = ({
} }
}); });
const closeHandler = () => { return <></>;
setMode(Mode.CLOSED);
};
const saveHandler = () => {
console.log({
caller: 'Wpt / saveHandler',
wptId,
editedWpt: editedWpt(),
});
dispatch({ action: 'putWpt', params: { id: wptId, wpt: editedWpt() } });
setMode(Mode.CLOSED);
};
return (
<Dialog
open={mode() === Mode.EDIT}
title={getTitle()}
closeHandler={closeHandler}
>
<Box sx={{ flexGrow: 1, padding: '10px' }}>
<div>
<TextField
required
label={t('name')}
defaultValue={wpt()?.name}
onChange={(event: any, value: string) => {
setEditedWpt({ ...editedWpt(), name: value });
}}
/>
<TextField
label={t('sym')}
defaultValue={wpt()?.sym}
onChange={(event: any, value: string) => {
setEditedWpt({ ...editedWpt(), sym: value });
}}
/>
<TextField
label={t('minZoom')}
defaultValue={wpt()?.extensions?.['dyo:minZoom']?.toString()}
onChange={(event: any, value: string) => {
const extensions = {
...editedWpt()?.extensions,
'dyo:minZoom': parseFloat(value),
};
setEditedWpt({ ...editedWpt(), extensions });
}}
/>
<Stack spacing={2} direction='row' sx={{ marginTop: '20px' }}>
<Button variant='outlined' color='secondary' onClick={closeHandler}>
{t('cancel')}
</Button>
<Button variant='contained' color='success' onClick={saveHandler}>
{t('save')}
</Button>
</Stack>
</div>
</Box>
</Dialog>
);
}; };
export default Wpt; export default Wpt;

View File

@ -0,0 +1,120 @@
import { useI18n } from '@solid-primitives/i18n';
import {
Dialog,
Box,
TextField,
Stack,
Button,
IconButton,
} from '@suid/material';
import { cloneDeep } from 'lodash';
import { Component, createSignal } from 'solid-js';
import { emptyWpt } from '../../db/wpt';
import { peekCachedSignal } from '../../workers/cached-signals';
import dispatch from '../../workers/dispatcher-main';
import EditIcon from '@suid/icons-material/Edit';
enum Mode {
CLOSED,
EDIT,
}
interface Props {
wptId?: string;
}
const WptEditor: Component<Props> = ({ wptId }) => {
const [mode, setMode] = createSignal<Mode>(Mode.CLOSED);
const [editedWpt, setEditedWpt] = createSignal<Wpt>();
const [t, { add, locale, dict }] = useI18n();
const wpt =
wptId !== undefined
? peekCachedSignal({ id: wptId, method: 'getWpt' })
: () => emptyWpt;
const edit = () => {
setMode(Mode.EDIT);
setEditedWpt(cloneDeep(wpt()));
};
const closeHandler = () => {
setMode(Mode.CLOSED);
};
const saveHandler = () => {
console.log({
caller: 'Wpt / saveHandler',
wptId,
editedWpt: editedWpt(),
});
dispatch({ action: 'putWpt', params: { id: wptId, wpt: editedWpt() } });
setMode(Mode.CLOSED);
};
const getTitle = () => {
if (wpt()?.name) {
return `${wpt()?.name} (${t('wpt')})`;
}
return t('wpt');
};
return (
<>
<IconButton onClick={edit}>
<EditIcon />
</IconButton>
<Dialog
open={mode() === Mode.EDIT}
title={getTitle()}
closeHandler={closeHandler}
>
<Box sx={{ flexGrow: 1, padding: '10px' }}>
<div>
<TextField
required
label={t('name')}
defaultValue={wpt()?.name}
onChange={(event: any, value: string) => {
setEditedWpt({ ...editedWpt(), name: value });
}}
/>
<TextField
label={t('sym')}
defaultValue={wpt()?.sym}
onChange={(event: any, value: string) => {
setEditedWpt({ ...editedWpt(), sym: value });
}}
/>
<TextField
label={t('minZoom')}
defaultValue={wpt()?.extensions?.['dyo:minZoom']?.toString()}
onChange={(event: any, value: string) => {
const extensions = {
...editedWpt()?.extensions,
'dyo:minZoom': parseFloat(value),
};
setEditedWpt({ ...editedWpt(), extensions });
}}
/>
<Stack spacing={2} direction='row' sx={{ marginTop: '20px' }}>
<Button
variant='outlined'
color='secondary'
onClick={closeHandler}
>
{t('cancel')}
</Button>
<Button variant='contained' color='success' onClick={saveHandler}>
{t('save')}
</Button>
</Stack>
</div>
</Box>
</Dialog>
</>
);
};
export default WptEditor;

View File

@ -2,6 +2,8 @@ import { Component } from 'solid-js';
import WptIcon from '../../icons/location-pin-svgrepo-com.svg?component-solid'; import WptIcon from '../../icons/location-pin-svgrepo-com.svg?component-solid';
import { peekCachedSignal } from '../../workers/cached-signals'; import { peekCachedSignal } from '../../workers/cached-signals';
import Tree from '../tree'; import Tree from '../tree';
import { IconButton } from '@suid/material';
import WptEditor from './WptEditor';
interface Props { interface Props {
wptId: string; wptId: string;
@ -18,7 +20,9 @@ const WptViewer: Component<Props> = ({ wptId }) => {
<Tree <Tree
title={ title={
<> <>
<WptIcon fill='black' width="24" height="24" viewBox="0 0 300 300" /> {title()} <WptIcon fill='black' width='24' height='24' viewBox='0 0 300 300' />
{title()}
<WptEditor wptId={wptId} />
</> </>
} }
content={undefined} content={undefined}

View File

@ -1,3 +1,4 @@
export { default } from './Wpt'; export { default } from './Wpt';
export { default as WptViewer } from './WptViewer'; export { default as WptViewer } from './WptViewer';
export { default as WptEditor } from './WptEditor';