forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			159 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			Svelte
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
	
		
			5.6 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"
 | |
|   import { twJoin } from "tailwind-merge"
 | |
| 
 | |
|   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="low-interaction flex">
 | |
|     <InformationCircleIcon class="h-6 w-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="h-6 w-6" />
 | |
|         <Tr t={t.delete} />
 | |
|       </button>
 | |
|     {:else if currentState === "confirm"}
 | |
|       <TagRenderingQuestion
 | |
|         bind:selectedTags
 | |
|         {tags}
 | |
|         config={deleteConfig.constructTagRendering()}
 | |
|         {state}
 | |
|         selectedElement={feature}
 | |
|         {layer}
 | |
|       >
 | |
|         <button
 | |
|           slot="save-button"
 | |
|           on:click={onDelete}
 | |
|           class={twJoin(selectedTags === undefined && "disabled", "primary flex bg-red-600")}
 | |
|         >
 | |
|           <TrashIcon
 | |
|             class={twJoin(
 | |
|               "ml-1 mr-2 h-6 w-6 rounded-full p-1",
 | |
|               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="h-8 w-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="low-interaction flex">
 | |
|         <TrashIcon class="h-6 w-6" />
 | |
|         <Tr t={t.isDeleted} />
 | |
|       </div>
 | |
|     {/if}
 | |
|   </LoginToggle>
 | |
| {/if}
 |