forked from MapComplete/MapComplete
		
	
		
			
	
	
		
			156 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Svelte
		
	
	
	
	
	
		
		
			
		
	
	
			156 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}
							 |