Merge master

This commit is contained in:
Pieter Vander Vennet 2025-08-20 01:12:51 +02:00
commit 82c92e7f79
111 changed files with 3134 additions and 730 deletions

View file

@ -219,10 +219,10 @@
</h3>
{#if $showHome}
<a class="flex" href={($isAndroid ? "https://mapcomplete.org" : ".") + "/studio.html"}>
<Pencil class="mr-2 h-6 w-6" />
<Tr t={Translations.t.general.morescreen.createYourOwnTheme} />
</a>
<a class="flex" href={($isAndroid ? "https://mapcomplete.org" : ".") + "/studio.html"}>
<Pencil class="mr-2 h-6 w-6" />
<Tr t={Translations.t.general.morescreen.createYourOwnTheme} />
</a>
{/if}
<a class="flex" href="mailto:info@mapcomplete.org">
<EnvelopeOpen class="h-6 w-6" />

View file

@ -153,7 +153,7 @@
const t = Translations.t.offline
</script>
<div class="max-h-leave-room flex h-full flex-col overflow-auto ">
<div class="max-h-leave-room flex h-full flex-col overflow-auto">
<Checkbox selected={autoDownload}>
<Trans t={t.autoCheckmark} />
</Checkbox>
@ -163,9 +163,7 @@
<Trans t={t.autoExplanation} />
</div>
</AccordionSingle>
<div>
</div>
<div />
{#if $installed === undefined}
<Loading />
{:else}
@ -248,7 +246,6 @@
<button on:click={() => del(area)}>
<TrashIcon class="w-6" />
<Trans t={t.delete} />
</button>
</td>
</tr>

View file

@ -101,8 +101,9 @@
})
let id = 0
adaptor.lastClickLocation.addCallbackD(({ lon, lat }) => {
let projected: Feature<Point, { index: number; id: string; reuse?: string }> =
<any>GeoOperations.nearestPoint(wayGeojson, [lon, lat])
let projected: Feature<Point, { index: number; id: string; reuse?: string }> = <any>(
GeoOperations.nearestPoint(wayGeojson, [lon, lat])
)
console.log("Added splitpoint", projected, id)

View file

@ -8,6 +8,7 @@
import { OH } from "../../../OpeningHours/OpeningHours"
import { Lists } from "../../../../Utils/Lists"
import { Translation } from "../../../i18n/Translation"
import PlusCircle from "@babeard/svelte-heroicons/mini/PlusCircle"
export let value: UIEventSource<string>
@ -114,7 +115,7 @@
}}
>
<PlusCircle class="h-6 w-6" />
Add time
<Tr t={Translations.t.collectionTimes.addTime} />
</button>
</div>
<div class="flex w-fit flex-wrap">

View file

@ -30,7 +30,9 @@
let center = GeoOperations.centerpointCoordinates(feature)
if (feature.geometry.type === "LineString") {
center = <[number, number]>GeoOperations.nearestPoint(<Feature<LineString>>feature, center).geometry.coordinates
center = <[number, number]>(
GeoOperations.nearestPoint(<Feature<LineString>>feature, center).geometry.coordinates
)
}
export let initialCoordinate: { lon: number; lat: number } = { lon: center[0], lat: center[1] }
let mapLocation: UIEventSource<{ lon: number; lat: number }> = new UIEventSource(

View file

@ -5,7 +5,6 @@
import type { Feature } from "geojson"
import type { SpecialVisualizationState } from "../SpecialVisualization"
import type { Validator } from "./Validator"
import DistanceInput from "./Helpers/DistanceInput.svelte"
export let type: ValidatorType
@ -14,11 +13,13 @@
export let args: (string | number | boolean)[] | any = undefined
export let state: SpecialVisualizationState = undefined
let validator = Validators.get(type)
let validatorHelper: Validator = validator.inputHelper
let validatorHelper = validator.inputHelper
</script>
{#if type === "distance"}
<DistanceInput {value} {feature} {state} {args} />
{:else if validatorHelper !== undefined}
<svelte:component this={validatorHelper} {value} {feature} {state} {args} on:submit />
{:else}
<slot name="fallback" /> <!-- Used in the FilterWithView to inject the helper -->
{/if}

View file

@ -107,7 +107,6 @@ export default class Validators {
new TagValidator(),
new NameSuggestionIndexValidator(),
]
private static _byType = Validators._byTypeConstructor()

View file

@ -767,18 +767,17 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
* To avoid rendering artefacts or too frequenting pinging, this is ratelimited to one update every 'rateLimitMs' milliseconds
*/
public installQuicklocation(ratelimitMs = 50) {
this._maplibreMap.addCallbackAndRunD(map => {
this._maplibreMap.addCallbackAndRunD((map) => {
let lastUpdate = new Date().getTime()
map.on("drag", e => {
map.on("drag", (e) => {
let now = new Date().getTime()
if(now - lastUpdate < ratelimitMs){
if (now - lastUpdate < ratelimitMs) {
return
}
lastUpdate = now;
lastUpdate = now
const center = map.getCenter()
this.location.set({lon: center.lng, lat: center.lat})
this.location.set({ lon: center.lng, lat: center.lat })
})
})
}
}

View file

@ -7,7 +7,7 @@ export interface ShowDataLayerOptions {
/**
* Features to show
*/
features: FeatureSource<Feature<Geometry, Record<string, any> & {id: string}>>
features: FeatureSource<Feature<Geometry, Record<string, any> & { id: string }>>
/**
* Indication of the current selected element; overrides some filters.
* When a feature is tapped, the feature will be put in there

View file

@ -1,7 +1,6 @@
<script lang="ts">
import Loading from "../Base/Loading.svelte"
import MaplibreMap from "../Map/MaplibreMap.svelte"
import { Utils } from "../../Utils"
import { Store, UIEventSource } from "../../Logic/UIEventSource"
import FilteredLayer from "../../Models/FilteredLayer"
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"
@ -13,6 +12,8 @@
import type { AutoAction } from "./AutoApplyButtonVis"
import Tr from "../Base/Tr.svelte"
import Translations from "../i18n/Translations"
import { Lists } from "../../Utils/Lists"
import type { OsmFeature } from "../../Models/OsmFeature"
/**
* The ids to handle. Might be data from an external dataset, we cannot assume an OSM-id
@ -42,12 +43,12 @@
mla.allowZooming.setData(false)
mla.allowMoving.setData(false)
const features = ids.mapD((ids) =>
ids.map((id) => state.indexedFeatures.featuresById.data.get(id))
const features: Store<OsmFeature[]> = ids.mapD((ids) =>
ids.map<OsmFeature>((id) => state.indexedFeatures.featuresById.data.get(id))
)
new ShowDataLayer(mlmap, {
features: StaticFeatureSource.fromGeojson(features),
features: new StaticFeatureSource(features),
zoomToFeatures: true,
layer: layer.layerDef,
})
@ -121,10 +122,10 @@
<div class="alert">Target tagrendering {options.targetTagRendering} not found"</div>
{:else if $ids.length === 0}
<div>No elements found to perform action</div>
{:else if $buttonState.error !== undefined}
{:else if $buttonState["error"] !== undefined}
<div class="flex flex-col">
<div class="alert">Something went wrong</div>
<div>{$buttonState.error}</div>
<div>{$buttonState["error"]}</div>
</div>
{:else if $buttonState === "done"}
<div class="thanks">All done!</div>

View file

@ -51,7 +51,7 @@ export default class AutoApplyButtonVis extends SpecialVisualizationSvelte {
},
{
name: "text",
type:"translation",
type: "translation",
doc: "The text to show on the button",
required: true,
},

View file

@ -1,4 +1,8 @@
import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationSvelte } from "../SpecialVisualization"
import {
SpecialVisualisationParams,
SpecialVisualization,
SpecialVisualizationSvelte,
} from "../SpecialVisualization"
import { Feature, LineString } from "geojson"
import Translations from "../i18n/Translations"
import SvelteUIElement from "../Base/SvelteUIElement"

View file

@ -63,15 +63,13 @@ class DirectionAbsolute extends SpecialVisualization {
]
group = "data"
constr({
tags,
args,
}: SpecialVisualisationParams): BaseUIElement {
constr({ tags, args }: SpecialVisualisationParams): BaseUIElement {
const key = args[0] === "" ? "_direction:centerpoint" : args[0]
const offset = args[1] === "" ? 0 : Number(args[1])
return new VariableUiElement(
tags.map((tags) => {
tags
.map((tags) => {
console.log("Direction value", tags[key], key)
return tags[key]
})
@ -118,7 +116,9 @@ class OpeningHoursTableVis extends SpecialVisualizationSvelte {
const openingHoursStore: Store<opening_hours | "error" | undefined> =
OH.CreateOhObjectStore(tags, key, prefix, postfix)
return new SvelteUIElement(OpeningHoursWithError, {
tags, key, opening_hours_obj: openingHoursStore,
tags,
key,
opening_hours_obj: openingHoursStore,
})
}
}
@ -234,7 +234,7 @@ class PresetTypeSelect extends SpecialVisualizationSvelte {
args = []
group = "ui"
constr({ state, tags, feature, layer }: SpecialVisualisationParams,): SvelteUIElement {
constr({ state, tags, feature, layer }: SpecialVisualisationParams): SvelteUIElement {
const t = Translations.t.preset_type
if (layer._basedOn !== layer.id) {
console.warn("Trying to use the _original_ layer")
@ -285,7 +285,7 @@ class PointsInTimeVis extends SpecialVisualization {
args = [
{
name: "key",
type:"key",
type: "key",
required: true,
doc: "The key out of which the points_in_time will be parsed",
},
@ -305,22 +305,26 @@ class PointsInTimeVis extends SpecialVisualization {
}
class KnownIcons extends SpecialVisualization {
docs = "Displays all icons from the specified tagRenderings (if they are known and have an icon) together, e.g. to give a summary of the dietary options"
docs =
"Displays all icons from the specified tagRenderings (if they are known and have an icon) together, e.g. to give a summary of the dietary options"
needsUrls = []
group = "UI"
funcName = "show_icons"
args: SpecialVisualisationArg[] = [{
name: "labels",
doc: "A ';'-separated list of labels and/or ids of tagRenderings",
type: "key",
required: true,
}, {
name: "class",
doc: "CSS-classes of the container, space-separated",
type: "css",
required: false,
defaultValue: "inline-flex mx-4",
}]
args: SpecialVisualisationArg[] = [
{
name: "labels",
doc: "A ';'-separated list of labels and/or ids of tagRenderings",
type: "key",
required: true,
},
{
name: "class",
doc: "CSS-classes of the container, space-separated",
type: "css",
required: false,
defaultValue: "inline-flex mx-4",
},
]
private static readonly emojiHeights = {
small: "2rem",
@ -329,32 +333,34 @@ class KnownIcons extends SpecialVisualization {
}
constr(options: SpecialVisualisationParams): BaseUIElement {
const labels = new Set(options.args[0].split(";").map(s => s.trim()))
const labels = new Set(options.args[0].split(";").map((s) => s.trim()))
const matchingTrs = options.layer.tagRenderings.filter(
tr => labels.has(tr.id) || tr.labels.some(l => labels.has(l)),
(tr) => labels.has(tr.id) || tr.labels.some((l) => labels.has(l))
)
return new VariableUiElement(options.tags.map(tags =>
new Combine(matchingTrs.map(tr => {
const mapping = tr.GetRenderValueWithImage(tags)
if (!mapping?.icon) {
return undefined
}
return new VariableUiElement(
options.tags.map((tags) =>
new Combine(
matchingTrs.map((tr) => {
const mapping = tr.GetRenderValueWithImage(tags)
if (!mapping?.icon) {
return undefined
}
return new SvelteUIElement(Marker, {
emojiHeight: KnownIcons.emojiHeights[mapping.iconClass] ?? "2rem",
clss: `mapping-icon-${mapping.iconClass ?? "small"}`,
icons: mapping.icon,
size: twJoin(
"shrink-0",
`mapping-icon-${mapping.iconClass ?? "small"}-height mapping-icon-${
mapping.iconClass ?? "small"
}-width`),
})
})
).SetClass(options.args[1] ?? "inline-flex mx-4")
))
return new SvelteUIElement(Marker, {
emojiHeight: KnownIcons.emojiHeights[mapping.iconClass] ?? "2rem",
clss: `mapping-icon-${mapping.iconClass ?? "small"}`,
icons: mapping.icon,
size: twJoin(
"shrink-0",
`mapping-icon-${mapping.iconClass ?? "small"}-height mapping-icon-${
mapping.iconClass ?? "small"
}-width`
),
})
})
).SetClass(options.args[1] ?? "inline-flex mx-4")
)
)
}
}

View file

@ -1,5 +1,9 @@
import { Store, UIEventSource } from "../../Logic/UIEventSource"
import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
import {
SpecialVisualisationParams,
SpecialVisualization,
SpecialVisualizationState,
} from "../SpecialVisualization"
import { Feature } from "geojson"
import SvelteUIElement from "../Base/SvelteUIElement"
import Histogram from "../BigComponents/Histogram.svelte"
@ -14,7 +18,7 @@ export class HistogramViz extends SpecialVisualization {
args = [
{
name: "key",
type:"key",
type: "key",
doc: "The key to be read and to generate a histogram from",
required: true,
},
@ -36,7 +40,7 @@ export class HistogramViz extends SpecialVisualization {
]
}
constr( {tags, args}: SpecialVisualisationParams): SvelteUIElement {
constr({ tags, args }: SpecialVisualisationParams): SvelteUIElement {
const values: Store<string[]> = tags.map((tags) => {
const value = tags[args[0]]
try {

View file

@ -27,7 +27,10 @@ export interface ConflateFlowArguments extends ImportFlowArguments {
snap_onto_layers?: string
}
export default class ConflateImportButtonViz extends SpecialVisualizationSvelte implements AutoAction {
export default class ConflateImportButtonViz
extends SpecialVisualizationSvelte
implements AutoAction
{
supportsAutoAction: boolean = true
needsUrls = []
group = "data_import"
@ -37,7 +40,7 @@ export default class ConflateImportButtonViz extends SpecialVisualizationSvelte
...ImportFlowUtils.generalArguments,
{
name: "way_to_conflate",
type:"key",
type: "key",
doc: "The key, of which the corresponding value is the id of the OSM-way that must be conflated; typically a calculatedTag",
},
]
@ -90,9 +93,14 @@ export default class ConflateImportButtonViz extends SpecialVisualizationSvelte
feature.geometry.type === "LineString" ||
(feature.geometry.type === "Polygon" && feature.geometry.coordinates.length === 1)
if (!canBeImported) {
return new SvelteUIElement(Tr, { t: Translations.t.general.add.import.wrongTypeToConflate, cls: "alert" })
return new SvelteUIElement(Tr, {
t: Translations.t.general.add.import.wrongTypeToConflate,
cls: "alert",
})
}
const argsParsed: ConflateFlowArguments = <any>SpecialVisualizationUtils.parseArgs(this.args, args)
const argsParsed: ConflateFlowArguments = <any>(
SpecialVisualizationUtils.parseArgs(this.args, args)
)
const tagsToApply = ImportFlowUtils.getTagsToApply(<UIEventSource<OsmTags>>tags, argsParsed)
const idOfWayToReplaceGeometry = tags.data[argsParsed.way_to_conflate]
const importFlow = new ConflateImportFlowState(

View file

@ -54,7 +54,9 @@ export class PointImportButtonViz extends SpecialVisualizationSvelte {
if (summarizePointArg !== "no" && summarizePointArg !== "false") {
feature = GeoOperations.centerpoint(feature)
} else {
return new SvelteUIElement(Tr, { t: Translations.t.general.add.import.wrongType.SetClass("alert") })
return new SvelteUIElement(Tr, {
t: Translations.t.general.add.import.wrongType.SetClass("alert"),
})
}
}
const baseArgs: PointImportFlowArguments = <any>Utils.ParseVisArgs(this.args, args)

View file

@ -66,7 +66,9 @@ export default class WayImportButtonViz extends SpecialVisualizationSvelte imple
if (!(geometry.type == "LineString" || geometry.type === "Polygon")) {
throw "Invalid type to import, expected linestring of polygon but got " + geometry.type
}
const parsedArgs: WayImportFlowArguments = <any>SpecialVisualizationUtils.parseArgs(this.args, args)
const parsedArgs: WayImportFlowArguments = <any>(
SpecialVisualizationUtils.parseArgs(this.args, args)
)
console.log("Parsed args are", parsedArgs)
const tagsToApply = ImportFlowUtils.getTagsToApply(tags, parsedArgs)
const importFlow = new WayImportFlowState(
@ -74,7 +76,7 @@ export default class WayImportButtonViz extends SpecialVisualizationSvelte imple
<Feature<LineString | Polygon>>feature,
parsedArgs,
tagsToApply,
tags,
tags
)
return new SvelteUIElement(WayImportFlow, {
importFlow,

View file

@ -9,11 +9,17 @@ export class LanguageElement extends SpecialVisualizationSvelte {
docs: string =
"The language element allows to show and pick all known (modern) languages. The key can be set"
args: { name: string; defaultValue?: string; doc: string; required?: boolean; type?: string }[] = [
args: {
name: string
defaultValue?: string
doc: string
required?: boolean
type?: string
}[] = [
{
name: "key",
required: true,
type:"key",
type: "key",
doc: "What key to use, e.g. `language`, `tactile_writing:braille:language`, ... If a language is supported, the language code will be appended to this key, resulting in `<key>:nl=yes` if _nl_ is picked ",
},
{
@ -61,17 +67,8 @@ export class LanguageElement extends SpecialVisualizationSvelte {
\`\`\`
`
constr(
{
state,
tags,
args,
feature,
layer,
}: SpecialVisualisationParams,
): SvelteUIElement {
let [key, question, item_render, single_render, all_render, on_no_known_languages] =
args
constr({ state, tags, args, feature, layer }: SpecialVisualisationParams): SvelteUIElement {
let [key, question, item_render, single_render, all_render, on_no_known_languages] = args
if (item_render === undefined || item_render.trim() === "") {
item_render = "{language()}"
}

View file

@ -45,13 +45,13 @@
console.warn("No feature found for id ", id)
continue
}
features.push(<Feature<Geometry, OsmTags>> feature)
features.push(<Feature<Geometry, OsmTags>>feature)
}
}
return features
},
[tags],
onDestroy,
onDestroy
)
let mlmap = new UIEventSource(undefined)
@ -71,7 +71,7 @@
mlmap,
new StaticFeatureSource(featuresToShow),
state.theme.layers,
{ zoomToFeatures: true },
{ zoomToFeatures: true }
)
</script>

View file

@ -19,9 +19,7 @@ export class MultiApplyViz extends SpecialVisualizationSvelte {
doc: "One key (or multiple keys, seperated by ';') of the attribute that should be copied onto the other features.",
required: true,
},
{ name: "text",
type: "translation",
doc: "The text to show on the button" },
{ name: "text", type: "translation", doc: "The text to show on the button" },
{
name: "autoapply",
doc: "A boolean indicating wether this tagging should be applied automatically if the relevant tags on this object are changed. A visual element indicating the multi_apply is still shown",

View file

@ -31,7 +31,7 @@ export class PlantNetDetectionViz extends SpecialVisualizationSvelte {
args = [
{
name: "image_key",
type:"key",
type: "key",
defaultValue: AllImageProviders.defaultKeys.join(","),
doc: "The keys given to the images, e.g. if <span class='literal-code'>image</span> is given, the first picture URL will be added as <span class='literal-code'>image</span>, the second as <span class='literal-code'>image:0</span>, the third as <span class='literal-code'>image:1</span>, etc... Multiple values are allowed if ';'-separated ",
},

View file

@ -16,17 +16,13 @@ export class ShareLinkViz extends SpecialVisualizationSvelte {
},
{
name: "text",
type:"translation",
type: "translation",
doc: "The text to show on the button. If none is given, will act as a titleIcon",
},
]
needsUrls = []
public constr({
state,
tags,
args}:SpecialVisualisationParams
) {
public constr({ state, tags, args }: SpecialVisualisationParams) {
const text = args[1]
const generateShareData = () => {

View file

@ -38,7 +38,7 @@
let key = "cached_special_spec_" + $language
specs = t[key]
if (specs === undefined) {
specs = SpecialVisualizations.constructSpecification(txt)
specs = SpecialVisualizations.constructSpecification(txt) ?? []
t[key] = specs
}
}
@ -51,7 +51,7 @@
{
try {
return specpart.func
.constr({state, tags, args : specpart.args, feature, layer})
.constr({ state, tags, args: specpart.args, feature, layer })
?.SetClass(specpart.style)
} catch (e) {
console.error(
@ -70,7 +70,9 @@
}
</script>
{#if lang === "*"}
{#if specs === undefined}
<!-- Empty -->
{:else if lang === "*"}
{#each specs as specpart}
{#if typeof specpart === "string"}
<span class={clss}>

View file

@ -68,7 +68,7 @@ class MaprouletteSetStatusVis extends SpecialVisualizationSvelte {
},
{
name: "maproulette_id",
type:"key",
type: "key",
doc: "The property name containing the maproulette id",
defaultValue: "mr_taskId",
},
@ -111,7 +111,7 @@ class LinkedDataFromWebsite extends SpecialVisualization {
{
name: "key",
defaultValue: "website",
type:"key",
type: "key",
doc: "Attempt to load ld+json from the specified URL. This can be in an embedded <script type='ld+json'>",
},
{
@ -248,7 +248,7 @@ class CompareData extends SpecialVisualizationSvelte {
{
name: "url",
required: true,
type:"key",
type: "key",
doc: "The attribute containing the url where to fetch more data",
},
{

View file

@ -60,7 +60,7 @@ class ImageCarouselVis extends SpecialVisualizationSvelte {
]
needsUrls = AllImageProviders.apiUrls
constr({state, tags, args, feature}: SpecialVisualisationParams) {
constr({ state, tags, args, feature }: SpecialVisualisationParams) {
let imagePrefixes: string[] = undefined
if (args.length > 0) {
imagePrefixes = [].concat(...args.map((a) => a.split(";")))
@ -96,7 +96,7 @@ class ImageUpload extends SpecialVisualizationSvelte {
name: "label",
doc: "The text to show on the button",
required: false,
type: "translation"
type: "translation",
},
{
name: "disable_blur",
@ -105,7 +105,7 @@ class ImageUpload extends SpecialVisualizationSvelte {
},
]
constr({state, tags, args, feature}: SpecialVisualisationParams) {
constr({ state, tags, args, feature }: SpecialVisualisationParams) {
const targetKey = args[0] === "" ? undefined : args[0]
const noBlur = args[3]?.toLowerCase()?.trim()
return new SvelteUIElement(UploadImage, {

View file

@ -1,4 +1,8 @@
import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationSvelte } from "../SpecialVisualization"
import {
SpecialVisualisationParams,
SpecialVisualization,
SpecialVisualizationSvelte,
} from "../SpecialVisualization"
import Constants from "../../Models/Constants"
import { UIEventSource } from "../../Logic/UIEventSource"
import { Feature } from "geojson"
@ -24,7 +28,7 @@ class CloseNoteViz extends SpecialVisualizationSvelte {
{
name: "text",
doc: "Text to show on this button",
type: "translation",
type: "translation",
required: true,
},
{
@ -36,7 +40,7 @@ class CloseNoteViz extends SpecialVisualizationSvelte {
name: "idkey",
doc: "The property name where the ID of the note to close can be found",
defaultValue: "id",
type:"key"
type: "key",
},
{
name: "comment",
@ -81,7 +85,7 @@ class AddNoteCommentViz extends SpecialVisualizationSvelte {
name: "Id-key",
doc: "The property name where the ID of the note to close can be found",
defaultValue: "id",
type:"key"
type: "key",
},
]
public readonly group = "notes"
@ -116,7 +120,7 @@ class AddImageToNote extends SpecialVisualizationSvelte {
name: "Id-key",
doc: "The property name where the ID of the note to close can be found",
defaultValue: "id",
type:"key"
type: "key",
},
]
group = "notes"
@ -138,7 +142,7 @@ class VisualiseNoteComment extends SpecialVisualization {
name: "commentsKey",
doc: "The property name of the comments, which should be stringified json",
defaultValue: "comments",
type:"key"
type: "key",
},
{
name: "start",

View file

@ -45,7 +45,7 @@ class CreateReview extends SpecialVisualizationSvelte {
{
name: "subjectKey",
defaultValue: "name",
type:"key",
type: "key",
doc: "The key to use to determine the subject. If specified, the subject will be <b>tags[subjectKey]</b>",
},
{
@ -72,7 +72,7 @@ class CreateReview extends SpecialVisualizationSvelte {
nameKey: nameKey,
fallbackName,
},
<SpecialVisualizationState & WithUserRelatedState>state,
<SpecialVisualizationState & WithUserRelatedState>state
)
return new SvelteUIElement(ReviewForm, {
reviews,
@ -131,7 +131,7 @@ class Rating extends SpecialVisualizationSvelte {
{
name: "subjectKey",
defaultValue: "name",
type:"key",
type: "key",
doc: "The key to use to determine the subject. If the value is specified, the subject will be <b>tags[subjectKey]</b> and will use this to filter the reviews.",
},
{
@ -190,7 +190,7 @@ class Reviews extends SpecialVisualization {
{
name: "subjectKey",
defaultValue: "name",
type:"key",
type: "key",
doc: "The key to use to determine the subject. If specified, the subject will be <b>tags[subjectKey]</b>",
},
{
@ -206,10 +206,7 @@ class Reviews extends SpecialVisualization {
needsUrls = [CreateReview.MangroveReviewInfo]
constr(params: SpecialVisualisationParams): BaseUIElement {
return new Combine([
new CreateReview().constr(params),
new ListReview().constr(params),
])
return new Combine([new CreateReview().constr(params), new ListReview().constr(params)])
}
}

View file

@ -197,7 +197,7 @@ class Logout extends SpecialVisualizationSvelte {
group = "settings"
constr({ state }: SpecialVisualisationParams): SvelteUIElement {
return new SvelteUIElement(LogoutButton,state)
return new SvelteUIElement(LogoutButton, state)
}
}

View file

@ -1,5 +1,9 @@
import { AutoAction } from "../Popup/AutoApplyButtonVis"
import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
import {
SpecialVisualisationParams,
SpecialVisualization,
SpecialVisualizationState,
} from "../SpecialVisualization"
import { Utils } from "../../Utils"
import { Store, UIEventSource } from "../../Logic/UIEventSource"
import { Tag } from "../../Logic/Tags/Tag"
@ -26,7 +30,7 @@ export default class TagApplyViz extends SpecialVisualization implements AutoAct
},
{
name: "message",
type:"translation",
type: "translation",
doc: "The text to show to the contributor",
},
{

View file

@ -28,7 +28,7 @@ class StealViz extends SpecialVisualization {
args = [
{
name: "featureId",
type:"key",
type: "key",
doc: "The key of the attribute which contains the id of the feature from which to use the tags",
required: true,
},
@ -119,7 +119,7 @@ class Multi extends SpecialVisualization {
args = [
{
name: "key",
type:"key",
type: "key",
doc: "The property to read and to interpret as a list of properties",
required: true,
},
@ -215,7 +215,7 @@ class OpenInId extends SpecialVisualizationSvelte {
args = []
group = "web_and_communication"
constr({state, feature}: SpecialVisualisationParams): SvelteUIElement {
constr({ state, feature }: SpecialVisualisationParams): SvelteUIElement {
return new SvelteUIElement(OpenIdEditor, {
mapProperties: state.mapProperties,
objectId: feature.properties.id,

View file

@ -94,7 +94,7 @@ class Minimap extends SpecialVisualizationSvelte {
doc: "The key of one or more properties of the feature, semi-colon separated. The corresponding value is interpreted as either the id or the a list of ID's. The features with these ID's will be shown on this minimap. ",
name: "idKey",
defaultValue: "id",
type:"key"
type: "key",
},
{
name: "class",
@ -179,7 +179,8 @@ class QrCodeVis extends SpecialVisualizationSvelte {
funcName = "qr_code"
args = [
{
name: "text",type:"translation",
name: "text",
type: "translation",
doc: "Extra text on the side of the QR-code",
},
{
@ -209,7 +210,7 @@ class IfNothingKnown extends SpecialVisualizationSvelte {
{
name: "text",
doc: "Text to show",
type:"translation",
type: "translation",
required: true,
},
{ name: "cssClasses", doc: "Classes to apply onto the text" },
@ -302,7 +303,7 @@ class BracedVis extends SpecialVisualization {
name: "text",
required: true,
doc: "The value to show",
type:"translation"
type: "translation",
},
]

View file

@ -1,4 +1,8 @@
import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationSvelte } from "../SpecialVisualization"
import {
SpecialVisualisationParams,
SpecialVisualization,
SpecialVisualizationSvelte,
} from "../SpecialVisualization"
import { ImmutableStore, Store } from "../../Logic/UIEventSource"
import SvelteUIElement from "../Base/SvelteUIElement"
import FediverseLink from "../Popup/FediverseLink.svelte"
@ -20,7 +24,7 @@ class FediverseLinkVis extends SpecialVisualizationSvelte {
args = [
{
name: "key",
type:"key",
type: "key",
doc: "The attribute-name containing the link",
required: true,
},
@ -39,7 +43,7 @@ class WikipediaVis extends SpecialVisualizationSvelte {
args = [
{
name: "keyToShowWikipediaFor",
type:"key",
type: "key",
doc: "Use the wikidata entry from this key to show the wikipedia article for. Multiple keys can be given (separated by ';'), in which case the first matching value is used",
defaultValue: "wikidata;wikipedia",
},
@ -69,7 +73,7 @@ class WikidatalabelVis extends SpecialVisualization {
args = [
{
name: "keyToShowWikidataFor",
type:"key",
type: "key",
doc: "Use the wikidata entry from this key to show the label",
defaultValue: "wikidata",
},
@ -111,7 +115,7 @@ class SendEmailVis extends SpecialVisualizationSvelte {
{
name: "to",
doc: "Who to send the email to?",
type:"key",
type: "key",
required: true,
},
{

View file

@ -97,14 +97,11 @@ export interface SpecialVisualisationArg {
}
export class SpecialVisualizationUtils {
static parseArgs(specs: { name: string; defaultValue?: string }[], args: string[]){
static parseArgs(specs: { name: string; defaultValue?: string }[], args: string[]) {
return Utils.ParseVisArgs(specs, args)
}
}
export interface SpecialVisualisationParams {
state: SpecialVisualizationState
tags: UIEventSource<Record<string, string>>

View file

@ -1,4 +1,8 @@
import { RenderingSpecification, SpecialVisualization, SpecialVisualizationSvelte } from "./SpecialVisualization"
import {
RenderingSpecification,
SpecialVisualization,
SpecialVisualizationSvelte,
} from "./SpecialVisualization"
import { UploadToOsmViz } from "./Popup/UploadToOsmViz"
import { MultiApplyViz } from "./Popup/MultiApplyViz"
import AutoApplyButtonVis from "./Popup/AutoApplyButtonVis"
@ -193,7 +197,7 @@ export default class SpecialVisualizations {
...TagrenderingManipulationSpecialVisualisations.initList(),
...WebAndCommunicationSpecialVisualisations.initList(),
...DataVisualisations.initList(),
...specialVisualizationsSv
...specialVisualizationsSv,
]
specialVisualizations.push(new AutoApplyButtonVis(specialVisualizations))

View file

@ -18,6 +18,7 @@
import { DownloadIcon } from "@rgossiaux/svelte-heroicons/solid"
import { GeoOperations } from "../../Logic/GeoOperations"
import Filter from "../../assets/svg/Filter.svelte"
import { Lists } from "../../Utils/Lists"
export let paths: string[]

View file

@ -1,6 +1,6 @@
import { Utils } from "../../Utils"
import { Feature, Polygon } from "geojson"
import { OsmFeature } from "../../Models/OsmFeature"
import { Lists } from "../../Utils/Lists"
export interface ChangeSetData extends Feature<Polygon> {
id: number