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:
parent
eee5904c08
commit
b73dc41b70
7 changed files with 119 additions and 28 deletions
19
todoblue/src/app/board/[board]/BoardTaskEditForm.tsx
Normal file
19
todoblue/src/app/board/[board]/BoardTaskEditForm.tsx
Normal 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>
|
||||
)
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -27,11 +27,16 @@ export function TaskDisplay({task}: {task: TaskWithId}) {
|
|||
|
||||
let contents;
|
||||
if(isDisplayingActions) {
|
||||
contents = <div className={style.taskButtons}>
|
||||
<button>
|
||||
<FontAwesomeIcon icon={faTrashCanArrowUp}/> 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}/> Ricrea
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -60,6 +60,12 @@ export type TaskBoardAction = {
|
|||
"Task": [
|
||||
string,
|
||||
Task,
|
||||
] | [
|
||||
null,
|
||||
Task,
|
||||
] | [
|
||||
string,
|
||||
null,
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue