Add loading from JSON in the custom generator, small clarifications
This commit is contained in:
parent
93bfa73088
commit
115dc0249c
5 changed files with 42 additions and 16 deletions
|
@ -264,6 +264,11 @@ export class FromJSON {
|
||||||
const iconSize = FromJSON.TagRenderingWithDefault(json.iconSize, "iconSize", "40,40,center");
|
const iconSize = FromJSON.TagRenderingWithDefault(json.iconSize, "iconSize", "40,40,center");
|
||||||
const color = FromJSON.TagRenderingWithDefault(json.color, "layercolor", "#0000ff");
|
const color = FromJSON.TagRenderingWithDefault(json.color, "layercolor", "#0000ff");
|
||||||
const width = FromJSON.TagRenderingWithDefault(json.width, "layerwidth", "10");
|
const width = FromJSON.TagRenderingWithDefault(json.width, "layerwidth", "10");
|
||||||
|
if(json.title === "Layer"){
|
||||||
|
json.title = {};
|
||||||
|
}
|
||||||
|
let title= FromJSON.TagRendering(json.title);
|
||||||
|
|
||||||
|
|
||||||
let tagRenderingDefs = json.tagRenderings ?? [];
|
let tagRenderingDefs = json.tagRenderings ?? [];
|
||||||
let hasImageElement = false;
|
let hasImageElement = false;
|
||||||
|
@ -338,7 +343,7 @@ export class FromJSON {
|
||||||
icon: icon.GetContent(renderTags).txt,
|
icon: icon.GetContent(renderTags).txt,
|
||||||
overpassFilter: overpassTags,
|
overpassFilter: overpassTags,
|
||||||
|
|
||||||
title: FromJSON.TagRendering(json.title),
|
title: title,
|
||||||
minzoom: json.minzoom,
|
minzoom: json.minzoom,
|
||||||
presets: presets,
|
presets: presets,
|
||||||
elementsToShow: tagRenderings,
|
elementsToShow: tagRenderings,
|
||||||
|
|
|
@ -9,7 +9,7 @@ export class GenerateEmpty {
|
||||||
name: "Layer",
|
name: "Layer",
|
||||||
minzoom: 12,
|
minzoom: 12,
|
||||||
overpassTags: {and: [""]},
|
overpassTags: {and: [""]},
|
||||||
title: "Layer",
|
title: {},
|
||||||
description: {},
|
description: {},
|
||||||
tagRenderings: [],
|
tagRenderings: [],
|
||||||
icon: {
|
icon: {
|
||||||
|
|
|
@ -5,10 +5,14 @@ import {LayoutConfigJson} from "../../Customizations/JSON/LayoutConfigJson";
|
||||||
import Combine from "../Base/Combine";
|
import Combine from "../Base/Combine";
|
||||||
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
||||||
import {FixedUiElement} from "../Base/FixedUiElement";
|
import {FixedUiElement} from "../Base/FixedUiElement";
|
||||||
|
import {TextField} from "../Input/TextField";
|
||||||
|
import {SubtleButton} from "../Base/SubtleButton";
|
||||||
|
import {FromJSON} from "../../Customizations/JSON/FromJSON";
|
||||||
|
|
||||||
export default class SavePanel extends UIElement {
|
export default class SavePanel extends UIElement {
|
||||||
private json: UIElement;
|
private json: UIElement;
|
||||||
private lastSaveEl: UIElement;
|
private lastSaveEl: UIElement;
|
||||||
|
private loadFromJson: UIElement;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
connection: OsmConnection,
|
connection: OsmConnection,
|
||||||
|
@ -17,7 +21,6 @@ export default class SavePanel extends UIElement {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.lastSaveEl = new VariableUiElement(chronic
|
this.lastSaveEl = new VariableUiElement(chronic
|
||||||
.map(date => {
|
.map(date => {
|
||||||
if (date === undefined) {
|
if (date === undefined) {
|
||||||
|
@ -26,12 +29,25 @@ export default class SavePanel extends UIElement {
|
||||||
return "Your theme was last saved at " + date.toISOString()
|
return "Your theme was last saved at " + date.toISOString()
|
||||||
})).onClick(() => chronic.setData(new Date()));
|
})).onClick(() => chronic.setData(new Date()));
|
||||||
|
|
||||||
this.json = new VariableUiElement(config.map(config => {
|
const jsonStr = config.map(config =>
|
||||||
return JSON.stringify(config, null, 2)
|
JSON.stringify(config, null, 2));
|
||||||
.replace(/\n/g, "<br/>")
|
|
||||||
.replace(/ /g, " ");
|
|
||||||
}))
|
const jsonTextField = new TextField({
|
||||||
.SetClass("literal-code");
|
placeholder: "JSON Config",
|
||||||
|
fromString: str => str,
|
||||||
|
toString: str => str,
|
||||||
|
value: jsonStr,
|
||||||
|
startValidated: false,
|
||||||
|
textArea: true,
|
||||||
|
textAreaRows: 20
|
||||||
|
});
|
||||||
|
this.json = jsonTextField;
|
||||||
|
this.loadFromJson = new SubtleButton("./assets/reload.svg", "<b>Load the JSON file below</b>")
|
||||||
|
.onClick(() => {
|
||||||
|
const json = jsonTextField.GetValue().data;
|
||||||
|
config.setData(JSON.parse(json));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
InnerRender(): string {
|
InnerRender(): string {
|
||||||
|
@ -41,6 +57,8 @@ export default class SavePanel extends UIElement {
|
||||||
"<h3>JSON configuration</h3>",
|
"<h3>JSON configuration</h3>",
|
||||||
"The url hash is actually no more then a BASE64-encoding of the below JSON. This json contains the full configuration of the theme.<br/>" +
|
"The url hash is actually no more then a BASE64-encoding of the below JSON. This json contains the full configuration of the theme.<br/>" +
|
||||||
"This configuration is mainly useful for debugging",
|
"This configuration is mainly useful for debugging",
|
||||||
|
"<br/>",
|
||||||
|
this.loadFromJson,
|
||||||
this.json
|
this.json
|
||||||
]).SetClass("scrollable")
|
]).SetClass("scrollable")
|
||||||
.Render();
|
.Render();
|
||||||
|
|
|
@ -111,6 +111,7 @@ export class TextField<T> extends InputElement<T> {
|
||||||
private readonly startValidated: boolean;
|
private readonly startValidated: boolean;
|
||||||
public readonly IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
public readonly IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
||||||
private readonly _isArea: boolean;
|
private readonly _isArea: boolean;
|
||||||
|
private _textAreaRows: number;
|
||||||
|
|
||||||
constructor(options: {
|
constructor(options: {
|
||||||
/**
|
/**
|
||||||
|
@ -131,7 +132,8 @@ export class TextField<T> extends InputElement<T> {
|
||||||
fromString: (string: string) => T,
|
fromString: (string: string) => T,
|
||||||
value?: UIEventSource<T>,
|
value?: UIEventSource<T>,
|
||||||
startValidated?: boolean,
|
startValidated?: boolean,
|
||||||
textArea?: boolean
|
textArea?: boolean,
|
||||||
|
textAreaRows?: number
|
||||||
}) {
|
}) {
|
||||||
super(undefined);
|
super(undefined);
|
||||||
const self = this;
|
const self = this;
|
||||||
|
@ -144,7 +146,7 @@ export class TextField<T> extends InputElement<T> {
|
||||||
this._fromString = options.fromString ?? ((str) => (str))
|
this._fromString = options.fromString ?? ((str) => (str))
|
||||||
this.value.addCallback((str) => this.mappedValue.setData(options.fromString(str)));
|
this.value.addCallback((str) => this.mappedValue.setData(options.fromString(str)));
|
||||||
this.mappedValue.addCallback((t) => this.value.setData(options.toString(t)));
|
this.mappedValue.addCallback((t) => this.value.setData(options.toString(t)));
|
||||||
|
this._textAreaRows = options.textAreaRows;
|
||||||
|
|
||||||
this._placeholder = Translations.W(options.placeholder ?? "");
|
this._placeholder = Translations.W(options.placeholder ?? "");
|
||||||
this.ListenTo(this._placeholder._source);
|
this.ListenTo(this._placeholder._source);
|
||||||
|
@ -171,7 +173,7 @@ export class TextField<T> extends InputElement<T> {
|
||||||
InnerRender(): string {
|
InnerRender(): string {
|
||||||
|
|
||||||
if(this._isArea){
|
if(this._isArea){
|
||||||
return `<textarea id="text-${this.id}" class="form-text-field" rows="4" cols="50" style="max-width: 100%;box-sizing: border-box"></textarea>`
|
return `<textarea id="text-${this.id}" class="form-text-field" rows="${this._textAreaRows}" cols="50" style="max-width: 100%; width: 100%; box-sizing: border-box"></textarea>`
|
||||||
}
|
}
|
||||||
|
|
||||||
return `<form onSubmit='return false' class='form-text-field'>` +
|
return `<form onSubmit='return false' class='form-text-field'>` +
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
"id": "fietsstraten",
|
"id": "fietsstraten",
|
||||||
"version": "2020-08-30",
|
"version": "2020-08-30",
|
||||||
"title": "Fietsstraten",
|
"title": "Fietsstraten",
|
||||||
"description": "Een fietsstraat is een straat waar <b>automobilisten geen fietsers mogen inhalen</b> en waar een maximumsnelheid van <b>30km/u</b> geldt.<br/><br/>Op deze open kaart kan je alle gekende fietsstraten zien en kan je ontbrekende fietsstraten aanduiden. Om de kaart aan te passen, moet je je aanmelden met OpenStreetMap en helemaal inzoomen tot straatniveau.",
|
"description": "Een fietsstraat is een straat waar <ul><li><b>automobilisten geen fietsers mogen inhalen</b></li><li>Er een maximumsnelheid van <b>30km/u</b> geldt</li><li>Fietsers gemotoriseerde voortuigen links mogen inhalen</li><li>Fietsers nog steeds voorrang aan rechts moeten verlenen - ook aan auto's en voetgangers op het zebrapad</li></ul><br/><br/>Op deze open kaart kan je alle gekende fietsstraten zien en kan je ontbrekende fietsstraten aanduiden. Om de kaart aan te passen, moet je je aanmelden met OpenStreetMap en helemaal inzoomen tot straatniveau.",
|
||||||
|
|
||||||
"icon": "./assets/themes/cyclestreets/F111.svg",
|
"icon": "./assets/themes/cyclestreets/F111.svg",
|
||||||
"language": "nl",
|
"language": "nl",
|
||||||
"startLat": 51.2095,
|
"startLat": 51.2095,
|
||||||
|
|
Loading…
Reference in a new issue