Adding priority
This commit is contained in:
parent
09d71b71d8
commit
33f050085c
@ -80,6 +80,9 @@ public class TodosController : ApiController
|
|||||||
|
|
||||||
[JsonPropertyName("created")]
|
[JsonPropertyName("created")]
|
||||||
public long Created { get; init; } = 0;
|
public long Created { get; init; } = 0;
|
||||||
|
|
||||||
|
[JsonPropertyName("priority")]
|
||||||
|
public string? Priority { get; init; }
|
||||||
|
|
||||||
internal ReplaceTodoCommand To(string id) => new(
|
internal ReplaceTodoCommand To(string id) => new(
|
||||||
id,
|
id,
|
||||||
@ -87,6 +90,7 @@ public class TodosController : ApiController
|
|||||||
Project,
|
Project,
|
||||||
Description,
|
Description,
|
||||||
Status,
|
Status,
|
||||||
Created);
|
Created,
|
||||||
|
Priority);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,7 +11,8 @@ namespace Todo.Core.Application.Commands.Todo;
|
|||||||
public record CreateTodoCommand(
|
public record CreateTodoCommand(
|
||||||
[Required] string TodoTitle,
|
[Required] string TodoTitle,
|
||||||
string? TodoProject,
|
string? TodoProject,
|
||||||
string? TodoDescription) : IRequest<TodoViewModel>
|
string? TodoDescription,
|
||||||
|
string? Priority) : IRequest<TodoViewModel>
|
||||||
{
|
{
|
||||||
internal class Handler : IRequestHandler<CreateTodoCommand, TodoViewModel>
|
internal class Handler : IRequestHandler<CreateTodoCommand, TodoViewModel>
|
||||||
{
|
{
|
||||||
@ -41,6 +42,7 @@ public record CreateTodoCommand(
|
|||||||
request.TodoTitle,
|
request.TodoTitle,
|
||||||
request.TodoProject,
|
request.TodoProject,
|
||||||
request.TodoDescription,
|
request.TodoDescription,
|
||||||
|
request.Priority
|
||||||
userId,
|
userId,
|
||||||
DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
|
DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ public record ReplaceTodoCommand(
|
|||||||
string? Project,
|
string? Project,
|
||||||
string? Description,
|
string? Description,
|
||||||
bool Status,
|
bool Status,
|
||||||
long Created) : IRequest<Unit>
|
long Created,
|
||||||
|
string? Priority) : IRequest<Unit>
|
||||||
{
|
{
|
||||||
internal class Handler : IRequestHandler<ReplaceTodoCommand, Unit>
|
internal class Handler : IRequestHandler<ReplaceTodoCommand, Unit>
|
||||||
{
|
{
|
||||||
@ -51,5 +52,6 @@ public record ReplaceTodoCommand(
|
|||||||
Project,
|
Project,
|
||||||
authorId,
|
authorId,
|
||||||
Description,
|
Description,
|
||||||
Created);
|
Created,
|
||||||
|
Priority);
|
||||||
}
|
}
|
@ -7,4 +7,5 @@ public record Todo(
|
|||||||
string? Project,
|
string? Project,
|
||||||
string AuthorId,
|
string AuthorId,
|
||||||
string? Description,
|
string? Description,
|
||||||
long Created);
|
long Created,
|
||||||
|
string? Priority);
|
@ -8,6 +8,7 @@ public interface ITodoRepository
|
|||||||
string title,
|
string title,
|
||||||
string? projectName,
|
string? projectName,
|
||||||
string? description,
|
string? description,
|
||||||
|
string? priority,
|
||||||
string userId,
|
string userId,
|
||||||
long created);
|
long created);
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ public record MongoTodo
|
|||||||
public string? ProjectName { get; set; } = string.Empty;
|
public string? ProjectName { get; set; } = string.Empty;
|
||||||
public string AuthorId { get; set; }
|
public string AuthorId { get; set; }
|
||||||
public long Created { get; set; } = 0;
|
public long Created { get; set; } = 0;
|
||||||
|
public string? Priority { get; set; } = string.Empty;
|
||||||
|
|
||||||
public Core.Entities.Todo To() => new(
|
public Core.Entities.Todo To() => new(
|
||||||
Id,
|
Id,
|
||||||
@ -28,5 +29,6 @@ public record MongoTodo
|
|||||||
ProjectName,
|
ProjectName,
|
||||||
AuthorId,
|
AuthorId,
|
||||||
Description,
|
Description,
|
||||||
Created);
|
Created,
|
||||||
|
Priority);
|
||||||
}
|
}
|
54
src/client/src/components/todos/add/addPriorityButton.tsx
Normal file
54
src/client/src/components/todos/add/addPriorityButton.tsx
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { ButtonHTMLAttributes, FC, useState } from "react";
|
||||||
|
import { OutlinedButton } from "@src/components/common/buttons/outlinedButton";
|
||||||
|
import Tippy from "@tippyjs/react";
|
||||||
|
|
||||||
|
interface AddPriorityButtonProps
|
||||||
|
extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
|
initialPriority?: string;
|
||||||
|
onPriorityChanged: (project: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AddPriorityButton: FC<AddPriorityButtonProps> = (props) => {
|
||||||
|
const [menuIsOpen, setMenuIsOpen] = useState(false);
|
||||||
|
return (
|
||||||
|
<Tippy
|
||||||
|
placement="bottom"
|
||||||
|
visible={menuIsOpen}
|
||||||
|
onClickOutside={() => {
|
||||||
|
setMenuIsOpen(false);
|
||||||
|
}}
|
||||||
|
delay={0}
|
||||||
|
interactive={true}
|
||||||
|
duration={0}
|
||||||
|
content={
|
||||||
|
<div
|
||||||
|
className="py-2 px-2 bg-white dark:bg-gray-700 border border-accent-500 rounded-md flex flex-col gap-4"
|
||||||
|
tabIndex={0}
|
||||||
|
>
|
||||||
|
<div className="space-y-2">
|
||||||
|
{["p1", "p2", "p3"].map((p) => (
|
||||||
|
<div key={p}>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="whitespace-nowrap py-1 px-4 dark:text-white dark:bg-gray-500 rounded-sm"
|
||||||
|
onClick={() => props.onPriorityChanged(p)}
|
||||||
|
>
|
||||||
|
{p}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<OutlinedButton
|
||||||
|
className="whitespace-nowrap"
|
||||||
|
onClick={() => setMenuIsOpen(true)}
|
||||||
|
>
|
||||||
|
{props.children || "Add Priority"}
|
||||||
|
</OutlinedButton>
|
||||||
|
</span>
|
||||||
|
</Tippy>
|
||||||
|
);
|
||||||
|
};
|
@ -4,19 +4,26 @@ import { PrimaryButton } from "@src/components/common/buttons/primaryButton";
|
|||||||
import { TodoShortForm } from "@src/components/todos/collapsed/todoShortForm";
|
import { TodoShortForm } from "@src/components/todos/collapsed/todoShortForm";
|
||||||
|
|
||||||
export const AddTodoForm: FC<{
|
export const AddTodoForm: FC<{
|
||||||
onAdd: (todoName: string, project: string, description: string) => void;
|
onAdd: (
|
||||||
|
todoName: string,
|
||||||
|
project: string,
|
||||||
|
description: string,
|
||||||
|
priority: string
|
||||||
|
) => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
project: string;
|
project: string;
|
||||||
|
priority: string;
|
||||||
}> = ({ onAdd, onClose, ...props }) => {
|
}> = ({ onAdd, onClose, ...props }) => {
|
||||||
const [todoName, setTodoName] = useState("");
|
const [todoName, setTodoName] = useState("");
|
||||||
const [todoDescription, setTodoDescription] = useState("");
|
const [todoDescription, setTodoDescription] = useState("");
|
||||||
const [project, setProject] = useState(props.project);
|
const [project, setProject] = useState(props.project);
|
||||||
|
const [priority, setPriority] = useState(props.priority);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
onSubmit={(e) => {
|
onSubmit={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
onAdd(todoName, project, todoDescription);
|
onAdd(todoName, project, todoDescription, priority);
|
||||||
setTodoName("");
|
setTodoName("");
|
||||||
setTodoDescription("");
|
setTodoDescription("");
|
||||||
}}
|
}}
|
||||||
@ -25,6 +32,8 @@ export const AddTodoForm: FC<{
|
|||||||
<TodoShortForm
|
<TodoShortForm
|
||||||
project={project}
|
project={project}
|
||||||
onProjectChanged={(p) => setProject(p)}
|
onProjectChanged={(p) => setProject(p)}
|
||||||
|
priority={priority}
|
||||||
|
onPriorityChanged={setPriority}
|
||||||
name={todoName}
|
name={todoName}
|
||||||
onNameChange={(e) => setTodoName(e.target.value)}
|
onNameChange={(e) => setTodoName(e.target.value)}
|
||||||
description={todoDescription}
|
description={todoDescription}
|
||||||
|
@ -22,8 +22,9 @@ export function AddTodo(props: { project: string }) {
|
|||||||
return (
|
return (
|
||||||
<AddTodoForm
|
<AddTodoForm
|
||||||
project={props.project}
|
project={props.project}
|
||||||
onAdd={(todoName, project, description) => {
|
priority={""}
|
||||||
createTodo(todoName, project, description);
|
onAdd={(todoName, project, description, priority) => {
|
||||||
|
createTodo(todoName, description, project, priority);
|
||||||
}}
|
}}
|
||||||
onClose={() => setCollapsed(CollapsedState.collapsed)}
|
onClose={() => setCollapsed(CollapsedState.collapsed)}
|
||||||
/>
|
/>
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import TextareaAutosize from "react-textarea-autosize";
|
import TextareaAutosize from "react-textarea-autosize";
|
||||||
import { AddProjectButton } from "@src/components/todos/add/addProjectButton";
|
import { AddProjectButton } from "@src/components/todos/add/addProjectButton";
|
||||||
|
import { AddPriorityButton } from "@src/components/todos/add/addPriorityButton";
|
||||||
|
|
||||||
export const TodoShortForm = (props: {
|
export const TodoShortForm = (props: {
|
||||||
project: string;
|
project: string;
|
||||||
onProjectChanged: (project: string) => void;
|
onProjectChanged: (project: string) => void;
|
||||||
|
priority: string;
|
||||||
|
onPriorityChanged: (project: string) => void;
|
||||||
name: string;
|
name: string;
|
||||||
onNameChange: (e) => void;
|
onNameChange: (e) => void;
|
||||||
description: string;
|
description: string;
|
||||||
@ -34,20 +37,24 @@ export const TodoShortForm = (props: {
|
|||||||
minRows={3}
|
minRows={3}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row pb-1">
|
<div className="flex flex-col sm:flex-row pb-1 gap-2 justify-between">
|
||||||
<AddProjectButton
|
<div>
|
||||||
onProjectChanged={props.onProjectChanged}
|
<AddProjectButton
|
||||||
initialProject={props.project}
|
onProjectChanged={props.onProjectChanged}
|
||||||
>
|
initialProject={props.project}
|
||||||
{props.project}
|
>
|
||||||
</AddProjectButton>
|
{props.project}
|
||||||
<AddProjectButton
|
</AddProjectButton>
|
||||||
onProjectChanged={props.onProjectChanged}
|
</div>
|
||||||
initialProject={props.project}
|
|
||||||
>
|
<div>
|
||||||
{props.project}
|
<AddPriorityButton
|
||||||
</AddProjectButton>
|
onPriorityChanged={props.onPriorityChanged}
|
||||||
<div className="flex-grow w-1/2" />
|
initialPriority={props.priority}
|
||||||
|
>
|
||||||
|
{props.priority}
|
||||||
|
</AddPriorityButton>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -14,6 +14,7 @@ export interface Todo {
|
|||||||
project?: string;
|
project?: string;
|
||||||
authorId?: string;
|
authorId?: string;
|
||||||
created: number;
|
created: number;
|
||||||
|
priority?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const asTodo = (item: Todo): Todo => {
|
export const asTodo = (item: Todo): Todo => {
|
||||||
|
@ -55,7 +55,7 @@ const HomePage = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
{data && data.length === 0 && (
|
{onlyActiveTodos && onlyActiveTodos.length === 0 && (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<PageHeading title="You're done!" />
|
<PageHeading title="You're done!" />
|
||||||
<AddTodo project={""} />
|
<AddTodo project={""} />
|
||||||
|
@ -18,7 +18,12 @@ export const useCreateTodo = () => {
|
|||||||
const [createTodo, { isLoading }] = todosApi.useCreateTodoMutation();
|
const [createTodo, { isLoading }] = todosApi.useCreateTodoMutation();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createTodo: (todoName: string, project: string, description: string) => {
|
createTodo: (
|
||||||
|
todoName: string,
|
||||||
|
description: string,
|
||||||
|
project?: string,
|
||||||
|
priority?: string
|
||||||
|
) => {
|
||||||
createTodo({
|
createTodo({
|
||||||
id: nanoid(),
|
id: nanoid(),
|
||||||
created: 0,
|
created: 0,
|
||||||
@ -26,6 +31,7 @@ export const useCreateTodo = () => {
|
|||||||
title: todoName,
|
title: todoName,
|
||||||
project,
|
project,
|
||||||
description,
|
description,
|
||||||
|
priority,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user