feat: implement task API for status retrieval and expand task assignment logic to support custom assignee names
This commit is contained in:
130
index.php
130
index.php
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +176,17 @@ $all_g = query("SELECT id, name FROM groups")->fetchAll();
|
||||
|
||||
$group_in = implode(',', array_fill(0, count($my_group_ids), '?')) ?: '0';
|
||||
|
||||
$params = array_merge([$user_id], $my_group_ids, $my_group_ids, [$user_id]);
|
||||
$custom_tokens = [];
|
||||
if(!empty($current_user['username'])) $custom_tokens[] = (string)$current_user['username'];
|
||||
foreach($user_groups as $g) {
|
||||
if(!empty($g['name'])) $custom_tokens[] = (string)$g['name'];
|
||||
}
|
||||
$custom_tokens = array_values(array_unique(array_filter(array_map('trim', $custom_tokens), fn($v) => $v !== '')));
|
||||
|
||||
$custom_in = implode(',', array_fill(0, count($custom_tokens), '?')) ?: '0';
|
||||
$custom_like = $custom_tokens ? implode(' OR ', array_fill(0, count($custom_tokens), "(','||lower(replace(t.custom_assignee_name,' ',''))||',') LIKE ('%,'||lower(replace(?,' ',''))||',%')")) : '0';
|
||||
|
||||
$params = array_merge([$user_id], $my_group_ids, $my_group_ids, [$user_id], $custom_tokens, $custom_tokens);
|
||||
|
||||
$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
|
||||
FROM tasks t
|
||||
@@ -188,6 +198,14 @@ $sql = "SELECT t.*, u.username as assignor_user_name, g.name as assignor_group_n
|
||||
OR (t.assignee_type='group' AND t.assignee_id IN ($group_in))
|
||||
OR (t.assignor_type='group' AND t.assignor_group_id IN ($group_in))
|
||||
OR (t.assignor_type='user' AND t.assignor_id = ?)
|
||||
OR (
|
||||
COALESCE(t.assignee_type,'custom')='custom'
|
||||
AND t.custom_assignee_name IS NOT NULL
|
||||
AND (
|
||||
t.custom_assignee_name IN ($custom_in)
|
||||
OR ($custom_like)
|
||||
)
|
||||
)
|
||||
ORDER BY t.created_at DESC";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
|
||||
Reference in New Issue
Block a user