aboutsummaryrefslogtreecommitdiff
path: root/frontend/ts/src/pages/map/markerForm.ts
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/ts/src/pages/map/markerForm.ts')
-rw-r--r--frontend/ts/src/pages/map/markerForm.ts172
1 files changed, 172 insertions, 0 deletions
diff --git a/frontend/ts/src/pages/map/markerForm.ts b/frontend/ts/src/pages/map/markerForm.ts
new file mode 100644
index 0000000..f04a008
--- /dev/null
+++ b/frontend/ts/src/pages/map/markerForm.ts
@@ -0,0 +1,172 @@
+import { h, Html, Rx } from 'lib/rx'
+import * as rx from 'lib/rx'
+import * as request from 'request'
+import * as modal from 'ui/modal'
+import * as layout from 'ui/layout'
+import * as markerModel from 'models/marker'
+import * as form from 'lib/form'
+import * as icons from 'lib/icons'
+import * as L from 'lib/loadable'
+
+interface MarkerFormParams {
+ lat: number
+ lng: number
+ marker?: markerModel.Marker
+ colors: Array<string>
+ label: string
+ req: (body: string) => Promise<markerModel.Marker>
+ onSuccess: (m: markerModel.Marker) => void
+ onClose: () => void
+ lastUserAdded?: markerModel.Marker
+ onDeleteMarker?: () => void
+}
+
+export function view({ lat, lng, marker, colors, label, req, onSuccess, onClose, lastUserAdded, onDeleteMarker }: MarkerFormParams): Html {
+ const initName = marker?.name || ''
+ const initDescription = marker?.description || ''
+ const initColor = marker?.color || lastUserAdded?.color || (colors.length > 0 ? colors[0] : '#3584e4')
+ const initIcon = marker?.icon || ''
+ const initRadius = marker?.radius || 0
+
+ const isCreation = marker === undefined
+
+ const iconValues: { [key: string]: string } = {}
+ Object.keys(icons.values).forEach(key => iconValues[key] = icons.values[key].name)
+
+ return modal.view({
+ header: marker == undefined ? 'Nouveau marqueur' : 'Modification du marqueur',
+ body: rx.withState7<string, string, string, string, number, L.Loadable<void>, L.Loadable<void>>(
+ [initName, initDescription, initColor, initIcon, initRadius, L.init, L.init],
+ (nameVar, descriptionVar, colorVar, iconVar, radiusVar, updateReqVar, deleteReqVar) =>
+ h('form',
+ {
+ onsubmit: rx.map5([nameVar, descriptionVar, colorVar, iconVar, radiusVar], (name, description, color, icon, radius) =>
+ (event: Event) => {
+ event.preventDefault()
+ updateReqVar.update(_ => L.loading)
+ const payload = { lat, lng, color, name, description, icon, radius }
+
+ req(JSON.stringify(payload))
+ .then((m: markerModel.Marker) => {
+ updateReqVar.update(_ => L.loaded(undefined))
+ onSuccess(m)
+ })
+ .catch(({ message }) => updateReqVar.update(_ => L.failure(message)))
+ }
+ )
+ },
+ form.input({
+ label: 'Nom',
+ select: isCreation,
+ initValue: initName,
+ onUpdate: value => {
+ nameVar.update(_ => value)
+ updateReqVar.update(_ => L.init)
+ deleteReqVar.update(_ => L.init)
+ }
+ }),
+ form.textarea({
+ label: 'Description',
+ initValue: initDescription,
+ onUpdate: value => {
+ descriptionVar.update(_ => value)
+ updateReqVar.update(_ => L.init)
+ deleteReqVar.update(_ => L.init)
+ }
+ }),
+ colorSection({
+ colorRx: colorVar,
+ colors,
+ onUpdateColor: color => {
+ colorVar.update(_ => color)
+ updateReqVar.update(_ => L.init)
+ deleteReqVar.update(_ => L.init)
+ }
+ }),
+ layout.columns([
+ form.select({
+ label: 'IcĂ´ne',
+ initValue: initIcon,
+ values: iconValues,
+ onUpdate: value => {
+ iconVar.update(_ => value)
+ updateReqVar.update(_ => L.init)
+ deleteReqVar.update(_ => L.init)
+ }
+ }),
+ form.input({
+ type: 'number',
+ label: 'Radius',
+ initValue: initRadius.toString(),
+ onUpdate: value => {
+ radiusVar.update(_ => parseInt(value) || 0)
+ updateReqVar.update(_ => L.init)
+ deleteReqVar.update(_ => L.init)
+ }
+ })
+ ]),
+ form.error(updateReqVar),
+ form.error(deleteReqVar),
+ form.submit({
+ label,
+ className: 'g-Button--FullWidth',
+ requestVar: updateReqVar,
+ disabled: deleteReqVar.map(l => l != L.init)
+ }),
+ marker !== undefined && onDeleteMarker !== undefined && form.button({
+ style: 'margin-top: 1rem',
+ label: 'Supprimer',
+ className: 'g-Button--FullWidth g-Button--Danger',
+ requestVar: deleteReqVar,
+ disabled: updateReqVar.map(l => l != L.init),
+ onClick: () => {
+ deleteReqVar.update(_ => L.loading)
+ request
+ .del_(`/api/markers/${marker.id}`)
+ .then(_ => onDeleteMarker())
+ .catch(({ message }) => updateReqVar.update(_ => L.failure(message)))
+ }
+ })
+ )
+ ),
+ onClose: onClose
+ })
+}
+
+interface ColorSectionParams {
+ colorRx: Rx<string>,
+ colors: Array<string>,
+ onUpdateColor: (color: string) => void,
+}
+
+function colorSection({ colorRx, colors, onUpdateColor }: ColorSectionParams): Html {
+ return h('label',
+ { className: 'g-Label' },
+ 'Couleur',
+ h('div',
+ { className: 'g-ColorLine' },
+ h('input',
+ {
+ type: 'color',
+ className: 'g-Input',
+ oninput: (event: Event) => onUpdateColor((event.target as HTMLInputElement).value),
+ value: colorRx
+ }
+ ),
+ h('div',
+ { className: 'g-ColorButtons' },
+ colors.map(c =>
+ h('input',
+ {
+ type: 'button',
+ className: 'g-ColorButton',
+ style: `background-color: ${c}`,
+ onclick: (event: Event) => onUpdateColor(c)
+ }
+ )
+ )
+ )
+ )
+ )
+
+}