forked from MapComplete/MapComplete
Fix bugs with themes, add movement of tag renderings in custom theme generator
This commit is contained in:
parent
80f0dbe6e3
commit
b7b1bc13e4
180 changed files with 671 additions and 967 deletions
|
@ -18,6 +18,10 @@ export default class Combine extends UIElement {
|
|||
InnerRender(): string {
|
||||
let elements = "";
|
||||
for (const element of this.uiElements) {
|
||||
if(element === undefined){
|
||||
continue;
|
||||
}
|
||||
|
||||
if (element instanceof UIElement) {
|
||||
elements += element.Render();
|
||||
} else {
|
||||
|
|
|
@ -7,6 +7,9 @@ import Combine from "../Base/Combine";
|
|||
import {GenerateEmpty} from "./GenerateEmpty";
|
||||
import LayerPanelWithPreview from "./LayerPanelWithPreview";
|
||||
import {UserDetails} from "../../Logic/Osm/OsmConnection";
|
||||
import {MultiInput} from "../Input/MultiInput";
|
||||
import TagRenderingPanel from "./TagRenderingPanel";
|
||||
import SingleSetting from "./SingleSetting";
|
||||
|
||||
export default class AllLayersPanel extends UIElement {
|
||||
|
||||
|
@ -14,10 +17,13 @@ export default class AllLayersPanel extends UIElement {
|
|||
private panel: UIElement;
|
||||
private readonly _config: UIEventSource<LayoutConfigJson>;
|
||||
private readonly languages: UIEventSource<string[]>;
|
||||
private readonly userDetails: UserDetails;
|
||||
private readonly currentlySelected: UIEventSource<SingleSetting<any>>;
|
||||
|
||||
constructor(config: UIEventSource<LayoutConfigJson>,
|
||||
languages: UIEventSource<any>, userDetails: UserDetails) {
|
||||
super(undefined);
|
||||
this.userDetails = userDetails;
|
||||
this._config = config;
|
||||
this.languages = languages;
|
||||
|
||||
|
@ -32,6 +38,15 @@ export default class AllLayersPanel extends UIElement {
|
|||
const self = this;
|
||||
const tabs = [];
|
||||
|
||||
|
||||
const roamingTags = new MultiInput("Add a tagrendering",
|
||||
() => GenerateEmpty.createEmptyTagRendering(),
|
||||
() => {
|
||||
return new TagRenderingPanel(self.languages, self.currentlySelected, self.userDetails)
|
||||
|
||||
}, undefined, {allowMovement: true});
|
||||
new SingleSetting(this._config, roamingTags, "roamingRenderings", "Roaming Renderings", "These tagrenderings are shown everywhere");
|
||||
|
||||
const layers = this._config.data.layers;
|
||||
for (let i = 0; i < layers.length; i++) {
|
||||
|
||||
|
@ -43,15 +58,20 @@ export default class AllLayersPanel extends UIElement {
|
|||
tabs.push({
|
||||
header: "<img src='./assets/layersAdd.svg'>",
|
||||
content: new Combine([
|
||||
"<h2>Layer editor</h2>",
|
||||
"In this tab page, you can add and edit the layers of the theme. Click the layers above or add a new layer to get started.",
|
||||
new SubtleButton(
|
||||
"./assets/layersAdd.svg",
|
||||
"Add a new layer"
|
||||
).onClick(() => {
|
||||
self._config.data.layers.push(GenerateEmpty.createEmptyLayer())
|
||||
self._config.ping();
|
||||
})])
|
||||
"<h2>Layer editor</h2>",
|
||||
"In this tab page, you can add and edit the layers of the theme. Click the layers above or add a new layer to get started.",
|
||||
new SubtleButton(
|
||||
"./assets/layersAdd.svg",
|
||||
"Add a new layer"
|
||||
).onClick(() => {
|
||||
self._config.data.layers.push(GenerateEmpty.createEmptyLayer())
|
||||
self._config.ping();
|
||||
}),
|
||||
"<h2>TagRenderings for every layer</h2>",
|
||||
"Define tag renderings and questions here that should be shown on every layer of the theme.",
|
||||
roamingTags
|
||||
]
|
||||
),
|
||||
})
|
||||
|
||||
this.panel = new TabbedComponent(tabs, new UIEventSource<number>(Math.max(0, layers.length - 1)));
|
||||
|
|
|
@ -120,7 +120,7 @@ export default class LayerPanel extends UIElement {
|
|||
const tagPanel = new TagRenderingPanel(languages, currentlySelected, userDetails)
|
||||
self.registerTagRendering(tagPanel);
|
||||
return tagPanel;
|
||||
});
|
||||
}, undefined, {allowMovement:true});
|
||||
tagRenderings.GetValue().addCallback(
|
||||
tagRenderings => {
|
||||
(config.data.layers[index] as LayerConfigJson).tagRenderings = tagRenderings;
|
||||
|
@ -132,7 +132,8 @@ export default class LayerPanel extends UIElement {
|
|||
|
||||
const presetPanel = new MultiInput("Add a preset",
|
||||
() => ({tags: [], title: {}}),
|
||||
() => new PresetInputPanel(currentlySelected, languages));
|
||||
() => new PresetInputPanel(currentlySelected, languages),
|
||||
undefined, {allowMovement: true});
|
||||
new SingleSetting(config, presetPanel, ["layers", index, "presets"], "Presets", "")
|
||||
this.presetsPanel = presetPanel;
|
||||
} else {
|
||||
|
|
|
@ -33,7 +33,7 @@ export default class PresetInputPanel extends InputElement<{
|
|||
s(new MultiTagInput(), "tags","Preset tags","These tags will be applied on the newly created point"),
|
||||
s(new MultiLingualTextFields(languages), "title","Preset title","This little text is shown in bold on the 'create new point'-button" ),
|
||||
s(new MultiLingualTextFields(languages), "description","Description", "This text is shown in the button as description when creating a new point")
|
||||
], currentlySelected);
|
||||
], currentlySelected).SetStyle("display: block; border: 1px solid black; border-radius: 1em;padding: 1em;");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,14 +12,20 @@ export class MultiInput<T> extends InputElement<T[]> {
|
|||
private elements: UIElement[] = [];
|
||||
private inputELements: InputElement<T>[] = [];
|
||||
private addTag: UIElement;
|
||||
private _options: { allowMovement?: boolean };
|
||||
|
||||
constructor(
|
||||
addAElement: string,
|
||||
newElement: (() => T),
|
||||
createInput: (() => InputElement<T>),
|
||||
value: UIEventSource<T[]> = new UIEventSource<T[]>([])) {
|
||||
value: UIEventSource<T[]> = undefined,
|
||||
options?: {
|
||||
allowMovement?: boolean
|
||||
}) {
|
||||
super(undefined);
|
||||
this._value = value;
|
||||
this._value = value ?? new UIEventSource<T[]>([]);
|
||||
value = this._value;
|
||||
this._options = options ?? {};
|
||||
|
||||
this.addTag = new SubtleButton("./assets/addSmall.svg", addAElement)
|
||||
.SetClass("small-button")
|
||||
|
@ -54,7 +60,6 @@ export class MultiInput<T> extends InputElement<T[]> {
|
|||
this.elements = [];
|
||||
const self = this;
|
||||
for (let i = 0; i < this._value.data.length; i++) {
|
||||
let tag = this._value.data[i];
|
||||
const input = createInput();
|
||||
input.GetValue().addCallback(tag => {
|
||||
self._value.data[i] = tag;
|
||||
|
@ -63,12 +68,40 @@ export class MultiInput<T> extends InputElement<T[]> {
|
|||
);
|
||||
this.inputELements.push(input);
|
||||
input.IsSelected.addCallback(() => this.UpdateIsSelected());
|
||||
const deleteBtn = new FixedUiElement("<img src='./assets/delete.svg' style='max-width: 1.5em; margin-left: 5px;'>")
|
||||
|
||||
const moveUpBtn = new FixedUiElement("<img src='./assets/up.svg' style='max-width: 1.5em; margin-left: 5px;'>")
|
||||
.onClick(() => {
|
||||
const v = self._value.data[i];
|
||||
self._value.data[i] = self._value.data[i - 1];
|
||||
self._value.data[i - 1] = v;
|
||||
self._value.ping();
|
||||
});
|
||||
|
||||
const moveDownBtn = new FixedUiElement("<img src='./assets/down.svg' style='max-width: 1.5em; margin-left: 5px;'>")
|
||||
.onClick(() => {
|
||||
const v = self._value.data[i];
|
||||
self._value.data[i] = self._value.data[i + 1];
|
||||
self._value.data[i + 1] = v;
|
||||
self._value.ping();
|
||||
});
|
||||
|
||||
const controls = [];
|
||||
if (i > 0 && this._options.allowMovement) {
|
||||
controls.push(moveUpBtn);
|
||||
}
|
||||
|
||||
if (i + 1 < this._value.data.length && this._options.allowMovement) {
|
||||
controls.push(moveDownBtn);
|
||||
}
|
||||
|
||||
|
||||
const deleteBtn = new FixedUiElement("<img src='./assets/delete.svg' style='max-width: 1.5em;width:1.5em; margin-left: 5px;'>")
|
||||
.onClick(() => {
|
||||
self._value.data.splice(i, 1);
|
||||
self._value.ping();
|
||||
});
|
||||
this.elements.push(new Combine([input, deleteBtn, "<br/>"]).SetClass("tag-input-row"))
|
||||
controls.push(deleteBtn);
|
||||
this.elements.push(new Combine([input.SetStyle("width: calc(100% - 2em - 5px)"), new Combine(controls).SetStyle("display:flex;flex-direction:column;width:min-content;")]).SetClass("tag-input-row"))
|
||||
}
|
||||
|
||||
this.Update();
|
||||
|
|
|
@ -176,7 +176,7 @@ export class ShareScreen extends UIElement {
|
|||
new VariableUiElement(
|
||||
State.state.osmConnection.userDetails.map(
|
||||
userDetails => {
|
||||
if (userDetails.csCount <= State.userJourney.themeGeneratorUnlock) {
|
||||
if (userDetails.csCount <= State.userJourney.themeGeneratorReadOnlyUnlock) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import {Utils} from "../Utils";
|
|||
import {UIEventSource} from "../Logic/UIEventSource";
|
||||
import {SubtleButton} from "./Base/SubtleButton";
|
||||
import {InitUiElements} from "../InitUiElements";
|
||||
import Combine from "./Base/Combine";
|
||||
|
||||
/**
|
||||
* Handles and updates the user badge
|
||||
|
@ -110,14 +111,14 @@ export class UserBadge extends UIElement {
|
|||
" <a href='https://www.openstreetmap.org/user/" + user.name + "/history' target='_blank'><img class='small-userbadge-icon' src='./assets/star.svg' alt='star'/> " + user.csCount +
|
||||
"</a></span> ";
|
||||
|
||||
const userStats = "<div id='userstats'>" +
|
||||
this._homeButton.Render() +
|
||||
settings +
|
||||
messageSpan +
|
||||
csCount +
|
||||
this._logout.Render() +
|
||||
this._languagePicker.Render() +
|
||||
"</div>";
|
||||
const userStats = new Combine(["<div id='userstats'>",
|
||||
this._homeButton,
|
||||
settings,
|
||||
messageSpan,
|
||||
csCount,
|
||||
this._logout,
|
||||
this._languagePicker,
|
||||
"</div>"]).Render();
|
||||
|
||||
return userIcon + "<div id='usertext'>" + userName + userStats + "</div>";
|
||||
|
||||
|
|
|
@ -41,8 +41,7 @@ export class WelcomeMessage extends UIElement {
|
|||
|
||||
return new Combine([
|
||||
this.description,
|
||||
"<br/></br>",
|
||||
// TODO this button is broken - figure out why loginStatus,
|
||||
"<br/><br/>",
|
||||
loginStatus,
|
||||
this.tail,
|
||||
"<br/>",
|
||||
|
|
|
@ -874,7 +874,7 @@ export default class Translations {
|
|||
en: "<h2>Add a point?</h2>You clicked somewhere where no data is known yet.<br/>",
|
||||
ca: "<h2>Vols afegir un punt?</h2>Has marcat un lloc on no coneixem les dades.<br/>",
|
||||
es: "<h2>Quieres añadir un punto?</h2>Has marcado un lugar del que no conocemos los datos.<br/>",
|
||||
nl: "<h2>Punt toevoegen?</h2>Je klikte ergens waar er nog geen data is.<br/>",
|
||||
nl: "<h2>Punt toevoegen?</h2>Je klikte ergens waar er nog geen data is. Kies hieronder welk punt je wilt toevoegen<br/>",
|
||||
fr: "<h2>Pas de données</h2>Vous avez cliqué sur un endroit ou il n'y a pas encore de données. <br/>",
|
||||
gl: "<h2>Queres engadir un punto?</h2>Marcaches un lugar onde non coñecemos os datos.<br/>"
|
||||
}),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue