Gisle Aune
4 years ago
21 changed files with 347 additions and 166 deletions
-
9database/postgres/tasks.go
-
9migrations/postgres/20210124104325_rename_project_status_tag_todo.sql
-
9migrations/postgres/20210124104330_rename_project_status_tag_onhold.sql
-
11migrations/postgres/20210124105003_add_task_column_status_tag.sql
-
9migrations/postgres/20210124110913_update_task_default_inactive_tag.sql
-
9models/task.go
-
2svelte-ui/src/components/Progress.svelte
-
49svelte-ui/src/components/ProjectEntry.svelte
-
28svelte-ui/src/components/ProjectIcon.svelte
-
2svelte-ui/src/components/QLListItem.svelte
-
10svelte-ui/src/components/QuestLog.svelte
-
64svelte-ui/src/components/StatusColor.svelte
-
13svelte-ui/src/components/StatusTagSelect.svelte
-
53svelte-ui/src/components/TaskEntry.svelte
-
63svelte-ui/src/components/TaskIcon.svelte
-
30svelte-ui/src/components/TaskList.svelte
-
44svelte-ui/src/external/icons.ts
-
10svelte-ui/src/forms/ProjectForm.svelte
-
16svelte-ui/src/forms/TaskForm.svelte
-
7svelte-ui/src/models/goal.ts
-
4svelte-ui/src/models/task.ts
@ -0,0 +1,9 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
UPDATE project SET status_tag='to do' WHERE status_tag='idea'; |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
SELECT 'Nothing to do'; |
|||
-- +goose StatementEnd |
@ -0,0 +1,9 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
UPDATE project SET status_tag='on hold' WHERE status_tag='postponed'; |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
SELECT 'Nothing to do'; |
|||
-- +goose StatementEnd |
@ -0,0 +1,11 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
ALTER TABLE task |
|||
ADD COLUMN status_tag TEXT DEFAULT NULL; |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
ALTER TABLE task |
|||
DROP COLUMN status_tag; |
|||
-- +goose StatementEnd |
@ -0,0 +1,9 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
UPDATE task SET status_tag='completed' WHERE active=false; |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
SELECT 'Nothing to do'; |
|||
-- +goose StatementEnd |
@ -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> |
@ -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> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue