diff --git a/assets/layers/questions/questions.json b/assets/layers/questions/questions.json index c76de6bfe..2339a5d94 100644 --- a/assets/layers/questions/questions.json +++ b/assets/layers/questions/questions.json @@ -3611,7 +3611,8 @@ "it": "In questo posto non รจ possibile prenotare" } } - ] + ], + "onSoftDelete": "reservation=" }, { "id": "ref", diff --git a/scripts/generateDocs.ts b/scripts/generateDocs.ts index 15e75755d..fb8038b61 100644 --- a/scripts/generateDocs.ts +++ b/scripts/generateDocs.ts @@ -386,9 +386,11 @@ export class GenerateDocs extends Script { allLayers.forEach((layer) => { const element = layer.generateDocumentation( - themesPerLayer.get(layer.id), - layerIsNeededBy, - DependencyCalculator.getLayerDependencies(layer) + { + usedInThemes: themesPerLayer.get(layer.id), + layerIsNeededBy: layerIsNeededBy, + dependencies: DependencyCalculator.getLayerDependencies(layer), + }, ) const inlineSource = inlineLayers.get(layer.id) ScriptUtils.erasableLog("Exporting layer documentation for", layer.id) @@ -481,15 +483,17 @@ export class GenerateDocs extends Script { "questions.json", true ) + const reusedTagRenderings = DependencyCalculator.tagRenderingImportedBy(qLayer, Array.from(AllSharedLayers.sharedLayers.values())) + const docs = qLayer.generateDocumentation({ reusedTagRenderings }) this.WriteMarkdownFile( "./Docs/BuiltinQuestions.md", - qLayer.generateDocumentation([], new Map(), []), + docs, ["assets/layers/questions/questions.json"] ) } private generateForTheme(theme: ThemeConfig): void { - const allLayers = AllSharedLayers.getSharedLayersConfigs() + const allLayers = AllSharedLayers.sharedLayers const layersToShow = theme.layers.filter( (l) => l.id !== "favourite" && Constants.added_by_default.indexOf(l.id) < 0 ) @@ -520,7 +524,7 @@ export class GenerateDocs extends Script { MarkdownUtils.list(theme.language.filter((ln) => ln !== "_context")), "# Layers defined in this theme configuration file", "These layers can not be reused in different themes.", - ...layersToInline.map((l) => l.generateDocumentation(null)), + ...layersToInline.map((l) => l.generateDocumentation({ usedInThemes: null })), ].join("\n") this.WriteMarkdownFile( "./Docs/Themes/" + theme.id + ".md", @@ -587,11 +591,13 @@ export class GenerateDocs extends Script { Constants.priviliged_layers.map((id) => AllSharedLayers.sharedLayers.get(id)) ).map((l) => l.generateDocumentation( - themesPerLayer.get(l.id), - layerIsNeededBy, - DependencyCalculator.getLayerDependencies(l), - Constants.added_by_default.indexOf(l.id) >= 0, - Constants.no_include.indexOf(l.id) < 0 + { + usedInThemes: themesPerLayer.get(l.id), + layerIsNeededBy: layerIsNeededBy, + dependencies: DependencyCalculator.getLayerDependencies(l), + addedByDefault: Constants.added_by_default.indexOf(l.id) >= 0, + canBeIncluded: Constants.no_include.indexOf(l.id) < 0, + }, ) ), "# Normal layers", diff --git a/scripts/generateLayerOverview.ts b/scripts/generateLayerOverview.ts index a98e2cd9c..85cbd2aa9 100644 --- a/scripts/generateLayerOverview.ts +++ b/scripts/generateLayerOverview.ts @@ -14,11 +14,7 @@ import { import { Translation } from "../src/UI/i18n/Translation" import { PrepareLayer } from "../src/Models/ThemeConfig/Conversion/PrepareLayer" import { PrepareTheme } from "../src/Models/ThemeConfig/Conversion/PrepareTheme" -import { - Conversion, - DesugaringContext, - DesugaringStep, -} from "../src/Models/ThemeConfig/Conversion/Conversion" +import { Conversion, DesugaringContext, DesugaringStep } from "../src/Models/ThemeConfig/Conversion/Conversion" import { Utils } from "../src/Utils" import Script from "./Script" import { AllSharedLayers } from "../src/Customizations/AllSharedLayers" @@ -35,10 +31,7 @@ import { Translatable } from "../src/Models/ThemeConfig/Json/Translatable" import { ValidateThemeAndLayers } from "../src/Models/ThemeConfig/Conversion/ValidateThemeAndLayers" import { ExtractImages } from "../src/Models/ThemeConfig/Conversion/FixImages" import { TagRenderingConfigJson } from "../src/Models/ThemeConfig/Json/TagRenderingConfigJson" -import { - LayerConfigDependencyGraph, - LevelInfo, -} from "../src/Models/ThemeConfig/LayerConfigDependencyGraph" +import { LayerConfigDependencyGraph, LevelInfo } from "../src/Models/ThemeConfig/LayerConfigDependencyGraph" // This scripts scans 'src/assets/layers/*.json' for layer definition files and 'src/assets/themes/*.json' for theme definition files. // It spits out an overview of those to be used to load them @@ -54,7 +47,7 @@ class ParseLayer extends Conversion< private readonly _doesImageExist: DoesImageExist constructor(prepareLayer: PrepareLayer, doesImageExist: DoesImageExist) { - super("ParseLayer", "Parsed a layer from file, validates it", []) + super("ParseLayer", "Parsed a layer from file, validates it") this._prepareLayer = prepareLayer this._doesImageExist = doesImageExist } @@ -113,7 +106,7 @@ class AddIconSummary extends DesugaringStep<{ raw: LayerConfigJson; parsed: Laye static singleton = new AddIconSummary() constructor() { - super("Adds an icon summary for quick reference", ["_layerIcon"], "AddIconSummary") + super("AddIconSummary","Adds an icon summary for quick reference") } convert(json: { raw: LayerConfigJson; parsed: LayerConfig }) { @@ -158,7 +151,7 @@ class LayerBuilder extends Conversion> { states: Map, sharedTagRenderings: QuestionableTagRenderingConfigJson[] ) { - super("LayerBuilder", "Builds all the layers, writes them to file", []) + super("LayerBuilder", "Builds all the layers, writes them to file") this._levels = levels this._dependencies = dependencies this._states = states @@ -667,7 +660,7 @@ class LayerOverviewUtils extends Script { priviliged.delete("last_click") priviliged.delete("search") - const isBoostrapping = AllSharedLayers.getSharedLayersConfigs().size == 0 + const isBoostrapping = AllSharedLayers.sharedLayers.size == 0 if (!isBoostrapping && priviliged.size > 0) { throw ( "Priviliged layer " + diff --git a/src/Customizations/AllSharedLayers.ts b/src/Customizations/AllSharedLayers.ts index b0de3480f..64a461bb4 100644 --- a/src/Customizations/AllSharedLayers.ts +++ b/src/Customizations/AllSharedLayers.ts @@ -4,7 +4,7 @@ import * as known_layers from "../assets/generated/known_layers.json" import { LayerConfigJson } from "../Models/ThemeConfig/Json/LayerConfigJson" export class AllSharedLayers { - public static sharedLayers: Map = AllSharedLayers.getSharedLayers() + public static sharedLayers: ReadonlyMap = AllSharedLayers.getSharedLayers() public static getSharedLayersConfigs(): Map { const sharedLayers = new Map() for (const layer of known_layers["layers"]) { diff --git a/src/Models/ThemeConfig/Conversion/Conversion.ts b/src/Models/ThemeConfig/Conversion/Conversion.ts index 86beeecb3..dc6fd7d7e 100644 --- a/src/Models/ThemeConfig/Conversion/Conversion.ts +++ b/src/Models/ThemeConfig/Conversion/Conversion.ts @@ -9,7 +9,7 @@ export interface DesugaringContext { * Order of appearance in questions.json */ tagRenderingOrder: string[] - sharedLayers: Map + sharedLayers: Map> publicLayers?: Set } diff --git a/src/Models/ThemeConfig/DependencyCalculator.ts b/src/Models/ThemeConfig/DependencyCalculator.ts index af3129bbf..23519668e 100644 --- a/src/Models/ThemeConfig/DependencyCalculator.ts +++ b/src/Models/ThemeConfig/DependencyCalculator.ts @@ -3,9 +3,38 @@ import { ExtraFuncParams, ExtraFunctions } from "../../Logic/ExtraFunctions" import LayerConfig from "./LayerConfig" import { SpecialVisualization } from "../../UI/SpecialVisualization" import SpecialVisualizations from "../../UI/SpecialVisualizations" +import { LayerConfigJson } from "./Json/LayerConfigJson" export default class DependencyCalculator { - public static GetTagRenderingDependencies(tr: TagRenderingConfig): { + + /** + * For every tagRendering in the listed layers, determines in what layers they end up + */ + public static tagRenderingImportedBy(questionedLayer: LayerConfig, layers: LayerConfig[]): Map { + const result: Map = new Map() + + for (const layer of layers) { + const hasRightContext = layer.tagRenderings.filter(tr => tr._definedIn !== undefined && tr?._definedIn?.[0] === questionedLayer.id) + for (const tr of hasRightContext) { + const id = tr._definedIn[1] + if (!result.has(id)) { + result.set(id, []) + } + result.get(id).push({ layer: layer.id }) + } + } + + return result + } + + /** + * Calculates what layers are introduced by a tagRenderingConfig + * @param tr + * @private + */ + private static getTagRenderingDependencies(tr: TagRenderingConfig): { id: string minzoom?: number neededBy: string @@ -83,7 +112,7 @@ export default class DependencyCalculator { } for (const tr of layer.AllTagRenderings()) { - for (const dep of DependencyCalculator.GetTagRenderingDependencies(tr)) { + for (const dep of DependencyCalculator.getTagRenderingDependencies(tr)) { deps.push({ neededLayer: dep.id, reason: `tagrendering ${dep.neededBy} needs this layer`, diff --git a/src/Models/ThemeConfig/LayerConfig.ts b/src/Models/ThemeConfig/LayerConfig.ts index 3d516a7cd..3b0d7df45 100644 --- a/src/Models/ThemeConfig/LayerConfig.ts +++ b/src/Models/ThemeConfig/LayerConfig.ts @@ -439,15 +439,15 @@ export default class LayerConfig extends WithContextLoader { } public generateDocumentation( - usedInThemes: string[], - layerIsNeededBy?: Map, - dependencies: { - context?: string - reason: string - neededLayer: string - }[] = [], - addedByDefault = false, - canBeIncluded = true + { usedInThemes = [], layerIsNeededBy, dependencies = [], addedByDefault = false, canBeIncluded = true, lang = "en", reusedTagRenderings }: { + usedInThemes?: string[], + layerIsNeededBy?: Map, + dependencies?: { context?: string; reason: string; neededLayer: string }[], + addedByDefault?: boolean, + canBeIncluded?: boolean, + reusedTagRenderings?: Map, + lang?: string + } ): string { const extraProps: string[] = [] extraProps.push("This layer is shown at zoomlevel **" + this.minzoom + "** and higher") @@ -669,7 +669,7 @@ export default class LayerConfig extends WithContextLoader { this.generateDocumentationQuickTable(), ...this.tagRenderings .filter((tr) => tr.labels.indexOf("ignore_docs") < 0) - .map((tr) => tr.GenerateDocumentation()), + .map((tr) => tr.generateDocumentation(lang, reusedTagRenderings?.get(tr.id)?.map(l => l.layer))), ...filterDocs, ].join("\n\n") } diff --git a/src/Models/ThemeConfig/TagRenderingConfig.ts b/src/Models/ThemeConfig/TagRenderingConfig.ts index c7bf5c52d..f7055f4d7 100644 --- a/src/Models/ThemeConfig/TagRenderingConfig.ts +++ b/src/Models/ThemeConfig/TagRenderingConfig.ts @@ -941,7 +941,7 @@ export default class TagRenderingConfig { } } - GenerateDocumentation(lang: string = "en"): string { + generateDocumentation(lang: string = "en", usedInLayers?: string[]): string { let freeform: string = undefined if (this.render) { freeform = "\n*" + this.render.textFor(lang) + "*" @@ -1016,12 +1016,18 @@ export default class TagRenderingConfig { let labels: string = undefined if (this.labels?.length > 0) { labels = [ - "This tagrendering has labels ", + "This tagrendering has labels", ...this.labels.map((label) => "`" + label + "`"), - ].join("\n") + ].join(" ") + } + let reuse : string = undefined + if(usedInLayers?.length > 0){ + reuse = [`This tagRendering is used in ${usedInLayers.length} layers:`, + ...usedInLayers.map(l => `[${l}](./Layers/${l}.md)`) + ].join(" ") } - return [ + return Utils.NoNull([ "### " + this.id, this.description, this.question !== undefined @@ -1031,7 +1037,9 @@ export default class TagRenderingConfig { mappings, condition, labels, - ].join("\n") + "", + reuse + ]).join("\n") } public usedTags(): TagsFilter[] { diff --git a/src/UI/Studio/EditLayerState.ts b/src/UI/Studio/EditLayerState.ts index 1b2a131c1..82d18df6c 100644 --- a/src/UI/Studio/EditLayerState.ts +++ b/src/UI/Studio/EditLayerState.ts @@ -283,8 +283,7 @@ class ContextRewritingStep extends Conversion { ) { super( "ContextRewritingStep", - "When validating a layer, the tagRenderings are first expanded. Some builtin tagRendering-calls (e.g. `contact`) will introduce _multiple_ tagRenderings, causing the count to be off. This class rewrites the error messages to fix this", - [] + "When validating a layer, the tagRenderings are first expanded. Some builtin tagRendering-calls (e.g. `contact`) will introduce _multiple_ tagRenderings, causing the count to be off. This class rewrites the error messages to fix this" ) this._state = state this._step = step @@ -460,7 +459,7 @@ export default class EditLayerState extends EditJsonState { } const state: DesugaringContext = { tagRenderings: sharedQuestions, - sharedLayers: layers, + sharedLayers: new Map(layers), tagRenderingOrder: [], } const prepare = this.buildValidation(state)