Various bug fixes

This commit is contained in:
Pieter Vander Vennet 2020-09-14 20:16:03 +02:00
parent 9777a2666b
commit dc5fa5dabc
13 changed files with 103 additions and 111 deletions

View file

@ -184,7 +184,7 @@ export class FromJSON {
const k = FromJSON.Tag(mapping.if, `IN mapping #${i} of tagrendering ${propertyName}`) const k = FromJSON.Tag(mapping.if, `IN mapping #${i} of tagrendering ${propertyName}`)
if (question !== undefined && !mapping.hideInAnswer && !k.isUsableAsAnswer()) { if (question !== undefined && !mapping.hideInAnswer && !k.isUsableAsAnswer()) {
throw `Invalid mapping in ${propertyName}: the tags use an OR-expression or regex expression but are also assignable as answer.` throw `Invalid mapping in ${propertyName}.${i}: this mapping uses a regex tag or an OR, but is also answerable. Either mark 'Not an answer option' or only use '=' to map key/values.`
} }
return { return {

View file

@ -39,6 +39,7 @@ export class FilteredLayer {
* The leaflet layer object which should be removed on rerendering * The leaflet layer object which should be removed on rerendering
*/ */
private _geolayer; private _geolayer;
private _showOnPopup: (tags: UIEventSource<any>, feature: any) => UIElement; private _showOnPopup: (tags: UIEventSource<any>, feature: any) => UIElement;
private static readonly grid = codegrid.CodeGrid(); private static readonly grid = codegrid.CodeGrid();
@ -287,7 +288,7 @@ export class FilteredLayer {
}).setContent(uiElement.Render()) }).setContent(uiElement.Render())
.setLatLng(e.latlng) .setLatLng(e.latlng)
.openOn(State.state.bm.map); .openOn(State.state.bm.map);
uiElement.Update();
L.DomEvent.stop(e); // Marks the event as consumed L.DomEvent.stop(e); // Marks the event as consumed
}); });
} }

View file

@ -22,7 +22,7 @@ export class State {
// The singleton of the global state // The singleton of the global state
public static state: State; public static state: State;
public static vNumber = "0.0.7l"; public static vNumber = "0.0.7m";
// The user journey states thresholds when a new feature gets unlocked // The user journey states thresholds when a new feature gets unlocked
public static userJourney = { public static userJourney = {

View file

@ -31,6 +31,7 @@ export default class AllLayersPanel extends UIElement {
this.createPanels(userDetails); this.createPanels(userDetails);
const self = this; const self = this;
this.dumbMode = false;
config.map<number>(config => config.layers.length).addCallback(() => self.createPanels(userDetails)); config.map<number>(config => config.layers.length).addCallback(() => self.createPanels(userDetails));
} }

View file

@ -65,9 +65,6 @@ export default class TagRenderingPanel extends InputElement<TagRenderingConfigJs
setting(options?.noLanguage ? TextField.StringInput() : new MultiLingualTextFields(languages) setting(options?.noLanguage ? TextField.StringInput() : new MultiLingualTextFields(languages)
, "question", "Question", "If the key or mapping doesn't match, this question is asked"), , "question", "Question", "If the key or mapping doesn't match, this question is asked"),
setting(new AndOrTagInput(), "condition", "Condition",
"Only show this tag rendering if these tags matches. Optional field.<br/>Note that the Overpass-tags are already always included in this object"),
"<h3>Freeform key</h3>", "<h3>Freeform key</h3>",
setting(TextField.KeyInput(true), ["freeform", "key"], "Freeform key<br/>", setting(TextField.KeyInput(true), ["freeform", "key"], "Freeform key<br/>",
"If specified, the rendering will search if this key is present." + "If specified, the rendering will search if this key is present." +
@ -86,7 +83,7 @@ export default class TagRenderingPanel extends InputElement<TagRenderingConfigJs
options?.noLanguage ? TextField.StringInput() : options?.noLanguage ? TextField.StringInput() :
new MultiLingualTextFields(languages), "render", "Value to show", " Renders this value. Note that <span class='literal-code'>{key}</span>-parts are substituted by the corresponding values of the element. If neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value."), new MultiLingualTextFields(languages), "render", "Value to show", " Renders this value. Note that <span class='literal-code'>{key}</span>-parts are substituted by the corresponding values of the element. If neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value."),
questionsNotUnlocked ? `You need at least ${State.userJourney.themeGeneratorFullUnlock} changesets to unlock the 'question'-field and to use your theme to edit OSM data`: "", questionsNotUnlocked ? `You need at least ${State.userJourney.themeGeneratorFullUnlock} changesets to unlock the 'question'-field and to use your theme to edit OSM data` : "",
...(options?.disableQuestions ? [] : questionSettings), ...(options?.disableQuestions ? [] : questionSettings),
"<h3>Mappings</h3>", "<h3>Mappings</h3>",
@ -94,7 +91,12 @@ export default class TagRenderingPanel extends InputElement<TagRenderingConfigJs
() => ({if: {and: []}, then: {}}), () => ({if: {and: []}, then: {}}),
() => new MappingInput(languages, options?.disableQuestions ?? false), () => new MappingInput(languages, options?.disableQuestions ?? false),
undefined, {allowMovement: true}), "mappings", undefined, {allowMovement: true}), "mappings",
"If a tag matches, then show the first respective text", "") "If a tag matches, then show the first respective text", ""),
"<h3>Condition</h3>",
setting(new AndOrTagInput(), "condition", "Only show this tagrendering if the following condition applies",
"Only show this tag rendering if these tags matches. Optional field.<br/>Note that the Overpass-tags are already always included in this object"),
]; ];

View file

@ -2,7 +2,6 @@ import {UIElement} from "../UIElement";
import {UIEventSource} from "../../Logic/UIEventSource"; import {UIEventSource} from "../../Logic/UIEventSource";
import TagRenderingPanel from "./TagRenderingPanel"; import TagRenderingPanel from "./TagRenderingPanel";
import {VariableUiElement} from "../Base/VariableUIElement"; import {VariableUiElement} from "../Base/VariableUIElement";
import {TagRenderingConfigJson} from "../../Customizations/JSON/TagRenderingConfigJson";
import {FromJSON} from "../../Customizations/JSON/FromJSON"; import {FromJSON} from "../../Customizations/JSON/FromJSON";
import {FixedUiElement} from "../Base/FixedUiElement"; import {FixedUiElement} from "../Base/FixedUiElement";
import Combine from "../Base/Combine"; import Combine from "../Base/Combine";
@ -33,7 +32,6 @@ export default class TagRenderingPreview extends UIElement {
} }
let es = tagRenderingPanel.GetValue(); let es = tagRenderingPanel.GetValue();
let tagRenderingConfig: TagRenderingConfigJson = es.data;
let rendering: UIElement; let rendering: UIElement;
try { try {

View file

@ -39,7 +39,7 @@ export class FeatureInfoBox extends UIElement {
this._feature = feature; this._feature = feature;
this._tagsES = tagsES; this._tagsES = tagsES;
this.ListenTo(State.state.osmConnection.userDetails); this.ListenTo(State.state.osmConnection.userDetails);
this.SetClass("featureinfobox");
const deps = {tags: this._tagsES, changes: this._changes} const deps = {tags: this._tagsES, changes: this._changes}
this._infoboxes = []; this._infoboxes = [];
@ -153,7 +153,7 @@ export class FeatureInfoBox extends UIElement {
this._title, this._title,
"<div class='infoboxcontents'>", "<div class='infoboxcontents'>",
infoboxcontents, infoboxcontents,
"</div>"]).SetClass("featureinfobox") "</div>"])
.Render(); .Render();
} }

View file

@ -25,6 +25,7 @@ export class MultiInput<T> extends InputElement<T[]> {
super(undefined); super(undefined);
this._value = value ?? new UIEventSource<T[]>([]); this._value = value ?? new UIEventSource<T[]>([]);
value = this._value; value = this._value;
this.ListenTo(value.map((latest : T[]) => latest.length));
this._options = options ?? {}; this._options = options ?? {};
this.addTag = new SubtleButton("./assets/addSmall.svg", addAElement) this.addTag = new SubtleButton("./assets/addSmall.svg", addAElement)

View file

@ -42,7 +42,7 @@ export class SimpleAddUI extends UIElement {
this._loginButton = Translations.t.general.add.pleaseLogin.Clone().onClick(() => State.state.osmConnection.AttemptLogin()); this._loginButton = Translations.t.general.add.pleaseLogin.Clone().onClick(() => State.state.osmConnection.AttemptLogin());
this._addButtons = []; this._addButtons = [];
this.SetClass("add-ui"); this.SetStyle("font-size:large");
const self = this; const self = this;
for (const layer of State.state.filteredLayers.data) { for (const layer of State.state.filteredLayers.data) {
@ -140,7 +140,7 @@ export class SimpleAddUI extends UIElement {
return new Combine([ return new Combine([
Translations.t.general.add.confirmIntro.Subs({title: this._confirmPreset.data.name}), Translations.t.general.add.confirmIntro.Subs({title: this._confirmPreset.data.name}),
userDetails.data.dryRun ? "<span class='alert'>TESTING - changes won't be saved</span>":"", userDetails.data.dryRun ? "<span class='alert'>TESTING - changes won't be saved</span>" : "",
this.confirmButton, this.confirmButton,
this.cancelButton, this.cancelButton,
tagInfo tagInfo

View file

@ -292,14 +292,13 @@ export class TagRendering extends UIElement implements TagDependantUIElement {
private InputElementForMapping(mapping: { k: TagsFilter, txt: (string | Translation) }, substituteValues: boolean): FixedInputElement<TagsFilter> { private InputElementForMapping(mapping: { k: TagsFilter, txt: (string | Translation) }, substituteValues: boolean): FixedInputElement<TagsFilter> {
if (substituteValues) { if (substituteValues) {
return new FixedInputElement(this.ApplyTemplate(mapping.txt), return new FixedInputElement(this.ApplyTemplate(mapping.txt),
mapping.k.substituteValues(this.currentTags.data), mapping.k.substituteValues(this.currentTags.data),
(t0, t1) => t0.isEquivalent(t1) (t0, t1) => t0.isEquivalent(t1)
); );
} }
return new FixedInputElement(this.ApplyTemplate(mapping.txt), mapping.k, return new FixedInputElement(this.ApplyTemplate(mapping.txt), mapping.k,
(t0, t1) => t0.isEquivalent(t1)); (t0, t1) => t1.isEquivalent(t0));
} }

View file

@ -191,7 +191,6 @@ export abstract class UIElement extends UIEventSource<string> {
this.clss.push(clss); this.clss.push(clss);
this.Update(); this.Update();
} }
console.log(this.clss)
return this; return this;
} }

View file

@ -19,10 +19,21 @@
"if": { "if": {
"and": [ "and": [
"cyclestreet=yes", "cyclestreet=yes",
"maxspeed=30",
"proposed:cyclestreet=" "proposed:cyclestreet="
] ]
}, },
"then": "Deze straat is een fietsstraat" "then": "Deze straat is een fietsstraat (en dus zone 30)"
},
{
"if": {
"and": [
"cyclestreet=yes",
"proposed:cyclestreet="
]
},
"then": "Deze straat is een fietsstraat",
"hideInAnswer": true
}, },
{ {
"if": { "if": {

View file

@ -59,12 +59,10 @@ body {
background-color: #fee4d1; background-color: #fee4d1;
font-weight: bold; font-weight: bold;
border-radius: 1em; border-radius: 1em;
padding: 0.3em;
margin: 0.25em; margin: 0.25em;
text-align: center; text-align: center;
padding-top: 0.15em; padding: 0.15em 0.3em;
padding-bottom: 0.15em; }
}
form { form {
display: inline; display: inline;
@ -87,11 +85,9 @@ body {
background-color: #e5f5ff; background-color: #e5f5ff;
font-weight: bold; font-weight: bold;
border-radius: 1em; border-radius: 1em;
padding: 0.3em;
margin: 0.25em; margin: 0.25em;
text-align: center; text-align: center;
padding-top: 0.15em; padding: 0.15em 0.3em;
padding-bottom: 0.15em;
} }
@ -107,11 +103,9 @@ body {
background-color: #43d904; background-color: #43d904;
font-weight: bold; font-weight: bold;
border-radius: 1em; border-radius: 1em;
padding: 0.3em;
margin: 0.25em; margin: 0.25em;
text-align: center; text-align: center;
padding-top: 0.15em; padding: 0.15em 0.3em;
padding-bottom: 0.15em;
} }
.clickable { .clickable {
@ -139,8 +133,7 @@ body {
transition: all 500ms linear; transition: all 500ms linear;
pointer-events: all; pointer-events: all;
border-radius: 1.3em; border-radius: 1.3em;
margin: 0; margin: 0 0 0.5em;
margin-bottom: 0.5em;
width: 100%; width: 100%;
} }
@ -212,8 +205,7 @@ body {
/* Landscape and portrait */ /* Landscape and portrait */
#topleft-tools { #topleft-tools {
padding: 0.1em; padding: 0.1em 0.1em 0.1em unset;
padding-left: unset;
} }
@ -266,14 +258,12 @@ body {
#topleft-tools { #topleft-tools {
display: block; display: block;
position: absolute; position: absolute;
padding: 0;
padding-top: 0.5em;
padding-left:0.5em;
z-index: 5000; z-index: 5000;
transition: all 500ms linear; transition: all 500ms linear;
overflow: hidden; overflow: hidden;
pointer-events: none; pointer-events: none;
padding-right: 10px; /* Shadow offset */ /* Shadow offset */
padding: 0.5em 10px 0 0.5em;
} }
@ -321,7 +311,6 @@ body {
.collapse-button-img img{ .collapse-button-img img{
width: 1.5em; width: 1.5em;
padding: 0.5em;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
@ -329,9 +318,7 @@ body {
#welcomeMessage { #welcomeMessage {
display: inline-block; display: inline-block;
margin-left: 3.5em; margin-left: 3.5em;
border-radius: 2em; border-radius: 0 2em 2em 0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
max-width: 40em; max-width: 40em;
width: 45vw; width: 45vw;
max-height: calc(100vh - 15em); max-height: calc(100vh - 15em);
@ -526,8 +513,7 @@ body {
.infoboxcontents { .infoboxcontents {
margin: 0.5em; margin: 1em 0.5em 0.5em;
margin-top: 1em;
} }
@ -579,9 +565,7 @@ body {
border: solid white 2px; border: solid white 2px;
background-color: #3a3aeb; background-color: #3a3aeb;
color: white; color: white;
padding: 0.2em; padding: 0.2em 0.6em;
padding-left: 0.6em;
padding-right: 0.6em;
font-size: large; font-size: large;
font-weight: bold; font-weight: bold;
border-radius: 1.5em; border-radius: 1.5em;
@ -599,34 +583,33 @@ body {
border-radius: 1.5em; border-radius: 1.5em;
} }
/****** ShareScreen *****/ /****** ShareScreen *****/
.literal-code { .literal-code {
display: inline-block; display: inline-block;
background-color: lightgray; background-color: lightgray;
padding: 0.5em; padding: 0.5em;
word-break: break-all; word-break: break-all;
color: black; color: black;
box-sizing: border-box; box-sizing: border-box;
} }
.iframe-escape { .iframe-escape {
background-color: white; background-color: white;
border-radius: 2em; border-radius: 2em;
display: block; display: block;
width: min-content; width: min-content;
} }
.iframe-escape img { .iframe-escape img {
padding: 1em; padding: 1em;
width: 2em; width: 2em;
height: 2em; height: 2em;
} }
/** Switch layout **/ /** Switch layout **/
.subtle-button {
.subtle-button {
display: flex; display: flex;
flex-wrap: nowrap; flex-wrap: nowrap;
flex-direction: row; flex-direction: row;
@ -637,40 +620,37 @@ body {
align-items: center; align-items: center;
text-decoration: none; text-decoration: none;
color: black; color: black;
} }
.subtle-button a { .subtle-button a {
text-decoration: unset !important; text-decoration: unset !important;
color: unset !important; color: unset !important;
display: block ruby; display: block ruby;
} }
.round-button .subtle-button { .round-button .subtle-button {
width: 2em; width: 2em;
height: 2em; height: 2em;
border-radius: 1em; border-radius: 1em;
display: block !important; display: block !important;
margin: 0; margin: 0;
padding: 0.5em; padding: 0.5em;
} }
.small-button .subtle-button { .small-button .subtle-button {
height: 2em; height: 2em;
} }
.small-button .subtle-button img { .small-button .subtle-button img {
max-height: 1.8em; max-height: 1.8em;
} }
.subtle-button img { .subtle-button img {
max-width: 3em; max-width: 3em;
max-height: 3em; max-height: 3em;
margin-right: 0.5em; margin-right: 0.5em;
padding: 0.5em; padding: 0.5em;
} }
.add-ui {
font-size: large;
}