feat: Enhance note creation and project cancellation with user information and translations

This commit is contained in:
2025-09-18 11:11:22 +02:00
parent 1a49919000
commit 8964a9b29b
6 changed files with 52 additions and 6 deletions

View File

@@ -73,6 +73,20 @@ async function createNoteHandler(req) {
) )
.run(project_id || null, task_id || null, note, req.user?.id || null); .run(project_id || null, task_id || null, note, req.user?.id || null);
// Get the created note with user info
const createdNote = db
.prepare(
`
SELECT n.*,
u.name as created_by_name,
u.username as created_by_username
FROM notes n
LEFT JOIN users u ON n.created_by = u.id
WHERE n.note_id = ?
`
)
.get(result.lastInsertRowid);
// Log note creation // Log note creation
await logApiActionSafe( await logApiActionSafe(
req, req,
@@ -85,7 +99,7 @@ async function createNoteHandler(req) {
} }
); );
return NextResponse.json({ success: true }); return NextResponse.json(createdNote);
} catch (error) { } catch (error) {
console.error("Error creating note:", error); console.error("Error creating note:", error);
return NextResponse.json( return NextResponse.json(

View File

@@ -17,6 +17,7 @@ import {
AUDIT_ACTIONS, AUDIT_ACTIONS,
RESOURCE_TYPES, RESOURCE_TYPES,
} from "@/lib/auditLogSafe.js"; } from "@/lib/auditLogSafe.js";
import { getUserLanguage, serverT } from "@/lib/serverTranslations";
// Make sure the DB is initialized before queries run // Make sure the DB is initialized before queries run
initializeDatabase(); initializeDatabase();
@@ -86,7 +87,8 @@ async function updateProjectHandler(req, { params }) {
minute: '2-digit' minute: '2-digit'
}); });
const cancellationNote = `Projekt został wycofany w dniu ${cancellationDate}`; const language = getUserLanguage();
const cancellationNote = `${serverT("Project cancelled on", language)} ${cancellationDate}`;
try { try {
addNoteToProject(parseInt(id), cancellationNote, userId, true); // true for is_system addNoteToProject(parseInt(id), cancellationNote, userId, true); // true for is_system

View File

@@ -24,6 +24,11 @@ export default function ProjectViewPage() {
const [notes, setNotes] = useState([]); const [notes, setNotes] = useState([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
// Helper function to add a new note to the list
const addNote = (newNote) => {
setNotes(prevNotes => [newNote, ...prevNotes]);
};
// Helper function to check if user can delete a note // Helper function to check if user can delete a note
const canDeleteNote = (note) => { const canDeleteNote = (note) => {
if (!session?.user) return false; if (!session?.user) return false;
@@ -597,7 +602,7 @@ export default function ProjectViewPage() {
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="mb-6"> <div className="mb-6">
<NoteForm projectId={params.id} /> <NoteForm projectId={params.id} onNoteAdded={addNote} />
</div> </div>
{notes.length === 0 ? ( {notes.length === 0 ? (
<div className="text-center py-12"> <div className="text-center py-12">

View File

@@ -3,7 +3,7 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { useTranslation } from "@/lib/i18n"; import { useTranslation } from "@/lib/i18n";
export default function NoteForm({ projectId }) { export default function NoteForm({ projectId, onNoteAdded }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [note, setNote] = useState(""); const [note, setNote] = useState("");
const [status, setStatus] = useState(null); const [status, setStatus] = useState(null);
@@ -18,19 +18,33 @@ export default function NoteForm({ projectId }) {
}); });
if (res.ok) { if (res.ok) {
const newNote = await res.json();
setNote(""); setNote("");
setStatus(t("common.addNoteSuccess")); setStatus(t("common.addNoteSuccess"));
window.location.reload(); // Call the callback to add the new note to the parent component's state
if (onNoteAdded) {
onNoteAdded(newNote);
}
// Clear status message after 3 seconds
setTimeout(() => setStatus(null), 3000);
} else { } else {
setStatus(t("common.addNoteError")); setStatus(t("common.addNoteError"));
} }
} }
function handleKeyDown(e) {
if (e.ctrlKey && e.key === 'Enter') {
e.preventDefault();
handleSubmit(e);
}
}
return ( return (
<form onSubmit={handleSubmit} className="space-y-2 mb-4"> <form onSubmit={handleSubmit} className="space-y-2 mb-4">
<textarea <textarea
value={note} value={note}
onChange={(e) => setNote(e.target.value)} onChange={(e) => setNote(e.target.value)}
onKeyDown={handleKeyDown}
placeholder={t("common.addNotePlaceholder")} placeholder={t("common.addNotePlaceholder")}
className="border p-2 w-full" className="border p-2 w-full"
rows={3} rows={3}

View File

@@ -125,9 +125,12 @@ export function createProjectTask(data) {
// Add system note for task creation // Add system note for task creation
if (result.lastInsertRowid) { if (result.lastInsertRowid) {
const language = getUserLanguage();
const priority = data.priority || "normal"; const priority = data.priority || "normal";
const status = data.status || "pending"; const status = data.status || "pending";
const logMessage = `Task "${taskName}" created with priority: ${priority}, status: ${status}`; const translatedPriority = translatePriority(priority, language);
const translatedStatus = translateStatus(status, language);
const logMessage = `${serverT("Task created", language)} "${taskName}" ${serverT("with priority", language)}: ${translatedPriority}, ${serverT("status", language)}: ${translatedStatus}`;
addNoteToTask(result.lastInsertRowid, logMessage, true, data.created_by); addNoteToTask(result.lastInsertRowid, logMessage, true, data.created_by);
} }

View File

@@ -11,6 +11,10 @@ const serverTranslations = {
"Date started": "Data rozpoczęcia", "Date started": "Data rozpoczęcia",
"None": "Brak", "None": "Brak",
"Task updated": "Zadanie zaktualizowane", "Task updated": "Zadanie zaktualizowane",
"Task created": "Zadanie utworzone",
"with priority": "z priorytetem",
"status": "status",
"Project cancelled on": "Projekt został wycofany w dniu",
"pending": "oczekujące", "pending": "oczekujące",
"in_progress": "w trakcie", "in_progress": "w trakcie",
"completed": "ukończone", "completed": "ukończone",
@@ -31,6 +35,10 @@ const serverTranslations = {
"Date started": "Date started", "Date started": "Date started",
"None": "None", "None": "None",
"Task updated": "Task updated", "Task updated": "Task updated",
"Task created": "Task created",
"with priority": "with priority",
"status": "status",
"Project cancelled on": "Project cancelled on",
"pending": "pending", "pending": "pending",
"in_progress": "in_progress", "in_progress": "in_progress",
"completed": "completed", "completed": "completed",