1
Fork 0
mirror of https://github.com/Steffo99/todocolors.git synced 2024-11-25 17:54:18 +00:00

Implement task editor and other things

This commit is contained in:
Steffo 2023-08-04 13:06:16 +02:00
parent eee5904c08
commit b73dc41b70
Signed by: steffo
GPG key ID: 2A24051445686895
7 changed files with 119 additions and 28 deletions

View file

@ -0,0 +1,19 @@
import {useManagedBoard} from "@/app/board/[board]/BoardManager"
import {FormEvent, useCallback} from "react"
export function BoardTaskEditForm() {
const {editedTaskText, setEditedTaskText, editedTask, send} = useManagedBoard()
const submitTask = useCallback((e: FormEvent) => {
e.preventDefault();
send({"Task": [null, editedTask]});
setEditedTaskText("")
}, [send, editedTask])
return (
<form onSubmit={submitTask}>
<input type={"text"} placeholder={"What to do...?"} value={editedTaskText} onChange={(e) => setEditedTaskText(e.target.value)}/>
</form>
)
}

View file

@ -3,7 +3,7 @@
align-items: center;
min-width: unset;
width: 240px;
height: 44px;
min-height: 44px;
cursor: pointer;
}
@ -17,7 +17,7 @@
.taskDivBack {
grid-template-areas:
"buttons"
"id buttons"
;
grid-template-columns: 1fr;
}
@ -117,3 +117,10 @@
grid-area: buttons;
justify-self: end;
}
.taskId {
grid-area: id;
font-size: xx-small;
word-break: break-all;
}

View file

@ -27,11 +27,16 @@ export function TaskDisplay({task}: {task: TaskWithId}) {
let contents;
if(isDisplayingActions) {
contents = <div className={style.taskButtons}>
<button>
<FontAwesomeIcon icon={faTrashCanArrowUp}/>&nbsp;Ricrea
</button>
contents = <>
<small className={style.taskId}>
<code>
{task.id}
</code>
</small>
<div className={style.taskButtons}>
<RecreateButton task={task}/>
</div>
</>
}
else {
contents = <>
@ -71,3 +76,20 @@ export function TaskDisplay({task}: {task: TaskWithId}) {
</div>
)
}
function RecreateButton({task}: {task: TaskWithId}) {
const {setEditedTask, send} = useManagedBoard()
const id = task.id;
const recreateTask = useCallback(() => {
setEditedTask(task)
send({"Task": [id, null]})
}, [send, id])
return (
<button onClick={recreateTask}>
<FontAwesomeIcon icon={faTrashCanArrowUp}/>&nbsp;Ricrea
</button>
)
}

View file

@ -60,6 +60,12 @@ export type TaskBoardAction = {
"Task": [
string,
Task,
] | [
null,
Task,
] | [
string,
null,
]
}

View file

@ -3,6 +3,7 @@
import {BoardMain} from "@/app/board/[board]/BoardMain"
import {BoardManager} from "@/app/board/[board]/BoardManager"
import {BoardHeader} from "@/app/board/[board]/BoardHeader"
import {BoardTaskEditForm} from "@/app/board/[board]/BoardTaskEditForm"
export default function Page({params: {board}}: {params: {board: string}}) {
@ -10,6 +11,7 @@ export default function Page({params: {board}}: {params: {board: string}}) {
<BoardManager name={board}>
<BoardHeader/>
<BoardMain/>
<BoardTaskEditForm/>
</BoardManager>
)
}

View file

@ -3,6 +3,7 @@
import {TASK_GROUPERS} from "@/app/board/[board]/doTaskGrouping"
import {TASK_SORTERS} from "@/app/board/[board]/doTaskSorting"
import {BoardAction, Task} from "@/app/board/[board]/Types"
import {useBoardTaskEditor} from "@/app/board/[board]/useBoardTaskEditor"
import {useBoardWebSocket} from "@/app/board/[board]/useBoardWebSocket"
import {TaskGroup, useBoardTaskArranger} from "@/app/board/[board]/useBoardTaskArranger"
import {useBoardTitleEditor} from "@/app/board/[board]/useBoardTitleEditor"
@ -27,6 +28,10 @@ export interface UseBoardReturns {
editTitle: string,
setEditTitle: Dispatch<SetStateAction<string>>,
send: (action: BoardAction) => void,
editedTaskText: string,
setEditedTaskText: (text: string) => void,
editedTask: Task,
setEditedTask: (task: Task) => void,
}
export function useBoard(name: string): UseBoardReturns {
@ -38,6 +43,8 @@ export function useBoard(name: string): UseBoardReturns {
const {taskGroups} = useBoardTaskArranger(tasksById, taskGrouper, groupSorter, groupNamer, taskSorter);
const {isEditingTitle, stopEditingTitle, startEditingTitle, toggleEditingTitle, editTitle, setEditTitle} = useBoardTitleEditor(title, send);
const {editedTaskText, setEditedTaskText, editedTask, setEditedTask} = useBoardTaskEditor()
return {
title,
tasksById,
@ -56,5 +63,9 @@ export function useBoard(name: string): UseBoardReturns {
editTitle,
setEditTitle,
send,
editedTaskText,
setEditedTaskText,
editedTask,
setEditedTask,
}
}

View file

@ -1,12 +1,12 @@
import {Task} from "@/app/board/[board]/Types"
import {Task, TaskIcon, TaskImportance, TaskPriority} from "@/app/board/[board]/Types"
import {useCallback, useMemo, useState} from "react"
const PRIORITY_RE = /[^][1-5]\b/
const IMPORTANCE_RE = /![1-5]\b/
const ICON_RE = /\[[A-Za-z]+]\b/
const PRIORITY_RE = /\^[1-5]\s?/
const IMPORTANCE_RE = /![1-5]\s?/
const ICON_RE = /\[([A-Za-z]+)]\s?/
const MATCH_TO_IMPORTANCE = {
const MATCH_TO_IMPORTANCE: {[key: string]: TaskImportance} = {
"!1": "Lowest",
"!2": "Low",
"!3": "Normal",
@ -14,7 +14,15 @@ const MATCH_TO_IMPORTANCE = {
"!5": "Highest",
}
const MATCH_TO_PRIORITY = {
const IMPORTANCE_TO_MATCH: {[key in TaskImportance]: string} = {
"Lowest": "!1",
"Low": "!2",
"Normal": "!3",
"High": "!4",
"Highest": "!5",
}
const MATCH_TO_PRIORITY: {[key: string]: TaskPriority} = {
"^1": "Lowest",
"^2": "Low",
"^3": "Normal",
@ -22,7 +30,15 @@ const MATCH_TO_PRIORITY = {
"^5": "Highest",
}
const MATCH_TO_ICON = {
const PRIORITY_TO_MATCH: {[key in TaskPriority]: string} = {
"Lowest": "^1",
"Low": "^2",
"Normal": "^3",
"High": "^4",
"Highest": "^5",
}
const MATCH_TO_ICON: {[key: string]: TaskIcon} = {
"user": "User",
"image": "Image",
"envelope": "Envelope",
@ -46,19 +62,22 @@ const MATCH_TO_ICON = {
"moon": "Moon",
}
export function rawToEvent(raw: string): Task {
const priorityMatch = raw.match(PRIORITY_RE)
const importanceMatch = raw.match(IMPORTANCE_RE)
const iconMatch = raw.match(ICON_RE)
function rawToTask(raw: string): Task {
const priorityMatch = PRIORITY_RE.exec(raw)
const importanceMatch = IMPORTANCE_RE.exec(raw)
const iconMatch = ICON_RE.exec(raw)
const priority = MATCH_TO_PRIORITY[priorityMatch?.[0]];
const importance = MATCH_TO_IMPORTANCE[importanceMatch?.[0]];
const icon = MATCH_TO_ICON[iconMatch?.[0]?.toLowerCase()]
// @ts-ignore TS2538
const priority = MATCH_TO_PRIORITY[priorityMatch?.[0]?.trim()] ?? "Normal";
// @ts-ignore TS2538
const importance = MATCH_TO_IMPORTANCE[importanceMatch?.[0]?.trim()] ?? "Normal";
// @ts-ignore TS2538
const icon = MATCH_TO_ICON[iconMatch?.[1]?.trim()?.toLowerCase()] ?? "Circle";
// TODO: Splice so the regex aren't executed twice
raw = raw.replace(PRIORITY_RE, "")
raw = raw.replace(IMPORTANCE_RE, "")
raw = raw.replace(ICON_RE, "")
raw = raw?.replace(PRIORITY_RE, "")
raw = raw?.replace(IMPORTANCE_RE, "")
raw = raw?.replace(ICON_RE, "")
raw = raw.trim()
@ -71,13 +90,18 @@ export function rawToEvent(raw: string): Task {
}
}
function taskToRaw(task: Task): string {
return `[${task.icon}] ${IMPORTANCE_TO_MATCH[task.importance]} ${PRIORITY_TO_MATCH[task.priority]} ${task.text}`
}
export function useBoardTaskEditor() {
const [raw, setRaw] = useState<string>();
const [editedTaskText, setEditedTaskText] = useState<string>("");
const task = useMemo(() => rawToEvent(raw), [raw])
const editedTask = useMemo(() => rawToTask(editedTaskText), [editedTaskText])
const setTask = useCallback((t: Task) => {
setRaw("") // TODO
const setEditedTask = useCallback((t: Task) => {
setEditedTaskText(taskToRaw(t))
}, [])
return {editedTaskText, setEditedTaskText, editedTask, setEditedTask}
}