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.
201 lines
6.5 KiB
201 lines
6.5 KiB
<script lang="ts">
|
|
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 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();
|
|
|
|
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 = req?.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).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).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>
|
|
<input disabled name="req" type="text" value={requirementName} />
|
|
{/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>
|