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 label: string req: (body: string) => Promise 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, L.Loadable>( [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, colors: Array, 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) } ) ) ) ) ) }