Gisle Aune
4 years ago
11 changed files with 240 additions and 11 deletions
-
2svelte-ui/src/components/Checkbox.svelte
-
18svelte-ui/src/components/GroupEntry.svelte
-
15svelte-ui/src/components/ItemEntry.svelte
-
7svelte-ui/src/components/LogEntry.svelte
-
26svelte-ui/src/components/ProjectEntry.svelte
-
146svelte-ui/src/components/TableOfContent.svelte
-
23svelte-ui/src/components/TaskEntry.svelte
-
4svelte-ui/src/external/icons.ts
-
2svelte-ui/src/pages/FrontPage.svelte
-
2svelte-ui/src/pages/GroupPage.svelte
-
2svelte-ui/src/pages/ProjectPage.svelte
@ -0,0 +1,146 @@ |
|||||
|
<script lang="ts" context="module"> |
||||
|
import type { IconName } from "../external/icons"; |
||||
|
|
||||
|
interface ToCGroup { |
||||
|
icon: IconName |
||||
|
href: string |
||||
|
name: string |
||||
|
completed: boolean |
||||
|
items: ToCItem[] |
||||
|
} |
||||
|
|
||||
|
interface ToCItem { |
||||
|
href: string |
||||
|
name: string |
||||
|
completed: boolean |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import type { GroupResult } from "../models/group"; |
||||
|
import type { ProjectResult } from "../models/project"; |
||||
|
import Icon from "./Icon.svelte"; |
||||
|
|
||||
|
export let projects: ProjectResult[] = []; |
||||
|
export let groups: GroupResult[] = []; |
||||
|
export let hideInactive: boolean = false; |
||||
|
|
||||
|
let tocGroups: ToCGroup[]; |
||||
|
let show = false; |
||||
|
|
||||
|
function toggleShow() { |
||||
|
show = !show; |
||||
|
} |
||||
|
|
||||
|
$: { |
||||
|
tocGroups = []; |
||||
|
|
||||
|
for (const project of projects) { |
||||
|
tocGroups.push({ |
||||
|
icon: project.icon, |
||||
|
name: project.name, |
||||
|
href: `/projects#${project.id}`, |
||||
|
completed: !project.active, |
||||
|
items: project.tasks.filter(t => !hideInactive || t.active).map(task => ({ |
||||
|
name: task.name, |
||||
|
completed: !task.active, |
||||
|
href: `/projects#${task.id}`, |
||||
|
})), |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
for (const group of groups) { |
||||
|
tocGroups.push({ |
||||
|
icon: group.icon, |
||||
|
name: group.name, |
||||
|
href: `/items#${group.id}`, |
||||
|
completed: false, |
||||
|
items: group.items.map(item => ({ |
||||
|
name: item.name, |
||||
|
completed: false, |
||||
|
href: `/items#${item.id}`, |
||||
|
})), |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<div class="toc" class:show={show}> |
||||
|
<div class="show-button" on:click={toggleShow}> |
||||
|
<div class="icon"><Icon name={show ? "chevron_down" : "chevron_right"} /></div> |
||||
|
<div class="text">{show ? "Hide" : "Show"} Table of Contents</div> |
||||
|
</div> |
||||
|
{#if show} |
||||
|
{#each tocGroups as tocGroup (tocGroup.href)} |
||||
|
<div class="toc-group" class:completed={tocGroup.completed}> |
||||
|
<a href={tocGroup.href}> |
||||
|
<div class="icon"> |
||||
|
<Icon name={tocGroup.icon} /> |
||||
|
</div> |
||||
|
<div class="text">{tocGroup.name}</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
{#each tocGroup.items as tocItem (tocItem.href)} |
||||
|
<div class="toc-item" class:completed={tocItem.completed}> |
||||
|
<a href={tocItem.href}> |
||||
|
<div class="text">{tocItem.name}</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
{/each} |
||||
|
{/each} |
||||
|
{/if} |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
div.toc { |
||||
|
padding: 1em; |
||||
|
color: #777; |
||||
|
margin: 0 auto; |
||||
|
} |
||||
|
div.toc.show { |
||||
|
padding-bottom: 2em; |
||||
|
} |
||||
|
|
||||
|
div.toc-item { |
||||
|
margin-left: 1.5ch; |
||||
|
padding-left: 1ch; |
||||
|
border-left: 2px solid #222; |
||||
|
} |
||||
|
div.toc-item + div.toc-group, div.toc-group + div.toc-group { |
||||
|
padding-top: 1em; |
||||
|
} |
||||
|
|
||||
|
a { |
||||
|
color: inherit; |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
padding: 0.125em 0.5ch; |
||||
|
} |
||||
|
a > div.icon { |
||||
|
padding: 0.125em 0.5ch; |
||||
|
} |
||||
|
a > div.text { |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
div.show-button { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
-webkit-user-select: none; |
||||
|
-moz-user-select: none; |
||||
|
padding-bottom: 1em; |
||||
|
} |
||||
|
div.show-button div.icon { |
||||
|
margin-left: auto; |
||||
|
padding: 0 1ch; |
||||
|
} |
||||
|
div.show-button div.text { |
||||
|
margin-right: auto; |
||||
|
margin-top: auto; |
||||
|
margin-bottom: auto; |
||||
|
} |
||||
|
|
||||
|
div.completed { |
||||
|
color: #484; |
||||
|
} |
||||
|
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue