forked from MapComplete/MapComplete
Docs: add 'used in layers'-information for builtingQuestions + various small refactorings
This commit is contained in:
parent
2545982dbd
commit
bc2ea7841f
9 changed files with 83 additions and 47 deletions
|
@ -3611,7 +3611,8 @@
|
||||||
"it": "In questo posto non è possibile prenotare"
|
"it": "In questo posto non è possibile prenotare"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"onSoftDelete": "reservation="
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "ref",
|
"id": "ref",
|
||||||
|
|
|
@ -386,9 +386,11 @@ export class GenerateDocs extends Script {
|
||||||
|
|
||||||
allLayers.forEach((layer) => {
|
allLayers.forEach((layer) => {
|
||||||
const element = layer.generateDocumentation(
|
const element = layer.generateDocumentation(
|
||||||
themesPerLayer.get(layer.id),
|
{
|
||||||
layerIsNeededBy,
|
usedInThemes: themesPerLayer.get(layer.id),
|
||||||
DependencyCalculator.getLayerDependencies(layer)
|
layerIsNeededBy: layerIsNeededBy,
|
||||||
|
dependencies: DependencyCalculator.getLayerDependencies(layer),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
const inlineSource = inlineLayers.get(layer.id)
|
const inlineSource = inlineLayers.get(layer.id)
|
||||||
ScriptUtils.erasableLog("Exporting layer documentation for", layer.id)
|
ScriptUtils.erasableLog("Exporting layer documentation for", layer.id)
|
||||||
|
@ -481,15 +483,17 @@ export class GenerateDocs extends Script {
|
||||||
"questions.json",
|
"questions.json",
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
const reusedTagRenderings = DependencyCalculator.tagRenderingImportedBy(qLayer, Array.from(AllSharedLayers.sharedLayers.values()))
|
||||||
|
const docs = qLayer.generateDocumentation({ reusedTagRenderings })
|
||||||
this.WriteMarkdownFile(
|
this.WriteMarkdownFile(
|
||||||
"./Docs/BuiltinQuestions.md",
|
"./Docs/BuiltinQuestions.md",
|
||||||
qLayer.generateDocumentation([], new Map(), []),
|
docs,
|
||||||
["assets/layers/questions/questions.json"]
|
["assets/layers/questions/questions.json"]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private generateForTheme(theme: ThemeConfig): void {
|
private generateForTheme(theme: ThemeConfig): void {
|
||||||
const allLayers = AllSharedLayers.getSharedLayersConfigs()
|
const allLayers = AllSharedLayers.sharedLayers
|
||||||
const layersToShow = theme.layers.filter(
|
const layersToShow = theme.layers.filter(
|
||||||
(l) => l.id !== "favourite" && Constants.added_by_default.indexOf(<any>l.id) < 0
|
(l) => l.id !== "favourite" && Constants.added_by_default.indexOf(<any>l.id) < 0
|
||||||
)
|
)
|
||||||
|
@ -520,7 +524,7 @@ export class GenerateDocs extends Script {
|
||||||
MarkdownUtils.list(theme.language.filter((ln) => ln !== "_context")),
|
MarkdownUtils.list(theme.language.filter((ln) => ln !== "_context")),
|
||||||
"# Layers defined in this theme configuration file",
|
"# Layers defined in this theme configuration file",
|
||||||
"These layers can not be reused in different themes.",
|
"These layers can not be reused in different themes.",
|
||||||
...layersToInline.map((l) => l.generateDocumentation(null)),
|
...layersToInline.map((l) => l.generateDocumentation({ usedInThemes: null })),
|
||||||
].join("\n")
|
].join("\n")
|
||||||
this.WriteMarkdownFile(
|
this.WriteMarkdownFile(
|
||||||
"./Docs/Themes/" + theme.id + ".md",
|
"./Docs/Themes/" + theme.id + ".md",
|
||||||
|
@ -587,11 +591,13 @@ export class GenerateDocs extends Script {
|
||||||
Constants.priviliged_layers.map((id) => AllSharedLayers.sharedLayers.get(id))
|
Constants.priviliged_layers.map((id) => AllSharedLayers.sharedLayers.get(id))
|
||||||
).map((l) =>
|
).map((l) =>
|
||||||
l.generateDocumentation(
|
l.generateDocumentation(
|
||||||
themesPerLayer.get(l.id),
|
{
|
||||||
layerIsNeededBy,
|
usedInThemes: themesPerLayer.get(l.id),
|
||||||
DependencyCalculator.getLayerDependencies(l),
|
layerIsNeededBy: layerIsNeededBy,
|
||||||
Constants.added_by_default.indexOf(<any>l.id) >= 0,
|
dependencies: DependencyCalculator.getLayerDependencies(l),
|
||||||
Constants.no_include.indexOf(<any>l.id) < 0
|
addedByDefault: Constants.added_by_default.indexOf(<any>l.id) >= 0,
|
||||||
|
canBeIncluded: Constants.no_include.indexOf(<any>l.id) < 0,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
"# Normal layers",
|
"# Normal layers",
|
||||||
|
|
|
@ -14,11 +14,7 @@ import {
|
||||||
import { Translation } from "../src/UI/i18n/Translation"
|
import { Translation } from "../src/UI/i18n/Translation"
|
||||||
import { PrepareLayer } from "../src/Models/ThemeConfig/Conversion/PrepareLayer"
|
import { PrepareLayer } from "../src/Models/ThemeConfig/Conversion/PrepareLayer"
|
||||||
import { PrepareTheme } from "../src/Models/ThemeConfig/Conversion/PrepareTheme"
|
import { PrepareTheme } from "../src/Models/ThemeConfig/Conversion/PrepareTheme"
|
||||||
import {
|
import { Conversion, DesugaringContext, DesugaringStep } from "../src/Models/ThemeConfig/Conversion/Conversion"
|
||||||
Conversion,
|
|
||||||
DesugaringContext,
|
|
||||||
DesugaringStep,
|
|
||||||
} from "../src/Models/ThemeConfig/Conversion/Conversion"
|
|
||||||
import { Utils } from "../src/Utils"
|
import { Utils } from "../src/Utils"
|
||||||
import Script from "./Script"
|
import Script from "./Script"
|
||||||
import { AllSharedLayers } from "../src/Customizations/AllSharedLayers"
|
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 { ValidateThemeAndLayers } from "../src/Models/ThemeConfig/Conversion/ValidateThemeAndLayers"
|
||||||
import { ExtractImages } from "../src/Models/ThemeConfig/Conversion/FixImages"
|
import { ExtractImages } from "../src/Models/ThemeConfig/Conversion/FixImages"
|
||||||
import { TagRenderingConfigJson } from "../src/Models/ThemeConfig/Json/TagRenderingConfigJson"
|
import { TagRenderingConfigJson } from "../src/Models/ThemeConfig/Json/TagRenderingConfigJson"
|
||||||
import {
|
import { LayerConfigDependencyGraph, LevelInfo } from "../src/Models/ThemeConfig/LayerConfigDependencyGraph"
|
||||||
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.
|
// 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
|
// 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
|
private readonly _doesImageExist: DoesImageExist
|
||||||
|
|
||||||
constructor(prepareLayer: PrepareLayer, 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._prepareLayer = prepareLayer
|
||||||
this._doesImageExist = doesImageExist
|
this._doesImageExist = doesImageExist
|
||||||
}
|
}
|
||||||
|
@ -113,7 +106,7 @@ class AddIconSummary extends DesugaringStep<{ raw: LayerConfigJson; parsed: Laye
|
||||||
static singleton = new AddIconSummary()
|
static singleton = new AddIconSummary()
|
||||||
|
|
||||||
constructor() {
|
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 }) {
|
convert(json: { raw: LayerConfigJson; parsed: LayerConfig }) {
|
||||||
|
@ -158,7 +151,7 @@ class LayerBuilder extends Conversion<object, Map<string, LayerConfigJson>> {
|
||||||
states: Map<string, "clean" | "dirty" | "changed">,
|
states: Map<string, "clean" | "dirty" | "changed">,
|
||||||
sharedTagRenderings: QuestionableTagRenderingConfigJson[]
|
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._levels = levels
|
||||||
this._dependencies = dependencies
|
this._dependencies = dependencies
|
||||||
this._states = states
|
this._states = states
|
||||||
|
@ -667,7 +660,7 @@ class LayerOverviewUtils extends Script {
|
||||||
priviliged.delete("last_click")
|
priviliged.delete("last_click")
|
||||||
priviliged.delete("search")
|
priviliged.delete("search")
|
||||||
|
|
||||||
const isBoostrapping = AllSharedLayers.getSharedLayersConfigs().size == 0
|
const isBoostrapping = AllSharedLayers.sharedLayers.size == 0
|
||||||
if (!isBoostrapping && priviliged.size > 0) {
|
if (!isBoostrapping && priviliged.size > 0) {
|
||||||
throw (
|
throw (
|
||||||
"Priviliged layer " +
|
"Priviliged layer " +
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as known_layers from "../assets/generated/known_layers.json"
|
||||||
import { LayerConfigJson } from "../Models/ThemeConfig/Json/LayerConfigJson"
|
import { LayerConfigJson } from "../Models/ThemeConfig/Json/LayerConfigJson"
|
||||||
|
|
||||||
export class AllSharedLayers {
|
export class AllSharedLayers {
|
||||||
public static sharedLayers: Map<string, LayerConfig> = AllSharedLayers.getSharedLayers()
|
public static sharedLayers: ReadonlyMap<string, LayerConfig> = AllSharedLayers.getSharedLayers()
|
||||||
public static getSharedLayersConfigs(): Map<string, LayerConfigJson> {
|
public static getSharedLayersConfigs(): Map<string, LayerConfigJson> {
|
||||||
const sharedLayers = new Map<string, LayerConfigJson>()
|
const sharedLayers = new Map<string, LayerConfigJson>()
|
||||||
for (const layer of known_layers["layers"]) {
|
for (const layer of known_layers["layers"]) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ export interface DesugaringContext {
|
||||||
* Order of appearance in questions.json
|
* Order of appearance in questions.json
|
||||||
*/
|
*/
|
||||||
tagRenderingOrder: string[]
|
tagRenderingOrder: string[]
|
||||||
sharedLayers: Map<string, LayerConfigJson>
|
sharedLayers: Map<string, Readonly<LayerConfigJson>>
|
||||||
publicLayers?: Set<string>
|
publicLayers?: Set<string>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,38 @@ import { ExtraFuncParams, ExtraFunctions } from "../../Logic/ExtraFunctions"
|
||||||
import LayerConfig from "./LayerConfig"
|
import LayerConfig from "./LayerConfig"
|
||||||
import { SpecialVisualization } from "../../UI/SpecialVisualization"
|
import { SpecialVisualization } from "../../UI/SpecialVisualization"
|
||||||
import SpecialVisualizations from "../../UI/SpecialVisualizations"
|
import SpecialVisualizations from "../../UI/SpecialVisualizations"
|
||||||
|
import { LayerConfigJson } from "./Json/LayerConfigJson"
|
||||||
|
|
||||||
export default class DependencyCalculator {
|
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<string, {
|
||||||
|
layer: string
|
||||||
|
}[]> {
|
||||||
|
const result: Map<string, { layer: string }[]> = 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
|
id: string
|
||||||
minzoom?: number
|
minzoom?: number
|
||||||
neededBy: string
|
neededBy: string
|
||||||
|
@ -83,7 +112,7 @@ export default class DependencyCalculator {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const tr of layer.AllTagRenderings()) {
|
for (const tr of layer.AllTagRenderings()) {
|
||||||
for (const dep of DependencyCalculator.GetTagRenderingDependencies(tr)) {
|
for (const dep of DependencyCalculator.getTagRenderingDependencies(tr)) {
|
||||||
deps.push({
|
deps.push({
|
||||||
neededLayer: dep.id,
|
neededLayer: dep.id,
|
||||||
reason: `tagrendering ${dep.neededBy} needs this layer`,
|
reason: `tagrendering ${dep.neededBy} needs this layer`,
|
||||||
|
|
|
@ -439,15 +439,15 @@ export default class LayerConfig extends WithContextLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
public generateDocumentation(
|
public generateDocumentation(
|
||||||
usedInThemes: string[],
|
{ usedInThemes = [], layerIsNeededBy, dependencies = [], addedByDefault = false, canBeIncluded = true, lang = "en", reusedTagRenderings }: {
|
||||||
layerIsNeededBy?: Map<string, string[]>,
|
usedInThemes?: string[],
|
||||||
dependencies: {
|
layerIsNeededBy?: Map<string, string[]>,
|
||||||
context?: string
|
dependencies?: { context?: string; reason: string; neededLayer: string }[],
|
||||||
reason: string
|
addedByDefault?: boolean,
|
||||||
neededLayer: string
|
canBeIncluded?: boolean,
|
||||||
}[] = [],
|
reusedTagRenderings?: Map<string, {layer: string}[]>,
|
||||||
addedByDefault = false,
|
lang?: string
|
||||||
canBeIncluded = true
|
}
|
||||||
): string {
|
): string {
|
||||||
const extraProps: string[] = []
|
const extraProps: string[] = []
|
||||||
extraProps.push("This layer is shown at zoomlevel **" + this.minzoom + "** and higher")
|
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.generateDocumentationQuickTable(),
|
||||||
...this.tagRenderings
|
...this.tagRenderings
|
||||||
.filter((tr) => tr.labels.indexOf("ignore_docs") < 0)
|
.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,
|
...filterDocs,
|
||||||
].join("\n\n")
|
].join("\n\n")
|
||||||
}
|
}
|
||||||
|
|
|
@ -941,7 +941,7 @@ export default class TagRenderingConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateDocumentation(lang: string = "en"): string {
|
generateDocumentation(lang: string = "en", usedInLayers?: string[]): string {
|
||||||
let freeform: string = undefined
|
let freeform: string = undefined
|
||||||
if (this.render) {
|
if (this.render) {
|
||||||
freeform = "\n*" + this.render.textFor(lang) + "*"
|
freeform = "\n*" + this.render.textFor(lang) + "*"
|
||||||
|
@ -1016,12 +1016,18 @@ export default class TagRenderingConfig {
|
||||||
let labels: string = undefined
|
let labels: string = undefined
|
||||||
if (this.labels?.length > 0) {
|
if (this.labels?.length > 0) {
|
||||||
labels = [
|
labels = [
|
||||||
"This tagrendering has labels ",
|
"This tagrendering has labels",
|
||||||
...this.labels.map((label) => "`" + label + "`"),
|
...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.id,
|
||||||
this.description,
|
this.description,
|
||||||
this.question !== undefined
|
this.question !== undefined
|
||||||
|
@ -1031,7 +1037,9 @@ export default class TagRenderingConfig {
|
||||||
mappings,
|
mappings,
|
||||||
condition,
|
condition,
|
||||||
labels,
|
labels,
|
||||||
].join("\n")
|
"",
|
||||||
|
reuse
|
||||||
|
]).join("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
public usedTags(): TagsFilter[] {
|
public usedTags(): TagsFilter[] {
|
||||||
|
|
|
@ -283,8 +283,7 @@ class ContextRewritingStep<T> extends Conversion<LayerConfigJson, T> {
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
"ContextRewritingStep",
|
"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._state = state
|
||||||
this._step = step
|
this._step = step
|
||||||
|
@ -460,7 +459,7 @@ export default class EditLayerState extends EditJsonState<LayerConfigJson> {
|
||||||
}
|
}
|
||||||
const state: DesugaringContext = {
|
const state: DesugaringContext = {
|
||||||
tagRenderings: sharedQuestions,
|
tagRenderings: sharedQuestions,
|
||||||
sharedLayers: layers,
|
sharedLayers: new Map(layers),
|
||||||
tagRenderingOrder: [],
|
tagRenderingOrder: [],
|
||||||
}
|
}
|
||||||
const prepare = this.buildValidation(state)
|
const prepare = this.buildValidation(state)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue