Various bug fixes
This commit is contained in:
parent
9777a2666b
commit
dc5fa5dabc
13 changed files with 103 additions and 111 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
2
State.ts
2
State.ts
|
@ -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 = {
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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": {
|
||||||
|
|
82
index.css
82
index.css
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue