forked from MapComplete/MapComplete
Refactoring: port 'TagApplyButton' to svelte
This commit is contained in:
parent
2bc2a6cddf
commit
d1f7ae2462
8 changed files with 109 additions and 99 deletions
|
@ -79,7 +79,7 @@
|
|||
"source": {
|
||||
"geoJson": "https://maproulette.org/api/v2/challenge/view/39519"
|
||||
},
|
||||
"isShown": "mr_taskStatus=Created",
|
||||
|
||||
"calculatedTags": [
|
||||
"_closest_osm_poi=closest(feat)('atm')?.properties?.id",
|
||||
"_closest_osm_poi_distance=Math.round(distanceTo(feat)(feat.properties._closest_osm_poi))",
|
||||
|
@ -161,7 +161,7 @@
|
|||
"it": "Aggiungi tutti i tag suggeriti allo sportello bancomat più vicino"
|
||||
},
|
||||
"image": "./assets/svg/addSmall.svg",
|
||||
"maproulette_id": "mr_taskId"
|
||||
"maproulette_id": "id"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -171,6 +171,7 @@
|
|||
},
|
||||
"apply_button": {
|
||||
"appliedOnAnotherObject": "The object {id} will receive {tags}",
|
||||
"applying": "Applying changes",
|
||||
"isApplied": "The changes are applied"
|
||||
},
|
||||
"attribution": {
|
||||
|
|
|
@ -1,42 +1,14 @@
|
|||
import { Utils } from "../../Utils"
|
||||
/** This code is autogenerated - do not edit. Edit ./assets/layers/usersettings/usersettings.json instead */
|
||||
export class ThemeMetaTagging {
|
||||
public static readonly themeName = "usersettings"
|
||||
public static readonly themeName = "usersettings"
|
||||
|
||||
public metaTaggging_for_usersettings(feat: { properties: Record<string, string> }) {
|
||||
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_md", () =>
|
||||
feat.properties._description
|
||||
.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)
|
||||
?.at(1)
|
||||
)
|
||||
Utils.AddLazyProperty(
|
||||
feat.properties,
|
||||
"_d",
|
||||
() => feat.properties._description?.replace(/</g, "<")?.replace(/>/g, ">") ?? ""
|
||||
)
|
||||
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_a", () =>
|
||||
((feat) => {
|
||||
const e = document.createElement("div")
|
||||
e.innerHTML = feat.properties._d
|
||||
return Array.from(e.getElementsByTagName("a")).filter(
|
||||
(a) => a.href.match(/mastodon|en.osm.town/) !== null
|
||||
)[0]?.href
|
||||
})(feat)
|
||||
)
|
||||
Utils.AddLazyProperty(feat.properties, "_mastodon_link", () =>
|
||||
((feat) => {
|
||||
const e = document.createElement("div")
|
||||
e.innerHTML = feat.properties._d
|
||||
return Array.from(e.getElementsByTagName("a")).filter(
|
||||
(a) => a.getAttribute("rel")?.indexOf("me") >= 0
|
||||
)[0]?.href
|
||||
})(feat)
|
||||
)
|
||||
Utils.AddLazyProperty(
|
||||
feat.properties,
|
||||
"_mastodon_candidate",
|
||||
() => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a
|
||||
)
|
||||
feat.properties["__current_backgroun"] = "initial_value"
|
||||
}
|
||||
}
|
||||
public metaTaggging_for_usersettings(feat: {properties: Record<string, string>}) {
|
||||
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_md', () => feat.properties._description.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)?.at(1) )
|
||||
Utils.AddLazyProperty(feat.properties, '_d', () => feat.properties._description?.replace(/</g,'<')?.replace(/>/g,'>') ?? '' )
|
||||
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_a', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.href.match(/mastodon|en.osm.town/) !== null)[0]?.href }) (feat) )
|
||||
Utils.AddLazyProperty(feat.properties, '_mastodon_link', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.getAttribute("rel")?.indexOf('me') >= 0)[0]?.href})(feat) )
|
||||
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate', () => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a )
|
||||
feat.properties['__current_backgroun'] = 'initial_value'
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import { Utils } from "../../../Utils"
|
||||
import { ImmutableStore, Store, UIEventSource } from "../../../Logic/UIEventSource"
|
||||
import { Tag } from "../../../Logic/Tags/Tag"
|
||||
import TagApplyButton from "../TagApplyButton"
|
||||
import { PointImportFlowArguments } from "./PointImportFlowState"
|
||||
import { Translation } from "../../i18n/Translation"
|
||||
import Translations from "../../i18n/Translations"
|
||||
|
@ -11,6 +10,7 @@ import { LayerConfigJson } from "../../../Models/ThemeConfig/Json/LayerConfigJso
|
|||
import conflation_json from "../../../../assets/layers/conflation/conflation.json"
|
||||
import { SpecialVisualizationState } from "../../SpecialVisualization"
|
||||
import { OsmTags } from "../../../Models/OsmFeature"
|
||||
import TagApplyViz from "../../SpecialVisualisations/TagApplyViz"
|
||||
|
||||
export interface ImportFlowArguments {
|
||||
readonly text: string
|
||||
|
@ -96,9 +96,9 @@ ${Utils.special_visualizations_importRequirementDocs}
|
|||
return new ImmutableStore(tags)
|
||||
}
|
||||
|
||||
newTags = TagApplyButton.generateTagsToApply(items, originalFeatureTags)
|
||||
newTags = TagApplyViz.generateTagsToApply(items, originalFeatureTags)
|
||||
} else {
|
||||
newTags = TagApplyButton.generateTagsToApply(tags, originalFeatureTags)
|
||||
newTags = TagApplyViz.generateTagsToApply(tags, originalFeatureTags)
|
||||
}
|
||||
return newTags
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
}, 50)
|
||||
}
|
||||
|
||||
const _htmlElement = new UIEventSource<HTMLElement>(undefined)
|
||||
let _htmlElement = new UIEventSource<HTMLElement>(undefined)
|
||||
$: _htmlElement.setData(htmlElem)
|
||||
|
||||
function setHighlighting() {
|
||||
|
|
|
@ -2,7 +2,6 @@ import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisua
|
|||
import Maproulette from "../../Logic/Maproulette"
|
||||
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||
import MaprouletteSetStatus from "../MapRoulette/MaprouletteSetStatus.svelte"
|
||||
import TagApplyButton from "../Popup/TagApplyButton"
|
||||
import { PointImportButtonViz } from "../Popup/ImportButtons/PointImportButtonViz"
|
||||
import WayImportButtonViz from "../Popup/ImportButtons/WayImportButtonViz"
|
||||
import ConflateImportButtonViz from "../Popup/ImportButtons/ConflateImportButtonViz"
|
||||
|
@ -16,11 +15,12 @@ import LinkedDataLoader from "../../Logic/Web/LinkedDataLoader"
|
|||
import Toggle from "../Input/Toggle"
|
||||
import ComparisonTool from "../Comparison/ComparisonTool.svelte"
|
||||
import { Utils } from "../../Utils"
|
||||
import TagApplyViz from "./TagApplyViz"
|
||||
|
||||
export class DataImportSpecialVisualisations {
|
||||
public static initList(): (SpecialVisualization & { group })[] {
|
||||
return [
|
||||
new TagApplyButton(),
|
||||
new TagApplyViz(),
|
||||
new PointImportButtonViz(),
|
||||
new WayImportButtonViz(),
|
||||
new ConflateImportButtonViz(),
|
||||
|
|
65
src/UI/SpecialVisualisations/TagApplyButton.svelte
Normal file
65
src/UI/SpecialVisualisations/TagApplyButton.svelte
Normal file
|
@ -0,0 +1,65 @@
|
|||
<script lang="ts">
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Tag } from "../../Logic/Tags/Tag"
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import LoginToggle from "../Base/LoginToggle.svelte"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import Loading from "../Base/Loading.svelte"
|
||||
import TagApplyViz from "./TagApplyViz"
|
||||
import Icon from "../Map/Icon.svelte"
|
||||
import TagExplanation from "../Popup/TagExplanation.svelte"
|
||||
import { And } from "../../Logic/Tags/And"
|
||||
import Translations from "../i18n/Translations"
|
||||
|
||||
/**
|
||||
* Works closely together with 'TagApplyViz
|
||||
*/
|
||||
export let msg: string
|
||||
export let image: string | undefined
|
||||
export let tags: Store<Record<string, string>>
|
||||
export let tagsToApply: Store<Tag[]>
|
||||
export let targetIdKey: string
|
||||
export let onApply: () => Promise<void>
|
||||
export let state: SpecialVisualizationState
|
||||
const t = Translations.t.general.apply_button
|
||||
// THis button might be shown on MapRoulette-items, which might already have been applied
|
||||
// This will default to 'false' for non-maproulette challenges
|
||||
let isMaprouletteAndApplied = tags?.data?.["mr_taskStatus"] !== undefined &&
|
||||
tags?.data?.["mr_taskStatus"] !== "Created"
|
||||
|
||||
|
||||
let currentState: UIEventSource<"init" | "applying" | "applied"> = new UIEventSource(
|
||||
isMaprouletteAndApplied ? "applied" : "init")
|
||||
|
||||
async function apply() {
|
||||
currentState.set("applying")
|
||||
await onApply()
|
||||
currentState.set("applied")
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<LoginToggle {state} ignoreLoading>
|
||||
{#if $currentState === "init"}
|
||||
|
||||
<button on:click={() => apply()}>
|
||||
<Icon icon={image} />
|
||||
<div class="flex flex-col">
|
||||
<div>{msg}</div>
|
||||
{#if targetIdKey}
|
||||
<Tr cls="subtle break-all"
|
||||
t={t.appliedOnAnotherObject.Subs({ id: $tags[targetIdKey], tags: new And($tagsToApply).asHumanString(false, false, {}) })} />
|
||||
{:else}
|
||||
<TagExplanation tagsFilter={new And($tagsToApply)} />
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
{:else if $currentState === "applying"}
|
||||
<Loading>
|
||||
<Tr t={t.applying} />
|
||||
</Loading>
|
||||
|
||||
{:else if $currentState === "applied"}
|
||||
<Tr t={t.isApplied} cls="thanks" />
|
||||
{/if}
|
||||
</LoginToggle>
|
|
@ -1,23 +1,16 @@
|
|||
import { AutoAction } from "./AutoApplyButtonVis"
|
||||
import Translations from "../i18n/Translations"
|
||||
import { VariableUiElement } from "../Base/VariableUIElement"
|
||||
import BaseUIElement from "../BaseUIElement"
|
||||
import { FixedUiElement } from "../Base/FixedUiElement"
|
||||
import { AutoAction } from "../Popup/AutoApplyButtonVis"
|
||||
import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import { Utils } from "../../Utils"
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { SubtleButton } from "../Base/SubtleButton"
|
||||
import Combine from "../Base/Combine"
|
||||
import { Tag } from "../../Logic/Tags/Tag"
|
||||
import { Feature } from "geojson"
|
||||
import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction"
|
||||
import { And } from "../../Logic/Tags/And"
|
||||
import Toggle from "../Input/Toggle"
|
||||
import { Utils } from "../../Utils"
|
||||
import { Tag } from "../../Logic/Tags/Tag"
|
||||
import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import { Feature } from "geojson"
|
||||
import Maproulette from "../../Logic/Maproulette"
|
||||
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||
import Icon from "../Map/Icon.svelte"
|
||||
import TagApplyButton from "./TagApplyButton.svelte"
|
||||
|
||||
export default class TagApplyButton implements AutoAction, SpecialVisualization {
|
||||
export default class TagApplyViz implements AutoAction, SpecialVisualization {
|
||||
public readonly funcName = "tag_apply"
|
||||
needsUrls = []
|
||||
group = "data_import"
|
||||
|
@ -47,7 +40,7 @@ export default class TagApplyButton implements AutoAction, SpecialVisualization
|
|||
{
|
||||
name: "maproulette_id",
|
||||
defaultValue: undefined,
|
||||
doc: "If specified, this maproulette-challenge will be closed when the tags are applied. This should be the ID of the task, _not_ the task_id.",
|
||||
doc: "If specified, this maproulette-challenge will be closed when the tags are applied. This should be the `id` of the individual task, _not_ the task_id (which corresponds with the challenge).",
|
||||
},
|
||||
]
|
||||
public readonly example =
|
||||
|
@ -55,7 +48,7 @@ export default class TagApplyButton implements AutoAction, SpecialVisualization
|
|||
|
||||
public static generateTagsToApply(
|
||||
spec: string,
|
||||
tagSource: Store<Record<string, string>>
|
||||
tagSource: Store<Record<string, string>>,
|
||||
): Store<Tag[]> {
|
||||
// Check whether we need to look up a single value
|
||||
|
||||
|
@ -73,7 +66,7 @@ export default class TagApplyButton implements AutoAction, SpecialVisualization
|
|||
tgsSpec.push([key, properties[key]])
|
||||
}
|
||||
} else {
|
||||
tgsSpec = TagApplyButton.parseTagSpec(spec)
|
||||
tgsSpec = TagApplyViz.parseTagSpec(spec)
|
||||
}
|
||||
|
||||
return tagSource.map((tags) => {
|
||||
|
@ -135,9 +128,9 @@ export default class TagApplyButton implements AutoAction, SpecialVisualization
|
|||
_: Feature,
|
||||
state: SpecialVisualizationState,
|
||||
tags: UIEventSource<any>,
|
||||
args: string[]
|
||||
args: string[],
|
||||
): Promise<void> {
|
||||
const tagsToApply = TagApplyButton.generateTagsToApply(args[0], tags)
|
||||
const tagsToApply = TagApplyViz.generateTagsToApply(args[0], tags)
|
||||
const targetIdKey = args[3]
|
||||
|
||||
const targetId = tags.data[targetIdKey] ?? tags.data.id
|
||||
|
@ -148,7 +141,7 @@ export default class TagApplyButton implements AutoAction, SpecialVisualization
|
|||
{
|
||||
theme: state.theme.id,
|
||||
changeType: "answer",
|
||||
}
|
||||
},
|
||||
)
|
||||
await state.changes.applyAction(changeAction)
|
||||
try {
|
||||
|
@ -159,6 +152,7 @@ export default class TagApplyButton implements AutoAction, SpecialVisualization
|
|||
const maproulette_id_key = args[4]
|
||||
if (maproulette_id_key) {
|
||||
const maproulette_id = tags.data[maproulette_id_key]
|
||||
console.log("Looking for maproulette feature with id", maproulette_id,"based on key", maproulette_id_key)
|
||||
const maproulette_feature = state.indexedFeatures.featuresById.data.get(maproulette_id)
|
||||
const maproulette_task_id = Number(maproulette_feature.properties.mr_taskId)
|
||||
await Maproulette.singleton.closeTask(
|
||||
|
@ -167,7 +161,7 @@ export default class TagApplyButton implements AutoAction, SpecialVisualization
|
|||
state,
|
||||
{
|
||||
comment: "Tags are copied onto " + targetId + " with MapComplete",
|
||||
}
|
||||
},
|
||||
)
|
||||
maproulette_feature.properties["mr_taskStatus"] = "Fixed"
|
||||
state.featureProperties.getStore(maproulette_id).ping()
|
||||
|
@ -177,46 +171,24 @@ export default class TagApplyButton implements AutoAction, SpecialVisualization
|
|||
public constr(
|
||||
state: SpecialVisualizationState,
|
||||
tags: UIEventSource<Record<string, string>>,
|
||||
args: string[],
|
||||
feature: Feature
|
||||
): BaseUIElement {
|
||||
const tagsToApply = TagApplyButton.generateTagsToApply(args[0], tags)
|
||||
args: string[], feature: Feature,
|
||||
): SvelteUIElement {
|
||||
|
||||
const tagsToApply: Store<Tag[]> = TagApplyViz.generateTagsToApply(args[0], tags)
|
||||
const msg = args[1]
|
||||
let image = args[2]?.trim()
|
||||
if (image === "" || image === "undefined") {
|
||||
image = undefined
|
||||
}
|
||||
|
||||
const targetIdKey = args[3]
|
||||
const t = Translations.t.general.apply_button
|
||||
|
||||
const tagsExplanation = new VariableUiElement(
|
||||
tagsToApply.map((tagsToApply) => {
|
||||
const tagsStr = tagsToApply.map((t) => t.asHumanString(false, true)).join("&")
|
||||
let el: BaseUIElement = new FixedUiElement(tagsStr)
|
||||
if (targetIdKey !== undefined) {
|
||||
const targetId = tags.data[targetIdKey] ?? tags.data.id
|
||||
el = t.appliedOnAnotherObject.Subs({ tags: tagsStr, id: targetId })
|
||||
}
|
||||
return el
|
||||
})
|
||||
).SetClass("subtle break-all")
|
||||
const applied = new UIEventSource(
|
||||
tags?.data?.["mr_taskStatus"] !== undefined &&
|
||||
tags?.data?.["mr_taskStatus"] !== "Created"
|
||||
) // This will default to 'false' for non-maproulette challenges
|
||||
const applyButton = new SubtleButton(
|
||||
new SvelteUIElement(Icon, { icon: image }),
|
||||
new Combine([msg, tagsExplanation]).SetClass("flex flex-col")
|
||||
).onClick(async () => {
|
||||
applied.setData(true)
|
||||
const onApply = async () => {
|
||||
await this.applyActionOn(feature, state, tags, args)
|
||||
})
|
||||
}
|
||||
|
||||
return new Toggle(
|
||||
new Toggle(t.isApplied.SetClass("thanks"), applyButton, applied),
|
||||
undefined,
|
||||
state.osmConnection.isLoggedIn
|
||||
)
|
||||
|
||||
return new SvelteUIElement(TagApplyButton, {
|
||||
state, tags, tagsToApply, msg, image, targetIdKey, onApply
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue