Loggest thine Stuff
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.
 
 
 
 
 
 

208 lines
6.9 KiB

<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>