1
Fork 0
mirror of https://github.com/Steffo99/todocolors.git synced 2024-11-22 16:24:19 +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; align-items: center;
min-width: unset; min-width: unset;
width: 240px; width: 240px;
height: 44px; min-height: 44px;
cursor: pointer; cursor: pointer;
} }
@ -17,7 +17,7 @@
.taskDivBack { .taskDivBack {
grid-template-areas: grid-template-areas:
"buttons" "id buttons"
; ;
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
@ -117,3 +117,10 @@
grid-area: buttons; grid-area: buttons;
justify-self: end; 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; let contents;
if(isDisplayingActions) { if(isDisplayingActions) {
contents = <div className={style.taskButtons}> contents = <>
<button> <small className={style.taskId}>
<FontAwesomeIcon icon={faTrashCanArrowUp}/>&nbsp;Ricrea <code>
</button> {task.id}
</div> </code>
</small>
<div className={style.taskButtons}>
<RecreateButton task={task}/>
</div>
</>
} }
else { else {
contents = <> contents = <>
@ -71,3 +76,20 @@ export function TaskDisplay({task}: {task: TaskWithId}) {
</div> </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": [ "Task": [
string, string,
Task, Task,
] | [
null,
Task,
] | [
string,
null,
] ]
} }

View file

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

View file

@ -3,6 +3,7 @@
import {TASK_GROUPERS} from "@/app/board/[board]/doTaskGrouping" import {TASK_GROUPERS} from "@/app/board/[board]/doTaskGrouping"
import {TASK_SORTERS} from "@/app/board/[board]/doTaskSorting" import {TASK_SORTERS} from "@/app/board/[board]/doTaskSorting"
import {BoardAction, Task} from "@/app/board/[board]/Types" import {BoardAction, Task} from "@/app/board/[board]/Types"
import {useBoardTaskEditor} from "@/app/board/[board]/useBoardTaskEditor"
import {useBoardWebSocket} from "@/app/board/[board]/useBoardWebSocket" import {useBoardWebSocket} from "@/app/board/[board]/useBoardWebSocket"
import {TaskGroup, useBoardTaskArranger} from "@/app/board/[board]/useBoardTaskArranger" import {TaskGroup, useBoardTaskArranger} from "@/app/board/[board]/useBoardTaskArranger"
import {useBoardTitleEditor} from "@/app/board/[board]/useBoardTitleEditor" import {useBoardTitleEditor} from "@/app/board/[board]/useBoardTitleEditor"
@ -27,6 +28,10 @@ export interface UseBoardReturns {
editTitle: string, editTitle: string,
setEditTitle: Dispatch<SetStateAction<string>>, setEditTitle: Dispatch<SetStateAction<string>>,
send: (action: BoardAction) => void, send: (action: BoardAction) => void,
editedTaskText: string,
setEditedTaskText: (text: string) => void,
editedTask: Task,
setEditedTask: (task: Task) => void,
} }
export function useBoard(name: string): UseBoardReturns { 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 {taskGroups} = useBoardTaskArranger(tasksById, taskGrouper, groupSorter, groupNamer, taskSorter);
const {isEditingTitle, stopEditingTitle, startEditingTitle, toggleEditingTitle, editTitle, setEditTitle} = useBoardTitleEditor(title, send); const {isEditingTitle, stopEditingTitle, startEditingTitle, toggleEditingTitle, editTitle, setEditTitle} = useBoardTitleEditor(title, send);
const {editedTaskText, setEditedTaskText, editedTask, setEditedTask} = useBoardTaskEditor()
return { return {
title, title,
tasksById, tasksById,
@ -56,5 +63,9 @@ export function useBoard(name: string): UseBoardReturns {
editTitle, editTitle,
setEditTitle, setEditTitle,
send, 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" import {useCallback, useMemo, useState} from "react"
const PRIORITY_RE = /[^][1-5]\b/ const PRIORITY_RE = /\^[1-5]\s?/
const IMPORTANCE_RE = /![1-5]\b/ const IMPORTANCE_RE = /![1-5]\s?/
const ICON_RE = /\[[A-Za-z]+]\b/ const ICON_RE = /\[([A-Za-z]+)]\s?/
const MATCH_TO_IMPORTANCE = { const MATCH_TO_IMPORTANCE: {[key: string]: TaskImportance} = {
"!1": "Lowest", "!1": "Lowest",
"!2": "Low", "!2": "Low",
"!3": "Normal", "!3": "Normal",
@ -14,7 +14,15 @@ const MATCH_TO_IMPORTANCE = {
"!5": "Highest", "!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", "^1": "Lowest",
"^2": "Low", "^2": "Low",
"^3": "Normal", "^3": "Normal",
@ -22,7 +30,15 @@ const MATCH_TO_PRIORITY = {
"^5": "Highest", "^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", "user": "User",
"image": "Image", "image": "Image",
"envelope": "Envelope", "envelope": "Envelope",
@ -46,19 +62,22 @@ const MATCH_TO_ICON = {
"moon": "Moon", "moon": "Moon",
} }
export function rawToEvent(raw: string): Task { function rawToTask(raw: string): Task {
const priorityMatch = raw.match(PRIORITY_RE) const priorityMatch = PRIORITY_RE.exec(raw)
const importanceMatch = raw.match(IMPORTANCE_RE) const importanceMatch = IMPORTANCE_RE.exec(raw)
const iconMatch = raw.match(ICON_RE) const iconMatch = ICON_RE.exec(raw)
const priority = MATCH_TO_PRIORITY[priorityMatch?.[0]]; // @ts-ignore TS2538
const importance = MATCH_TO_IMPORTANCE[importanceMatch?.[0]]; const priority = MATCH_TO_PRIORITY[priorityMatch?.[0]?.trim()] ?? "Normal";
const icon = MATCH_TO_ICON[iconMatch?.[0]?.toLowerCase()] // @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 // TODO: Splice so the regex aren't executed twice
raw = raw.replace(PRIORITY_RE, "") raw = raw?.replace(PRIORITY_RE, "")
raw = raw.replace(IMPORTANCE_RE, "") raw = raw?.replace(IMPORTANCE_RE, "")
raw = raw.replace(ICON_RE, "") raw = raw?.replace(ICON_RE, "")
raw = raw.trim() 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() { 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) => { const setEditedTask = useCallback((t: Task) => {
setRaw("") // TODO setEditedTaskText(taskToRaw(t))
}, []) }, [])
return {editedTaskText, setEditedTaskText, editedTask, setEditedTask}
} }