forked from MapComplete/MapComplete
First part of a huge refactoring
This commit is contained in:
parent
0c22b15c8d
commit
11150a258d
56 changed files with 1425 additions and 1324 deletions
|
@ -1,9 +1,9 @@
|
|||
import UserRelatedState from "../Logic/State/UserRelatedState";
|
||||
import {FixedUiElement} from "./Base/FixedUiElement";
|
||||
import Combine from "./Base/Combine";
|
||||
import MoreScreen from "./BigComponents/MoreScreen";
|
||||
import Translations from "./i18n/Translations";
|
||||
import Constants from "../Models/Constants";
|
||||
import UserRelatedState from "../Logic/State/UserRelatedState";
|
||||
import {Utils} from "../Utils";
|
||||
import LanguagePicker from "./LanguagePicker";
|
||||
import IndexText from "./BigComponents/IndexText";
|
||||
|
@ -13,7 +13,6 @@ import {SubtleButton} from "./Base/SubtleButton";
|
|||
|
||||
export default class AllThemesGui {
|
||||
constructor() {
|
||||
|
||||
try {
|
||||
|
||||
new FixedUiElement("").AttachTo("centermessage")
|
||||
|
@ -41,6 +40,7 @@ export default class AllThemesGui {
|
|||
.SetStyle("pointer-events: all;")
|
||||
.AttachTo("topleft-tools");
|
||||
} catch (e) {
|
||||
console.error(">>>> CRITICAL", e)
|
||||
new FixedUiElement("Seems like no layers are compiled - check the output of `npm run generate:layeroverview`. Is this visible online? Contact pietervdvn immediately!").SetClass("alert")
|
||||
.AttachTo("centermessage")
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import {QueryParameters} from "../Logic/Web/QueryParameters";
|
|||
import {SubstitutedTranslation} from "./SubstitutedTranslation";
|
||||
import {AutoAction} from "./Popup/AutoApplyButton";
|
||||
import DynamicGeoJsonTileSource from "../Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource";
|
||||
import * as themeOverview from "../assets/generated/theme_overview.json"
|
||||
|
||||
|
||||
class AutomationPanel extends Combine{
|
||||
|
@ -177,7 +178,7 @@ class AutomationPanel extends Combine{
|
|||
const feature = ffs.feature
|
||||
const renderingTr = targetAction.GetRenderValue(feature.properties)
|
||||
const rendering = renderingTr.txt
|
||||
log.push("<a href='https://openstreetmap.org/"+feature.properties.id+"' target='_blank'>"+feature.properties.id+"</a>: "+new SubstitutedTranslation(renderingTr, new UIEventSource<any>(feature.properties)).ConstructElement().innerText)
|
||||
log.push("<a href='https://openstreetmap.org/"+feature.properties.id+"' target='_blank'>"+feature.properties.id+"</a>: "+new SubstitutedTranslation(renderingTr, new UIEventSource<any>(feature.properties), state).ConstructElement().innerText)
|
||||
const actions = Utils.NoNull(SubstitutedTranslation.ExtractSpecialComponents(rendering)
|
||||
.map(obj => obj.special))
|
||||
for (const action of actions) {
|
||||
|
@ -251,7 +252,7 @@ class AutomatonGui {
|
|||
private static GenerateMainPanel(): BaseUIElement {
|
||||
|
||||
const themeSelect = new DropDown<string>("Select a theme",
|
||||
AllKnownLayouts.layoutsList.map(l => ({value: l.id, shown: l.id}))
|
||||
Array.from(themeOverview).map(l => ({value: l.id, shown: l.id}))
|
||||
)
|
||||
|
||||
LocalStorageSource.Get("automation-theme-id", "missing_streets").syncWith(themeSelect.GetValue())
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as welcome_messages from "../../assets/welcome_message.json"
|
|||
import BaseUIElement from "../BaseUIElement";
|
||||
import {FixedUiElement} from "../Base/FixedUiElement";
|
||||
import MoreScreen from "./MoreScreen";
|
||||
import {AllKnownLayouts} from "../../Customizations/AllKnownLayouts";
|
||||
import * as themeOverview from "../../assets/generated/theme_overview.json"
|
||||
import Translations from "../i18n/Translations";
|
||||
import Title from "../Base/Title";
|
||||
|
||||
|
@ -33,6 +33,12 @@ export default class FeaturedMessage extends Combine {
|
|||
|
||||
public static WelcomeMessages(): { start_date: Date, end_date: Date, message: string, featured_theme?: string }[] {
|
||||
const all_messages: { start_date: Date, end_date: Date, message: string, featured_theme?: string }[] = []
|
||||
|
||||
const themesById = new Map<string, {id: string, title: any, shortDescription: any}>();
|
||||
for (const theme of themeOverview["default"]) {
|
||||
themesById.set(theme.id, theme);
|
||||
}
|
||||
|
||||
for (const i in welcome_messages) {
|
||||
if (isNaN(Number(i))) {
|
||||
continue
|
||||
|
@ -41,7 +47,8 @@ export default class FeaturedMessage extends Combine {
|
|||
if (wm === null) {
|
||||
continue
|
||||
}
|
||||
if (AllKnownLayouts.allKnownLayouts.get(wm.featured_theme) === undefined) {
|
||||
if (themesById.get(wm.featured_theme) === undefined) {
|
||||
console.log("THEMES BY ID:", themesById)
|
||||
console.error("Unkown featured theme for ", wm)
|
||||
continue
|
||||
}
|
||||
|
@ -71,7 +78,10 @@ export default class FeaturedMessage extends Combine {
|
|||
const msg = new FixedUiElement(welcome_message.message).SetClass("link-underline font-lg")
|
||||
els.push(new Combine([title, msg]).SetClass("m-4"))
|
||||
if (welcome_message.featured_theme !== undefined) {
|
||||
els.push(MoreScreen.createLinkButton({}, AllKnownLayouts.allKnownLayouts.get(welcome_message.featured_theme))
|
||||
|
||||
const theme = themeOverview["default"].filter(th => th.id === welcome_message.featured_theme)[0];
|
||||
|
||||
els.push(MoreScreen.createLinkButton({}, theme)
|
||||
.SetClass("m-4 self-center md:w-160")
|
||||
.SetStyle("height: min-content;"))
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import {DropDown} from "../Input/DropDown";
|
||||
import Translations from "../i18n/Translations";
|
||||
import State from "../../State";
|
||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
||||
|
||||
export default class LicensePicker extends DropDown<string> {
|
||||
|
||||
constructor() {
|
||||
constructor(state: {osmConnection: OsmConnection}) {
|
||||
super(Translations.t.image.willBePublished.Clone(),
|
||||
[
|
||||
{value: "CC0", shown: Translations.t.image.cco.Clone()},
|
||||
{value: "CC-BY-SA 4.0", shown: Translations.t.image.ccbs.Clone()},
|
||||
{value: "CC-BY 4.0", shown: Translations.t.image.ccb.Clone()}
|
||||
],
|
||||
State.state?.osmConnection?.GetPreference("pictures-license") ?? new UIEventSource<string>("CC0")
|
||||
state?.osmConnection?.GetPreference("pictures-license") ?? new UIEventSource<string>("CC0")
|
||||
)
|
||||
this.SetClass("flex flex-col sm:flex-row").SetStyle("float:left");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import {VariableUiElement} from "../Base/VariableUIElement";
|
||||
import {AllKnownLayouts} from "../../Customizations/AllKnownLayouts";
|
||||
import Svg from "../../Svg";
|
||||
import Combine from "../Base/Combine";
|
||||
import {SubtleButton} from "../Base/SubtleButton";
|
||||
|
@ -15,6 +14,8 @@ import UserRelatedState from "../../Logic/State/UserRelatedState";
|
|||
import Toggle from "../Input/Toggle";
|
||||
import {Utils} from "../../Utils";
|
||||
import Title from "../Base/Title";
|
||||
import * as themeOverview from "../../assets/generated/theme_overview.json"
|
||||
import {Translation} from "../i18n/Translation";
|
||||
|
||||
export default class MoreScreen extends Combine {
|
||||
|
||||
|
@ -47,7 +48,12 @@ export default class MoreScreen extends Combine {
|
|||
state: {
|
||||
locationControl?: UIEventSource<Loc>,
|
||||
layoutToUse?: LayoutConfig
|
||||
}, layout: LayoutConfig, customThemeDefinition: string = undefined
|
||||
}, layout: {
|
||||
id: string,
|
||||
icon: string,
|
||||
title: any,
|
||||
shortDescription: any
|
||||
}, customThemeDefinition: string = undefined
|
||||
):
|
||||
BaseUIElement {
|
||||
if (layout === undefined) {
|
||||
|
@ -75,11 +81,11 @@ export default class MoreScreen extends Combine {
|
|||
let linkPrefix = `${path}/${layout.id.toLowerCase()}.html?`
|
||||
let linkSuffix = ""
|
||||
if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
|
||||
linkPrefix = `${path}/index.html?layout=${layout.id}&`
|
||||
linkPrefix = `${path}/theme.html?layout=${layout.id}&`
|
||||
}
|
||||
|
||||
if (customThemeDefinition) {
|
||||
linkPrefix = `${path}/index.html?userlayout=${layout.id}&`
|
||||
linkPrefix = `${path}/theme.html?userlayout=${layout.id}&`
|
||||
linkSuffix = `#${customThemeDefinition}`
|
||||
}
|
||||
|
||||
|
@ -98,10 +104,10 @@ export default class MoreScreen extends Combine {
|
|||
return new SubtleButton(layout.icon,
|
||||
new Combine([
|
||||
`<dt class='text-lg leading-6 font-medium text-gray-900 group-hover:text-blue-800'>`,
|
||||
Translations.WT(layout.title),
|
||||
new Translation(layout.title),
|
||||
`</dt>`,
|
||||
`<dd class='mt-1 text-base text-gray-500 group-hover:text-blue-900 overflow-ellipsis'>`,
|
||||
Translations.WT(layout.shortDescription)?.SetClass("subtle") ?? "",
|
||||
new Translation(layout.shortDescription)?.SetClass("subtle") ?? "",
|
||||
`</dd>`,
|
||||
]), {url: linkText, newTab: false});
|
||||
}
|
||||
|
@ -122,27 +128,29 @@ export default class MoreScreen extends Combine {
|
|||
private static createPreviouslyVistedHiddenList(state: UserRelatedState, buttonClass: string, themeListStyle: string) {
|
||||
const t = Translations.t.general.morescreen
|
||||
const prefix = "mapcomplete-hidden-theme-"
|
||||
const hiddenTotal = AllKnownLayouts.layoutsList.filter(layout => layout.hideFromOverview).length
|
||||
const hiddenThemes = themeOverview["default"].filter(layout => layout.hideFromOverview)
|
||||
const hiddenTotal = hiddenThemes.length
|
||||
|
||||
return new Toggle(
|
||||
new VariableUiElement(
|
||||
state.osmConnection.preferencesHandler.preferences.map(allPreferences => {
|
||||
const knownThemes = Utils.NoNull(Object.keys(allPreferences)
|
||||
const knownThemes: Set<string> = new Set(Utils.NoNull(Object.keys(allPreferences)
|
||||
.filter(key => key.startsWith(prefix))
|
||||
.map(key => key.substring(prefix.length, key.length - "-enabled".length))
|
||||
.map(theme => AllKnownLayouts.allKnownLayouts.get(theme)))
|
||||
.filter(theme => theme?.hideFromOverview)
|
||||
if (knownThemes.length === 0) {
|
||||
.map(key => key.substring(prefix.length, key.length - "-enabled".length))));
|
||||
|
||||
if(knownThemes.size === 0){
|
||||
return undefined
|
||||
}
|
||||
|
||||
const knownThemeDescriptions = hiddenThemes.filter(theme => knownThemes.has(theme.id))
|
||||
.map(theme => MoreScreen.createLinkButton(state, theme)?.SetClass(buttonClass));
|
||||
|
||||
const knownLayouts = new Combine(knownThemes.map(layout =>
|
||||
MoreScreen.createLinkButton(state, layout)?.SetClass(buttonClass)
|
||||
)).SetClass(themeListStyle)
|
||||
const knownLayouts = new Combine(knownThemeDescriptions).SetClass(themeListStyle)
|
||||
|
||||
return new Combine([
|
||||
new Title(t.previouslyHiddenTitle),
|
||||
t.hiddenExplanation.Subs({
|
||||
hidden_discovered: "" + knownThemes.length,
|
||||
hidden_discovered: "" + knownThemes.size,
|
||||
total_hidden: "" + hiddenTotal
|
||||
}),
|
||||
knownLayouts
|
||||
|
@ -158,7 +166,7 @@ export default class MoreScreen extends Combine {
|
|||
}
|
||||
|
||||
private static createOfficialThemesList(state: { osmConnection: OsmConnection, locationControl?: UIEventSource<Loc> }, buttonClass: string): BaseUIElement {
|
||||
let officialThemes = AllKnownLayouts.layoutsList
|
||||
let officialThemes = themeOverview["default"];
|
||||
|
||||
let buttons = officialThemes.map((layout) => {
|
||||
if (layout === undefined) {
|
||||
|
|
|
@ -15,13 +15,14 @@ import LeftControls from "./BigComponents/LeftControls";
|
|||
import RightControls from "./BigComponents/RightControls";
|
||||
import CenterMessageBox from "./CenterMessageBox";
|
||||
import ShowDataLayer from "./ShowDataLayer/ShowDataLayer";
|
||||
import AllKnownLayers from "../Customizations/AllKnownLayers";
|
||||
import ScrollableFullScreen from "./Base/ScrollableFullScreen";
|
||||
import Translations from "./i18n/Translations";
|
||||
import SimpleAddUI from "./BigComponents/SimpleAddUI";
|
||||
import StrayClickHandler from "../Logic/Actors/StrayClickHandler";
|
||||
import Lazy from "./Base/Lazy";
|
||||
import {DefaultGuiState} from "./DefaultGuiState";
|
||||
import LayerConfig from "../Models/ThemeConfig/LayerConfig";
|
||||
import * as home_location_json from "../assets/layers/home_location/home_location.json";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -111,7 +112,7 @@ export default class DefaultGUI {
|
|||
|
||||
new ShowDataLayer({
|
||||
leafletMap: state.leafletMap,
|
||||
layerToShow: AllKnownLayers.sharedLayers.get("home_location"),
|
||||
layerToShow: new LayerConfig(home_location_json, "all_known_layers", true),
|
||||
features: state.homeLocation,
|
||||
enablePopups: false,
|
||||
})
|
||||
|
|
|
@ -2,20 +2,21 @@ import {UIEventSource} from "../../Logic/UIEventSource";
|
|||
import Translations from "../i18n/Translations";
|
||||
import Toggle from "../Input/Toggle";
|
||||
import Combine from "../Base/Combine";
|
||||
import State from "../../State";
|
||||
import Svg from "../../Svg";
|
||||
import {Tag} from "../../Logic/Tags/Tag";
|
||||
import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction";
|
||||
import {Changes} from "../../Logic/Osm/Changes";
|
||||
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
||||
|
||||
export default class DeleteImage extends Toggle {
|
||||
|
||||
constructor(key: string, tags: UIEventSource<any>) {
|
||||
constructor(key: string, tags: UIEventSource<any>, state: {changes?: Changes, osmConnection?: OsmConnection}) {
|
||||
const oldValue = tags.data[key]
|
||||
const isDeletedBadge = Translations.t.image.isDeleted.Clone()
|
||||
.SetClass("rounded-full p-1")
|
||||
.SetStyle("color:white;background:#ff8c8c")
|
||||
.onClick(async () => {
|
||||
await State.state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data, {
|
||||
await state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data, {
|
||||
changeType: "answer",
|
||||
theme: "test"
|
||||
}))
|
||||
|
@ -25,7 +26,7 @@ export default class DeleteImage extends Toggle {
|
|||
.SetClass("block w-full pl-4 pr-4")
|
||||
.SetStyle("color:white;background:#ff8c8c; border-top-left-radius:30rem; border-top-right-radius: 30rem;")
|
||||
.onClick(async () => {
|
||||
await State.state?.changes?.applyAction(
|
||||
await state?.changes?.applyAction(
|
||||
new ChangeTagAction(tags.data.id, new Tag(key, ""), tags.data, {
|
||||
changeType: "answer",
|
||||
theme: "test"
|
||||
|
@ -53,7 +54,7 @@ export default class DeleteImage extends Toggle {
|
|||
tags.map(tags => (tags[key] ?? "") !== "")
|
||||
),
|
||||
undefined /*Login (and thus editing) is disabled*/,
|
||||
State.state.osmConnection.isLoggedIn
|
||||
state.osmConnection.isLoggedIn
|
||||
)
|
||||
this.SetClass("cursor-pointer")
|
||||
}
|
||||
|
|
|
@ -6,12 +6,14 @@ import {AttributedImage} from "./AttributedImage";
|
|||
import BaseUIElement from "../BaseUIElement";
|
||||
import Toggle from "../Input/Toggle";
|
||||
import ImageProvider from "../../Logic/ImageProviders/ImageProvider";
|
||||
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
||||
import {Changes} from "../../Logic/Osm/Changes";
|
||||
|
||||
export class ImageCarousel extends Toggle {
|
||||
|
||||
constructor(images: UIEventSource<{ key: string, url: string, provider: ImageProvider }[]>,
|
||||
tags: UIEventSource<any>,
|
||||
keys: string[]) {
|
||||
state: {osmConnection?: OsmConnection, changes?: Changes}) {
|
||||
const uiElements = images.map((imageURLS: { key: string, url: string, provider: ImageProvider }[]) => {
|
||||
const uiElements: BaseUIElement[] = [];
|
||||
for (const url of imageURLS) {
|
||||
|
@ -21,7 +23,7 @@ export class ImageCarousel extends Toggle {
|
|||
if (url.key !== undefined) {
|
||||
image = new Combine([
|
||||
image,
|
||||
new DeleteImage(url.key, tags).SetClass("delete-image-marker absolute top-0 left-0 pl-3")
|
||||
new DeleteImage(url.key, tags, state).SetClass("delete-image-marker absolute top-0 left-0 pl-3")
|
||||
]).SetClass("relative");
|
||||
}
|
||||
image
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||
import State from "../../State";
|
||||
import Combine from "../Base/Combine";
|
||||
import Translations from "../i18n/Translations";
|
||||
import Svg from "../../Svg";
|
||||
|
@ -13,13 +12,23 @@ import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction";
|
|||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
||||
import {FixedUiElement} from "../Base/FixedUiElement";
|
||||
import {VariableUiElement} from "../Base/VariableUIElement";
|
||||
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
|
||||
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
||||
import {Changes} from "../../Logic/Osm/Changes";
|
||||
|
||||
export class ImageUploadFlow extends Toggle {
|
||||
|
||||
|
||||
private static readonly uploadCountsPerId = new Map<string, UIEventSource<number>>()
|
||||
|
||||
constructor(tagsSource: UIEventSource<any>, imagePrefix: string = "image", text: string = undefined) {
|
||||
constructor(tagsSource: UIEventSource<any>,
|
||||
state: {
|
||||
osmConnection: OsmConnection;
|
||||
layoutToUse: LayoutConfig;
|
||||
changes: Changes,
|
||||
featureSwitchUserbadge: UIEventSource<boolean>;
|
||||
},
|
||||
imagePrefix: string = "image", text: string = undefined) {
|
||||
const perId = ImageUploadFlow.uploadCountsPerId
|
||||
const id = tagsSource.data.id
|
||||
if (!perId.has(id)) {
|
||||
|
@ -41,17 +50,17 @@ export class ImageUploadFlow extends Toggle {
|
|||
console.log("Adding image:" + key, url);
|
||||
uploadedCount.data++
|
||||
uploadedCount.ping()
|
||||
Promise.resolve(State.state.changes
|
||||
Promise.resolve(state.changes
|
||||
.applyAction(new ChangeTagAction(
|
||||
tags.id, new Tag(key, url), tagsSource.data,
|
||||
{
|
||||
changeType: "add-image",
|
||||
theme: State.state.layoutToUse.id
|
||||
theme: state.layoutToUse.id
|
||||
}
|
||||
)))
|
||||
})
|
||||
|
||||
const licensePicker = new LicensePicker()
|
||||
const licensePicker = new LicensePicker(state)
|
||||
|
||||
const t = Translations.t.image;
|
||||
|
||||
|
@ -90,7 +99,7 @@ export class ImageUploadFlow extends Toggle {
|
|||
|
||||
const tags = tagsSource.data;
|
||||
|
||||
const layout = State.state?.layoutToUse
|
||||
const layout = state?.layoutToUse
|
||||
let matchingLayer: LayerConfig = undefined
|
||||
for (const layer of layout?.layers ?? []) {
|
||||
if (layer.source.osmTags.matchesProperties(tags)) {
|
||||
|
@ -102,7 +111,7 @@ export class ImageUploadFlow extends Toggle {
|
|||
|
||||
const title = matchingLayer?.title?.GetRenderValue(tags)?.ConstructElement()?.innerText ?? tags.name ?? "Unknown area";
|
||||
const description = [
|
||||
"author:" + State.state.osmConnection.userDetails.data.name,
|
||||
"author:" + state.osmConnection.userDetails.data.name,
|
||||
"license:" + license,
|
||||
"osmid:" + tags.id,
|
||||
].join("\n");
|
||||
|
@ -146,17 +155,17 @@ export class ImageUploadFlow extends Toggle {
|
|||
|
||||
|
||||
const pleaseLoginButton = t.pleaseLogin.Clone()
|
||||
.onClick(() => State.state.osmConnection.AttemptLogin())
|
||||
.onClick(() => state.osmConnection.AttemptLogin())
|
||||
.SetClass("login-button-friendly");
|
||||
super(
|
||||
new Toggle(
|
||||
/*We can show the actual upload button!*/
|
||||
uploadFlow,
|
||||
/* User not logged in*/ pleaseLoginButton,
|
||||
State.state?.osmConnection?.isLoggedIn
|
||||
state?.osmConnection?.isLoggedIn
|
||||
),
|
||||
undefined /* Nothing as the user badge is disabled*/,
|
||||
State.state.featureSwitchUserbadge
|
||||
state.featureSwitchUserbadge
|
||||
)
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||
import Combine from "../Base/Combine";
|
||||
import State from "../../State";
|
||||
import {FixedUiElement} from "../Base/FixedUiElement";
|
||||
import {OH} from "./OpeningHours";
|
||||
import Translations from "../i18n/Translations";
|
||||
|
@ -11,6 +10,7 @@ import Toggle from "../Input/Toggle";
|
|||
import {VariableUiElement} from "../Base/VariableUIElement";
|
||||
import Table from "../Base/Table";
|
||||
import {Translation} from "../i18n/Translation";
|
||||
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
||||
|
||||
export default class OpeningHoursVisualization extends Toggle {
|
||||
private static readonly weekdays: Translation[] = [
|
||||
|
@ -23,7 +23,7 @@ export default class OpeningHoursVisualization extends Toggle {
|
|||
Translations.t.general.weekdays.abbreviations.sunday,
|
||||
]
|
||||
|
||||
constructor(tags: UIEventSource<any>, key: string, prefix = "", postfix = "") {
|
||||
constructor(tags: UIEventSource<any>, state:{osmConnection?: OsmConnection}, key: string, prefix = "", postfix = "") {
|
||||
const tagsDirect = tags.data;
|
||||
const ohTable = new VariableUiElement(tags
|
||||
.map(tags => {
|
||||
|
@ -57,7 +57,7 @@ export default class OpeningHoursVisualization extends Toggle {
|
|||
new Toggle(
|
||||
new FixedUiElement(e).SetClass("subtle"),
|
||||
undefined,
|
||||
State.state?.osmConnection?.userDetails.map(userdetails => userdetails.csCount >= Constants.userJourney.tagsVisibleAndWikiLinked)
|
||||
state?.osmConnection?.userDetails.map(userdetails => userdetails.csCount >= Constants.userJourney.tagsVisibleAndWikiLinked)
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ export default class EditableTagRendering extends Toggle {
|
|||
}
|
||||
|
||||
private static CreateRendering(tags: UIEventSource<any>, configuration: TagRenderingConfig, units: Unit[], editMode: UIEventSource<boolean>): BaseUIElement {
|
||||
const answer: BaseUIElement = new TagRenderingAnswer(tags, configuration)
|
||||
const answer: BaseUIElement = new TagRenderingAnswer(tags, configuration, State.state)
|
||||
answer.SetClass("w-full")
|
||||
let rendering = answer;
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ import {Utils} from "../../Utils";
|
|||
import {SubstitutedTranslation} from "../SubstitutedTranslation";
|
||||
import MoveWizard from "./MoveWizard";
|
||||
import Toggle from "../Input/Toggle";
|
||||
import {FixedUiElement} from "../Base/FixedUiElement";
|
||||
|
||||
export default class FeatureInfoBox extends ScrollableFullScreen {
|
||||
|
||||
|
@ -41,7 +40,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
|
|||
|
||||
private static GenerateTitleBar(tags: UIEventSource<any>,
|
||||
layerConfig: LayerConfig): BaseUIElement {
|
||||
const title = new TagRenderingAnswer(tags, layerConfig.title ?? new TagRenderingConfig("POI"))
|
||||
const title = new TagRenderingAnswer(tags, layerConfig.title ?? new TagRenderingConfig("POI"), State.state)
|
||||
.SetClass("break-words font-bold sm:p-0.5 md:p-1 sm:p-1.5 md:p-2");
|
||||
const titleIcons = new Combine(
|
||||
layerConfig.titleIcons.map(icon => new TagRenderingAnswer(tags, icon,
|
||||
|
@ -89,7 +88,8 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
|
|||
|
||||
if (tr.render !== undefined) {
|
||||
questionBox.SetClass("text-sm")
|
||||
const renderedQuestion = new TagRenderingAnswer(tags, tr, tr.group + " questions", "", {
|
||||
const renderedQuestion = new TagRenderingAnswer(tags, tr,State.state,
|
||||
tr.group + " questions", "", {
|
||||
specialViz: new Map<string, BaseUIElement>([["questions", questionBox]])
|
||||
})
|
||||
const possiblyHidden = new Toggle(
|
||||
|
@ -164,7 +164,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
|
|||
|
||||
const hasMinimap = layerConfig.tagRenderings.some(tr => FeatureInfoBox.hasMinimap(tr))
|
||||
if (!hasMinimap) {
|
||||
allRenderings.push(new TagRenderingAnswer(tags, SharedTagRenderings.SharedTagRendering.get("minimap")))
|
||||
allRenderings.push(new TagRenderingAnswer(tags, SharedTagRenderings.SharedTagRendering.get("minimap"), State.state))
|
||||
}
|
||||
|
||||
editElements.push(
|
||||
|
@ -178,7 +178,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
|
|||
return undefined
|
||||
}
|
||||
|
||||
return new TagRenderingAnswer(tags, SharedTagRenderings.SharedTagRendering.get("last_edit"));
|
||||
return new TagRenderingAnswer(tags, SharedTagRenderings.SharedTagRendering.get("last_edit"), State.state);
|
||||
|
||||
}, [State.state.featureSwitchIsDebugging, State.state.featureSwitchIsTesting])
|
||||
)
|
||||
|
|
|
@ -19,7 +19,6 @@ import Svg from "../../Svg";
|
|||
import {Utils} from "../../Utils";
|
||||
import Minimap from "../Base/Minimap";
|
||||
import ShowDataLayer from "../ShowDataLayer/ShowDataLayer";
|
||||
import AllKnownLayers from "../../Customizations/AllKnownLayers";
|
||||
import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource";
|
||||
import ShowDataMultiLayer from "../ShowDataLayer/ShowDataMultiLayer";
|
||||
import CreateWayWithPointReuseAction, {MergePointConfig} from "../../Logic/Osm/Actions/CreateWayWithPointReuseAction";
|
||||
|
@ -35,6 +34,8 @@ import ReplaceGeometryAction from "../../Logic/Osm/Actions/ReplaceGeometryAction
|
|||
import CreateMultiPolygonWithPointReuseAction from "../../Logic/Osm/Actions/CreateMultiPolygonWithPointReuseAction";
|
||||
import {Tag} from "../../Logic/Tags/Tag";
|
||||
import TagApplyButton from "./TagApplyButton";
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
||||
import * as conflation_json from "../../assets/layers/conflation/conflation.json";
|
||||
|
||||
|
||||
abstract class AbstractImportButton implements SpecialVisualizations {
|
||||
|
@ -255,7 +256,7 @@ ${Utils.special_visualizations_importRequirementDocs}
|
|||
zoomToFeatures: false,
|
||||
features: changePreview,
|
||||
allElements: state.allElements,
|
||||
layerToShow: AllKnownLayers.sharedLayers.get("conflation")
|
||||
layerToShow: new LayerConfig(conflation_json, "all_known_layers", true)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig";
|
|||
export default class TagRenderingAnswer extends VariableUiElement {
|
||||
|
||||
constructor(tagsSource: UIEventSource<any>, configuration: TagRenderingConfig,
|
||||
state: any,
|
||||
contentClasses: string = "", contentStyle: string = "", options?:{
|
||||
specialViz: Map<string, BaseUIElement>
|
||||
}) {
|
||||
|
@ -37,7 +38,7 @@ export default class TagRenderingAnswer extends VariableUiElement {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const valuesToRender: BaseUIElement[] = trs.map(tr => new SubstitutedTranslation(tr, tagsSource, options?.specialViz))
|
||||
const valuesToRender: BaseUIElement[] = trs.map(tr => new SubstitutedTranslation(tr, tagsSource, state, options?.specialViz))
|
||||
if (valuesToRender.length === 1) {
|
||||
return valuesToRender[0];
|
||||
} else if (valuesToRender.length > 1) {
|
||||
|
|
|
@ -71,7 +71,7 @@ export default class TagRenderingQuestion extends Combine {
|
|||
}
|
||||
options = options ?? {}
|
||||
const applicableUnit = (options.units ?? []).filter(unit => unit.isApplicableToKey(configuration.freeform?.key))[0];
|
||||
const question = new SubstitutedTranslation(configuration.question, tags)
|
||||
const question = new SubstitutedTranslation(configuration.question, tags, State.state)
|
||||
.SetClass("question-text");
|
||||
|
||||
|
||||
|
@ -352,7 +352,7 @@ export default class TagRenderingQuestion extends Combine {
|
|||
}
|
||||
|
||||
return new FixedInputElement(
|
||||
new SubstitutedTranslation(mapping.then, tagsSource),
|
||||
new SubstitutedTranslation(mapping.then, tagsSource, State.state),
|
||||
tagging,
|
||||
(t0, t1) => t1.isEquivalent(t0));
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ import {Tiles} from "../../Models/TileRange";
|
|||
import * as clusterstyle from "../../assets/layers/cluster_style/cluster_style.json"
|
||||
|
||||
export default class ShowTileInfo {
|
||||
public static readonly styling = new LayerConfig(
|
||||
clusterstyle, "tileinfo", true)
|
||||
public static readonly styling = new LayerConfig(clusterstyle, "ShowTileInfo", true)
|
||||
|
||||
constructor(options: {
|
||||
source: FeatureSource & Tiled, leafletMap: UIEventSource<any>, layer?: LayerConfig,
|
||||
|
|
|
@ -27,7 +27,6 @@ import AllImageProviders from "../Logic/ImageProviders/AllImageProviders";
|
|||
import WikipediaBox from "./Wikipedia/WikipediaBox";
|
||||
import SimpleMetaTagger from "../Logic/SimpleMetaTagger";
|
||||
import MultiApply from "./Popup/MultiApply";
|
||||
import AllKnownLayers from "../Customizations/AllKnownLayers";
|
||||
import ShowDataLayer from "./ShowDataLayer/ShowDataLayer";
|
||||
import {SubtleButton} from "./Base/SubtleButton";
|
||||
import {DefaultGuiState} from "./DefaultGuiState";
|
||||
|
@ -37,6 +36,7 @@ import FeaturePipelineState from "../Logic/State/FeaturePipelineState";
|
|||
import {ConflateButton, ImportPointButton, ImportWayButton} from "./Popup/ImportButton";
|
||||
import TagApplyButton from "./Popup/TagApplyButton";
|
||||
import AutoApplyButton from "./Popup/AutoApplyButton";
|
||||
import * as left_right_style_json from "../assets/layers/left_right_style/left_right_style.json";
|
||||
|
||||
export interface SpecialVisualization {
|
||||
funcName: string,
|
||||
|
@ -51,7 +51,6 @@ export default class SpecialVisualizations {
|
|||
|
||||
public static specialVisualizations = SpecialVisualizations.init()
|
||||
|
||||
|
||||
private static init(){
|
||||
const specialVisualizations: SpecialVisualization[] =
|
||||
[
|
||||
|
@ -104,7 +103,7 @@ export default class SpecialVisualizations {
|
|||
if (args.length > 0) {
|
||||
imagePrefixes = [].concat(...args.map(a => a.split(",")));
|
||||
}
|
||||
return new ImageCarousel(AllImageProviders.LoadImagesFor(tags, imagePrefixes), tags, imagePrefixes);
|
||||
return new ImageCarousel(AllImageProviders.LoadImagesFor(tags, imagePrefixes), tags, state);
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -120,7 +119,7 @@ export default class SpecialVisualizations {
|
|||
defaultValue: "Add image"
|
||||
}],
|
||||
constr: (state: State, tags, args) => {
|
||||
return new ImageUploadFlow(tags, args[0], args[1])
|
||||
return new ImageUploadFlow(tags, state, args[0], args[1])
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -161,7 +160,7 @@ export default class SpecialVisualizations {
|
|||
}
|
||||
],
|
||||
example: "`{minimap()}`, `{minimap(17, id, _list_of_embedded_feature_ids_calculated_by_calculated_tag):height:10rem; border: 2px solid black}`",
|
||||
constr: (state, tagSource, args, defaultGuiState) => {
|
||||
constr: (state, tagSource, args, _) => {
|
||||
|
||||
const keys = [...args]
|
||||
keys.splice(0, 1)
|
||||
|
@ -267,7 +266,7 @@ export default class SpecialVisualizations {
|
|||
leafletMap: minimap["leafletMap"],
|
||||
enablePopups: false,
|
||||
zoomToFeatures: true,
|
||||
layerToShow: AllKnownLayers.sharedLayers.get("left_right_style"),
|
||||
layerToShow: new LayerConfig(left_right_style_json, "all_known_layers", true),
|
||||
features: new StaticFeatureSource([copy], false),
|
||||
allElements: State.state.allElements
|
||||
}
|
||||
|
@ -324,7 +323,7 @@ export default class SpecialVisualizations {
|
|||
}],
|
||||
example: "A normal opening hours table can be invoked with `{opening_hours_table()}`. A table for e.g. conditional access with opening hours can be `{opening_hours_table(access:conditional, no @ &LPARENS, &RPARENS)}`",
|
||||
constr: (state: State, tagSource: UIEventSource<any>, args) => {
|
||||
return new OpeningHoursVisualization(tagSource, args[0], args[1], args[2])
|
||||
return new OpeningHoursVisualization(tagSource, state, args[0], args[1], args[2])
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import {UIEventSource} from "../Logic/UIEventSource";
|
||||
import {Translation} from "./i18n/Translation";
|
||||
import Locale from "./i18n/Locale";
|
||||
import State from "../State";
|
||||
import {FixedUiElement} from "./Base/FixedUiElement";
|
||||
import SpecialVisualizations, {SpecialVisualization} from "./SpecialVisualizations";
|
||||
import {Utils} from "../Utils";
|
||||
|
@ -15,6 +14,7 @@ export class SubstitutedTranslation extends VariableUiElement {
|
|||
public constructor(
|
||||
translation: Translation,
|
||||
tagsSource: UIEventSource<any>,
|
||||
state,
|
||||
mapping: Map<string, BaseUIElement> = undefined) {
|
||||
|
||||
const extraMappings: SpecialVisualization[] = [];
|
||||
|
@ -50,7 +50,7 @@ export class SubstitutedTranslation extends VariableUiElement {
|
|||
}
|
||||
const viz = proto.special;
|
||||
try {
|
||||
return viz.func.constr(State.state, tagsSource, proto.special.args, DefaultGuiState.state).SetStyle(proto.special.style);
|
||||
return viz.func.constr(state, tagsSource, proto.special.args, DefaultGuiState.state).SetStyle(proto.special.style);
|
||||
} catch (e) {
|
||||
console.error("SPECIALRENDERING FAILED for", tagsSource.data?.id, e)
|
||||
return new FixedUiElement(`Could not generate special rendering for ${viz.func}(${viz.args.join(", ")}) ${e}`).SetStyle("alert")
|
||||
|
|
|
@ -13,6 +13,9 @@ export class Translation extends BaseUIElement {
|
|||
if (translations === undefined) {
|
||||
throw `Translation without content (${context})`
|
||||
}
|
||||
if(typeof translations === "string"){
|
||||
translations = {"*": translations};
|
||||
}
|
||||
let count = 0;
|
||||
for (const translationsKey in translations) {
|
||||
if (!translations.hasOwnProperty(translationsKey)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue