feat: add task sets functionality with CRUD operations and UI integration
- Implemented NewTaskSetPage for creating task sets with templates. - Created TaskSetsPage for listing and filtering task sets. - Enhanced TaskTemplatesPage with navigation to task sets. - Updated ProjectTaskForm to support task set selection. - Modified PageHeader to support multiple action buttons. - Initialized database with task_sets and task_set_templates tables. - Added queries for task sets including creation, retrieval, and deletion. - Implemented applyTaskSetToProject function for bulk task creation. - Added test script for verifying task sets functionality.
This commit is contained in:
@@ -413,3 +413,192 @@ export function updateProjectTask(taskId, updates, userId = null) {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ===== TASK SETS =====
|
||||
|
||||
// Get all task sets
|
||||
export function getAllTaskSets() {
|
||||
const taskSets = db
|
||||
.prepare("SELECT * FROM task_sets ORDER BY name ASC")
|
||||
.all();
|
||||
|
||||
// Add templates to each task set
|
||||
return taskSets.map(taskSet => {
|
||||
const templates = db
|
||||
.prepare(`
|
||||
SELECT
|
||||
tst.sort_order,
|
||||
t.task_id,
|
||||
t.name,
|
||||
t.max_wait_days,
|
||||
t.description
|
||||
FROM task_set_templates tst
|
||||
JOIN tasks t ON tst.task_template_id = t.task_id
|
||||
WHERE tst.set_id = ?
|
||||
ORDER BY tst.sort_order ASC
|
||||
`)
|
||||
.all(taskSet.set_id);
|
||||
|
||||
return { ...taskSet, templates };
|
||||
});
|
||||
}
|
||||
|
||||
// Get task sets by task category
|
||||
export function getTaskSetsByTaskCategory(taskCategory) {
|
||||
const taskSets = db
|
||||
.prepare("SELECT * FROM task_sets WHERE task_category = ? ORDER BY name ASC")
|
||||
.all(taskCategory);
|
||||
|
||||
// Add templates to each task set
|
||||
return taskSets.map(taskSet => {
|
||||
const templates = db
|
||||
.prepare(`
|
||||
SELECT
|
||||
tst.sort_order,
|
||||
t.task_id,
|
||||
t.name,
|
||||
t.max_wait_days,
|
||||
t.description
|
||||
FROM task_set_templates tst
|
||||
JOIN tasks t ON tst.task_template_id = t.task_id
|
||||
WHERE tst.set_id = ?
|
||||
ORDER BY tst.sort_order ASC
|
||||
`)
|
||||
.all(taskSet.set_id);
|
||||
|
||||
return { ...taskSet, templates };
|
||||
});
|
||||
}
|
||||
|
||||
// Get task set by ID with templates
|
||||
export function getTaskSetById(setId) {
|
||||
const taskSet = db
|
||||
.prepare("SELECT * FROM task_sets WHERE set_id = ?")
|
||||
.get(setId);
|
||||
|
||||
if (taskSet) {
|
||||
const templates = db
|
||||
.prepare(`
|
||||
SELECT
|
||||
tst.sort_order,
|
||||
t.task_id,
|
||||
t.name,
|
||||
t.max_wait_days,
|
||||
t.description
|
||||
FROM task_set_templates tst
|
||||
JOIN tasks t ON tst.task_template_id = t.task_id
|
||||
WHERE tst.set_id = ?
|
||||
ORDER BY tst.sort_order ASC
|
||||
`)
|
||||
.all(setId);
|
||||
|
||||
return { ...taskSet, templates };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create a new task set
|
||||
export function createTaskSet(data) {
|
||||
const result = db
|
||||
.prepare(`
|
||||
INSERT INTO task_sets (name, description, task_category, created_at, updated_at)
|
||||
VALUES (?, ?, ?, datetime('now', 'localtime'), datetime('now', 'localtime'))
|
||||
`)
|
||||
.run(data.name, data.description || null, data.task_category);
|
||||
|
||||
return result.lastInsertRowid;
|
||||
}
|
||||
|
||||
// Update a task set
|
||||
export function updateTaskSet(setId, data) {
|
||||
const fields = [];
|
||||
const values = [];
|
||||
|
||||
if (data.name !== undefined) {
|
||||
fields.push("name = ?");
|
||||
values.push(data.name);
|
||||
}
|
||||
|
||||
if (data.description !== undefined) {
|
||||
fields.push("description = ?");
|
||||
values.push(data.description || null);
|
||||
}
|
||||
|
||||
if (data.task_category !== undefined) {
|
||||
fields.push("task_category = ?");
|
||||
values.push(data.task_category);
|
||||
}
|
||||
|
||||
fields.push("updated_at = datetime('now', 'localtime')");
|
||||
values.push(setId);
|
||||
|
||||
const stmt = db.prepare(`
|
||||
UPDATE task_sets
|
||||
SET ${fields.join(", ")}
|
||||
WHERE set_id = ?
|
||||
`);
|
||||
|
||||
return stmt.run(...values);
|
||||
}
|
||||
|
||||
// Delete a task set
|
||||
export function deleteTaskSet(setId) {
|
||||
// Delete task set templates first (cascade should handle this, but being explicit)
|
||||
db.prepare("DELETE FROM task_set_templates WHERE set_id = ?").run(setId);
|
||||
|
||||
// Delete the task set
|
||||
return db.prepare("DELETE FROM task_sets WHERE set_id = ?").run(setId);
|
||||
}
|
||||
|
||||
// Add task template to set
|
||||
export function addTaskTemplateToSet(setId, taskTemplateId, sortOrder = 0) {
|
||||
return db
|
||||
.prepare(`
|
||||
INSERT OR REPLACE INTO task_set_templates (set_id, task_template_id, sort_order)
|
||||
VALUES (?, ?, ?)
|
||||
`)
|
||||
.run(setId, taskTemplateId, sortOrder);
|
||||
}
|
||||
|
||||
// Remove task template from set
|
||||
export function removeTaskTemplateFromSet(setId, taskTemplateId) {
|
||||
return db
|
||||
.prepare(`
|
||||
DELETE FROM task_set_templates
|
||||
WHERE set_id = ? AND task_template_id = ?
|
||||
`)
|
||||
.run(setId, taskTemplateId);
|
||||
}
|
||||
|
||||
// Apply task set to project (bulk create project tasks)
|
||||
export function applyTaskSetToProject(setId, projectId, userId = null) {
|
||||
// Get the task set with templates
|
||||
const taskSet = getTaskSetById(setId);
|
||||
if (!taskSet) {
|
||||
throw new Error(`Task set with ID ${setId} not found`);
|
||||
}
|
||||
|
||||
const createdTasks = [];
|
||||
const language = getUserLanguage();
|
||||
|
||||
// Create project tasks for each template in the set
|
||||
for (const template of taskSet.templates) {
|
||||
const result = createProjectTask({
|
||||
project_id: projectId,
|
||||
task_template_id: template.task_id,
|
||||
status: "pending",
|
||||
priority: "normal",
|
||||
created_by: userId,
|
||||
assigned_to: null, // Will be assigned based on user role logic in createProjectTask
|
||||
});
|
||||
|
||||
createdTasks.push(result.lastInsertRowid);
|
||||
|
||||
// Add system note for task set application
|
||||
const logMessage = `${serverT("Task added from set", language)} "${taskSet.name}"`;
|
||||
addNoteToTask(result.lastInsertRowid, logMessage, true, userId);
|
||||
}
|
||||
|
||||
return createdTasks;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user