Automatically load appropriate suggestions for brands and operators
This commit is contained in:
parent
3146fa0d26
commit
67f23eea14
11 changed files with 70 additions and 47 deletions
|
@ -4,22 +4,12 @@ import * as nsiWD from "../node_modules/name-suggestion-index/dist/wikidata.min.
|
|||
import { existsSync, writeFileSync } from "fs"
|
||||
import ScriptUtils from "./ScriptUtils"
|
||||
import { Utils } from "../src/Utils"
|
||||
import { WikimediaImageProvider } from "../src/Logic/ImageProviders/WikimediaImageProvider"
|
||||
import { renameSync } from "node:fs"
|
||||
|
||||
export default class DownloadNsiLogos extends Script {
|
||||
class DownloadNsiLogos extends Script {
|
||||
constructor() {
|
||||
super("Downloads all images of the NSI")
|
||||
}
|
||||
|
||||
private async getWikimediaUrl(startUrl: string) {
|
||||
if (!startUrl) {
|
||||
return startUrl
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private async downloadLogo(nsiItem: NSIItem, type: string, basePath: string) {
|
||||
try {
|
||||
return await this.downloadLogoUnsafe(nsiItem, type, basePath)
|
||||
|
@ -71,8 +61,8 @@ export default class DownloadNsiLogos extends Script {
|
|||
}
|
||||
if ((<string>logos.wikidata).toLowerCase().endsWith(".svg")) {
|
||||
console.log("Written SVG", path)
|
||||
if(!path.endsWith(".svg")){
|
||||
throw "Undetected svg path:"+logos.wikidata
|
||||
if (!path.endsWith(".svg")) {
|
||||
throw "Undetected svg path:" + logos.wikidata
|
||||
}
|
||||
writeFileSync(path, dloaded["content"], "utf8")
|
||||
return true
|
||||
|
@ -90,8 +80,12 @@ export default class DownloadNsiLogos extends Script {
|
|||
|
||||
}
|
||||
|
||||
async main(args: string[]): Promise<void> {
|
||||
const type = "brand"
|
||||
async main(): Promise<void> {
|
||||
await this.downloadFor("operator")
|
||||
await this.downloadFor("brand")
|
||||
}
|
||||
|
||||
async downloadFor(type: "brand" | "operator"): Promise<void> {
|
||||
const items = NameSuggestionIndex.allPossible(type)
|
||||
const basePath = "./public/assets/data/nsi/logos/"
|
||||
let downloadCount = 0
|
||||
|
|
|
@ -883,7 +883,8 @@ export class TagRenderingConfigUtils {
|
|||
return config
|
||||
}
|
||||
const clone: TagRenderingConfig = Object.create(config)
|
||||
clone.mappings = [...clone.mappings ?? [], ...extraMappings]
|
||||
const oldMappingsCloned = clone.mappings?.map(m => ({ ...m, priorityIf: m.priorityIf ?? TagUtils.Tag("id~*") })) ?? []
|
||||
clone.mappings = [...oldMappingsCloned, ...extraMappings]
|
||||
return clone
|
||||
})
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
import UserRelatedState from "../../Logic/State/UserRelatedState"
|
||||
import Delete_icon from "../../assets/svg/Delete_icon.svelte"
|
||||
import BackButton from "../Base/BackButton.svelte"
|
||||
import TagRenderingEditableDynamic from "../Popup/TagRendering/TagRenderingEditableDynamic.svelte"
|
||||
|
||||
export let state: SpecialVisualizationState
|
||||
export let selectedElement: Feature
|
||||
|
@ -68,7 +69,7 @@
|
|||
tabindex="-1"
|
||||
>
|
||||
{#each $knownTagRenderings as config (config.id)}
|
||||
<TagRenderingEditable
|
||||
<TagRenderingEditableDynamic
|
||||
{tags}
|
||||
{config}
|
||||
{state}
|
||||
|
|
|
@ -550,14 +550,13 @@ export default class ShowDataLayer {
|
|||
return
|
||||
}
|
||||
const bbox = BBox.bboxAroundAll(features.map(BBox.get))
|
||||
console.log("Zooming to features", bbox.asGeoJson())
|
||||
console.debug("Zooming to features", bbox.asGeoJson())
|
||||
window.requestAnimationFrame(() => {
|
||||
|
||||
map.resize()
|
||||
map.fitBounds(bbox.toLngLat(), {
|
||||
padding: { top: 10, bottom: 10, left: 10, right: 10 },
|
||||
animate: false
|
||||
})
|
||||
map.resize()
|
||||
map.fitBounds(bbox.toLngLat(), {
|
||||
padding: { top: 10, bottom: 10, left: 10, right: 10 },
|
||||
animate: false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ export default class OpeningHoursVisualization extends Toggle {
|
|||
applicableWeek.startingMonday
|
||||
)
|
||||
Locale.language.mapD((lng) => {
|
||||
console.log("Setting OH description to", lng, textual)
|
||||
console.debug("Setting OH description to", lng, textual)
|
||||
vis.ConstructElement().ariaLabel = textual.textFor(lng)
|
||||
})
|
||||
return vis
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
* Shows all questions for which the answers are unknown.
|
||||
* The questions can either be shown all at once or one at a time (in which case they can be skipped)
|
||||
*/
|
||||
import TagRenderingConfig, { TagRenderingConfigUtils } from "../../../Models/ThemeConfig/TagRenderingConfig"
|
||||
import { Store, UIEventSource } from "../../../Logic/UIEventSource"
|
||||
import TagRenderingConfig from "../../../Models/ThemeConfig/TagRenderingConfig"
|
||||
import { UIEventSource } from "../../../Logic/UIEventSource"
|
||||
import type { Feature } from "geojson"
|
||||
import type { SpecialVisualizationState } from "../../SpecialVisualization"
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
|
||||
import TagRenderingQuestion from "./TagRenderingQuestion.svelte"
|
||||
import Tr from "../../Base/Tr.svelte"
|
||||
import Translations from "../../i18n/Translations.js"
|
||||
import { Utils } from "../../../Utils"
|
||||
import { onDestroy } from "svelte"
|
||||
import TagRenderingQuestion from "./TagRenderingQuestion.svelte"
|
||||
import TagRenderingQuestionDynamic from "./TagRenderingQuestionDynamic.svelte"
|
||||
|
||||
export let layer: LayerConfig
|
||||
|
@ -26,7 +26,8 @@
|
|||
export let onlyForLabels: string[] | undefined = undefined
|
||||
const _onlyForLabels = new Set(onlyForLabels)
|
||||
/**
|
||||
* If set, only questions _not_ having these labels will be shown
|
||||
* If set, only questions _not_ having these labels will be shown.
|
||||
* This is used for a partial questionbox
|
||||
*/
|
||||
export let notForLabels: string[] | undefined = undefined
|
||||
const _notForLabels = new Set(notForLabels)
|
||||
|
@ -41,14 +42,15 @@
|
|||
}
|
||||
return true
|
||||
}
|
||||
const baseQuestions = (layer.tagRenderings ?? [])?.filter(
|
||||
(tr) => allowed(tr.labels) && tr.question !== undefined
|
||||
)
|
||||
|
||||
let skippedQuestions = new UIEventSource<Set<string>>(new Set<string>())
|
||||
let questionboxElem: HTMLDivElement
|
||||
let questionsToAsk = tags.map(
|
||||
(tags) => {
|
||||
const baseQuestions = (layer.tagRenderings ?? [])?.filter(
|
||||
(tr) => allowed(tr.labels) && tr.question !== undefined
|
||||
)
|
||||
|
||||
const questionsToAsk: TagRenderingConfig[] = []
|
||||
for (const baseQuestion of baseQuestions) {
|
||||
if (skippedQuestions.data.has(baseQuestion.id)) {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
import { Utils } from "../../../Utils"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
import EditButton from "./EditButton.svelte"
|
||||
import TagRenderingAnswerDynamic from "./TagRenderingAnswerDynamic.svelte"
|
||||
import TagRenderingAnswer from "./TagRenderingAnswer.svelte"
|
||||
|
||||
export let config: TagRenderingConfig
|
||||
export let tags: UIEventSource<Record<string, string>>
|
||||
|
@ -100,7 +100,7 @@
|
|||
</TagRenderingQuestion>
|
||||
{:else}
|
||||
<div class="low-interaction flex items-center justify-between overflow-hidden rounded px-2">
|
||||
<TagRenderingAnswerDynamic id={answerId} {config} {tags} {selectedElement} {state} {layer} />
|
||||
<TagRenderingAnswer id={answerId} {config} {tags} {selectedElement} {state} {layer} />
|
||||
<EditButton
|
||||
arialabel={config.editButtonAriaLabel}
|
||||
ariaLabelledBy={answerId}
|
||||
|
@ -112,7 +112,7 @@
|
|||
{/if}
|
||||
{:else}
|
||||
<div class="h-full w-full overflow-hidden">
|
||||
<TagRenderingAnswerDynamic {config} {tags} {selectedElement} {state} {layer} />
|
||||
<TagRenderingAnswer {config} {tags} {selectedElement} {state} {layer} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
26
src/UI/Popup/TagRendering/TagRenderingEditableDynamic.svelte
Normal file
26
src/UI/Popup/TagRendering/TagRenderingEditableDynamic.svelte
Normal file
|
@ -0,0 +1,26 @@
|
|||
<script lang="ts">
|
||||
import TagRenderingConfig, { TagRenderingConfigUtils } from "../../../Models/ThemeConfig/TagRenderingConfig"
|
||||
import { Store, UIEventSource } from "../../../Logic/UIEventSource"
|
||||
import type { Feature } from "geojson"
|
||||
import type { SpecialVisualizationState } from "../../SpecialVisualization"
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
|
||||
import TagRenderingEditable from "./TagRenderingEditable.svelte"
|
||||
|
||||
export let config: TagRenderingConfig
|
||||
export let tags: UIEventSource<Record<string, string>>
|
||||
export let selectedElement: Feature | undefined
|
||||
export let state: SpecialVisualizationState
|
||||
export let layer: LayerConfig = undefined
|
||||
|
||||
export let editingEnabled: Store<boolean> | undefined = state?.featureSwitchUserbadge
|
||||
|
||||
export let highlightedRendering: UIEventSource<string> = undefined
|
||||
export let clss = undefined
|
||||
export let editMode = !config.IsKnown(tags.data)
|
||||
|
||||
let dynamicConfig = TagRenderingConfigUtils.withNameSuggestionIndex(config, tags, selectedElement)
|
||||
|
||||
</script>
|
||||
|
||||
<TagRenderingEditable config={$dynamicConfig} {editMode} {clss} {highlightedRendering} {editingEnabled} {layer} {state}
|
||||
{selectedElement} {tags} />
|
|
@ -3,7 +3,6 @@
|
|||
import type { SpecialVisualizationState } from "../../SpecialVisualization"
|
||||
import Tr from "../../Base/Tr.svelte"
|
||||
import type { Feature } from "geojson"
|
||||
import type { Mapping } from "../../../Models/ThemeConfig/TagRenderingConfig"
|
||||
import TagRenderingConfig from "../../../Models/ThemeConfig/TagRenderingConfig"
|
||||
import { TagsFilter } from "../../../Logic/Tags/TagsFilter"
|
||||
import FreeformInput from "./FreeformInput.svelte"
|
||||
|
@ -59,7 +58,6 @@
|
|||
*/
|
||||
let checkedMappings: boolean[]
|
||||
|
||||
let mappings: Mapping[] = config?.mappings ?? []
|
||||
let searchTerm: UIEventSource<string> = new UIEventSource("")
|
||||
|
||||
let dispatch = createEventDispatcher<{
|
||||
|
@ -74,7 +72,7 @@
|
|||
*/
|
||||
|
||||
function initialize(tgs: Record<string, string>, confg: TagRenderingConfig): void {
|
||||
mappings = confg.mappings?.filter((m) => {
|
||||
const mappings = confg.mappings?.filter((m) => {
|
||||
if (typeof m.hideInAnswer === "boolean") {
|
||||
return !m.hideInAnswer
|
||||
}
|
||||
|
@ -169,7 +167,7 @@
|
|||
|
||||
onDestroy(
|
||||
freeformInput.subscribe((freeformValue) => {
|
||||
if (!mappings || mappings?.length == 0 || config.freeform?.key === undefined) {
|
||||
if (!config?.mappings || config?.mappings?.length == 0 || config.freeform?.key === undefined) {
|
||||
return
|
||||
}
|
||||
// If a freeform value is given, mark the 'mapping' as marked
|
||||
|
@ -178,11 +176,11 @@
|
|||
// Initialization didn't yet run
|
||||
return
|
||||
}
|
||||
checkedMappings[mappings.length] = freeformValue?.length > 0
|
||||
checkedMappings[config?.mappings.length] = freeformValue?.length > 0
|
||||
return
|
||||
}
|
||||
if (freeformValue?.length > 0) {
|
||||
selectedMapping = mappings.length
|
||||
selectedMapping = config.mappings.length
|
||||
}
|
||||
})
|
||||
)
|
||||
|
@ -192,7 +190,7 @@
|
|||
allowDeleteOfFreeform &&
|
||||
$freeformInput === undefined &&
|
||||
$freeformInputUnvalidated === "" &&
|
||||
(mappings?.length ?? 0) === 0
|
||||
(config?.mappings?.length ?? 0) === 0
|
||||
) {
|
||||
selectedTags = new Tag(config.freeform.key, "")
|
||||
} else {
|
||||
|
@ -353,7 +351,7 @@
|
|||
|
||||
|
||||
|
||||
{#if config.freeform?.key && !(mappings?.length > 0)}
|
||||
{#if config.freeform?.key && !(config?.mappings?.length > 0)}
|
||||
<!-- There are no options to choose from, simply show the input element: fill out the text field -->
|
||||
<FreeformInput
|
||||
{config}
|
||||
|
@ -367,7 +365,7 @@
|
|||
unvalidatedText={freeformInputUnvalidated}
|
||||
on:submit={() => onSave()}
|
||||
/>
|
||||
{:else if mappings !== undefined && !config.multiAnswer}
|
||||
{:else if config.mappings !== undefined && !config.multiAnswer}
|
||||
<!-- Simple radiobuttons as mapping -->
|
||||
<div class="flex flex-col">
|
||||
{#each config.mappings as mapping, i (mapping.then)}
|
||||
|
@ -416,7 +414,7 @@
|
|||
</label>
|
||||
{/if}
|
||||
</div>
|
||||
{:else if mappings !== undefined && config.multiAnswer}
|
||||
{:else if config.mappings !== undefined && config.multiAnswer}
|
||||
<!-- Multiple answers can be chosen: checkboxes -->
|
||||
<div class="flex flex-col">
|
||||
{#each config.mappings as mapping, i (mapping.then)}
|
||||
|
@ -480,7 +478,7 @@
|
|||
<!-- TagRenderingQuestion-buttons -->
|
||||
<slot name="cancel" />
|
||||
<slot name="save-button" {selectedTags}>
|
||||
{#if allowDeleteOfFreeform && (mappings?.length ?? 0) === 0 && $freeformInput === undefined && $freeformInputUnvalidated === ""}
|
||||
{#if allowDeleteOfFreeform && (config?.mappings?.length ?? 0) === 0 && $freeformInput === undefined && $freeformInputUnvalidated === ""}
|
||||
<button
|
||||
class="primary flex"
|
||||
on:click|stopPropagation|preventDefault={() => onSave()}
|
||||
|
|
|
@ -8,6 +8,7 @@ import type { SpecialVisualizationState } from "../../SpecialVisualization"
|
|||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
|
||||
import TagRenderingQuestion from "./TagRenderingQuestion.svelte"
|
||||
import type { UploadableTag } from "../../../Logic/Tags/TagUtils"
|
||||
import { writable } from "svelte/store"
|
||||
|
||||
export let config: TagRenderingConfig
|
||||
export let tags: UIEventSource<Record<string, string>>
|
||||
|
@ -22,6 +23,7 @@ export let allowDeleteOfFreeform: boolean = false
|
|||
|
||||
|
||||
let dynamicConfig = TagRenderingConfigUtils.withNameSuggestionIndex(config, tags, selectedElement)
|
||||
|
||||
</script>
|
||||
|
||||
<TagRenderingQuestion
|
||||
|
|
|
@ -685,6 +685,6 @@
|
|||
<CloseAnimation isOpened={state.guistate.themeIsOpened} moveTo={openMapButton} debug="theme"/>
|
||||
<CloseAnimation isOpened={state.guistate.menuIsOpened} moveTo={openMenuButton} debug="menu"/>
|
||||
<CloseAnimation isOpened={selectedLayer.map(sl => (sl !== undefined && sl === currentViewLayer))} moveTo={openCurrentViewLayerButton} debug="currentViewLayer"/>
|
||||
<CloseAnimation isOpened={selectedElement.map(sl =>{ console.log("SE is", sl); return sl !== undefined && sl?.properties?.id === LastClickFeatureSource.newPointElementId })} moveTo={openNewElementButton} debug="newElement"/>
|
||||
<CloseAnimation isOpened={selectedElement.map(sl => sl !== undefined && sl?.properties?.id === LastClickFeatureSource.newPointElementId)} moveTo={openNewElementButton} debug="newElement"/>
|
||||
<CloseAnimation isOpened={state.guistate.filtersPanelIsOpened} moveTo={openFilterButton} debug="filter"/>
|
||||
<CloseAnimation isOpened={state.guistate.backgroundLayerSelectionIsOpened} moveTo={openBackgroundButton} debug="bg"/>
|
||||
|
|
Loading…
Reference in a new issue