feat: implement task API for status retrieval and expand task assignment logic to support custom assignee names

This commit is contained in:
root
2026-03-29 14:33:15 +07:00
parent 99f948ba5d
commit 2a670d80d1
2 changed files with 148 additions and 2 deletions

130
index.php
View File

@@ -7,14 +7,142 @@ $action = (string)($_GET['action'] ?? 'dashboard');
// API updates for task kanban drag n drop
if ($action === 'api') {
$api_action = $_GET['api_action'] ?? '';
if(!isset($_SESSION['user_id'])) die(json_encode(['status'=>'error','msg'=>'unauthorized']));
header('Content-Type: application/json; charset=utf-8');
// Ensure newer task columns exist (API might be called without visiting the tasks page first).
try { $pdo->exec("ALTER TABLE tasks ADD COLUMN assignor_type TEXT DEFAULT 'user'"); } catch(Exception $e) {}
try { $pdo->exec("ALTER TABLE tasks ADD COLUMN assignor_group_id INTEGER"); } catch(Exception $e) {}
try { $pdo->exec("ALTER TABLE tasks ADD COLUMN status_updated_at DATETIME"); } catch(Exception $e) {}
try { $pdo->exec("ALTER TABLE tasks ADD COLUMN due_date DATE"); } catch(Exception $e) {}
try { $pdo->exec("ALTER TABLE tasks ADD COLUMN custom_assignee_name TEXT"); } catch(Exception $e) {}
try { $pdo->exec("CREATE TABLE IF NOT EXISTS task_attachments (id INTEGER PRIMARY KEY AUTOINCREMENT, task_id INTEGER, file_name TEXT, file_path TEXT, owner_id INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP)"); } catch(Exception $e) {}
$format_dt = function($value) {
$value = is_string($value) ? trim($value) : $value;
if(!$value) return null;
$ts = strtotime((string)$value);
if($ts === false) return null;
return date('Y-m-d H:i', $ts);
};
$format_status = function($value) {
if(!$value) return null;
$s = strtolower(trim((string)$value));
if($s === 'in_progress') return 'In Progress';
$s = str_replace('_', ' ', $s);
return ucfirst($s);
};
if($api_action === 'update_task_status') {
if(!isset($_SESSION['user_id'])) die(json_encode(['status'=>'error','msg'=>'unauthorized']));
$task_id = $_POST['task_id'] ?? null;
$status = $_POST['status'] ?? null;
$stmt = $pdo->prepare("UPDATE tasks SET status = ?, status_updated_at = CURRENT_TIMESTAMP WHERE id = ?");
$stmt->execute([$status, $task_id]);
echo json_encode(['status'=>'ok']);
exit;
}
if($api_action === 'get_tasks_status') {
$task_id = $_GET['task_id'] ?? null;
// Correlated subquery gives attachment count per task.
$sql = "
SELECT
t.*,
u.username as assignor_user_name,
g.name as assignor_group_name,
au.username as assignee_user_name,
ag.name as assignee_group_name,
(SELECT COUNT(*) FROM task_attachments ta WHERE ta.task_id = t.id) AS attachments_count
FROM tasks t
LEFT JOIN users u ON t.assignor_id = u.id
LEFT JOIN groups g ON t.assignor_group_id = g.id
LEFT JOIN users au ON (t.assignee_type='user' AND t.assignee_id = au.id)
LEFT JOIN groups ag ON (t.assignee_type='group' AND t.assignee_id = ag.id)
";
$params = [];
if($task_id !== null && $task_id !== '') {
if(!ctype_digit((string)$task_id)) {
echo json_encode(['status'=>'error','msg'=>'Invalid task_id']);
exit;
}
$sql .= " WHERE t.id = ? LIMIT 1";
$params[] = (int)$task_id;
} else {
$sql .= " ORDER BY t.created_at DESC";
}
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$rows = $stmt->fetchAll();
if($task_id !== null && $task_id !== '') {
$row = $rows ? $rows[0] : null;
if(!$row) {
echo json_encode(['status'=>'error','msg'=>'Task not found']);
exit;
}
$from = null;
if(($row['assignor_type'] ?? null) === 'group') $from = $row['assignor_group_name'] ?? null;
elseif(($row['assignor_type'] ?? null) === 'user') $from = $row['assignor_user_name'] ?? null;
$to = null;
if(($row['assignee_type'] ?? null) === 'user') $to = $row['assignee_user_name'] ?? null;
elseif(($row['assignee_type'] ?? null) === 'group') $to = $row['assignee_group_name'] ?? null;
elseif(($row['assignee_type'] ?? null) === 'custom') $to = $row['custom_assignee_name'] ?? null;
$desc = (string)($row['description'] ?? '');
$desc = trim($desc) !== '' ? $desc : (string)($row['title'] ?? '');
$payload = [
'task_id' => (string)$row['id'],
'task_created_date' => $format_dt($row['created_at'] ?? null),
'from' => $from,
'to' => $to,
'task_description' => $desc,
'due_date' => $format_dt($row['due_date'] ?? null),
'current_status' => $format_status($row['status'] ?? null),
'attachments_count' => (int)($row['attachments_count'] ?? 0),
];
echo json_encode($payload);
exit;
}
$result = [];
foreach($rows as $row) {
$from = null;
if(($row['assignor_type'] ?? null) === 'group') $from = $row['assignor_group_name'] ?? null;
elseif(($row['assignor_type'] ?? null) === 'user') $from = $row['assignor_user_name'] ?? null;
$to = null;
if(($row['assignee_type'] ?? null) === 'user') $to = $row['assignee_user_name'] ?? null;
elseif(($row['assignee_type'] ?? null) === 'group') $to = $row['assignee_group_name'] ?? null;
elseif(($row['assignee_type'] ?? null) === 'custom') $to = $row['custom_assignee_name'] ?? null;
$desc = (string)($row['description'] ?? '');
$desc = trim($desc) !== '' ? $desc : (string)($row['title'] ?? '');
$result[] = [
'task_id' => (string)$row['id'],
'task_created_date' => $format_dt($row['created_at'] ?? null),
'from' => $from,
'to' => $to,
'task_description' => $desc,
'due_date' => $format_dt($row['due_date'] ?? null),
'current_status' => $format_status($row['status'] ?? null),
'attachments_count' => (int)($row['attachments_count'] ?? 0),
];
}
echo json_encode($result);
exit;
}
echo json_encode(['status'=>'error','msg'=>'Unknown api_action']);
exit;
}