Refactoring to facilitate creating new Wpts
This commit is contained in:
parent
bd700d8782
commit
e3dc1fc083
|
@ -7,7 +7,7 @@ import { useI18n } from '@solid-primitives/i18n';
|
||||||
import proj4 from 'proj4';
|
import proj4 from 'proj4';
|
||||||
|
|
||||||
import style from './Finder.module.css';
|
import style from './Finder.module.css';
|
||||||
import { Box, IconButton, TextField } from '@suid/material';
|
import { Box, Button, IconButton, TextField } from '@suid/material';
|
||||||
import Dialog from '../dialog';
|
import Dialog from '../dialog';
|
||||||
import { getMap, getState } from '../map';
|
import { getMap, getState } from '../map';
|
||||||
import { Overlay } from 'ol';
|
import { Overlay } from 'ol';
|
||||||
|
@ -47,7 +47,7 @@ const Finder: Component<Props> = (props) => {
|
||||||
const utm = `+proj=utm +zone=${utmMatch[1]}`;
|
const utm = `+proj=utm +zone=${utmMatch[1]}`;
|
||||||
coordinates = proj4(utm, 'EPSG:4326', [+utmMatch[3], +utmMatch[4]]);
|
coordinates = proj4(utm, 'EPSG:4326', [+utmMatch[3], +utmMatch[4]]);
|
||||||
setPopupContent(
|
setPopupContent(
|
||||||
<>{`${coordinates[0]}, ${coordinates[1]} (${utmMatch[0]})`}</>
|
<>{`${coordinates[0]}, ${coordinates[1]} (UTM ${utmMatch[0]})`}</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
console.log({
|
console.log({
|
||||||
|
@ -118,11 +118,15 @@ const Finder: Component<Props> = (props) => {
|
||||||
<div id='popup' class={style.ol_popup}>
|
<div id='popup' class={style.ol_popup}>
|
||||||
<a
|
<a
|
||||||
href='#'
|
href='#'
|
||||||
id='popup-closer'
|
|
||||||
onclick={popupCloseHandler}
|
onclick={popupCloseHandler}
|
||||||
class={style.ol_popup_closer}
|
class={style.ol_popup_closer}
|
||||||
></a>
|
></a>
|
||||||
<div id='popup-content'>{popupContent()}</div>
|
<div>
|
||||||
|
<div>{popupContent()}</div>
|
||||||
|
<div>
|
||||||
|
<Button>New waypoint</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { useI18n } from '@solid-primitives/i18n';
|
||||||
|
import { 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';
|
||||||
|
import Dialog from '../dialog';
|
||||||
|
import WptEditDialog from './WptEditDialog';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
wptId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const WptEditButtonAndDialog: Component<Props> = ({ wptId }) => {
|
||||||
|
const [open, setOpen] = createSignal(false);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
setOpen(true);
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<EditIcon />
|
||||||
|
</IconButton>
|
||||||
|
<WptEditDialog
|
||||||
|
wptId={wptId}
|
||||||
|
open={open}
|
||||||
|
closeHandler={() => setOpen(false)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default WptEditButtonAndDialog;
|
|
@ -0,0 +1,122 @@
|
||||||
|
import { Box, Button, Stack, TextField } from '@suid/material';
|
||||||
|
import { Component, createEffect, createSignal } from 'solid-js';
|
||||||
|
import { useI18n } from '@solid-primitives/i18n';
|
||||||
|
|
||||||
|
import Dialog from '../dialog';
|
||||||
|
import { peekCachedSignal } from '../../workers/cached-signals';
|
||||||
|
import dispatch from '../../workers/dispatcher-main';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
wptId: string;
|
||||||
|
open: () => boolean;
|
||||||
|
closeHandler?: () => vpod;
|
||||||
|
}
|
||||||
|
|
||||||
|
const WptEditDialog: Component<Props> = (props) => {
|
||||||
|
const { wptId, closeHandler, open } = props;
|
||||||
|
const [t, { add, locale, dict }] = useI18n();
|
||||||
|
|
||||||
|
const wpt = peekCachedSignal({ id: wptId, method: 'getWpt' });
|
||||||
|
const [editedWpt, setEditedWpt] = createSignal<Wpt>();
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
console.log({
|
||||||
|
caller: 'WptEditDialog / createEffect',
|
||||||
|
wptId,
|
||||||
|
wpt: wpt(),
|
||||||
|
});
|
||||||
|
setEditedWpt(wpt());
|
||||||
|
});
|
||||||
|
|
||||||
|
const _closeHandler = () => {
|
||||||
|
if (!!closeHandler) {
|
||||||
|
closeHandler();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveHandler = () => {
|
||||||
|
console.log({
|
||||||
|
caller: 'WptEditDialog / saveHandler',
|
||||||
|
wptId,
|
||||||
|
editedWpt: editedWpt(),
|
||||||
|
});
|
||||||
|
dispatch({ action: 'putWpt', params: { id: wptId, wpt: editedWpt() } });
|
||||||
|
_closeHandler();
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTitle = () => {
|
||||||
|
if (wpt()?.name) {
|
||||||
|
return `${wpt()?.name} (${t('wpt')})`;
|
||||||
|
}
|
||||||
|
return t('wpt');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
open={open() && !!wpt()}
|
||||||
|
title={getTitle()}
|
||||||
|
closeHandler={_closeHandler}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
component='form'
|
||||||
|
sx={{
|
||||||
|
width: '100%',
|
||||||
|
'& .MuiTextField-root': { m: 1, width: '100%' },
|
||||||
|
paddingTop: '5px',
|
||||||
|
}}
|
||||||
|
noValidate
|
||||||
|
autoComplete='off'
|
||||||
|
>
|
||||||
|
<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 });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
label={t('gpxDesc')}
|
||||||
|
type='text'
|
||||||
|
rows={5}
|
||||||
|
multiline={true}
|
||||||
|
value={editedWpt()?.desc || ''}
|
||||||
|
onChange={(event: any) => {
|
||||||
|
setEditedWpt({ ...editedWpt(), desc: event.target.value });
|
||||||
|
}}
|
||||||
|
InputProps={{ inputComponent: 'textarea' }}
|
||||||
|
/>
|
||||||
|
<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 WptEditDialog;
|
|
@ -1,139 +0,0 @@
|
||||||
import { useI18n } from '@solid-primitives/i18n';
|
|
||||||
import { 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';
|
|
||||||
import Dialog from '../dialog';
|
|
||||||
|
|
||||||
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()));
|
|
||||||
console.log({
|
|
||||||
caller: 'WptEditor / edit',
|
|
||||||
wptId,
|
|
||||||
editedWpt: editedWpt(),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeHandler = () => {
|
|
||||||
setMode(Mode.CLOSED);
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveHandler = () => {
|
|
||||||
console.log({
|
|
||||||
caller: 'WptEditor / 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 && wpt()}
|
|
||||||
title={getTitle()}
|
|
||||||
closeHandler={closeHandler}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
component='form'
|
|
||||||
sx={{
|
|
||||||
width: '100%',
|
|
||||||
'& .MuiTextField-root': { m: 1, width: '100%' },
|
|
||||||
paddingTop: '5px',
|
|
||||||
}}
|
|
||||||
noValidate
|
|
||||||
autoComplete='off'
|
|
||||||
>
|
|
||||||
<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 });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
label={t('gpxDesc')}
|
|
||||||
type='text'
|
|
||||||
rows={5}
|
|
||||||
multiline={true}
|
|
||||||
value={editedWpt()?.desc || ''}
|
|
||||||
onChange={(event: any) => {
|
|
||||||
setEditedWpt({ ...editedWpt(), desc: event.target.value });
|
|
||||||
}}
|
|
||||||
InputProps={{ inputComponent: 'textarea' }}
|
|
||||||
/>
|
|
||||||
<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;
|
|
|
@ -2,8 +2,7 @@ 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 WptEditButtonAndDialog from './WptEditButtonAndDialog';
|
||||||
import WptEditor from './WptEditor';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
wptId: string;
|
wptId: string;
|
||||||
|
@ -22,7 +21,7 @@ const WptViewer: Component<Props> = ({ wptId }) => {
|
||||||
<>
|
<>
|
||||||
<WptIcon fill='black' width='24' height='24' viewBox='0 0 300 300' />
|
<WptIcon fill='black' width='24' height='24' viewBox='0 0 300 300' />
|
||||||
{title()}
|
{title()}
|
||||||
<WptEditor wptId={wptId} />
|
<WptEditButtonAndDialog wptId={wptId} />
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
content={undefined}
|
content={undefined}
|
||||||
|
|
|
@ -1,4 +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';
|
export { default as WptEditButtonAndDialog } from './WptEditButtonAndDialog';
|
||||||
|
|
Loading…
Reference in New Issue