You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
5.6 KiB
196 lines
5.6 KiB
<script lang="ts" context="module">
|
|
interface DeletionSideEffect {
|
|
name: string
|
|
op: string
|
|
}
|
|
</script>
|
|
|
|
<script lang="ts">
|
|
import { goto } from "$app/navigation";
|
|
import { getStores } from "$app/stores";
|
|
|
|
import { sl3 } from "$lib/clients/sl3";
|
|
import Modal from "$lib/components/common/Modal.svelte";
|
|
import ModalBody from "$lib/components/common/ModalBody.svelte";
|
|
import { getItemListContext } from "$lib/components/contexts/ItemListContext.svelte";
|
|
import { getItemMultiListContext } from "$lib/components/contexts/ItemMultiListContext.svelte";
|
|
import { getModalContext } from "$lib/components/contexts/ModalContext.svelte";
|
|
import { getProjectContext } from "$lib/components/contexts/ProjectContext.svelte";
|
|
import { getProjectListContext } from "$lib/components/contexts/ProjectListContext.svelte";
|
|
import { getScopeContext } from "$lib/components/contexts/ScopeContext.svelte";
|
|
import { getSprintListContext } from "$lib/components/contexts/SprintListContext.svelte";
|
|
import type Stat from "$lib/models/stat";
|
|
import { scopePrettyId } from "$lib/utils/prettyIds";
|
|
|
|
const {currentModal, closeModal} = getModalContext();
|
|
const {scope, deleteStat} = getScopeContext();
|
|
const {project, reloadProject} = getProjectContext();
|
|
const {reloadProjectList} = getProjectListContext();
|
|
const {reloadSprintList} = getSprintListContext();
|
|
const {reloadItemList} = getItemListContext();
|
|
const {reloadItemLists} = getItemMultiListContext();
|
|
const {page} = getStores();
|
|
|
|
let endpoint: string;
|
|
|
|
let error: string
|
|
let loading: boolean;
|
|
let show: boolean;
|
|
let noun: string;
|
|
let sideEffects: DeletionSideEffect[];
|
|
let name: string;
|
|
let dangerZone: boolean;
|
|
let dangerZoneConfirm: string;
|
|
let navigate: string;
|
|
|
|
$: switch ($currentModal.name) {
|
|
case "scope.delete":
|
|
init("", [{op: "Delete", name: "everything under the scope."}])
|
|
noun = "Scope";
|
|
name = $currentModal.scope.name;
|
|
dangerZone = true;
|
|
navigate = "/";
|
|
break;
|
|
|
|
case "item.delete":
|
|
init(`items/${$currentModal.item.id}`, [], $currentModal.item.scopeId)
|
|
noun = "Item";
|
|
name = $currentModal.item.name;
|
|
break;
|
|
|
|
case "stat.delete":
|
|
init(`stats/${$currentModal.stat.id}`)
|
|
noun = "Stat";
|
|
name = $currentModal.stat.name;
|
|
dangerZone = true;
|
|
break;
|
|
|
|
case "sprint.delete":
|
|
init(`sprints/${$currentModal.sprint.id}`, [], $currentModal.sprint.scopeId)
|
|
noun = "Sprint";
|
|
name = $currentModal.sprint.name;
|
|
break;
|
|
|
|
case "requirement.delete":
|
|
init(`projects/${$project.id}/requirements/${$currentModal.requirement.id}`,
|
|
$currentModal.requirement.items.map(i => ({
|
|
op: "Detach item",
|
|
name: i.name,
|
|
})),
|
|
);
|
|
noun = "Requirement";
|
|
name = $currentModal.requirement.name;
|
|
break;
|
|
|
|
case "project.delete":
|
|
init(`projects/${$currentModal.project.id}`,
|
|
$currentModal.project.requirements.flatMap(r => ([{
|
|
op: "Delete requirement",
|
|
name: `${r.name} (${r.statusName})`,
|
|
}, ...r.items.map(i => ({
|
|
op: "Detach item",
|
|
name: i.name,
|
|
}))]))
|
|
)
|
|
noun = "Project";
|
|
name = $currentModal.project.name;
|
|
dangerZone = true;
|
|
navigate = `/${scopePrettyId($scope)}`;
|
|
break;
|
|
|
|
default:
|
|
loading = false;
|
|
error = null;
|
|
show = false;
|
|
}
|
|
|
|
function init(newEndpoint: string, newSideEffects: DeletionSideEffect[] = [], overrideScopeId?: number) {
|
|
let scopeId = $scope.id;
|
|
if (overrideScopeId != null) {
|
|
scopeId = overrideScopeId;
|
|
}
|
|
|
|
endpoint = `scopes/${scopeId}/${newEndpoint}`;
|
|
if (endpoint.endsWith("/")) {
|
|
endpoint = endpoint.slice(0, -1);
|
|
}
|
|
sideEffects = newSideEffects;
|
|
show = true;
|
|
error = null;
|
|
dangerZone = false;
|
|
dangerZoneConfirm = "";
|
|
navigate = null;
|
|
}
|
|
|
|
async function submit() {
|
|
error = null;
|
|
loading = true;
|
|
|
|
try {
|
|
const res = await sl3(fetch, $page.stuff.idToken).fetch("DELETE", endpoint);
|
|
|
|
if (navigate) {
|
|
if (noun === "Project") {
|
|
await reloadProjectList();
|
|
}
|
|
|
|
goto(navigate);
|
|
} else {
|
|
// Wait for project reload if it's updating a project
|
|
await reloadProject();
|
|
|
|
if (noun === "Stat") {
|
|
reloadItemLists();
|
|
deleteStat((res as {stat: Stat}).stat);
|
|
}
|
|
|
|
if (noun === "Sprint") {
|
|
await reloadSprintList();
|
|
}
|
|
|
|
if (noun === "Item") {
|
|
reloadItemLists();
|
|
await reloadItemList();
|
|
}
|
|
|
|
// TODO: History context upsert
|
|
}
|
|
|
|
closeModal();
|
|
} catch(err) {
|
|
if (err.statusCode != null) {
|
|
error = err.statusMessage;
|
|
} else {
|
|
error = err
|
|
}
|
|
|
|
} finally {
|
|
loading = false;
|
|
}
|
|
}
|
|
|
|
let disabled;
|
|
$: disabled = loading || (!!dangerZone && name !== dangerZoneConfirm)
|
|
</script>
|
|
|
|
<form on:submit|preventDefault={submit}>
|
|
<Modal closable show={show} verb="Delete" noun={noun} disabled={disabled} error={error}>
|
|
<ModalBody>
|
|
<p>Are you sure you want to delete this {noun.toLocaleLowerCase()}?</p>
|
|
{#if sideEffects.length > 0}
|
|
<p>There are side-effects to this deletion.</p>
|
|
<ul>
|
|
{#each sideEffects as sideEffect}
|
|
<li>{sideEffect.op} {sideEffect.name}</li>
|
|
{/each}
|
|
</ul>
|
|
{/if}
|
|
<label for="name">{noun} name</label>
|
|
<input type="text" disabled name="name" value={name} />
|
|
{#if dangerZone}
|
|
<label for="confirm">Re-type name to confirm</label>
|
|
<input type="text" name="confirm" bind:value={dangerZoneConfirm} />
|
|
{/if}
|
|
</ModalBody>
|
|
</Modal>
|
|
</form>
|