mapcomplete/UI/Popup/DeleteFlow/DeleteWizard.svelte

155 lines
6.1 KiB
Svelte

<script lang="ts">
import LoginToggle from "../../Base/LoginToggle.svelte";
import type {SpecialVisualizationState} from "../../SpecialVisualization";
import Translations from "../../i18n/Translations";
import Tr from "../../Base/Tr.svelte";
import {InformationCircleIcon, TrashIcon} from "@babeard/svelte-heroicons/mini";
import type {OsmId, OsmTags} from "../../../Models/OsmFeature";
import DeleteConfig from "../../../Models/ThemeConfig/DeleteConfig";
import TagRenderingQuestion from "../TagRendering/TagRenderingQuestion.svelte";
import type {Feature} from "geojson";
import {UIEventSource} from "../../../Logic/UIEventSource";
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig";
import {TagsFilter} from "../../../Logic/Tags/TagsFilter";
import {XCircleIcon} from "@rgossiaux/svelte-heroicons/solid";
import {TagUtils} from "../../../Logic/Tags/TagUtils";
import OsmChangeAction from "../../../Logic/Osm/Actions/OsmChangeAction";
import DeleteAction from "../../../Logic/Osm/Actions/DeleteAction";
import ChangeTagAction from "../../../Logic/Osm/Actions/ChangeTagAction";
import Loading from "../../Base/Loading.svelte";
import {DeleteFlowState} from "./DeleteFlowState";
export let state: SpecialVisualizationState
export let deleteConfig: DeleteConfig
export let tags: UIEventSource<OsmTags>
let featureId: OsmId = <OsmId> tags.data.id
export let feature: Feature
export let layer: LayerConfig
const deleteAbility = new DeleteFlowState(
featureId,
state,
deleteConfig.neededChangesets
)
const canBeDeleted: UIEventSource<boolean | undefined> = deleteAbility.canBeDeleted
const canBeDeletedReason = deleteAbility.canBeDeletedReason
const hasSoftDeletion = deleteConfig.softDeletionTags !== undefined
let currentState: "start" | "confirm" | "applying" | "deleted" = ("start")
$: {
console.log("Current state is", currentState, $canBeDeleted, canBeDeletedReason)
deleteAbility.CheckDeleteability(true)
}
const t = Translations.t.delete
let selectedTags: TagsFilter
let changedProperties = undefined
$: changedProperties = TagUtils.changeAsProperties(selectedTags?.asChange(tags?.data ?? {}) ?? [])
let isHardDelete = undefined
$: isHardDelete = changedProperties[DeleteConfig.deleteReasonKey] !== undefined
async function onDelete() {
currentState = "applying"
let actionToTake: OsmChangeAction
const changedProperties = TagUtils.changeAsProperties(selectedTags.asChange(tags?.data ?? {}))
const deleteReason = changedProperties[DeleteConfig.deleteReasonKey]
console.log("Deleting! Hard?:", canBeDeleted.data, deleteReason)
if (deleteReason) {
// This is a proper, hard deletion
actionToTake = new DeleteAction(
featureId,
deleteConfig.softDeletionTags,
{
theme: state?.layout?.id ?? "unknown",
specialMotivation: deleteReason,
},
canBeDeleted.data
)
} else {
// no _delete_reason is given, which implies that this is _not_ a deletion but merely a retagging via a nonDeleteMapping
actionToTake = new ChangeTagAction(featureId,
selectedTags,
tags.data,
{
theme: state?.layout?.id ?? "unkown",
changeType: "special-delete",
})
}
await state.changes?.applyAction(actionToTake)
tags.data["_deleted"] = "yes"
tags.ping()
currentState = "deleted"
}
</script>
{#if $canBeDeleted === false && !hasSoftDeletion}
<div class="flex low-interaction">
<InformationCircleIcon class="w-6 h-6"/>
<Tr t={$canBeDeletedReason}/>
<Tr class="subtle" t={t.useSomethingElse}/>
</div>
{:else}
<LoginToggle ignoreLoading={true} {state}>
{#if currentState === "start"}
<button class="flex" on:click={() => {currentState = "confirm"}}>
<TrashIcon class="w-6 h-6"/>
<Tr t={t.delete}/>
</button>
{:else if currentState === "confirm"}
<TagRenderingQuestion
bind:selectedTags={selectedTags}
{tags} config={deleteConfig.constructTagRendering()}
{state} selectedElement={feature}
{layer}>
<button slot="save-button" on:click={onDelete}
class={(selectedTags === undefined ? "disabled" : "")+ " flex primary bg-red-600"}>
<TrashIcon
class={"w-6 h-6 rounded-full p-1 ml-1 mr-2 "+(selectedTags !== undefined ? "bg-red-600" : "")}/>
<Tr t={t.delete}/>
</button>
<button slot="cancel" on:click={() => currentState = "start"}>
<Tr t={t.cancel}/>
</button>
<XCircleIcon slot="upper-right" class="w-8 h-8 cursor-pointer"
on:click={() => {currentState = "start"}}/>
<div slot="under-buttons">
{#if selectedTags !== undefined}
{#if canBeDeleted && isHardDelete}
<!-- This is a hard delete - explain that this is a hard delete...-->
<Tr t={t.explanations.hardDelete}/>
{:else}
<!-- This is a soft deletion: we explain _why_ the deletion is soft -->
<Tr t={t.explanations.softDelete.Subs({reason: $canBeDeletedReason})}/>
{/if}
{/if}
</div>
</TagRenderingQuestion>
{:else if currentState === "applying"}
<Loading/>
{:else}
<!-- currentState === 'deleted' -->
<div class="flex low-interaction">
<TrashIcon class="w-6 h-6"/>
<Tr t={t.isDeleted}/>
</div>
{/if}
</LoginToggle>
{/if}