|
|
<script lang="ts"> 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 { getScopeContext } from "$lib/components/contexts/ScopeContext.svelte"; import { getScopeListContext } from "$lib/components/contexts/ScopeListContext.svelte"; import { getSprintListContext } from "$lib/components/contexts/SprintListContext.svelte"; import AcquiredTimeInput from "$lib/components/controls/AcquiredTimeInput.svelte"; import RequirementSelect from "$lib/components/controls/RequirementSelect.svelte"; import StatInput from "$lib/components/controls/StatInput.svelte"; import type Item from "$lib/models/item"; import type { ItemInput } from "$lib/models/item"; import type { Requirement } from "$lib/models/project"; import type Scope from "$lib/models/scope"; import { formatFormTime } from "$lib/utils/date"; import { statDiff } from "$lib/utils/stat";
const {currentModal, closeModal} = getModalContext(); const {scope} = getScopeContext(); const {scopes} = getScopeListContext(); const {project, reloadProject} = getProjectContext(); const {reloadItemList} = getItemListContext(); const {reloadSprintList} = getSprintListContext(); const {reloadItemLists} = getItemMultiListContext(); const {page} = getStores();
let item: ItemInput let itemId: number let scopeId: number let currentStats: ItemInput["stats"] let openedDate: Date let requirementName: string let op: string let initOnList: number[] = [];
let error: string let loading: boolean let show: boolean
$: switch ($currentModal.name) { case "item.create": initCreate($scope, $currentModal.requirement) break; case "item.edit": { const reqId = $currentModal.item.requirementId; initEdit($currentModal.item, $project.requirements.find(r => r.id === reqId), $scope) break; }
default: loading = false; error = null; show = false; }
function initCreate(scope: Scope, requirement?: Requirement) { let stats = requirement?.stats.map(s => ({statId: s.id, required: 0, acquired: 0})); if (stats == null) { stats = scope.stats.map(s => ({statId: s.id, required: 0, acquired: 0})) } else { initOnList = requirement.stats.filter(s => s.required > 0).map(s => s.id); }
item = { name: "", description: "", requirementId: requirement?.id, stats: stats, acquiredTime: null, scheduledDate: null, }
op = "Create" scopeId = scope.id; openedDate = new Date(); requirementName = requirement?.name; show = true; }
function initEdit(current: Item, requirement?: Requirement, scope?: Scope) { const req = $project.requirements?.find(r => r.id === current.requirementId); let ctxStats = requirement?.stats.map(s => ({statId: s.id, required: 0, acquired: 0})); if (ctxStats == null || ctxStats.length === 0) { let actualScope = scope; if (actualScope.id !== current.scopeId && $scopes?.length > 0) { actualScope = $scopes.find(s => s.id === current.scopeId) }
ctxStats = actualScope.stats.map(s => ({statId: s.id, required: 0, acquired: 0})); } const inputStats = current.stats.map(s => ({statId: s.id, acquired: s.acquired, required: s.required}));
item = { name: current.name, description: current.description, requirementId: current.requirementId, stats: ctxStats.map(s => inputStats.find(s2 => s2.statId === s.statId) || s), acquiredTime: formatFormTime(current.acquiredTime), scheduledDate: current.scheduledDate, }; itemId = current.id; scopeId = current.scopeId; currentStats = [...item.stats];
op = "Edit" openedDate = new Date(); requirementName = current.requirement?.name; show = true; }
async function submit() { error = null; loading = true;
const submission: ItemInput = { ...item, acquiredTime: item.acquiredTime ? new Date(item.acquiredTime).toISOString() : void(0), stats: item.stats.filter(s => s.required > 0), }
try { switch (op) { case "Create": if (!!submission.acquiredTime) { for (const stat of submission.stats) { stat.acquired = stat.required } } else { for (const stat of submission.stats) { stat.acquired = 0 } }
await sl3(fetch, $page.stuff.idToken).createItem(scopeId, submission); break; case "Edit": if (!submission.acquiredTime) { for (const stat of submission.stats) { stat.acquired = 0 } submission.clearAcquiredTime = true; }
submission.stats = statDiff(currentStats, submission.stats) await sl3(fetch, $page.stuff.idToken).updateItem(scopeId, itemId, submission); break; } // Wait for project reload if it's updating a project if (item.requirementId != null) { await reloadProject(); }
await reloadItemList(); await reloadSprintList(); reloadItemLists();
closeModal(); } catch(err) { if (err.statusCode != null) { error = err.statusMessage; } else { error = err }
} finally { loading = false; } } </script>
<form on:submit|preventDefault={submit}> <Modal wide closable show={show} verb={op} noun="Item" disabled={loading} error={error}> <ModalBody> <label for="name">Name</label> <input name="name" type="text" bind:value={item.name} /> <label for="acquiredTime">Acquired</label> <AcquiredTimeInput openDate={openedDate} bind:value={item.acquiredTime} /> <label for="description">Description</label> <textarea name="description" bind:value={item.description} /> </ModalBody> <ModalBody> {#if requirementName != null} <label for="req">Project Requirement</label> {#if $project.id != null} <RequirementSelect disabled={op === "Create"} requirements={$project.requirements} bind:value={item.requirementId} /> {:else} <input disabled name="req" type="text" value={requirementName} /> {/if} {/if} <label for="stats">Stats</label> <StatInput zeroDeletes showRequired overrideScopeId={scopeId} initOnList={initOnList} showAcquired={op === "Edit" && !!item.acquiredTime} hideUnseen={!!item.requirementId} bind:value={item.stats} /> </ModalBody> </Modal> </form>
|