This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type Item from "../models/item";
|
||||
import type { LogResult } from "../models/log";
|
||||
import type { ProjectResult } from "../models/project";
|
||||
import Icon from "./Icon.svelte";
|
||||
|
||||
@@ -8,95 +9,150 @@
|
||||
amount: number
|
||||
target: number
|
||||
extras: number
|
||||
noTarget?: boolean
|
||||
}
|
||||
|
||||
export let project: ProjectResult;
|
||||
export let project: ProjectResult = null;
|
||||
export let logs: LogResult[] = [];
|
||||
export let centered = false;
|
||||
export let vertical = false;
|
||||
|
||||
let list: ListEntry[] = [];
|
||||
|
||||
$: {
|
||||
list = [];
|
||||
for (const task of project.tasks) {
|
||||
let entry = list.find(e => e.item.id === task.item.id);
|
||||
if (entry == null) {
|
||||
entry = {item: task.item, amount: 0, target: 0, extras: 0};
|
||||
list.push(entry);
|
||||
}
|
||||
|
||||
if (task.completedAmount > task.itemAmount) {
|
||||
entry.extras += task.completedAmount - task.itemAmount;
|
||||
entry.amount += task.itemAmount;
|
||||
} else {
|
||||
entry.amount += task.completedAmount;
|
||||
}
|
||||
if (project != null) {
|
||||
for (const task of project.tasks) {
|
||||
let entry = list.find(e => e.item.id === task.item.id);
|
||||
if (entry == null) {
|
||||
entry = {item: task.item, amount: 0, target: 0, extras: 0};
|
||||
list.push(entry);
|
||||
}
|
||||
|
||||
if (["completed", "failed", "declined"].includes(task.statusTag)) {
|
||||
entry.target += task.itemAmount - Math.max(0, task.itemAmount - task.completedAmount);
|
||||
} else {
|
||||
entry.target += task.itemAmount;
|
||||
}
|
||||
if (task.completedAmount > task.itemAmount) {
|
||||
entry.extras += task.completedAmount - task.itemAmount;
|
||||
entry.amount += task.itemAmount;
|
||||
} else {
|
||||
entry.amount += task.completedAmount;
|
||||
}
|
||||
|
||||
for (const log of task.logs) {
|
||||
if (log.secondaryItem != null) {
|
||||
let entry = list.find(e => e.item.id === log.secondaryItemId);
|
||||
if (["completed", "failed", "declined"].includes(task.statusTag)) {
|
||||
entry.target += task.itemAmount - Math.max(0, task.itemAmount - task.completedAmount);
|
||||
} else {
|
||||
entry.target += task.itemAmount;
|
||||
}
|
||||
|
||||
for (const log of task.logs) {
|
||||
if (log.secondaryItem != null) {
|
||||
let entry = list.find(e => e.item.id === log.secondaryItemId);
|
||||
if (entry == null) {
|
||||
entry = {item: log.secondaryItem, amount: 0, target: 0, extras: 0};
|
||||
list.push(entry);
|
||||
}
|
||||
|
||||
entry.extras += log.secondaryItemAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const log of logs) {
|
||||
const items: [Item, number][] = [
|
||||
[log.item, log.itemAmount],
|
||||
[log.secondaryItem, log.secondaryItemAmount]
|
||||
];
|
||||
|
||||
for (const [item, count] of items) {
|
||||
if (item != null) {
|
||||
let entry = list.find(e => e.item.id === item.id);
|
||||
if (entry == null) {
|
||||
entry = {item: log.secondaryItem, amount: 0, target: 0, extras: 0};
|
||||
entry = {item, amount: 0, target: 0, extras: 0, noTarget: true};
|
||||
list.push(entry);
|
||||
}
|
||||
|
||||
entry.extras += log.secondaryItemAmount;
|
||||
entry.amount += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list = list.sort((a,b) => {
|
||||
if (a.noTarget && b.noTarget) {
|
||||
return a.amount - b.amount;
|
||||
}
|
||||
|
||||
if (a.target === b.target) {
|
||||
return a.item.name.localeCompare(b.item.name);
|
||||
} else {
|
||||
return b.target - a.target;
|
||||
}
|
||||
}).filter(l => l.extras > 0 || l.target > 0);
|
||||
}).filter(l => l.extras > 0 || (l.target > 0 || l.noTarget));
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="ItemProgress">
|
||||
{#each list as entry (entry.item.id)}
|
||||
<div class="entry">
|
||||
<div class="icon">
|
||||
<Icon name={entry.item.icon} />
|
||||
</div>
|
||||
<div class="name">
|
||||
{entry.item.name}
|
||||
</div>
|
||||
{#if entry.target !== 0}
|
||||
<div class="amount">
|
||||
<span>{entry.amount}</span>
|
||||
<span> / </span>
|
||||
<span>{entry.target}</span>
|
||||
{#if entry.extras > 0}
|
||||
<span class="extras">+ {entry.extras}</span>
|
||||
{/if}
|
||||
<div class="wrapper" class:centered class:vertical={vertical || list.length > 3}>
|
||||
{#each list as entry (entry.item.id)}
|
||||
<div class="entry">
|
||||
{#if entry.noTarget}
|
||||
<div class="amount">
|
||||
<span>{entry.amount}× </span>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="icon">
|
||||
<Icon name={entry.item.icon} />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="name">
|
||||
{entry.item.name}
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
<div class="extras">
|
||||
×{entry.extras}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
{#if entry.target !== 0}
|
||||
<div class="amount">
|
||||
<span>{entry.amount}</span>
|
||||
<span> / </span>
|
||||
<span>{entry.target}</span>
|
||||
{#if entry.extras > 0}
|
||||
<span class="extras">+ {entry.extras}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{:else if !entry.noTarget}
|
||||
<div class="extras">
|
||||
×{entry.extras}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div.ItemProgress {
|
||||
display: inline-block;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
div.ItemProgress div.wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
padding: 0.25em;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
div.ItemProgress div.wrapper.centered {
|
||||
margin: 0 auto;
|
||||
}
|
||||
div.ItemProgress div.wrapper.vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
div.ItemProgress div.entry {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
color: #777;
|
||||
padding-right: 1ch;
|
||||
}
|
||||
div.ItemProgress div.wrapper.vertical div.entry {
|
||||
padding-right: 0;
|
||||
}
|
||||
div.ItemProgress div.entry div {
|
||||
padding: 0.1em 0.25em;
|
||||
@@ -105,7 +161,7 @@
|
||||
color: #555;
|
||||
}
|
||||
div.ItemProgress div.entry .icon {
|
||||
padding: 0.20em;
|
||||
padding: 0.20em 0.5ch;
|
||||
}
|
||||
div.ItemProgress div.entry .extras {
|
||||
color: #484;
|
||||
|
||||
@@ -121,7 +121,7 @@ import ItemProgress from "./ItemProgress.svelte";
|
||||
{/if}
|
||||
</div>
|
||||
{#if showAllOptions}
|
||||
<ItemProgress project={project} />
|
||||
<ItemProgress project={project} vertical />
|
||||
|
||||
<OptionRow>
|
||||
<Option open={mdAddTask}>Add Task</Option>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import ItemSelect from "../components/ItemSelect.svelte";
|
||||
import projectStore from "../stores/project";
|
||||
import projectGroupStore from "../stores/projectGroup";
|
||||
import ItemProgress from "../components/ItemProgress.svelte";
|
||||
|
||||
const lsValue = localStorage.getItem("sl2.logspage.range")
|
||||
|
||||
@@ -150,6 +151,7 @@
|
||||
<div class="log-list" class:loading={$logStore.loading}>
|
||||
{#each groupedLogs as logGroup (logGroup.day.getTime())}
|
||||
<h2>{logGroup.text}</h2>
|
||||
<ItemProgress logs={logGroup.logs} centered />
|
||||
{#each logGroup.logs as log (log.id)}
|
||||
<LogEntry log={log} />
|
||||
{/each}
|
||||
|
||||
Reference in New Issue
Block a user