chore: move defaultOptions from forms to schema

This commit is contained in:
Yohan Boniface 2024-02-28 11:56:32 +01:00
parent 68f3a9686a
commit fcf22195cb
4 changed files with 404 additions and 395 deletions

View file

@ -1,7 +1,7 @@
import URLs from './urls.js' import URLs from './urls.js'
import Browser from './browser.js' import Browser from './browser.js'
import * as Utils from './utils.js' import * as Utils from './utils.js'
import SCHEMA from './schema.js' import {SCHEMA} from './schema.js'
import { Request, ServerRequest, RequestError, HTTPError, NOKError } from './request.js' import { Request, ServerRequest, RequestError, HTTPError, NOKError } from './request.js'
// Import modules and export them to the global scope. // Import modules and export them to the global scope.

View file

@ -1,62 +1,360 @@
import { translate } from './i18n.js' import { translate } from './i18n.js'
const SCHEMA = { export const SCHEMA = {
zoom: { type: undefined }, zoom: {
scrollWheelZoom: { type: Boolean }, type: Number,
scaleControl: { type: Boolean }, },
moreControl: { type: Boolean }, scrollWheelZoom: {
miniMap: { type: Boolean }, type: Boolean,
displayPopupFooter: { type: undefined }, label: translate('Allow scroll wheel zoom?'),
onLoadPanel: { type: String }, },
defaultView: { type: String }, scaleControl: {
name: { type: String, label: translate('name') }, type: Boolean,
description: { type: String }, label: translate('Do you want to display the scale control?'),
licence: { type: undefined }, },
tilelayer: { type: undefined }, moreControl: {
overlay: { type: undefined }, type: Boolean,
limitBounds: { type: undefined }, label: translate('Do you want to display the «more» control?'),
color: { type: String }, },
iconClass: { type: String }, miniMap: {
iconUrl: { type: String }, type: Boolean,
smoothFactor: { type: undefined }, label: translate('Do you want to display a minimap?'),
iconOpacity: { type: undefined }, },
opacity: { type: undefined }, displayPopupFooter: {
weight: { type: undefined }, type: Boolean,
fill: { type: undefined }, label: translate('Do you want to display popup footer?'),
fillColor: { type: undefined }, },
fillOpacity: { type: undefined }, onLoadPanel: {
dashArray: { type: undefined }, type: String,
popupShape: { type: String }, label: translate('Do you want to display a panel on load?'),
popupTemplate: { type: String }, choices: [
popupContentTemplate: { type: String }, ['none', translate('None')],
zoomTo: { type: Number }, ['caption', translate('Caption')],
captionBar: { type: Boolean }, ['databrowser', translate('Data browser')],
captionMenus: { type: Boolean }, ['facet', translate('Facet search')],
slideshow: { type: undefined }, ],
sortKey: { type: undefined }, default: 'none',
labelKey: { type: String }, },
filterKey: { type: undefined }, defaultView: {
facetKey: { type: undefined }, type: String,
slugKey: { type: undefined }, label: translate('Default view'),
showLabel: { type: 'NullableBoolean' }, choices: [
labelDirection: { type: undefined }, ['center', translate('Saved center and zoom')],
labelInteractive: { type: undefined }, ['data', translate('Fit all data')],
outlinkTarget: { type: undefined }, ['latest', translate('Latest feature')],
shortCredit: { type: undefined }, ['locate', translate('User location')],
longCredit: { type: undefined }, ],
permanentCredit: { type: undefined }, default: 'center',
permanentCreditBackground: { type: undefined }, },
zoomControl: { type: 'NullableBoolean' }, name: {
datalayersControl: { type: 'NullableBoolean' }, type: String,
searchControl: { type: 'NullableBoolean' }, label: translate('name'),
locateControl: { type: 'NullableBoolean' }, },
fullscreenControl: { type: 'NullableBoolean' }, description: {
editinosmControl: { type: 'NullableBoolean' }, label: translate('description'),
embedControl: { type: 'NullableBoolean' }, type: 'Text',
measureControl: { type: 'NullableBoolean' }, helpEntries: 'textFormatting',
tilelayersControl: { type: 'NullableBoolean' }, },
starControl: { type: 'NullableBoolean' }, licence: {
easing: { type: undefined }, type: String,
label: translate('licence'),
},
tilelayer: {
type: Object,
},
overlay: {
type: Object,
},
limitBounds: {
type: Object,
},
color: {
type: String,
handler: 'ColorPicker',
label: translate('color'),
helpEntries: 'colorValue',
inheritable: true,
},
iconClass: {
type: String,
label: translate('Icon shape'),
inheritable: true,
choices: [
['Default', translate('Default')],
['Circle', translate('Circle')],
['Drop', translate('Drop')],
['Ball', translate('Ball')],
],
},
iconUrl: {
type: String,
handler: 'IconUrl',
label: translate('Icon symbol'),
inheritable: true,
helpText: 'formatIconSymbol',
},
smoothFactor: {
type: Number,
min: 0,
max: 10,
step: 0.5,
label: translate('Simplify'),
helpEntries: 'smoothFactor',
inheritable: true,
},
iconOpacity: {
type: Number,
min: 0.1,
max: 1,
step: 0.1,
label: translate('icon opacity'),
inheritable: true,
},
opacity: {
type: Number,
min: 0.1,
max: 1,
step: 0.1,
label: translate('opacity'),
inheritable: true,
},
weight: {
type: Number,
min: 1,
max: 20,
step: 1,
label: translate('weight'),
inheritable: true,
},
fill: {
type: Boolean,
label: translate('fill'),
helpEntries: 'fill',
inheritable: true,
},
fillColor: {
type: String,
handler: 'ColorPicker',
label: translate('fill color'),
helpEntries: 'fillColor',
inheritable: true,
},
fillOpacity: {
type: Number,
min: 0.1,
max: 1,
step: 0.1,
label: translate('fill opacity'),
inheritable: true,
},
dashArray: {
type: String,
label: translate('dash array'),
helpEntries: 'dashArray',
inheritable: true,
},
popupShape: {
type: String,
label: translate('Popup shape'),
inheritable: true,
choices: [
['Default', translate('Popup')],
['Large', translate('Popup (large)')],
['Panel', translate('Side panel')],
],
default: 'Default',
},
popupTemplate: {
type: String,
label: translate('Popup content style'),
inheritable: true,
choices: [
['Default', translate('Default')],
['Table', translate('Table')],
['GeoRSSImage', translate('GeoRSS (title + image)')],
['GeoRSSLink', translate('GeoRSS (only link)')],
['OSM', translate('OpenStreetMap')],
],
default: 'Default',
},
popupContentTemplate: {
type: 'Text',
label: translate('Popup content template'),
helpEntries: ['dynamicProperties', 'textFormatting'],
placeholder: '# {name}',
inheritable: true,
},
zoomTo: {
type: Number,
placeholder: translate('Inherit'),
helpEntries: 'zoomTo',
label: translate('Default zoom level'),
inheritable: true,
},
captionBar: {
type: Boolean,
label: translate('Do you want to display a caption bar?'),
},
captionMenus: {
type: Boolean,
label: translate('Do you want to display caption menus?'),
},
slideshow: {
type: Object,
},
sortKey: {
type: String,
},
labelKey: {
type: String,
helpEntries: 'labelKey',
placeholder: translate('Default: name'),
label: translate('Label key'),
inheritable: true,
},
filterKey: {
type: String,
},
facetKey: {
type: String,
},
slugKey: {
type: String,
},
showLabel: {
type: Boolean,
nullable: true,
label: translate('Display label'),
inheritable: true,
default: false,
},
labelDirection: {
type: String,
label: translate('Label direction'),
inheritable: true,
choices: [
['auto', translate('Automatic')],
['left', translate('On the left')],
['right', translate('On the right')],
['top', translate('On the top')],
['bottom', translate('On the bottom')],
],
},
labelInteractive: {
type: Boolean,
label: translate('Labels are clickable'),
inheritable: true,
},
outlinkTarget: {
type: String,
label: translate('Open link in…'),
inheritable: true,
default: 'blank',
choices: [
['blank', translate('new window')],
['self', translate('iframe')],
['parent', translate('parent window')],
],
},
shortCredit: {
type: String,
label: translate('Short credits'),
helpEntries: ['shortCredit', 'textFormatting'],
},
longCredit: {
type: 'Text',
label: translate('Long credits'),
helpEntries: ['longCredit', 'textFormatting'],
},
permanentCredit: {
type: 'Text',
label: translate('Permanent credits'),
helpEntries: ['permanentCredit', 'textFormatting'],
},
permanentCreditBackground: {
type: Boolean,
label: translate('Permanent credits background'),
},
zoomControl: {
type: Boolean,
nullable: true,
label: translate('Display the zoom control'),
},
datalayersControl: {
type: Boolean,
nullable: true,
handler: 'DataLayersControl',
label: translate('Display the data layers control'),
},
searchControl: {
type: Boolean,
nullable: true,
label: translate('Display the search control'),
},
locateControl: {
type: Boolean,
nullable: true,
label: translate('Display the locate control'),
},
fullscreenControl: {
type: Boolean,
nullable: true,
label: translate('Display the fullscreen control'),
},
editinosmControl: {
type: Boolean,
nullable: true,
label: translate('Display the control to open OpenStreetMap editor'),
},
embedControl: {
type: Boolean,
nullable: true,
label: translate('Display the embed control'),
},
measureControl: {
type: Boolean,
nullable: true,
label: translate('Display the measure control'),
},
tilelayersControl: {
type: Boolean,
nullable: true,
label: translate('Display the tile layers control'),
},
starControl: {
type: Boolean,
nullable: true,
label: translate('Display the star map button'),
},
easing: {
type: Boolean,
},
interactive: {
type: Boolean,
label: translate('Allow interactions'),
helpEntries: 'interactive',
inheritable: true,
},
fromZoom: {
type: Number,
label: translate('From zoom'),
helpText: translate('Optional.'),
},
toZoom: {
type: Number,
label: translate('To zoom'),
helpText: translate('Optional.'),
},
stroke: {
type: Boolean,
label: translate('stroke'),
helpEntries: 'stroke',
inheritable: true,
},
outlink: {
label: translate('Link to…'),
helpEntries: 'outlink',
placeholder: 'http://...',
inheritable: true,
},
} }
export default { SCHEMA }

View file

@ -340,15 +340,6 @@ L.FormBuilder.TextColorPicker = L.FormBuilder.ColorPicker.extend({
], ],
}) })
L.FormBuilder.IconClassSwitcher = L.FormBuilder.Select.extend({
selectOptions: [
['Default', L._('Default')],
['Circle', L._('Circle')],
['Drop', L._('Drop')],
['Ball', L._('Ball')],
],
})
L.FormBuilder.ProxyTTLSelect = L.FormBuilder.Select.extend({ L.FormBuilder.ProxyTTLSelect = L.FormBuilder.Select.extend({
selectOptions: [ selectOptions: [
[undefined, L._('No cache')], [undefined, L._('No cache')],
@ -358,24 +349,6 @@ L.FormBuilder.ProxyTTLSelect = L.FormBuilder.Select.extend({
], ],
}) })
L.FormBuilder.PopupShape = L.FormBuilder.Select.extend({
selectOptions: [
['Default', L._('Popup')],
['Large', L._('Popup (large)')],
['Panel', L._('Side panel')],
],
})
L.FormBuilder.PopupContent = L.FormBuilder.Select.extend({
selectOptions: [
['Default', L._('Default')],
['Table', L._('Table')],
['GeoRSSImage', L._('GeoRSS (title + image)')],
['GeoRSSLink', L._('GeoRSS (only link)')],
['OSM', L._('OpenStreetMap')],
],
})
L.FormBuilder.LayerTypeChooser = L.FormBuilder.Select.extend({ L.FormBuilder.LayerTypeChooser = L.FormBuilder.Select.extend({
getOptions: function () { getOptions: function () {
const layer_classes = [ const layer_classes = [
@ -427,24 +400,6 @@ L.FormBuilder.DataLayerSwitcher = L.FormBuilder.Select.extend({
}, },
}) })
L.FormBuilder.DefaultView = L.FormBuilder.Select.extend({
selectOptions: [
['center', L._('Saved center and zoom')],
['data', L._('Fit all data')],
['latest', L._('Latest feature')],
['locate', L._('User location')],
],
})
L.FormBuilder.OnLoadPanel = L.FormBuilder.Select.extend({
selectOptions: [
['none', L._('None')],
['caption', L._('Caption')],
['databrowser', L._('Data browser')],
['facet', L._('Facet search')],
],
})
L.FormBuilder.DataFormat = L.FormBuilder.Select.extend({ L.FormBuilder.DataFormat = L.FormBuilder.Select.extend({
selectOptions: [ selectOptions: [
[undefined, L._('Choose the data format')], [undefined, L._('Choose the data format')],
@ -457,16 +412,6 @@ L.FormBuilder.DataFormat = L.FormBuilder.Select.extend({
], ],
}) })
L.FormBuilder.LabelDirection = L.FormBuilder.Select.extend({
selectOptions: [
['auto', L._('Automatic')],
['left', L._('On the left')],
['right', L._('On the right')],
['top', L._('On the top')],
['bottom', L._('On the bottom')],
],
})
L.FormBuilder.LicenceChooser = L.FormBuilder.Select.extend({ L.FormBuilder.LicenceChooser = L.FormBuilder.Select.extend({
getOptions: function () { getOptions: function () {
const licences = [] const licences = []
@ -905,7 +850,7 @@ L.FormBuilder.TernaryChoices = L.FormBuilder.MultiChoice.extend({
}, },
}) })
L.FormBuilder.ControlChoice = L.FormBuilder.TernaryChoices.extend({ L.FormBuilder.NullableChoices = L.FormBuilder.TernaryChoices.extend({
choices: [ choices: [
[true, L._('always')], [true, L._('always')],
[false, L._('never')], [false, L._('never')],
@ -913,17 +858,7 @@ L.FormBuilder.ControlChoice = L.FormBuilder.TernaryChoices.extend({
], ],
}) })
L.FormBuilder.LabelChoice = L.FormBuilder.TernaryChoices.extend({ L.FormBuilder.DataLayersControl = L.FormBuilder.TernaryChoices.extend({
default: false,
choices: [
[true, L._('always')],
[false, L._('never')],
['null', L._('on hover')],
],
})
L.FormBuilder.DataLayersControl = L.FormBuilder.ControlChoice.extend({
choices: [ choices: [
[true, L._('collapsed')], [true, L._('collapsed')],
['expanded', L._('expanded')], ['expanded', L._('expanded')],
@ -934,21 +869,11 @@ L.FormBuilder.DataLayersControl = L.FormBuilder.ControlChoice.extend({
toJS: function () { toJS: function () {
let value = this.value() let value = this.value()
if (value !== 'expanded') if (value !== 'expanded')
value = L.FormBuilder.ControlChoice.prototype.toJS.call(this) value = L.FormBuilder.TernaryChoices.prototype.toJS.call(this)
return value return value
}, },
}) })
L.FormBuilder.OutlinkTarget = L.FormBuilder.MultiChoice.extend({
default: 'blank',
choices: [
['blank', L._('new window')],
['self', L._('iframe')],
['parent', L._('parent window')],
],
})
L.FormBuilder.Range = L.FormBuilder.FloatInput.extend({ L.FormBuilder.Range = L.FormBuilder.FloatInput.extend({
type: function () { type: function () {
return 'range' return 'range'
@ -1053,232 +978,44 @@ U.FormBuilder = L.FormBuilder.extend({
}, },
defaultOptions: { defaultOptions: {
name: { label: L._('name') }, color: { handler: 'ColorPicker' },
description: { fillColor: { handler: 'ColorPicker' },
label: L._('description'), iconUrl: { handler: 'IconUrl' },
handler: 'Textarea', datalayer: { handler: 'DataLayerSwitcher' },
helpEntries: 'textFormatting', datalayersControl: { handler: 'DataLayersControl' },
}, licence: { handler: 'LicenceChooser' },
color: {
handler: 'ColorPicker',
label: L._('color'),
helpEntries: 'colorValue',
inheritable: true,
},
iconOpacity: {
handler: 'Range',
min: 0.1,
max: 1,
step: 0.1,
label: L._('icon opacity'),
inheritable: true,
},
opacity: {
handler: 'Range',
min: 0.1,
max: 1,
step: 0.1,
label: L._('opacity'),
inheritable: true,
},
stroke: {
handler: 'Switch',
label: L._('stroke'),
helpEntries: 'stroke',
inheritable: true,
},
weight: {
handler: 'Range',
min: 1,
max: 20,
step: 1,
label: L._('weight'),
inheritable: true,
},
fill: {
handler: 'Switch',
label: L._('fill'),
helpEntries: 'fill',
inheritable: true,
},
fillColor: {
handler: 'ColorPicker',
label: L._('fill color'),
helpEntries: 'fillColor',
inheritable: true,
},
fillOpacity: {
handler: 'Range',
min: 0.1,
max: 1,
step: 0.1,
label: L._('fill opacity'),
inheritable: true,
},
smoothFactor: {
handler: 'Range',
min: 0,
max: 10,
step: 0.5,
label: L._('Simplify'),
helpEntries: 'smoothFactor',
inheritable: true,
},
dashArray: {
label: L._('dash array'),
helpEntries: 'dashArray',
inheritable: true,
},
iconClass: {
handler: 'IconClassSwitcher',
label: L._('Icon shape'),
inheritable: true,
},
iconUrl: {
handler: 'IconUrl',
label: L._('Icon symbol'),
inheritable: true,
helpText: U.Help.formatIconSymbol,
},
popupShape: { handler: 'PopupShape', label: L._('Popup shape'), inheritable: true },
popupTemplate: {
handler: 'PopupContent',
label: L._('Popup content style'),
inheritable: true,
},
popupContentTemplate: {
label: L._('Popup content template'),
handler: 'Textarea',
helpEntries: ['dynamicProperties', 'textFormatting'],
placeholder: '# {name}',
inheritable: true,
},
datalayer: {
handler: 'DataLayerSwitcher',
label: L._('Choose the layer of the feature'),
},
moreControl: {
handler: 'Switch',
label: L._('Do you want to display the «more» control?'),
},
scrollWheelZoom: { handler: 'Switch', label: L._('Allow scroll wheel zoom?') },
miniMap: { handler: 'Switch', label: L._('Do you want to display a minimap?') },
scaleControl: {
handler: 'Switch',
label: L._('Do you want to display the scale control?'),
},
onLoadPanel: {
handler: 'OnLoadPanel',
label: L._('Do you want to display a panel on load?'),
},
defaultView: {
handler: 'DefaultView',
label: L._('Default view'),
},
displayPopupFooter: {
handler: 'Switch',
label: L._('Do you want to display popup footer?'),
},
captionBar: {
handler: 'Switch',
label: L._('Do you want to display a caption bar?'),
},
captionMenus: {
handler: 'Switch',
label: L._('Do you want to display caption menus?'),
},
zoomTo: {
handler: 'IntInput',
placeholder: L._('Inherit'),
helpEntries: 'zoomTo',
label: L._('Default zoom level'),
inheritable: true,
},
showLabel: {
handler: 'LabelChoice',
label: L._('Display label'),
inheritable: true,
},
labelDirection: {
handler: 'LabelDirection',
label: L._('Label direction'),
inheritable: true,
},
labelInteractive: {
handler: 'Switch',
label: L._('Labels are clickable'),
inheritable: true,
},
outlink: {
label: L._('Link to…'),
helpEntries: 'outlink',
placeholder: 'http://...',
inheritable: true,
},
outlinkTarget: {
handler: 'OutlinkTarget',
label: L._('Open link in…'),
inheritable: true,
},
labelKey: {
helpEntries: 'labelKey',
placeholder: L._('Default: name'),
label: L._('Label key'),
inheritable: true,
},
zoomControl: { handler: 'ControlChoice', label: L._('Display the zoom control') },
searchControl: {
handler: 'ControlChoice',
label: L._('Display the search control'),
},
fullscreenControl: {
handler: 'ControlChoice',
label: L._('Display the fullscreen control'),
},
embedControl: { handler: 'ControlChoice', label: L._('Display the embed control') },
locateControl: {
handler: 'ControlChoice',
label: L._('Display the locate control'),
},
measureControl: {
handler: 'ControlChoice',
label: L._('Display the measure control'),
},
tilelayersControl: {
handler: 'ControlChoice',
label: L._('Display the tile layers control'),
},
editinosmControl: {
handler: 'ControlChoice',
label: L._('Display the control to open OpenStreetMap editor'),
},
datalayersControl: {
handler: 'DataLayersControl',
label: L._('Display the data layers control'),
},
starControl: {
handler: 'ControlChoice',
label: L._('Display the star map button'),
},
fromZoom: {
handler: 'IntInput',
label: L._('From zoom'),
helpText: L._('Optional.'),
},
toZoom: { handler: 'IntInput', label: L._('To zoom'), helpText: L._('Optional.') },
interactive: {
handler: 'Switch',
label: L._('Allow interactions'),
helpEntries: 'interactive',
inheritable: true,
}, },
computeDefaultOptions: function () {
for (let [key, schema] of Object.entries(U.SCHEMA)) {
schema = L.Util.extend({}, schema, this.defaultOptions[key])
if (!schema.handler) {
if (schema.type === Boolean) {
if (schema.nullable) schema.handler = 'NullableChoices'
else schema.handler = 'Switch'
} else if (schema.type === 'Text') {
schema.handler = 'Textarea'
} else if (schema.type === Number) {
if (schema.step) schema.handler = 'Range'
else schema.handler = 'IntInput'
} else if (schema.choices) {
if (schema.choices.length <= 5) {
schema.handler = 'MultiChoice'
} else {
schema.handler = 'Select'
schema.selectOptions = schema.choices
}
}
}
// FormBuilder use this key for the input type itself
delete schema.type
this.defaultOptions[key] = schema
}
}, },
initialize: function (obj, fields, options) { initialize: function (obj, fields, options) {
this.map = obj.map || obj.getMap() this.map = obj.map || obj.getMap()
for (const [key, schema] of Object.entries(U.SCHEMA)) { this.computeDefaultOptions()
this.defaultOptions[key] = this.defaultOptions[key] || schema
}
L.FormBuilder.prototype.initialize.call(this, obj, fields, options) L.FormBuilder.prototype.initialize.call(this, obj, fields, options)
this.on('finish', this.finish) this.on('finish', this.finish)
}, },

View file

@ -271,13 +271,11 @@ U.Map = L.Map.extend({
// FIXME retrocompat // FIXME retrocompat
L.Util.setBooleanFromQueryString(options, 'displayDataBrowserOnLoad') L.Util.setBooleanFromQueryString(options, 'displayDataBrowserOnLoad')
L.Util.setBooleanFromQueryString(options, 'displayCaptionOnLoad') L.Util.setBooleanFromQueryString(options, 'displayCaptionOnLoad')
for (const [key, { type }] of Object.entries(U.SCHEMA)) { for (const [key, schema] of Object.entries(U.SCHEMA)) {
switch (type) { switch (schema.type) {
case Boolean: case Boolean:
L.Util.setBooleanFromQueryString(options, key) if (schema.nullable) L.Util.setNullableBooleanFromQueryString(options, key)
break else L.Util.setBooleanFromQueryString(options, key)
case 'NullableBoolean':
L.Util.setNullableBooleanFromQueryString(options, key)
break break
case Number: case Number:
L.Util.setNumberFromQueryString(options, key) L.Util.setNumberFromQueryString(options, key)
@ -1497,35 +1495,11 @@ U.Map = L.Map.extend({
_editCredits: function (container) { _editCredits: function (container) {
const credits = L.DomUtil.createFieldset(container, L._('Credits')) const credits = L.DomUtil.createFieldset(container, L._('Credits'))
const creditsFields = [ const creditsFields = [
['options.licence', { handler: 'LicenceChooser', label: L._('licence') }], 'options.licence',
[
'options.shortCredit', 'options.shortCredit',
{
handler: 'Input',
label: L._('Short credits'),
helpEntries: ['shortCredit', 'textFormatting'],
},
],
[
'options.longCredit', 'options.longCredit',
{
handler: 'Textarea',
label: L._('Long credits'),
helpEntries: ['longCredit', 'textFormatting'],
},
],
[
'options.permanentCredit', 'options.permanentCredit',
{
handler: 'Textarea',
label: L._('Permanent credits'),
helpEntries: ['permanentCredit', 'textFormatting'],
},
],
[
'options.permanentCreditBackground', 'options.permanentCreditBackground',
{ handler: 'Switch', label: L._('Permanent credits background') },
],
] ]
const creditsBuilder = new U.FormBuilder(this, creditsFields, { const creditsBuilder = new U.FormBuilder(this, creditsFields, {
callback: this.renderControls, callback: this.renderControls,