Browse Source

add project progress indicator and sort front page projects by deadline.

main
Gisle Aune 4 years ago
parent
commit
838a787409
  1. 18
      svelte-ui/src/components/Progress.svelte
  2. 12
      svelte-ui/src/components/ProjectEntry.svelte
  3. 4
      svelte-ui/src/components/TaskEntry.svelte
  4. 22
      svelte-ui/src/pages/FrontPage.svelte

18
svelte-ui/src/components/Progress.svelte

@ -11,6 +11,8 @@
<script lang="ts"> <script lang="ts">
export let target = 1; export let target = 1;
export let count = 0; export let count = 0;
export let green = false;
export let thin = false;
let offClass = COLORS[0]; let offClass = COLORS[0];
let onClass = COLORS[1]; let onClass = COLORS[1];
@ -19,7 +21,7 @@
$: { $: {
let level = Math.floor(count / target); let level = Math.floor(count / target);
if (level >= COLORS.length - 1) {
if (level >= COLORS.length - 1 || (level > 1 && green)) {
offs = 0; offs = 0;
ons = target; ons = target;
offClass = "gold"; offClass = "gold";
@ -34,10 +36,15 @@
offClass = COLORS[level]; offClass = COLORS[level];
onClass = COLORS[level + 1]; onClass = COLORS[level + 1];
} }
if (green) {
onClass = "green"
offClass = "none"
}
} }
</script> </script>
<div class="bar">
<div class="bar" class:thin>
{#each {length: ons} as _} {#each {length: ons} as _}
<div class={"on " + onClass}></div> <div class={"on " + onClass}></div>
{/each} {/each}
@ -61,7 +68,7 @@
flex-basis: 0; flex-basis: 0;
display: inline-block; display: inline-block;
box-sizing: border-box; box-sizing: border-box;
border: 0.1px solid #000;
border: 1px solid #000;
} }
div.none { background-color: #555555; } div.none { background-color: #555555; }
@ -69,6 +76,7 @@
div.silver { background-color: #d8dce4; } div.silver { background-color: #d8dce4; }
div.gold { background-color: #ffd966; } div.gold { background-color: #ffd966; }
div.diamond { background-color: #84f5ff; } div.diamond { background-color: #84f5ff; }
div.green { background-color: #78ff78; }
div.on { div.on {
opacity: 0.75; opacity: 0.75;
@ -77,4 +85,8 @@
div.off { div.off {
opacity: 0.33; opacity: 0.33;
} }
div.bar.thin {
height: 0.25em;
}
</style> </style>

12
svelte-ui/src/components/ProjectEntry.svelte

@ -1,31 +1,32 @@
<script lang="ts"> <script lang="ts">
import type { IconName } from "../external/icons";
import TaskAddForm from "../forms/TaskAddForm.svelte";
import type { ProjectResult } from "../models/project"; import type { ProjectResult } from "../models/project";
import type { ModalData } from "../stores/modal"; import type { ModalData } from "../stores/modal";
import DaysLeft from "./DaysLeft.svelte"; import DaysLeft from "./DaysLeft.svelte";
import Icon from "./Icon.svelte"; import Icon from "./Icon.svelte";
import Option from "./Option.svelte"; import Option from "./Option.svelte";
import OptionRow from "./OptionRow.svelte"; import OptionRow from "./OptionRow.svelte";
import Progress from "./Progress.svelte";
import TaskEntry from "./TaskEntry.svelte"; import TaskEntry from "./TaskEntry.svelte";
export let project: ProjectResult = null; export let project: ProjectResult = null;
export let showAllOptions: boolean = false; export let showAllOptions: boolean = false;
export let hideInactive: boolean = false; export let hideInactive: boolean = false;
let iconName: IconName = "question";
let mdAddTask: ModalData; let mdAddTask: ModalData;
let mdProjectEdit: ModalData; let mdProjectEdit: ModalData;
let mdProjectDelete: ModalData; let mdProjectDelete: ModalData;
let progressAmount: number;
let progressTarget: number;
$: iconName = project.icon as IconName;
$: mdAddTask = {name:"task.add", project}; $: mdAddTask = {name:"task.add", project};
$: mdProjectEdit = {name:"project.edit", project}; $: mdProjectEdit = {name:"project.edit", project};
$: mdProjectDelete = {name:"project.delete", project}; $: mdProjectDelete = {name:"project.delete", project};
$: progressAmount = project.tasks.map(t => Math.min(t.completedAmount, t.itemAmount) * t.item.groupWeight).reduce((n,m) => n+m, 0);
$: progressTarget = Math.max(project.tasks.map(t => t.itemAmount * t.item.groupWeight).reduce((n,m) => n+m, 0), 1);
</script> </script>
<div class="project"> <div class="project">
<div class="icon" class:inactive={!project.active}><Icon block name={iconName} /></div>
<div class="icon" class:inactive={!project.active}><Icon block name={project.icon} /></div>
<div class="body"> <div class="body">
<div class="header"> <div class="header">
<div class="name">{project.name}</div> <div class="name">{project.name}</div>
@ -35,6 +36,7 @@ import TaskAddForm from "../forms/TaskAddForm.svelte";
</div> </div>
{/if} {/if}
</div> </div>
<Progress thin green count={progressAmount} target={progressTarget} />
{#if showAllOptions} {#if showAllOptions}
<div class="description"> <div class="description">
<p>{project.description}</p> <p>{project.description}</p>

4
svelte-ui/src/components/TaskEntry.svelte

@ -11,7 +11,6 @@
export let task: TaskResult = null; export let task: TaskResult = null;
export let showAllOptions: boolean = false; export let showAllOptions: boolean = false;
let itomIconName: IconName = "question";
let showLogs = false; let showLogs = false;
let mdLogAdd: ModalData; let mdLogAdd: ModalData;
let mdTaskEdit: ModalData; let mdTaskEdit: ModalData;
@ -21,7 +20,6 @@
showLogs = !showLogs; showLogs = !showLogs;
} }
$: itomIconName = task.item.icon as IconName;
$: mdLogAdd = {name: "log.add", task}; $: mdLogAdd = {name: "log.add", task};
$: mdTaskEdit = {name: "task.edit", task}; $: mdTaskEdit = {name: "task.edit", task};
$: mdTaskDelete = {name: "task.delete", task}; $: mdTaskDelete = {name: "task.delete", task};
@ -53,7 +51,7 @@
<p>{task.description}</p> <p>{task.description}</p>
<div class="item"> <div class="item">
<div class="item-icon"> <div class="item-icon">
<Icon name={itomIconName} />
<Icon name={task.item.icon} />
</div> </div>
<div class="item-name">{task.item.name} ({task.item.groupWeight})</div> <div class="item-name">{task.item.name} ({task.item.groupWeight})</div>
</div> </div>

22
svelte-ui/src/pages/FrontPage.svelte

@ -4,10 +4,11 @@
import ProjectEntry from "../components/ProjectEntry.svelte"; import ProjectEntry from "../components/ProjectEntry.svelte";
import type { ProjectResult } from "../models/project"; import type { ProjectResult } from "../models/project";
import { fpGoalStore } from "../stores/goal"; import { fpGoalStore } from "../stores/goal";
import { fpProjectStore } from "../stores/project";
import { fpTaskStore } from "../stores/tasks";
import projectStore, { fpProjectStore } from "../stores/project";
import taskStore, { fpTaskStore } from "../stores/tasks";
let fakeProject: ProjectResult let fakeProject: ProjectResult
let sortedProjects: ProjectResult[]
$: { $: {
if ($fpGoalStore.stale && !$fpGoalStore.loading) { if ($fpGoalStore.stale && !$fpGoalStore.loading) {
@ -44,12 +45,22 @@
description: "", description: "",
icon: "list", icon: "list",
name: "Individual Tasks", name: "Individual Tasks",
tasks: $fpTaskStore.tasks.filter(t => $fpProjectStore.projects.find(p => p.id === t.id) == null),
tasks: $fpTaskStore.tasks.filter(t => $fpProjectStore.projects.find(p => p.id === t.id) == null)
.sort((a,b) => Date.parse(a.endTime) - Date.parse(b.endTime)),
endTime: null, endTime: null,
} }
if (fakeProject.tasks.length > 0) {
fakeProject.endTime = fakeProject.tasks[0].endTime;
}
console.log(fakeProject, $fpTaskStore); console.log(fakeProject, $fpTaskStore);
} }
$: {
const projects = fakeProject.tasks.length > 0 ? [...$fpProjectStore.projects, fakeProject] : [...$fpProjectStore.projects];
sortedProjects = projects.sort((a,b) => Date.parse(a.endTime) - Date.parse(b.endTime));
}
</script> </script>
<div class="page"> <div class="page">
@ -68,12 +79,9 @@
{#if !$fpProjectStore.loading || $fpProjectStore.projects.length > 0} {#if !$fpProjectStore.loading || $fpProjectStore.projects.length > 0}
<h1>Upcoming Deadlines</h1> <h1>Upcoming Deadlines</h1>
{/if} {/if}
{#each $fpProjectStore.projects as project (project.id)}
{#each sortedProjects as project (project.id)}
<ProjectEntry hideInactive project={project} /> <ProjectEntry hideInactive project={project} />
{/each} {/each}
{#if fakeProject.tasks.length > 0}
<ProjectEntry project={fakeProject} />
{/if}
{#if fakeProject.tasks.length === 0 && !$fpProjectStore.loading && $fpProjectStore.projects.length === 0} {#if fakeProject.tasks.length === 0 && !$fpProjectStore.loading && $fpProjectStore.projects.length === 0}
<EmptyList icon="check" text="All good!" /> <EmptyList icon="check" text="All good!" />
{/if} {/if}

Loading…
Cancel
Save