feat: add task comments feature with CRUD operations

- Introduced a new `task_comments` table in the database schema.
- Implemented task comments API endpoints for listing, creating, and deleting comments.
- Enhanced the task detail dialog to display comments and allow users to add new comments.
- Updated task row component to handle click events for viewing task details.
- Added a theme provider to manage light/dark mode across the application.
- Refactored Milkdown editor to use Crepe for improved markdown editing experience.
- Updated global styles to accommodate new editor and theme changes.
- Enhanced task filtering and sorting functionality in the tasks page.
This commit is contained in:
Roberto Musso
2026-02-23 12:54:14 +01:00
parent 98acf6220e
commit c1aa6829c9
24 changed files with 996 additions and 234 deletions

View File

@@ -141,141 +141,47 @@ body {
overflow: hidden;
}
/* Milkdown editor overrides */
[data-milkdown-root] {
/* Crepe editor layout */
.milkdown-container {
display: flex;
flex-direction: column;
height: 100%;
}
.milkdown {
display: flex;
flex-direction: column;
.milkdown-container .milkdown {
flex: 1;
min-height: 0;
color: var(--foreground);
font-family: inherit;
line-height: 1.75;
--crepe-color-background: var(--background);
--crepe-font-default: 'Geist', 'Inter', system-ui, sans-serif;
--crepe-font-title: 'Geist', 'Inter', system-ui, sans-serif;
}
.milkdown .editor {
/* Override Crepe's default 60px 120px padding for panel use.
Left padding >=72px to leave room for the block handle (plus + drag buttons). */
.milkdown-container .milkdown .ProseMirror {
@apply pr-6 pl-18 py-0;
flex: 1;
outline: none;
padding: 0;
overflow-y: auto;
word-break: break-word;
overflow-wrap: break-word;
}
.milkdown .editor > * + * {
margin-top: 0.75em;
}
.milkdown .editor h1 {
font-size: 1.875rem;
font-weight: 700;
line-height: 1.2;
color: var(--foreground);
}
.milkdown .editor h2 {
font-size: 1.5rem;
font-weight: 600;
line-height: 1.3;
color: var(--foreground);
}
.milkdown .editor h3 {
font-size: 1.25rem;
font-weight: 600;
line-height: 1.4;
color: var(--foreground);
}
.milkdown .editor h4 {
font-size: 1.125rem;
font-weight: 600;
color: var(--foreground);
}
.milkdown .editor h5,
.milkdown .editor h6 {
font-size: 1rem;
font-weight: 600;
color: var(--foreground);
}
.milkdown .editor p {
color: var(--foreground);
}
.milkdown .editor blockquote {
border-left: 3px solid var(--border);
padding-left: 1rem;
color: var(--muted-foreground);
font-style: italic;
}
.milkdown .editor pre {
background: var(--muted);
color: var(--foreground);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 0.75rem 1rem;
overflow-x: auto;
font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
font-size: 0.875rem;
}
.milkdown .editor code {
background: var(--muted);
color: var(--foreground);
padding: 0.125rem 0.375rem;
border-radius: calc(var(--radius) - 4px);
font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
font-size: 0.875em;
}
.milkdown .editor pre code {
background: transparent;
padding: 0;
border-radius: 0;
}
.milkdown .editor ul,
.milkdown .editor ol {
padding-left: 1.5rem;
color: var(--foreground);
}
.milkdown .editor ul {
list-style-type: disc;
}
.milkdown .editor ol {
list-style-type: decimal;
}
.milkdown .editor li + li {
margin-top: 0.25em;
}
.milkdown .editor a {
color: var(--primary);
text-decoration: underline;
text-underline-offset: 2px;
}
.milkdown .editor hr {
border: none;
border-top: 1px solid var(--border);
margin: 1.5em 0;
}
.milkdown .editor strong {
font-weight: 600;
}
.milkdown .editor em {
font-style: italic;
/* Dark theme: scope nord-dark variables under .dark class */
.dark .milkdown {
--crepe-color-on-background: #f8f9ff;
--crepe-color-surface: #111418;
--crepe-color-surface-low: #191c20;
--crepe-color-on-surface: #e1e2e8;
--crepe-color-on-surface-variant: #c3c6cf;
--crepe-color-outline: #8d9199;
--crepe-color-primary: #a1c9fd;
--crepe-color-secondary: #3c4858;
--crepe-color-on-secondary: #d7e3f8;
--crepe-color-inverse: #e1e2e8;
--crepe-color-on-inverse: #2e3135;
--crepe-color-inline-code: #ffb4ab;
--crepe-color-error: #ffb4ab;
--crepe-color-hover: #1d2024;
--crepe-color-selected: #32353a;
--crepe-color-inline-area: #111418;
--crepe-shadow-1: 0px 1px 2px 0px rgba(255, 255, 255, 0.3), 0px 1px 3px 1px rgba(255, 255, 255, 0.15);
--crepe-shadow-2: 0px 1px 2px 0px rgba(255, 255, 255, 0.3), 0px 2px 6px 2px rgba(255, 255, 255, 0.15);
}