refactor(js): add geo-area stimulus controller

This commit is contained in:
Paul Chavard 2022-04-22 09:40:52 +02:00
parent 22aefbaa4a
commit b585808924
4 changed files with 60 additions and 7 deletions

View file

@ -37,9 +37,7 @@ export function useFeatureCollection(
type: 'FeatureCollection',
features: callback(features)
}));
ajax({ url, type: 'GET' })
.then(() => fire(document, 'ds:page:update'))
.catch(() => null);
ajax({ url, type: 'GET' }).catch(() => null);
},
[url, setFeatureCollection]
);

View file

@ -0,0 +1,53 @@
import { Controller } from '@hotwired/stimulus';
import { debounce } from '@utils';
type Detail = Record<string, unknown>;
export class GeoAreaController extends Controller {
static values = {
id: String,
description: String
};
static targets = ['description'];
declare readonly idValue: string;
declare readonly descriptionTarget: HTMLInputElement;
onFocus() {
this.globalDispatch('map:feature:focus', { id: this.idValue });
}
onClick(event: MouseEvent) {
event.preventDefault();
this.globalDispatch('map:feature:focus', { id: this.idValue });
}
onInput() {
this.debounce(this.updateDescription, 200);
}
private updateDescription(): void {
this.globalDispatch('map:feature:update', {
id: this.idValue,
properties: { description: this.descriptionTarget.value.trim() }
});
}
#debounced = new Map<() => void, () => void>();
private debounce(fn: () => void, interval: number): void {
let debounced = this.#debounced.get(fn);
if (!debounced) {
debounced = debounce(fn.bind(this), interval);
this.#debounced.set(fn, debounced);
}
debounced();
}
private globalDispatch(type: string, detail: Detail): void {
this.dispatch(type, {
detail,
prefix: '',
target: document.documentElement
});
}
}

View file

@ -19,6 +19,7 @@ import {
registerComponents
} from '../controllers/react_controller';
import { TurboEventController } from '../controllers/turbo_event_controller';
import { GeoAreaController } from '../controllers/geo_area_controller';
import '../new_design/dropdown';
import '../new_design/form-validation';
@ -95,6 +96,7 @@ Turbo.session.drive = false;
const Stimulus = Application.start();
Stimulus.register('react', ReactController);
Stimulus.register('turbo-event', TurboEventController);
Stimulus.register('geo-area', GeoAreaController);
// Expose globals
window.DS = window.DS || DS;

View file

@ -1,10 +1,10 @@
%li{ class: editing ? 'mb-1' : 'flex column mb-2' }
%li{ class: editing ? 'mb-1' : 'flex column mb-2', data: { controller: 'geo-area', geo_area_id_value: geo_area.id } }
- if editing
= link_to '#', data: { geo_area: geo_area.id } do
= link_to '#', data: { action: 'geo-area#onClick' } do
= geo_area_label(geo_area)
= text_field_tag :description, geo_area.description, data: { geo_area: geo_area.id }, placeholder: 'Description', class: 'no-margin'
= text_field_tag :description, geo_area.description, data: { action: 'focus->geo-area#onFocus input->geo-area#onInput', geo_area_target: 'description' }, placeholder: 'Description', class: 'no-margin'
- else
= link_to '#', data: { geo_area: geo_area.id } do
= link_to '#', data: { action: 'geo-area#onClick' } do
= geo_area_label(geo_area)
- if geo_area.description.present?
%span