Fix: cleanup various typing mistakes, remove unused variables, add error handling in opening hours related special visualisations

This commit is contained in:
Pieter Vander Vennet 2025-07-06 02:29:48 +02:00
parent 35cd979b5e
commit 091b7fbba5
16 changed files with 103 additions and 58 deletions

View file

@ -34,9 +34,13 @@
},
"minzoom": 12,
"title": {
"render": {
"*": "{name}"
"render": "{name}",
"mappings": [{
"if": "name=",
"then": {
"en": "Information office"
}
}]
},
"pointRendering": [
{

View file

@ -204,7 +204,7 @@ export class WikimediaImageProvider extends ImageProvider {
return undefined
}
visitUrl(img: ProvidedImage): string | undefined {
visitUrl(img: {id: string}): string | undefined {
return "https://commons.wikimedia.org/wiki/"+img.id
}
}

View file

@ -12,8 +12,6 @@ import { VariableUiElement } from "../../UI/Base/VariableUIElement"
import { TagRenderingConfigJson } from "./Json/TagRenderingConfigJson"
import SvelteUIElement from "../../UI/Base/SvelteUIElement"
import DynamicMarker from "../../UI/Map/DynamicMarker.svelte"
import { UIElement } from "../../UI/UIElement"
import Img from "../../UI/Base/Img"
export class IconConfig extends WithContextLoader {
public static readonly defaultIcon = new IconConfig({ icon: "pin", color: "#ff9939" })
@ -98,6 +96,9 @@ export default class PointRenderingConfig extends WithContextLoader {
this.labelCss = this.tr("labelCss", undefined)
this.labelCssClasses = this.tr("labelCssClasses", undefined)
this.iconBadges = (json.iconBadges ?? []).map((overlay, i) => {
if(typeof overlay === "string"){
throw "Found an invalid,unexpanded overlay"
}
return {
if: TagUtils.Tag(overlay.if),
then: new TagRenderingConfig(overlay.then, `iconBadges.${i}`),

View file

@ -38,7 +38,6 @@ export default class SvelteUIElement<
this._props = props ?? <Props>{}
this._events = events
this._slots = slots
console.trace("Constructing a special stack element")
}
public setSpan() {

View file

@ -9,7 +9,10 @@
let isSvelte = false
let uiElement: BaseUIElement | SvelteUIElement | undefined
let svelteElem: SvelteUIElement
let err = false
onMount(() => {
try {
uiElement = typeof construct === "function" ? construct() : construct
if (uiElement?.["isSvelte"]) {
@ -23,6 +26,11 @@
if (html !== undefined) {
elem?.replaceWith(html)
}
} catch (e) {
console.error("Could not construct a ToSvelte:", e)
err = true
}
})
onDestroy(() => {
@ -30,8 +38,10 @@
uiElement?.Destroy()
})
</script>
{#if svelteElem?._svelteComponent}
{#if err}
<div class="alert">Something went wrong</div>
{:else if isSvelte}
{#if svelteElem?._svelteComponent}
{#if svelteElem.getClass() || svelteElem.getStyle()}
<svelte:component
this={svelteElem?._svelteComponent}
@ -42,6 +52,7 @@
{:else}
<svelte:component this={svelteElem?._svelteComponent} {...svelteElem._props} />
{/if}
{/if}
{:else}
<span bind:this={elem} />
{/if}

View file

@ -16,19 +16,34 @@
export let keyToUse: string = "opening_hours"
export let prefix: string = undefined
export let postfix: string = undefined
let oh: Store<opening_hours | "error" | undefined> = OH.CreateOhObjectStore(
let oh: Store<opening_hours | undefined> = OH.CreateOhObjectStore(
tags,
keyToUse,
prefix,
postfix
)
).map(oh => (typeof oh === "string") ? undefined : oh)
let currentState = oh.mapD((oh) => (typeof oh === "string" ? undefined : oh.getState()))
let currentState = oh.mapD((oh) => {
try {
return oh.getState()
} catch (e) {
console.error("Could not getState for current OpeningHOurs:", e)
return undefined
}
})
let tomorrow = new Date()
tomorrow.setTime(tomorrow.getTime() + 24 * 60 * 60 * 1000)
let nextChange = oh
.mapD(
(oh) => (typeof oh === "string" ? undefined : oh.getNextChange(new Date(), tomorrow)),
(oh) => {
try {
return (oh.getNextChange(new Date(), tomorrow))
} catch (e) {
console.error("Could not getNextChange", e)
return undefined
}
},
[Stores.Chronic(5 * 60 * 1000)]
)
.mapD((date) => Utils.TwoDigits(date.getHours()) + ":" + Utils.TwoDigits(date.getMinutes()))

View file

@ -3,27 +3,26 @@
* Full opening hours visualisations table, dispatches to special cases
*/
import type { OpeningRange } from "../OpeningHours"
import { OH, ToTextualDescription } from "../OpeningHours"
import opening_hours from "opening_hours"
import { ariaLabel } from "../../../Utils/ariaLabel"
import RegularOpeningHoursTable from "./RegularOpeningHoursTable.svelte"
import SpecialCase from "./SpecialCase.svelte"
import { Translation } from "../../i18n/Translation"
import type { OpeningRange } from "../OpeningHours"
export let opening_hours_obj: opening_hours
let applicableWeek = OH.createRangesForApplicableWeek(opening_hours_obj)
let oh = opening_hours_obj
export let applicableWeek: { ranges: OpeningRange[][]; startingMonday: Date }
let ranges = applicableWeek.ranges
let lastMonday = applicableWeek.startingMonday
let textual: Translation = ToTextualDescription.createTextualDescriptionFor(
oh,
applicableWeek.ranges
)
let applicableWeekRanges: { ranges: OpeningRange[][]; startingMonday: Date } =
OH.createRangesForApplicableWeek(oh)
let ranges = applicableWeekRanges.ranges
let lastMonday = applicableWeekRanges.startingMonday
</script>
<div use:ariaLabel={textual} class="no-weblate">

View file

@ -6,7 +6,6 @@
*/
export let availableArea: number
export let earliestOpen: number
export let latestclose: number
export let range: OpeningRange
export let isWeekstable: boolean

View file

@ -8,10 +8,24 @@
import Loading from "../../Base/Loading.svelte"
import Tr from "../../Base/Tr.svelte"
import OpeningHours from "./OpeningHours.svelte"
import { OH } from "../OpeningHours"
import AccordionSingle from "../../Flowbite/AccordionSingle.svelte"
export let tags: UIEventSource<Record<string, string>>
export let opening_hours_obj: Store<opening_hours | "error">
export let key: string
let applicableWeek = opening_hours_obj.map(oh => {
if (oh === "error") {
return "error"
}
try {
return OH.createRangesForApplicableWeek(oh)
} catch (e) {
return e.toString()
}
})
</script>
{#if $tags._country === undefined}
@ -20,8 +34,18 @@
</Loading>
{:else if $opening_hours_obj === undefined}
<div class="alert">No opening hours defined with key {key}</div>
{:else if $opening_hours_obj === "error"}
<Tr cls="alert" t={Translations.t.general.opening_hours.error_loading} />
{:else if typeof $applicableWeek === "string"}
<div class="alert" style="margin-top: 1rem">
<Tr t={Translations.t.general.opening_hours.error_loading} />
</div>
{#if $applicableWeek !== "error"}
<AccordionSingle noBorder>
<div slot="header" class="subtle text-sm">Technical details</div>
<div class="subtle">
{$applicableWeek}
</div>
</AccordionSingle>
{/if}
{:else}
<OpeningHours opening_hours_obj={$opening_hours_obj} />
<OpeningHours opening_hours_obj={$opening_hours_obj} applicableWeek={$applicableWeek} />
{/if}

View file

@ -115,7 +115,6 @@
<OpeningHoursRangeElement
{availableArea}
{earliestOpen}
{latestclose}
{range}
{isWeekstable}
/>

View file

@ -108,7 +108,7 @@ class OpeningHoursTableVis extends SpecialVisualizationSvelte {
},
]
group = "data"
needsUrls = [Constants.countryCoderEndpoint]
needsUrls = [Constants.countryCoderInfo]
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)}`"

View file

@ -21,7 +21,6 @@ export class ShareLinkViz extends SpecialVisualizationSvelte {
},
]
needsUrls = []
svelteBased = true
public constr(
state: SpecialVisualizationState,

View file

@ -16,8 +16,9 @@ import ComparisonTool from "../Comparison/ComparisonTool.svelte"
import { Utils } from "../../Utils"
import TagApplyViz from "./TagApplyViz"
import { ServerSourceInfo } from "../../Models/SourceOverview"
import MaprouletteSetStatus from "../MapRoulette/MaprouletteSetStatus.svelte"
class MaprouletteSetStatus extends SpecialVisualizationSvelte {
class MaprouletteSetStatusVis extends SpecialVisualizationSvelte {
funcName = "maproulette_set_status"
group = "data_import"
docs = "Change the status of the given MapRoulette task"
@ -305,7 +306,7 @@ export class DataImportSpecialVisualisations {
new WayImportButtonViz(),
new ConflateImportButtonViz(),
new PlantNetDetectionViz(),
new MaprouletteSetStatus(),
new MaprouletteSetStatusVis(),
new LinkedDataFromWebsite(),
new CompareData(),
]

View file

@ -1,8 +1,4 @@
import {
SpecialVisualization,
SpecialVisualizationState,
SpecialVisualizationSvelte,
} from "../SpecialVisualization"
import { SpecialVisualization, SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
import Constants from "../../Models/Constants"
import { UIEventSource } from "../../Logic/UIEventSource"
import { Feature } from "geojson"
@ -13,7 +9,6 @@ import { Utils } from "../../Utils"
import CloseNoteButton from "../Popup/Notes/CloseNoteButton.svelte"
import Translations from "../i18n/Translations"
import AddNoteComment from "../Popup/Notes/AddNoteComment.svelte"
import { Imgur } from "../../Logic/ImageProviders/Imgur"
import UploadImage from "../Image/UploadImage.svelte"
import { VariableUiElement } from "../Base/VariableUIElement"
import Combine from "../Base/Combine"
@ -81,7 +76,7 @@ class CloseNoteViz extends SpecialVisualizationSvelte {
class AddNoteCommentViz extends SpecialVisualizationSvelte {
funcName = "add_note_comment"
needsUrls = [Constants.osmAuthConfig.url]
needsUrls = [Constants.osmAuthConfig]
docs = "A textfield to add a comment to a node (with the option to close the note)."
args = [
{
@ -104,7 +99,7 @@ class OpenNote extends SpecialVisualizationSvelte {
funcName = "open_note"
args = []
group = "notes"
needsUrls = [Constants.osmAuthConfig.url]
needsUrls = [Constants.osmAuthConfig]
docs = "Creates a new map note on the given location. This options is placed in the 'last_click'-popup automatically if the 'notes'-layer is enabled"
constr(
@ -157,7 +152,7 @@ class VisualiseNoteComment extends SpecialVisualization {
defaultValue: "0",
},
]
needsUrls = [Constants.osmAuthConfig.url]
needsUrls = [Constants.osmAuthConfig]
constr(state, tags, args) {
return new VariableUiElement(

View file

@ -33,7 +33,6 @@ class StealViz extends SpecialVisualization {
},
]
needsUrls = []
svelteBased = true
constr(state: SpecialVisualizationState, featureTags, args) {
const [featureIdKey, layerAndtagRenderingIds] = args

View file

@ -189,7 +189,7 @@ class LinkVis extends SpecialVisualizationSvelte {
ariaLabel: tagSource.map((tags) => Utils.SubstituteKeys(ariaLabel, tags)),
newTab: new ImmutableStore(newTab),
icon: tagSource.map((tags) => Utils.SubstituteKeys(icon, tags)),
}).setSpan()
})
}
}
export class WebAndCommunicationSpecialVisualisations {