296 lines
7.7 KiB
TypeScript
296 lines
7.7 KiB
TypeScript
import {
|
|
Box,
|
|
Button,
|
|
FormControl,
|
|
InputLabel,
|
|
NativeSelect,
|
|
Stack,
|
|
TextField,
|
|
} from '@suid/material';
|
|
import { Component, createEffect, createSignal, Show } from 'solid-js';
|
|
import { useI18n } from '@solid-primitives/i18n';
|
|
|
|
import Dialog from '../dialog';
|
|
import {
|
|
cachedSignalValue,
|
|
peekCachedSignal,
|
|
} from '../../workers/cached-signals';
|
|
import dispatch from '../../workers/dispatcher-main';
|
|
import { emptyWpt } from '../../db/wpt';
|
|
import GpxChooser from '../gpx-chooser';
|
|
import { currentGpxId } from '../gpx-dialog';
|
|
import { emptyGpx } from '../../db/gpx';
|
|
import getUri from '../../lib/ids';
|
|
import { Coordinate } from 'ol/coordinate';
|
|
|
|
export enum Category {
|
|
NOTE = 'note',
|
|
POI = 'poi',
|
|
PICTURE = 'picture',
|
|
UNKNOWN = '',
|
|
}
|
|
|
|
export enum SubCategory {
|
|
ACCOMMODATION = 'accommodation',
|
|
UNKNOWN = '',
|
|
}
|
|
|
|
interface Props {
|
|
wptId?: string;
|
|
coordinate?: () => Coordinate | undefined;
|
|
open: () => boolean;
|
|
closeHandler?: () => void;
|
|
initialWpt: () => Wpt;
|
|
imageUrl?: string | undefined;
|
|
}
|
|
|
|
const WptEditDialog: Component<Props> = (props) => {
|
|
const {
|
|
wptId,
|
|
closeHandler,
|
|
open,
|
|
coordinate,
|
|
initialWpt = () => emptyWpt,
|
|
imageUrl,
|
|
} = props;
|
|
const [t, { add, locale, dict }] = useI18n();
|
|
|
|
const wpt = !!wptId
|
|
? peekCachedSignal({ id: wptId, method: 'getWpt' })
|
|
: initialWpt;
|
|
|
|
const [gpxId, setGpxId] = !wptId
|
|
? createSignal<string>(currentGpxId())
|
|
: [() => '', () => {}];
|
|
|
|
createEffect(() => {
|
|
setGpxId(currentGpxId());
|
|
});
|
|
|
|
const [editedWpt, setEditedWpt] = createSignal<Wpt>();
|
|
|
|
createEffect(() => {
|
|
console.log({
|
|
caller: 'WptEditDialog / createEffect',
|
|
wptId,
|
|
gpxId: gpxId(),
|
|
wpt: wpt(),
|
|
});
|
|
const newWpt = editedWpt() || wpt();
|
|
if (!!coordinate && !!coordinate()) {
|
|
newWpt.$.lon = coordinate()[0];
|
|
newWpt.$.lat = coordinate()[1];
|
|
}
|
|
console.log({
|
|
caller: 'WptEditDialog / createEffect',
|
|
wptId,
|
|
gpxId: gpxId(),
|
|
wpt: wpt(),
|
|
newWpt,
|
|
});
|
|
setEditedWpt(newWpt);
|
|
});
|
|
|
|
const _closeHandler = () => {
|
|
if (!!closeHandler) {
|
|
closeHandler();
|
|
}
|
|
};
|
|
|
|
const saveHandler = async () => {
|
|
console.log({
|
|
caller: 'WptEditDialog / saveHandler',
|
|
wptId,
|
|
editedWpt: editedWpt(),
|
|
});
|
|
let newWptId = wptId;
|
|
if (!newWptId) {
|
|
if (gpxId() === 'new') {
|
|
const id = (await dispatch({
|
|
action: 'putGpx',
|
|
params: {
|
|
id: 'new',
|
|
gpx: emptyGpx,
|
|
},
|
|
})) as string;
|
|
setGpxId(id);
|
|
}
|
|
const gpx = await cachedSignalValue({ method: 'getGpx', id: gpxId() });
|
|
const gpxIdObj = getUri('gpx', gpxId());
|
|
const lastWptId = gpx.wpt?.at(-1);
|
|
const lastWptIdObj = !!lastWptId
|
|
? getUri('wpt', lastWptId)
|
|
: {
|
|
gpx: gpxIdObj.gpx,
|
|
wpt: -1,
|
|
};
|
|
newWptId = getUri('wpt', { ...lastWptIdObj, wpt: lastWptIdObj.wpt + 1 });
|
|
}
|
|
console.log({
|
|
caller: 'WptEditDialog / saveHandler',
|
|
wptId,
|
|
editedWpt: editedWpt(),
|
|
newWptId,
|
|
});
|
|
dispatch({
|
|
action: 'putWpt',
|
|
params: { id: newWptId, wpt: editedWpt() },
|
|
});
|
|
setEditedWpt(undefined);
|
|
_closeHandler();
|
|
};
|
|
|
|
const getTitle = () => {
|
|
if (wpt()?.name) {
|
|
return `${wpt()?.name} (${t('wpt')})`;
|
|
}
|
|
return t('wpt');
|
|
};
|
|
|
|
// <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 });
|
|
// }}
|
|
// />
|
|
|
|
return (
|
|
<Dialog
|
|
open={open() && !!wpt()}
|
|
title={getTitle()}
|
|
closeHandler={_closeHandler}
|
|
>
|
|
<Show when={!wptId}>
|
|
<GpxChooser gpxId={gpxId} setGpxId={setGpxId} />
|
|
</Show>
|
|
|
|
<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 });
|
|
}}
|
|
/>
|
|
<FormControl>
|
|
<InputLabel variant='normal' htmlFor='category'>
|
|
Type
|
|
</InputLabel>
|
|
<NativeSelect
|
|
inputProps={{
|
|
name: 'category',
|
|
id: 'category',
|
|
}}
|
|
onChange={(event: any, value: string) => {
|
|
setEditedWpt({
|
|
...editedWpt(),
|
|
extensions: { ...editedWpt().extensions, category: value },
|
|
});
|
|
}}
|
|
>
|
|
<option
|
|
value={Category.POI}
|
|
selected={editedWpt()?.extensions?.category === Category.POI}
|
|
>
|
|
Point d'intérêt
|
|
</option>
|
|
<option
|
|
value={Category.NOTE}
|
|
selected={editedWpt()?.extensions?.category === Category.NOTE}
|
|
>
|
|
Note
|
|
</option>
|
|
<option
|
|
value={Category.PICTURE}
|
|
selected={
|
|
editedWpt()?.extensions?.category === Category.PICTURE
|
|
}
|
|
>
|
|
Picture
|
|
</option>
|
|
<option
|
|
value={undefined}
|
|
selected={!editedWpt()?.extensions?.category}
|
|
>
|
|
Autre
|
|
</option>
|
|
</NativeSelect>
|
|
</FormControl>
|
|
<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' }}
|
|
/>
|
|
<TextField
|
|
label='Début'
|
|
type='datetime-local'
|
|
value={(editedWpt()?.extensions?.startTime || '').replace('Z', '')}
|
|
onChange={(event: any) => {
|
|
setEditedWpt({
|
|
...editedWpt(),
|
|
extensions: {
|
|
...editedWpt().extensions,
|
|
startTime: new Date(event.target.value).toISOString(),
|
|
},
|
|
});
|
|
}}
|
|
/>
|
|
<TextField
|
|
label='Fin'
|
|
type='datetime-local'
|
|
value={(editedWpt()?.extensions?.endTime || '').replace('Z', '')}
|
|
onChange={(event: any) => {
|
|
setEditedWpt({
|
|
...editedWpt(),
|
|
extensions: {
|
|
...editedWpt().extensions,
|
|
endTime: new Date(event.target.value).toISOString(),
|
|
},
|
|
});
|
|
}}
|
|
/>
|
|
<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;
|