add status tags to tasks and reorganize them to have more familiar names.
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -60,7 +60,7 @@
|
||||
|
||||
// Mark it non-segmented if the target is too high. This prevents a clunky progress bar,
|
||||
// or a browser freeze if you set the target very high.
|
||||
nonSegmented = (target >= 50);
|
||||
nonSegmented = (target >= 60);
|
||||
}
|
||||
|
||||
$: {
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
<script lang="ts">
|
||||
import type { ProjectResult } from "../models/project";
|
||||
import type { TaskResult } from "../models/task";
|
||||
import type { TaskResult } from "../models/task";
|
||||
import type { ModalData } from "../stores/modal";
|
||||
import projectStore from "../stores/project";
|
||||
import taskStore from "../stores/tasks";
|
||||
import Composition from "./Composition.svelte";
|
||||
import Option from "./Option.svelte";
|
||||
import OptionRow from "./OptionRow.svelte";
|
||||
import ParentEntry from "./ParentEntry.svelte";
|
||||
import StatusColor from "./StatusColor.svelte";
|
||||
import TaskEntry from "./TaskEntry.svelte";
|
||||
import StatusColor from "./StatusColor.svelte";
|
||||
import TaskList from "./TaskList.svelte";
|
||||
|
||||
export let project: ProjectResult = null;
|
||||
export let showAllOptions: boolean = false;
|
||||
@@ -22,12 +19,38 @@ import StatusColor from "./StatusColor.svelte";
|
||||
let mdProjectEdit: ModalData;
|
||||
let mdProjectDelete: ModalData;
|
||||
|
||||
let activeTasks: TaskResult[] = [];
|
||||
let inactiveTasks: TaskResult[] = [];
|
||||
let completedTasks: TaskResult[] = [];
|
||||
let todoTasks: TaskResult[] = [];
|
||||
let onholdTasks: TaskResult[] = [];
|
||||
let failedTasks: TaskResult[] = [];
|
||||
|
||||
$: mdAddTask = {name:"task.add", project};
|
||||
$: mdProjectEdit = {name:"project.edit", project};
|
||||
$: mdProjectDelete = {name:"project.delete", project};
|
||||
|
||||
$: {
|
||||
activeTasks = project.tasks.filter(t => t.active);
|
||||
|
||||
if (!hideInactive) {
|
||||
inactiveTasks = project.tasks.filter(t => !t.active);
|
||||
|
||||
completedTasks = inactiveTasks.filter(t => t.statusTag === "completed" || t.statusTag == null);
|
||||
todoTasks = inactiveTasks.filter(t => t.statusTag === "to do" || t.statusTag === "idea");
|
||||
onholdTasks = inactiveTasks.filter(t => t.statusTag === "on hold" || t.statusTag === "postponed");
|
||||
failedTasks = inactiveTasks.filter(t => t.statusTag === "failed" || t.statusTag === "declined" || t.statusTag === "wont do");
|
||||
} else {
|
||||
inactiveTasks = [];
|
||||
completedTasks = [];
|
||||
todoTasks = [];
|
||||
onholdTasks = [];
|
||||
failedTasks = [];
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<StatusColor selected project={project}>
|
||||
<StatusColor affects="project" selected entry={project}>
|
||||
<ParentEntry
|
||||
full={showAllOptions}
|
||||
entry={project}
|
||||
@@ -43,10 +66,14 @@ import StatusColor from "./StatusColor.svelte";
|
||||
<Option open={mdProjectDelete}>Delete</Option>
|
||||
</OptionRow>
|
||||
{/if}
|
||||
{#each project.tasks as task (task.id)}
|
||||
{#if !hideInactive || task.active}
|
||||
<TaskEntry showAllOptions={showAllOptions} task={task} project={project} />
|
||||
{/if}
|
||||
{/each}
|
||||
{#if hideInactive}
|
||||
<TaskList header="" tasks={activeTasks} project={project} showAllOptions={showAllOptions} />
|
||||
{:else}
|
||||
<TaskList header="Active" tasks={activeTasks} project={project} showAllOptions={showAllOptions} />
|
||||
<TaskList header="Completed" tasks={completedTasks} project={project} showAllOptions={showAllOptions} />
|
||||
<TaskList header="To Do" tasks={todoTasks} project={project} showAllOptions={showAllOptions} />
|
||||
<TaskList header="On Hold" tasks={onholdTasks} project={project} showAllOptions={showAllOptions} />
|
||||
<TaskList header="Failed" tasks={failedTasks} project={project} showAllOptions={showAllOptions} />
|
||||
{/if}
|
||||
</ParentEntry>
|
||||
</StatusColor>
|
||||
|
||||
@@ -5,37 +5,11 @@
|
||||
|
||||
interface ProjectLike {
|
||||
icon?: IconName
|
||||
active?: boolean
|
||||
statusTag?: string
|
||||
}
|
||||
|
||||
export let project: ProjectLike
|
||||
export let selected: boolean;
|
||||
|
||||
let completed: boolean;
|
||||
let failed: boolean;
|
||||
let postponed: boolean;
|
||||
let idea: boolean;
|
||||
|
||||
$: completed = !project.active && project.statusTag === "completed";
|
||||
$: failed = !project.active && project.statusTag === "failed";
|
||||
$: postponed = !project.active && project.statusTag === "postponed";
|
||||
$: idea = !project.active && project.statusTag === "idea";
|
||||
</script>
|
||||
|
||||
<span class:selected class:completed class:failed class:postponed class:idea>
|
||||
<span class="sccfg" >
|
||||
<Icon block name={project.icon} />
|
||||
</span>
|
||||
|
||||
<style>
|
||||
span { color: #444; }
|
||||
span.selected { color: #666; }
|
||||
span.completed { color: #484; }
|
||||
span.completed.selected { color: #78ff78; }
|
||||
span.failed { color: #884844; }
|
||||
span.failed.selected { color: #ff9878; }
|
||||
span.postponed { color: #446d88; }
|
||||
span.postponed.selected { color: #78c9ff; }
|
||||
span.idea { color: #878844; }
|
||||
span.idea.selected { color: #fffd78; }
|
||||
</style>
|
||||
@@ -22,7 +22,7 @@
|
||||
$: completed = !project.active;
|
||||
</script>
|
||||
|
||||
<StatusColor project={project} selected={selected}>
|
||||
<StatusColor affects="project" entry={project} selected={selected}>
|
||||
<div class="ql-list-item" on:click={handleClick} class:selected>
|
||||
<div class="icon sccfg" class:completed>
|
||||
<Icon block name={project.icon} />
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
$: activeProjects = projects.filter(p => p.active && !p.endTime).sort((a,b) => a.name.localeCompare(b.name));
|
||||
$: inactiveProjects = projects.filter(p => !p.active).sort((a,b) => a.name.localeCompare(b.name));
|
||||
$: completedProjects = inactiveProjects.filter(p => p.statusTag === "completed" || p.statusTag == null);
|
||||
$: failedProjects = inactiveProjects.filter(p => p.statusTag === "failed" || p.statusTag == null);
|
||||
$: postponedProjects = inactiveProjects.filter(p => p.statusTag === "postponed" || p.statusTag == null);
|
||||
$: ideaProjects = inactiveProjects.filter(p => p.statusTag === "idea" || p.statusTag == null);
|
||||
$: failedProjects = inactiveProjects.filter(p => p.statusTag === "failed" || p.statusTag === "declined");
|
||||
$: postponedProjects = inactiveProjects.filter(p => p.statusTag === "on hold" || p.statusTag === "postponed");
|
||||
$: ideaProjects = inactiveProjects.filter(p => p.statusTag === "to do" || p.statusTag === "idea");
|
||||
|
||||
$: {
|
||||
if (project === null && projects.length > 0) {
|
||||
@@ -38,9 +38,9 @@
|
||||
<div class="list">
|
||||
<QlList label="Deadlines" projects={expiringProjects} />
|
||||
<QlList label="Active" projects={activeProjects} />
|
||||
<QlList label="To Do" projects={ideaProjects} />
|
||||
<QlList label="On Hold" projects={postponedProjects} />
|
||||
<QlList label="Completed" projects={completedProjects} />
|
||||
<QlList label="Postponed" projects={postponedProjects} />
|
||||
<QlList label="Ideas" projects={ideaProjects} />
|
||||
<QlList label="Failed" projects={failedProjects} />
|
||||
</div>
|
||||
<div class="body">
|
||||
|
||||
@@ -1,42 +1,58 @@
|
||||
<script lang="ts">
|
||||
interface ProjectLike {
|
||||
interface EntryCommon {
|
||||
active: boolean
|
||||
statusTag?: string
|
||||
}
|
||||
|
||||
export let selected = false;
|
||||
export let project: ProjectLike;
|
||||
export let entry: EntryCommon;
|
||||
export let affects: "project" | "task" = "project";
|
||||
|
||||
let completed: boolean;
|
||||
let failed: boolean;
|
||||
let postponed: boolean;
|
||||
let idea: boolean;
|
||||
let onhold: boolean;
|
||||
let todo: boolean;
|
||||
let wontdo: boolean;
|
||||
let project: boolean;
|
||||
let task: boolean;
|
||||
|
||||
$: completed = !project.active && project.statusTag === "completed";
|
||||
$: failed = !project.active && project.statusTag === "failed";
|
||||
$: postponed = !project.active && project.statusTag === "postponed";
|
||||
$: idea = !project.active && project.statusTag === "idea";
|
||||
$: completed = !entry.active && entry.statusTag === "completed";
|
||||
$: failed = !entry.active && entry.statusTag === "failed";
|
||||
$: onhold = !entry.active && entry.statusTag === "on hold";
|
||||
$: todo = !entry.active && entry.statusTag === "to do";
|
||||
$: wontdo = !entry.active && entry.statusTag === "declined";
|
||||
$: task = affects === "task";
|
||||
$: project = affects === "project";
|
||||
|
||||
</script>
|
||||
|
||||
<div class="status-color-context" class:selected class:completed class:failed class:postponed class:idea>
|
||||
<div class="status-color-context" class:project class:task class:selected class:completed class:failed class:onhold class:todo class:wontdo>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.status-color-context :global(.sccfg) { color: #444 !important; }
|
||||
.status-color-context.selected :global(.sccfg) { color: #666 !important; }
|
||||
.status-color-context :global(.sccpb) { background-color: #78ff78 !important; }
|
||||
.status-color-context.completed :global(.sccfg) { color: #484 !important; }
|
||||
.status-color-context.completed.selected :global(.sccfg) { color: #78ff78 !important; }
|
||||
.status-color-context.completed :global(.sccpb) { background-color: #78ff78 !important; }
|
||||
.status-color-context.failed :global(.sccfg) { color: #852a24 !important; }
|
||||
.status-color-context.failed.selected :global(.sccfg) { color: #ff4545 !important; }
|
||||
.status-color-context.failed :global(.sccpb) { background-color: #ff4545 !important; }
|
||||
.status-color-context.postponed :global(.sccfg) { color: #446d88 !important; }
|
||||
.status-color-context.postponed.selected :global(.sccfg) { color: #78c9ff !important; }
|
||||
.status-color-context.postponed :global(.sccpb) { background-color: #78c9ff !important; }
|
||||
.status-color-context.idea :global(.sccfg) { color: #878844 !important; }
|
||||
.status-color-context.idea.selected :global(.sccfg) { color: #e7e55e !important; }
|
||||
.status-color-context.idea :global(.sccpb) { background-color: #e7e55e !important; }
|
||||
.status-color-context.project :global(.sccfg) { color: #444 !important; }
|
||||
.status-color-context.project.selected :global(.sccfg) { color: #666 !important; }
|
||||
.status-color-context.project :global(.sccpb) { background-color: #78ff78 !important; }
|
||||
.status-color-context.project.completed :global(.sccfg) { color: #484 !important; }
|
||||
.status-color-context.project.completed.selected :global(.sccfg) { color: #78ff78 !important; }
|
||||
.status-color-context.project.completed :global(.sccpb) { background-color: #78ff78 !important; }
|
||||
.status-color-context.project.failed :global(.sccfg) { color: #852a24 !important; }
|
||||
.status-color-context.project.failed.selected :global(.sccfg) { color: #ff4545 !important; }
|
||||
.status-color-context.project.failed :global(.sccpb) { background-color: #ff4545 !important; }
|
||||
.status-color-context.project.onhold :global(.sccfg) { color: #446d88 !important; }
|
||||
.status-color-context.project.onhold.selected :global(.sccfg) { color: #78c9ff !important; }
|
||||
.status-color-context.project.onhold :global(.sccpb) { background-color: #78c9ff !important; }
|
||||
.status-color-context.project.todo :global(.sccfg) { color: #7a7429 !important; }
|
||||
.status-color-context.project.todo.selected :global(.sccfg) { color: #e7e55e !important; }
|
||||
.status-color-context.project.todo :global(.sccpb) { background-color: #e7e55e !important; }
|
||||
.status-color-context.project.wontdo :global(.sccfg) { color: #7a2973 !important; }
|
||||
.status-color-context.project.wontdo.selected :global(.sccfg) { color: #e75ed0 !important; }
|
||||
.status-color-context.project.wontdo :global(.sccpb) { background-color: #e75ed0 !important; }
|
||||
|
||||
.status-color-context.task.completed :global(.sccsi) { background-color: #484 !important; color: #78ff78 !important; }
|
||||
.status-color-context.task.failed :global(.sccsi) { background-color: #85242c !important; color: #ff4545 !important; }
|
||||
.status-color-context.task.onhold :global(.sccsi) { background-color: #447288 !important; color: #78c9ff !important; }
|
||||
.status-color-context.task.todo :global(.sccsi) { background-color: #7a7429 !important; color: #e7e55e !important; }
|
||||
.status-color-context.task.wontdo :global(.sccsi) { background-color: #7a2973 !important; color: #e75ed0 !important; }
|
||||
</style>
|
||||
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
export let value: string;
|
||||
export let disabled: boolean = false;
|
||||
</script>
|
||||
|
||||
<select name="statusTag" bind:value={value} disabled={disabled}>
|
||||
<option value="" selected={"" === value}>Active / In Progress</option>
|
||||
<option value="completed" selected={"completed" === value}>Completed</option>
|
||||
<option value="failed" selected={"failed" === value}>Failed</option>
|
||||
<option value="on hold" selected={"on hold" === value}>On Hold</option>
|
||||
<option value="to do" selected={"to do" === value}>To Do</option>
|
||||
<option value="declined" selected={"declined" === value}>Won't Do</option>
|
||||
</select>
|
||||
@@ -4,11 +4,12 @@
|
||||
import type { ModalData } from "../stores/modal";
|
||||
import ChildEntry from "./ChildEntry.svelte";
|
||||
import DateSpan from "./DateSpan.svelte";
|
||||
import Icon from "./Icon.svelte";
|
||||
import ItemLink from "./ItemLink.svelte";
|
||||
import Markdown from "./Markdown.svelte";
|
||||
import Markdown from "./Markdown.svelte";
|
||||
import Option from "./Option.svelte";
|
||||
import OptionRow from "./OptionRow.svelte";
|
||||
import StatusColor from "./StatusColor.svelte";
|
||||
import TaskIcon from "./TaskIcon.svelte";
|
||||
|
||||
export let task: TaskResult = null;
|
||||
export let project: Project = null;
|
||||
@@ -28,74 +29,38 @@ import Markdown from "./Markdown.svelte";
|
||||
$: mdTaskDelete = {name: "task.delete", task: {...task, project}};
|
||||
</script>
|
||||
|
||||
<ChildEntry entry={task}>
|
||||
<div slot="icon" class="icon" class:done={!task.active}>
|
||||
{#if !task.active}
|
||||
<span class="on"><Icon block name="check" /></span>
|
||||
<span class="off">
|
||||
{task.completedAmount} / {task.itemAmount}
|
||||
</span>
|
||||
{:else}
|
||||
{task.completedAmount} / {task.itemAmount}
|
||||
{/if}
|
||||
</div>
|
||||
<ItemLink item={task.item} />
|
||||
<OptionRow>
|
||||
{#if task.logs.length > 0}
|
||||
<Option on:click={toggleShowLogs}>{showLogs ? "Hide Logs" : "Show Logs"}</Option>
|
||||
{/if}
|
||||
<Option open={mdLogAdd}>Add Log</Option>
|
||||
{#if showAllOptions}
|
||||
<Option open={mdTaskEdit}>Edit</Option>
|
||||
<Option open={mdTaskDelete}>Delete</Option>
|
||||
{/if}
|
||||
</OptionRow>
|
||||
{#if showLogs && task.logs.length > 0}
|
||||
<div class="log-list">
|
||||
{#each task.logs as log (log.id)}
|
||||
<div class="log">
|
||||
<div class="log-time"><DateSpan time={log.loggedTime} /></div>
|
||||
<div class="log-description">
|
||||
<Markdown source={log.description} />
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
<StatusColor affects="task" entry={task}>
|
||||
<ChildEntry entry={task}>
|
||||
<div slot="icon">
|
||||
<TaskIcon task={task} />
|
||||
</div>
|
||||
{/if}
|
||||
</ChildEntry>
|
||||
<ItemLink item={task.item} />
|
||||
<OptionRow>
|
||||
{#if task.logs.length > 0}
|
||||
<Option on:click={toggleShowLogs}>{showLogs ? "Hide Logs" : "Show Logs"}</Option>
|
||||
{/if}
|
||||
<Option open={mdLogAdd}>Add Log</Option>
|
||||
{#if showAllOptions}
|
||||
<Option open={mdTaskEdit}>Edit</Option>
|
||||
<Option open={mdTaskDelete}>Delete</Option>
|
||||
{/if}
|
||||
</OptionRow>
|
||||
{#if showLogs && task.logs.length > 0}
|
||||
<div class="log-list">
|
||||
{#each task.logs as log (log.id)}
|
||||
<div class="log">
|
||||
<div class="log-time"><DateSpan time={log.loggedTime} /></div>
|
||||
<div class="log-description">
|
||||
<Markdown source={log.description} />
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</ChildEntry>
|
||||
</StatusColor>
|
||||
|
||||
<style>
|
||||
div.icon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 1em;
|
||||
padding: 0.2em .5ch;
|
||||
|
||||
margin-right: 0.5em;
|
||||
background: #444;
|
||||
color: #CCC;
|
||||
}
|
||||
div.icon.done {
|
||||
padding-top: 0.285em;
|
||||
padding-bottom: 0.115em;
|
||||
|
||||
background: #484;
|
||||
color: #78ff78;
|
||||
}
|
||||
div.icon.done span.off {
|
||||
display: none;
|
||||
}
|
||||
div.icon.done:hover {
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
div.icon.done:hover span.on {
|
||||
display: none;
|
||||
}
|
||||
div.icon.done:hover span.off {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.log-list {
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<script lang="ts">
|
||||
import type { IconName } from "../external/icons";
|
||||
|
||||
import type { TaskResult } from "../models/task";
|
||||
import Icon from "./Icon.svelte";
|
||||
|
||||
export let task: TaskResult;
|
||||
export let iconName: IconName;
|
||||
|
||||
$: {
|
||||
switch (task.statusTag) {
|
||||
case "to do": iconName = "lightbulb"; break;
|
||||
case "on hold": iconName = "hourglass"; break;
|
||||
case "declined": iconName = "times"; break;
|
||||
case "failed": iconName = "times"; break;
|
||||
default: iconName = "check"; break;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="icon sccsi" class:inactive={!task.active}>
|
||||
{#if !task.active}
|
||||
<span class="on"><Icon block name={iconName} /></span>
|
||||
<span class="off">
|
||||
{task.completedAmount} / {task.itemAmount}
|
||||
</span>
|
||||
{:else}
|
||||
{task.completedAmount} / {task.itemAmount}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div.icon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 1em;
|
||||
padding: 0.2em .5ch;
|
||||
|
||||
margin-right: 0.5em;
|
||||
background: #444;
|
||||
color: #CCC;
|
||||
}
|
||||
div.icon.inactive {
|
||||
padding-top: 0.295em;
|
||||
padding-bottom: 0.115em;
|
||||
|
||||
background: #484;
|
||||
color: #78ff78;
|
||||
}
|
||||
div.icon.inactive span.off {
|
||||
display: none;
|
||||
}
|
||||
div.icon.inactive:hover {
|
||||
padding-top: 0.16em;
|
||||
padding-bottom: 0.27em;
|
||||
}
|
||||
div.icon.inactive:hover span.on {
|
||||
display: none;
|
||||
}
|
||||
div.icon.inactive:hover span.off {
|
||||
display: inline;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,30 @@
|
||||
<script lang="ts">
|
||||
import type Project from "../models/project";
|
||||
import type { TaskResult } from "../models/task";
|
||||
import TaskEntry from "./TaskEntry.svelte";
|
||||
|
||||
export let project: Project;
|
||||
export let tasks: TaskResult[];
|
||||
export let showAllOptions: boolean;
|
||||
export let header: string;
|
||||
</script>
|
||||
|
||||
{#if tasks.length > 0}
|
||||
<h3>{header}</h3>
|
||||
{#each tasks as task (task.id)}
|
||||
<TaskEntry showAllOptions={showAllOptions} task={task} project={project} />
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
h3:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h3 {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin-top: 0.5em;
|
||||
font-weight: 100;
|
||||
}
|
||||
</style>
|
||||
Vendored
+44
@@ -72,6 +72,28 @@ import { faMoon } from "@fortawesome/free-solid-svg-icons/faMoon";
|
||||
import { faCloudMoon } from "@fortawesome/free-solid-svg-icons/faCloudMoon";
|
||||
import { faChevronRight } from "@fortawesome/free-solid-svg-icons/faChevronRight";
|
||||
import { faChevronDown } from "@fortawesome/free-solid-svg-icons/faChevronDown";
|
||||
import { faFilter } from "@fortawesome/free-solid-svg-icons/faFilter";
|
||||
import { faShoppingBag } from "@fortawesome/free-solid-svg-icons/faShoppingBag";
|
||||
import { faTags } from "@fortawesome/free-solid-svg-icons/faTags";
|
||||
import { faBalanceScale } from "@fortawesome/free-solid-svg-icons/faBalanceScale";
|
||||
import { faSpinner } from "@fortawesome/free-solid-svg-icons/faSpinner";
|
||||
import { faHourglass } from "@fortawesome/free-solid-svg-icons/faHourglass";
|
||||
import { faCalendar } from "@fortawesome/free-solid-svg-icons/faCalendar";
|
||||
import { faWeight } from "@fortawesome/free-solid-svg-icons/faWeight";
|
||||
import { faAnchor } from "@fortawesome/free-solid-svg-icons/faAnchor";
|
||||
import { faAngry } from "@fortawesome/free-solid-svg-icons/faAngry";
|
||||
import { faAnkh } from "@fortawesome/free-solid-svg-icons/faAnkh";
|
||||
import { faDumbbell } from "@fortawesome/free-solid-svg-icons/faDumbbell";
|
||||
import { faDollarSign } from "@fortawesome/free-solid-svg-icons/faDollarSign";
|
||||
import { faExpand } from "@fortawesome/free-solid-svg-icons/faExpand";
|
||||
import { faFeather } from "@fortawesome/free-solid-svg-icons/faFeather";
|
||||
import { faFingerprint } from "@fortawesome/free-solid-svg-icons/faFingerprint";
|
||||
import { faPaintBrush } from "@fortawesome/free-solid-svg-icons/faPaintBrush";
|
||||
import { faPaintRoller } from "@fortawesome/free-solid-svg-icons/faPaintRoller";
|
||||
import { faPastafarianism } from "@fortawesome/free-solid-svg-icons/faPastafarianism";
|
||||
import { faSpider } from "@fortawesome/free-solid-svg-icons/faSpider";
|
||||
import { faStroopwafel } from "@fortawesome/free-solid-svg-icons/faStroopwafel";
|
||||
import { faSearch } from "@fortawesome/free-solid-svg-icons/faSearch";
|
||||
|
||||
const icons = {
|
||||
"question": faQuestion,
|
||||
@@ -148,6 +170,28 @@ const icons = {
|
||||
"cloud_moon": faCloudMoon,
|
||||
"chevron_right": faChevronRight,
|
||||
"chevron_down": faChevronDown,
|
||||
"filter": faFilter,
|
||||
"shopping_bag": faShoppingBag,
|
||||
"tags": faTags,
|
||||
"balance_scale": faBalanceScale,
|
||||
"spinner": faSpinner,
|
||||
"hourglass": faHourglass,
|
||||
"calendar": faCalendar,
|
||||
"weight": faWeight,
|
||||
"anchor": faAnchor,
|
||||
"angry": faAngry,
|
||||
"ankh": faAnkh,
|
||||
"dumbbell": faDumbbell,
|
||||
"dollar_sign": faDollarSign,
|
||||
"expand": faExpand,
|
||||
"feather": faFeather,
|
||||
"fingerprint": faFingerprint,
|
||||
"paint_brush": faPaintBrush,
|
||||
"paint_roller": faPaintRoller,
|
||||
"pastafarianism": faPastafarianism,
|
||||
"spider": faSpider,
|
||||
"stroopwafel": faStroopwafel,
|
||||
"bottle_opener": faSearch,
|
||||
};
|
||||
|
||||
export type IconName = keyof typeof icons;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import Checkbox from "../components/Checkbox.svelte";
|
||||
import IconSelect from "../components/IconSelect.svelte";
|
||||
import Modal from "../components/Modal.svelte";
|
||||
import StatusTagSelect from "../components/StatusTagSelect.svelte";
|
||||
import { iconNames } from "../external/icons";
|
||||
import type { ProjectResult } from "../models/project";
|
||||
import markStale from "../stores/markStale";
|
||||
@@ -103,13 +104,8 @@
|
||||
<label for="endTime">Deadline (Optional)</label>
|
||||
<input disabled={deletion} name="endTime" type="datetime-local" bind:value={endTime} />
|
||||
<label for="statusTag">Status</label>
|
||||
<select name="statusTag" bind:value={statusTag} disabled={deletion}>
|
||||
<option value="" selected={"" === statusTag}>Active / In Progress</option>
|
||||
<option value="completed" selected={"completed" === statusTag}>Completed</option>
|
||||
<option value="failed" selected={"failed" === statusTag}>Failed</option>
|
||||
<option value="postponed" selected={"postponed" === statusTag}>Postponed</option>
|
||||
<option value="idea" selected={"idea" === statusTag}>Idea</option>
|
||||
</select>
|
||||
<StatusTagSelect disabled={deletion} bind:value={statusTag} />
|
||||
|
||||
<hr />
|
||||
|
||||
<button disabled={loading} type="submit">{verb} Project</button>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import stuffLogClient from "../clients/stufflog";
|
||||
import Checkbox from "../components/Checkbox.svelte";
|
||||
import ItemSelect from "../components/ItemSelect.svelte";
|
||||
import Modal from "../components/Modal.svelte";
|
||||
import StatusTagSelect from "../components/StatusTagSelect.svelte";
|
||||
import { iconNames } from "../external/icons";
|
||||
import type { TaskResult } from "../models/task";
|
||||
import markStale from "../stores/markStale";
|
||||
@@ -26,6 +26,7 @@
|
||||
item: null,
|
||||
logs: [],
|
||||
completedAmount: 0,
|
||||
statusTag: null,
|
||||
}
|
||||
let verb = "Add";
|
||||
if (md.name === "task.edit" || md.name === "task.delete") {
|
||||
@@ -47,7 +48,8 @@
|
||||
let name = task.name;
|
||||
let description = task.description;
|
||||
let itemAmount = task.itemAmount;
|
||||
let completed = !task.active;
|
||||
let statusTag = task.statusTag || "";
|
||||
|
||||
let error = null;
|
||||
let loading = false;
|
||||
|
||||
@@ -59,7 +61,8 @@
|
||||
stuffLogClient.createTask({
|
||||
projectId: task.projectId,
|
||||
itemId: itemId,
|
||||
active: !completed,
|
||||
active: statusTag === "",
|
||||
statusTag: statusTag || null,
|
||||
endTime: (endTime == "") ? null : new Date(endTime),
|
||||
|
||||
name, description, itemAmount,
|
||||
@@ -84,7 +87,9 @@
|
||||
stuffLogClient.updateTask(task.id, {
|
||||
endTime: (endTime == "") ? null : new Date(endTime),
|
||||
clearEndTime: endTime == "",
|
||||
active: !completed,
|
||||
active: statusTag === "",
|
||||
statusTag: statusTag || null,
|
||||
clearStatusTag: statusTag === "",
|
||||
|
||||
itemId, name, description, itemAmount,
|
||||
}).then(() => {
|
||||
@@ -113,7 +118,8 @@
|
||||
<input disabled={deletion} name="itemAmount" type="number" bind:value={itemAmount} />
|
||||
<label for="endTime">Deadline (Optional)</label>
|
||||
<input disabled={deletion} name="endTime" type="datetime-local" bind:value={endTime} />
|
||||
<Checkbox disabled={deletion} bind:checked={completed} label="Task is completed." />
|
||||
<label for="statusTag">Status</label>
|
||||
<StatusTagSelect disabled={deletion} bind:value={statusTag} />
|
||||
|
||||
<hr />
|
||||
|
||||
|
||||
@@ -28,15 +28,10 @@ export interface GoalFilter {
|
||||
export interface GoalResult extends Goal {
|
||||
group: Group
|
||||
items: GoalResultItem[]
|
||||
logs: GoalLogResult[]
|
||||
logs: LogResult[]
|
||||
completedAmount: number
|
||||
}
|
||||
|
||||
export interface GoalLogResult extends LogResult {
|
||||
itemCounted: boolean
|
||||
secondaryItemCounted: boolean
|
||||
}
|
||||
|
||||
interface GoalResultItem extends Item {
|
||||
completedAmount: number
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ export default interface Task {
|
||||
active: boolean
|
||||
createdTime: string
|
||||
endTime?: string
|
||||
statusTag?: string
|
||||
}
|
||||
export interface TaskResult extends Task {
|
||||
item: Item
|
||||
@@ -35,6 +36,7 @@ export interface TaskInput {
|
||||
description: string
|
||||
active: boolean
|
||||
endTime?: string | Date
|
||||
statusTag?: string
|
||||
}
|
||||
|
||||
export interface TaskUpdate {
|
||||
@@ -45,4 +47,6 @@ export interface TaskUpdate {
|
||||
active?: boolean
|
||||
endTime?: string | Date
|
||||
clearEndTime?: boolean
|
||||
statusTag?: string
|
||||
clearStatusTag?: boolean
|
||||
}
|
||||
Reference in New Issue
Block a user