feat: integrate Tagify for multi-tag support and add a new view-note modal across the application
This commit is contained in:
@@ -4,6 +4,7 @@ try { $pdo->exec("ALTER TABLE tasks ADD COLUMN assignor_type TEXT DEFAULT 'user'
|
||||
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 tags TEXT DEFAULT NULL"); } 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) {}
|
||||
try {
|
||||
$pdo->exec("CREATE TABLE IF NOT EXISTS system_config (k TEXT PRIMARY KEY, v TEXT)");
|
||||
@@ -117,8 +118,9 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['create_task'])) {
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare("INSERT INTO tasks (title, description, assignor_id, assignor_type, assignor_group_id, assignee_type, assignee_id, custom_assignee_name, status_updated_at, due_date) VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, ?)");
|
||||
if(!$stmt->execute([$title, $desc, $user_id, $assignor_type, $assignor_group_id, $a_type, $a_id, $custom_name, $due_date])) {
|
||||
$tags = trim($_POST['tags'] ?? '');
|
||||
$stmt = $pdo->prepare("INSERT INTO tasks (title, description, assignor_id, assignor_type, assignor_group_id, assignee_type, assignee_id, custom_assignee_name, status_updated_at, due_date, tags) VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, ?, ?)");
|
||||
if(!$stmt->execute([$title, $desc, $user_id, $assignor_type, $assignor_group_id, $a_type, $a_id, $custom_name, $due_date, $tags])) {
|
||||
if(isset($_POST['ajax_submit'])) { echo json_encode(['success'=>false, 'error'=>'Task insert failed']); exit; }
|
||||
}
|
||||
$new_task_id = $pdo->lastInsertId();
|
||||
@@ -434,6 +436,16 @@ body.dark-mode .kanban-task { border: 1px solid rgba(255,255,255,0.05); border-l
|
||||
<i class="fas fa-paperclip" style="font-size:0.85rem;"></i>
|
||||
<input type="file" multiple style="display:none;" onchange="handleTaskFilesSelect(this)">
|
||||
</label>
|
||||
|
||||
<div style="position:relative;" title="Tags">
|
||||
<div id="tag-icon-btn" style="cursor:pointer; display:flex; align-items:center; justify-content:center; width:30px; height:30px; border-radius:50%; background:var(--surface); border:1px solid var(--border); color:var(--text-light); transition:background 0.2s;" onclick="document.getElementById('tags-dropdown-container').style.display='block';">
|
||||
<i class="fas fa-tag" style="font-size:0.85rem;"></i>
|
||||
</div>
|
||||
<div id="tags-dropdown-container" style="display:none; position:absolute; top:35px; right:-20px; background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:0.75rem; z-index:100; box-shadow:0 10px 15px -3px rgba(0,0,0,0.1); width:280px; align-items:stretch;">
|
||||
<label style="font-size:0.75rem; font-weight:600; color:var(--text); margin-bottom:0.4rem; display:block; text-align:left;">Tags</label>
|
||||
<input type="text" name="tags" class="form-control tagify-input" style="font-size:0.8rem; border:1px solid var(--border); border-radius:4px; padding:4px; max-width:100%;" placeholder="Add tags...">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn" style="padding:0.3rem 1rem; border-radius:20px; font-weight:600; font-size:0.8rem;" onclick="submitCreateTaskForm()">Create</button>
|
||||
<button type="submit" id="hidden-create-btn" name="create_task" style="display:none;"></button>
|
||||
@@ -494,7 +506,15 @@ body.dark-mode .kanban-task { border: 1px solid rgba(255,255,255,0.05); border-l
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; justify-content:space-between; align-items:center; width:100%; font-size:0.75rem;">
|
||||
<?php if(!empty($t['tags'])): ?>
|
||||
<div style="display:flex; flex-wrap:wrap; gap:0.25rem; margin-top:0.5rem;">
|
||||
<?php foreach(explode(',', $t['tags']) as $tag): $tag=trim($tag); if(!$tag) continue; ?>
|
||||
<span style="font-size:0.65rem; padding:2px 8px; border-radius:12px; background:rgba(var(--primary-rgb),0.12); color:var(--primary); font-weight:600;"><i class="fa fa-tag" style="font-size:0.6rem;"></i> <?= htmlspecialchars($tag) ?></span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div style="display:flex; justify-content:space-between; align-items:center; width:100%; font-size:0.75rem; margin-top:0.5rem;">
|
||||
<?php
|
||||
echo '<span class="badge-role role-to" style="padding:2px 8px;">';
|
||||
if($t['assignee_type'] == 'custom') echo '👤 '.htmlspecialchars((string)$t['custom_assignee_name']);
|
||||
@@ -773,9 +793,14 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
|
||||
document.addEventListener('mousedown', function(e) {
|
||||
let container = document.getElementById('to-dropdown-container');
|
||||
if(container && !container.contains(e.target) && e.target.id !== 'to-input' && !e.target.closest('label')) {
|
||||
if(container && !container.contains(e.target) && e.target.id !== 'to-input' && !e.target.closest('#to-icon-btn')) {
|
||||
container.style.display = 'none';
|
||||
}
|
||||
|
||||
let tagContainer = document.getElementById('tags-dropdown-container');
|
||||
if(tagContainer && !tagContainer.contains(e.target) && !e.target.closest('#tag-icon-btn') && !e.target.closest('.tagify')) {
|
||||
tagContainer.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
let pendingTaskFiles = [];
|
||||
|
||||
Reference in New Issue
Block a user