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.
100 lines
3.0 KiB
100 lines
3.0 KiB
<script lang="ts">
|
|
import { addDays, endOfDay, formatWeekdayDate, formatWeekdayTitle, startOfDay } from "$lib/utils/date";
|
|
import { significantDecimals } from "$lib/utils/numbers";
|
|
import { morningOf } from "$lib/utils/timeinterval";
|
|
import { getItemMultiListContext } from "../contexts/ItemMultiListContext.svelte";
|
|
import { getTimeContext } from "../contexts/TimeContext.svelte";
|
|
import Row from "../layout/Row.svelte";
|
|
import ItemSubSection, { type ItemSubSectionEvent } from "../project/ItemSubSection.svelte";
|
|
|
|
export let key: string;
|
|
export let title: string;
|
|
export let showAcquiredTime: boolean = false;
|
|
export let useAcquiredTotal: boolean = false;
|
|
export let useDayFilter: number | null = null;
|
|
export let selectedDay: number = 0;
|
|
export let event: ItemSubSectionEvent = "none";
|
|
|
|
const {now} = getTimeContext();
|
|
const {lists} = getItemMultiListContext();
|
|
|
|
let dayTitle = "";
|
|
let filteredList = [];
|
|
$: {
|
|
if (useDayFilter != null) {
|
|
const maxTime = addDays(morningOf($now), -(selectedDay - 1)).toISOString();
|
|
const minTime = addDays(morningOf($now), -selectedDay).toISOString();
|
|
filteredList = $lists[key].filter(i => i.acquiredTime >= minTime && i.acquiredTime <= maxTime)
|
|
dayTitle = formatWeekdayTitle(morningOf($now), new Date(minTime))
|
|
} else {
|
|
filteredList = $lists[key] || [];
|
|
}
|
|
}
|
|
|
|
let totalStr = "";
|
|
$: {
|
|
totalStr = significantDecimals(filteredList.map(v => useAcquiredTotal ? v.weightedAcquired : v.weightedRequired).reduce((p,c) => p + c, 0));
|
|
if (Number(totalStr) < 0.01) {
|
|
totalStr = "";
|
|
}
|
|
}
|
|
</script>
|
|
|
|
|
|
{#if (filteredList.length > 0 || useDayFilter != null)}
|
|
<Row title={title || dayTitle}>
|
|
<div class="total" slot="right">{totalStr}</div>
|
|
<div class="day-filters" slot="over">
|
|
{#if (useDayFilter != null)}
|
|
{#each {length: useDayFilter} as _, i}
|
|
<div on:click={() => selectedDay = i} class="option" class:selected={i === selectedDay}>
|
|
<div class="inner"></div>
|
|
</div>
|
|
{/each}
|
|
{/if}
|
|
</div>
|
|
{#each filteredList as item (item.id)}
|
|
<ItemSubSection event={event} showAcquiredTime={showAcquiredTime} item={item} />
|
|
{/each}
|
|
</Row>
|
|
{/if}
|
|
|
|
<style lang="sass">
|
|
@import "../../css/colors.sass"
|
|
|
|
div.total
|
|
color: $color-entry5
|
|
margin-top: 0.25em
|
|
|
|
div.day-filters
|
|
display: flex
|
|
flex-direction: row
|
|
max-width: 100%
|
|
flex-wrap: wrap
|
|
|
|
div.option
|
|
padding: 0.1em 0.25em
|
|
cursor: pointer
|
|
|
|
&:first-child
|
|
margin-left: -0.25em
|
|
@media screen and (max-width: 749px)
|
|
margin-left: 0
|
|
|
|
> div.inner
|
|
width: 1.25ch
|
|
height: 1.25ch
|
|
border: 1px solid $color-entry2
|
|
|
|
@media screen and (max-width: 749px)
|
|
width: 2.5ch
|
|
height: 2.5ch
|
|
|
|
|
|
&.selected > div.inner
|
|
border-color: $color-entry7
|
|
background-color: $color-entry7
|
|
|
|
&:hover > div.inner
|
|
border-color: $color-entry9
|
|
</style>
|