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.
121 lines
3.4 KiB
121 lines
3.4 KiB
<script lang="ts">
|
|
import type Sprint from "$lib/models/sprint";
|
|
import type { StatAggregate, StatEntry } from "$lib/models/stat";
|
|
import { calculateAggregate } from "$lib/utils/aggregate";
|
|
|
|
import currentTime from "$lib/stores/currentTime";
|
|
|
|
import Entry from "../layout/Entry.svelte";
|
|
import EntryDescription from "../layout/EntryDescription.svelte";
|
|
import EntryName from "../layout/EntryName.svelte";
|
|
import EntryProgress from "../layout/EntryProgress.svelte";
|
|
import EntryProgressRow from "../layout/EntryProgressRow.svelte";
|
|
import ItemLink from "./ItemLink.svelte";
|
|
import RequirementLink from "./RequirementLink.svelte";
|
|
|
|
export let sprint: Sprint
|
|
|
|
let fromDate: Date;
|
|
let toDate: Date;
|
|
let boat: number;
|
|
let itemsAcquired: number;
|
|
let itemsRequired: number;
|
|
let aggregate: StatAggregate;
|
|
let reqAggregate: Record<string, StatAggregate>;
|
|
|
|
$: {
|
|
fromDate = new Date(sprint.from);
|
|
toDate = new Date(sprint.to);
|
|
boat = ($currentTime.getTime() - fromDate.getTime()) / (toDate.getTime() - fromDate.getTime());
|
|
boat = Math.max(0, Math.min(1, boat));
|
|
}
|
|
|
|
$: {
|
|
if (sprint.items != null) {
|
|
itemsAcquired = sprint.items.filter(i => !!i.acquireDate).length;
|
|
itemsRequired = sprint.items.length;
|
|
} else {
|
|
itemsAcquired = 0;
|
|
itemsRequired = 0;
|
|
}
|
|
}
|
|
|
|
$: {
|
|
switch (sprint.kind) {
|
|
case "item": {
|
|
aggregate = calculateAggregate(sprint.items.map(i => i.stats).flat());
|
|
break;
|
|
}
|
|
case "requirements": {
|
|
aggregate = calculateAggregate(sprint.requirements.map(r => r.stats).flat());
|
|
break;
|
|
}
|
|
case "stats": {
|
|
aggregate = calculateAggregate(sprint.stats);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (sprint.aggregateRequired > 0) {
|
|
aggregate.required = sprint.aggregateRequired;
|
|
}
|
|
|
|
reqAggregate = {};
|
|
for (const requirement of (sprint.requirements || [])) {
|
|
reqAggregate[requirement.id] = calculateAggregate(requirement.stats);
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<a href="/{sprint.scope.id}/sprints?sprint={sprint.id}">
|
|
<Entry>
|
|
<EntryName subtitle="{sprint.scope.abbreviation} {sprint.kind} sprint">{sprint.name}</EntryName>
|
|
<EntryDescription>{sprint.description}</EntryDescription>
|
|
<EntryProgressRow>
|
|
{#if sprint.kind === "item"}
|
|
<EntryProgress
|
|
fullwidth green
|
|
percentage={sprint.aggregateRequired == 0}
|
|
name="Items"
|
|
acquired={itemsAcquired}
|
|
required={itemsRequired}
|
|
boat={boat}
|
|
/>
|
|
{:else}
|
|
<EntryProgress
|
|
fullwidth
|
|
percentage={sprint.aggregateRequired == 0}
|
|
name="Total"
|
|
acquired={aggregate.acquired}
|
|
required={aggregate.required}
|
|
boat={boat}
|
|
/>
|
|
{/if}
|
|
{#if !sprint.coarse}
|
|
{#each sprint.stats as stat (stat.id)}
|
|
<EntryProgress
|
|
name={stat.name}
|
|
acquired={stat.acquired}
|
|
required={stat.required}
|
|
boat={boat}
|
|
/>
|
|
{/each}
|
|
{/if}
|
|
</EntryProgressRow>
|
|
{#each sprint.items as item (item.id)}
|
|
{#if !item.acquireDate}
|
|
<ItemLink compact item={item} />
|
|
{/if}
|
|
{/each}
|
|
{#each sprint.requirements as requirement (requirement.id)}
|
|
<RequirementLink compact boat={boat} requirement={requirement} />
|
|
{/each}
|
|
</Entry>
|
|
</a>
|
|
|
|
<style lang="scss">
|
|
a {
|
|
text-decoration: none;
|
|
color: inherit;
|
|
}
|
|
</style>
|