Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <style>
- /* ============================== */
- /* ========= TASK TABLE ========= */
- /* ============================== */
- /* @task table @task @table */
- /*==== @task table container ====*/
- .task-table-container { /* Table container with scroll */
- overflow-x: auto; /* Horizontal scroll if neede*/
- background: #16213e; /* Dark blue background */
- border-radius: 8px; /* Rounded corners */
- padding: 10px; /* Inner spacing */
- transition: background 0.3s ease; /* Smooth color transition */
- }
- /*==== @task table container filter backgrounds ====*/
- /* Light tinted backgrounds when filter is active - tied to tab colors via CSS variables */
- .task-filter-btn[data-status="active"].active ~ .task-search-container ~ .task-count-display ~ .task-table-container,
- body:has(.task-filter-btn[data-status="active"].active) .task-table-container {
- background: var(--bg-active); /* Very light green tint */
- }
- body:has(.task-filter-btn[data-status="all"].active) .task-table-container {
- background: var(--bg-all); /* Very light gray tint */
- }
- body:has(.task-filter-btn[data-status="pinned"].active) .task-table-container {
- background: var(--bg-pinned); /* Very light orange tint */
- }
- body:has(.task-filter-btn[data-status="favorite"].active) .task-table-container {
- background: var(--bg-favorite); /* Very light yellow tint */
- }
- body:has(.task-filter-btn[data-status="moo"].active) .task-table-container {
- background: var(--bg-moo); /* Very light purple tint */
- }
- body:has(.task-filter-btn[data-status="completed"].active) .task-table-container {
- background: var(--bg-completed); /* Very light bright green tint */
- }
- body:has(.task-filter-btn[data-status="review"].active) .task-table-container {
- background: var(--bg-review); /* Very light blue tint */
- }
- body:has(.task-filter-btn[data-status="future"].active) .task-table-container {
- background: var(--bg-future); /* Very light blue tint */
- }
- body:has(.task-filter-btn[data-status="archived"].active) .task-table-container {
- background: var(--bg-archived); /* Very light gray tint */
- }
- body:has(.task-filter-btn[data-status="dump"].active) .task-table-container {
- background: var(--bg-dump); /* Very light gray tint */
- }
- body:has(.task-filter-btn[data-status="deleted"].active) .task-table-container {
- background: var(--bg-deleted); /* Very light red tint */
- }
- /*==== @task table ====*/
- .task-table { /* Main task table */
- width: 100%; /* Full width */
- border-collapse: collapse; /* Remove cell spacing */
- color: #eee; /* Light text */
- table-layout: fixed; /* Force column widths to be respected */
- }
- /*==== @task table header ====*/
- .task-table thead { /* Table header */
- background: #0f3460; /* Dark blue background */
- }
- .task-table th { /* Table header cells */
- padding: 12px 8px; /* Cell padding */
- text-align: left; /* Left align text */
- font-size: 0.9rem; /* Text size */
- font-weight: 600; /* Semi-bold */
- color: #aaa; /* Gray text */
- border-bottom: 2px solid #1a1a2e; /* Bottom border */
- white-space: nowrap; /* Don't wrap text */
- }
- /*==== @sortable columns ====*/
- .task-table th.sortable { /* Sortable column headers */
- cursor: pointer; /* Show pointer cursor */
- user-select: none; /* Prevent text selection */
- transition: color 0.2s ease, background 0.2s ease; /* Smooth transitions */
- }
- .task-table th.sortable:hover { /* Sortable header hover */
- color: #4a90e2; /* Blue text on hover */
- background: rgba(74, 144, 226, 0.1); /* Light blue background */
- }
- .task-table th.sortable.sorted-asc,
- .task-table th.sortable.sorted-desc { /* Active sorted column */
- color: #4a90e2; /* Blue text for sorted column */
- background: rgba(74, 144, 226, 0.15); /* Slightly darker blue background */
- }
- /*==== @sort indicators ====*/
- .sort-indicator { /* Sort arrow container */
- display: inline-block; /* Inline block */
- width: 12px; /* Fixed width */
- margin-left: 4px; /* Space from text */
- opacity: 0.3; /* Dim by default */
- transition: opacity 0.2s ease; /* Smooth opacity change */
- }
- .task-table th.sortable:hover .sort-indicator { /* Show indicator on hover */
- opacity: 0.6; /* More visible on hover */
- }
- .task-table th.sortable.sorted-asc .sort-indicator::after { /* Ascending arrow */
- content: '▲'; /* Up arrow */
- opacity: 1; /* Fully visible */
- color: #4a90e2; /* Blue color */
- }
- .task-table th.sortable.sorted-desc .sort-indicator::after { /* Descending arrow */
- content: '▼'; /* Down arrow */
- opacity: 1; /* Fully visible */
- color: #4a90e2; /* Blue color */
- }
- /*==== @task table body ====*/
- .task-table tbody tr { /* Table body rows */
- border-bottom: 1px solid #1a1a2e; /* Row separator */
- transition: background 0.2s ease; /* Smooth hover */
- }
- .task-table tbody tr:hover { /* Table row hover state */
- background: #0f3460; /* Darker background on hover */
- }
- .task-table td { /* Table body cells */
- padding: 12px 8px; /* Cell padding */
- font-size: 0.9rem; /* Text size */
- vertical-align: middle; /* Center vertically */
- /* DIAGNOSTIC: Show cell boundaries */
- border: 2px solid rgba(255, 0, 0, 0.3) !important;
- box-sizing: border-box;
- }
- .task-table th { /* DIAGNOSTIC: Show header boundaries */
- border: 2px solid rgba(0, 255, 0, 0.3) !important;
- box-sizing: border-box;
- }
- /* DIAGNOSTIC: Show column numbers */
- .task-table td[data-col]::before {
- content: "[" attr(data-col) "] ";
- color: #ff6b9d;
- font-weight: bold;
- font-size: 0.7rem;
- }
- .task-table th {
- position: relative;
- }
- .task-table th:nth-child(1)::before { content: "[1] "; color: #00ff00; font-weight: bold; }
- .task-table th:nth-child(2)::before { content: "[2] "; color: #00ff00; font-weight: bold; }
- .task-table th:nth-child(3)::before { content: "[3] "; color: #00ff00; font-weight: bold; }
- .task-table th:nth-child(4)::before { content: "[4] "; color: #00ff00; font-weight: bold; }
- .task-table th:nth-child(5)::before { content: "[5] "; color: #00ff00; font-weight: bold; }
- .task-table th:nth-child(6)::before { content: "[6] "; color: #00ff00; font-weight: bold; }
- .task-table th:nth-child(7)::before { content: "[7] "; color: #00ff00; font-weight: bold; }
- .task-table th:nth-child(8)::before { content: "[8] "; color: #00ff00; font-weight: bold; }
- .task-table th:nth-child(9)::before { content: "[9] "; color: #00ff00; font-weight: bold; }
- .task-table th:nth-child(10)::before { content: "[10] "; color: #00ff00; font-weight: bold; }
- .task-table th:nth-child(11)::before { content: "[11] "; color: #00ff00; font-weight: bold; }
- .task-table th:nth-child(12)::before { content: "[12] "; color: #00ff00; font-weight: bold; }
- /*==== @no tasks message ====*/
- .no-tasks-message { /* Empty state message */
- text-align: center; /* Center text */
- color: #7f8c8d; /* Gray text */
- padding: 40px 20px; /* Large padding */
- font-style: italic; /* Italic text */
- }
- /*==== @task score cell ====*/
- .task-score { /* Score column styling */
- font-weight: 600; /* Bold */
- font-size: 1rem; /* Larger text */
- }
- /*==== @task name cell ====*/
- .task-name { /* Task name column */
- font-weight: 500; /* Medium weight */
- color: #fff; /* White text */
- }
- /*==== @task bends values ====*/
- .task-bends-value { /* BENDS score cells (B, E, N, D, S) */
- font-size: 0.85rem; /* Smaller text */
- text-align: center; /* Center align */
- }
- /* ================================================================= */
- /* ===================== TASK ACTION BUTTONS ======================= */
- /* ================================================================= */
- /* @task @action @buttons @move @status @view @edit */
- /* ============================== */
- /* ======= BUTTON CONTAINER ===== */
- /* ============================== */
- /* @container @actions */
- /*==== @task actions container ====*/
- .task-actions { /* Actions column container for task buttons */
- display: flex; /* Horizontal layout */
- flex-direction: row; /* Explicitly set to row (horizontal) */
- gap: 4px; /* Space between buttons */
- flex-wrap: wrap; /* Wrap into multiple rows */
- max-width: 600px; /* Wider to allow more buttons per row */
- align-items: flex-start; /* Align items to top of container */
- }
- /* Star column (1st) - Combined pin + star */
- .task-table td:nth-child(1),
- .task-table th:nth-child(1) {
- min-width: 50px;
- width: 50px;
- max-width: 50px;
- text-align: center;
- vertical-align: top;
- }
- /* Details column (2nd) */
- .task-table td:nth-child(2),
- .task-table th:nth-child(2) {
- min-width: 120px;
- width: 120px;
- max-width: 120px;
- vertical-align: top;
- }
- /* Steps column (3rd) */
- .task-table td:nth-child(3),
- .task-table th:nth-child(3) {
- min-width: 95px;
- width: 95px;
- }
- /* Score column (4th) */
- .task-table td:nth-child(4),
- .task-table th:nth-child(4) {
- min-width: 55px;
- width: 55px;
- text-align: center;
- }
- /* Task Name column (5th) - Let it grow */
- .task-table td:nth-child(5),
- .task-table th:nth-child(5) {
- min-width: 250px;
- /* No max-width - allow to expand */
- }
- /* Status column (6th) */
- .task-table td:nth-child(6),
- .task-table th:nth-child(6) {
- min-width: 85px;
- width: 85px;
- }
- /* Category column (7th) */
- .task-table td:nth-child(7),
- .task-table th:nth-child(7) {
- min-width: 80px;
- width: 80px;
- }
- /* Date Added column (8th) */
- .task-table td:nth-child(8),
- .task-table th:nth-child(8) {
- min-width: 75px;
- width: 75px;
- }
- /* Due Date column (9th) */
- .task-table td:nth-child(9),
- .task-table th:nth-child(9) {
- min-width: 70px;
- width: 70px;
- }
- /* Times Moved column (10th) */
- .task-table td:nth-child(10),
- .task-table th:nth-child(10) {
- min-width: 60px;
- width: 60px;
- text-align: center;
- }
- /* Last Moved From column (11th) */
- .task-table td:nth-child(11),
- .task-table th:nth-child(11) {
- min-width: 80px;
- width: 80px;
- }
- /* Actions column (12th) - Keep horizontal layout */
- .task-table td:nth-child(12),
- .task-table th:nth-child(12) {
- min-width: 400px;
- }
- /* Ensure actions column stays horizontal */
- .task-table td:nth-child(12).task-actions {
- flex-wrap: wrap; /* Allow wrapping but keep horizontal first */
- }
- /* ============================== */
- /* ====== ICON BUTTON STYLE ===== */
- /* ============================== */
- /* @icon @buttons */
- /*==== @task icon button base ====*/
- .task-icon-btn { /* Icon buttons for pin/star */
- padding: 6px 10px;
- background: rgba(255, 255, 255, 0.1);
- border: 2px solid rgba(255, 255, 255, 0.2);
- border-radius: 4px;
- font-size: 1.1rem;
- cursor: pointer;
- transition: all 0.2s ease;
- display: inline-block;
- }
- /*==== @task icon button hover ====*/
- .task-icon-btn:hover {
- transform: scale(1.1);
- box-shadow: 0 2px 8px rgba(0,0,0,0.3);
- }
- /*==== @pin button red box ====*/
- .pin-btn {
- background: rgba(231, 76, 60, 0.2); /* Red background */
- border-color: var(--color-deleted); /* Red border */
- }
- .pin-btn:hover {
- background: var(--color-deleted); /* Solid red on hover */
- }
- /*==== @star button ====*/
- .star-btn {
- background: rgba(255, 215, 0, 0.15); /* Subtle gold background */
- border-color: rgba(255, 215, 0, 0.3);
- }
- .star-btn:hover {
- background: rgba(255, 215, 0, 0.25);
- border-color: gold;
- }
- /*==== @star column stacked buttons ====*/
- .task-star-cell {
- display: flex;
- flex-direction: column;
- gap: 4px;
- align-items: center;
- overflow: hidden;
- }
- .task-star-cell .task-icon-btn {
- box-sizing: border-box;
- }
- /*==== @details column stacked buttons ====*/
- .task-details-cell {
- display: flex;
- flex-direction: column;
- gap: 4px;
- align-items: stretch;
- overflow: hidden;
- }
- .task-details-cell .task-action-btn {
- width: 90px;
- padding: 2px 4px;
- font-size: 0.65rem;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- box-sizing: border-box;
- }
- /* ============================== */
- /* ====== BASE BUTTON STYLE ===== */
- /* ============================== */
- /* @button @base @style */
- /*==== @task action button base ====*/
- .task-action-btn { /* Individual action button base style */
- padding: 3px; /* Small padding for compact buttons */
- width: 80px;
- background: transparent; /* Transparent background by default */
- border: 2px solid; /* Border color set by specific classes */
- border-radius: 4px; /* Rounded corners */
- font-size: 0.7rem; /* Small text size */
- font-weight: 600; /* Semi-bold text */
- cursor: pointer; /* Hand cursor on hover */
- transition: all 0.2s ease; /* Smooth animation for all properties */
- white-space: nowrap; /* Prevent text wrapping */
- }
- /*==== @task action button hover ====*/
- .task-action-btn:hover { /* Action button hover state */
- transform: scale(1.05); /* Slightly larger on hover */
- box-shadow: 0 2px 8px rgba(0,0,0,0.3); /* Shadow on hover */
- }
- /* ======================================= */
- /* ========= VIEW/EDIT BUTTONS =========== */
- /* ======================================= */
- /* @view @edit @buttons */
- /*==== @view button ====*/
- .btn-view { /* View task details button */
- border-color: #3498db; /* Blue border */
- color: #3498db; /* Blue text */
- }
- /*==== @view button hover ====*/
- .btn-view:hover { /* View button hover state */
- background: #3498db; /* Blue background */
- color: #fff; /* White text */
- }
- /*==== @edit button ====*/
- .btn-edit { /* Edit task button */
- border-color: #9b59b6; /* Purple border */
- color: #9b59b6; /* Purple text */
- }
- /*==== @edit button hover ====*/
- .btn-edit:hover { /* Edit button hover state */
- background: #9b59b6; /* Purple background */
- color: #fff; /* White text */
- }
- /* ======================================= */
- /* ====== STATUS MOVEMENT BUTTONS ======== */
- /* ======================================= */
- /* @status @buttons @move @color-coded */
- /*==== @active status button ====*/
- .btn-active { /* Move to Active status button */
- border-color: var(--color-active); /* Green border */
- color: var(--color-active); /* Green text */
- }
- /*==== @active status button hover ====*/
- .btn-active:hover { /* Active button hover state */
- background: var(--color-active); /* Green background */
- color: #fff; /* White text */
- }
- /*==== @review status button ====*/
- .btn-review { /* Move to Review status button */
- border-color: var(--color-review); /* Blue border */
- color: var(--color-review); /* Blue text */
- }
- /*==== @review status button hover ====*/
- .btn-review:hover { /* Review button hover state */
- background: var(--color-review); /* Blue background */
- color: #fff; /* White text */
- }
- /*==== @completed status button ====*/
- .btn-completed { /* Move to Completed status button */
- border-color: var(--color-completed); /* Bright green border */
- color: var(--color-completed); /* Bright green text */
- }
- /*==== @completed status button hover ====*/
- .btn-completed:hover { /* Completed button hover state */
- background: var(--color-completed); /* Bright green background */
- color: #fff; /* White text */
- }
- /*==== @future status button ====*/
- .btn-future { /* Move to Future status button */
- border-color: var(--color-future); /* Blue border (same as review) */
- color: var(--color-future); /* Blue text */
- }
- /*==== @future status button hover ====*/
- .btn-future:hover { /* Future button hover state */
- background: var(--color-future); /* Blue background */
- color: #fff; /* White text */
- }
- /*==== @archived status button ====*/
- .btn-archived { /* Move to Archived status button */
- border-color: var(--color-archived); /* Gray border */
- color: var(--color-archived); /* Gray text */
- }
- /*==== @archived status button hover ====*/
- .btn-archived:hover { /* Archived button hover state */
- background: var(--color-archived); /* Gray background */
- color: #fff; /* White text */
- }
- /*==== @dump status button ====*/
- .btn-dump { /* Move to Dump status button */
- border-color: var(--color-dump); /* Gray border (same as archive) */
- color: var(--color-dump); /* Gray text */
- }
- /*==== @dump status button hover ====*/
- .btn-dump:hover { /* Dump button hover state */
- background: var(--color-dump); /* Gray background */
- color: #fff; /* White text */
- }
- /*==== @deleted status button ====*/
- .btn-deleted { /* Move to Deleted status button */
- border-color: var(--color-deleted); /* Red border */
- color: var(--color-deleted); /* Red text */
- }
- /*==== @deleted status button hover ====*/
- .btn-deleted:hover { /* Deleted button hover state */
- background: var(--color-deleted); /* Red background */
- color: #fff; /* White text */
- }
- /*==== @permanent delete button ====*/
- .btn-permanent-delete { /* Permanent delete button (only on deleted tab) */
- border-color: #8b0000; /* Dark red border */
- color: #8b0000; /* Dark red text */
- font-weight: 600; /* Semi-bold */
- }
- /*==== @permanent delete button hover ====*/
- .btn-permanent-delete:hover { /* Permanent delete button hover state */
- background: #8b0000; /* Dark red background */
- color: #fff; /* White text */
- font-weight: 600; /* Semi-bold */
- }
- /*==== @moo status button ====*/
- .btn-moo { /* Move to Moo status button */
- border-color: var(--color-moo); /* Purple border (was future's color) */
- color: var(--color-moo); /* Purple text */
- }
- /*==== @moo status button hover ====*/
- .btn-moo:hover { /* Moo button hover state */
- background: var(--color-moo); /* Purple background */
- color: #fff; /* White text */
- }
- /* ======================================= */
- /* ======= PIN/FAVORITE BUTTONS ========== */
- /* ======================================= */
- /* @pin @favorite @toggle @buttons */
- /*==== @pin button ====*/
- .btn-pin { /* Pin task button */
- width: 25px; /* Specific smaller fixed width */
- height: 25px; /* Specific smaller fixed height */
- padding: 0; /* Remove padding to fit the icon neatly */
- display: flex; /* Use flexbox to center the emoji */
- justify-content: center; /* Center horizontally */
- align-items: center; /* Center vertically */
- font-size: 0.9rem; /* Slightly larger emoji size */
- flex-shrink: 0; /* Prevents flexbox from squeezing these buttons border-color: var(--color-pinned); /* Orange border */
- color: var(--color-pinned); /* Orange text */
- }
- /*==== @pin button hover ====*/
- .btn-pin:hover { /* Pin button hover state */
- background: var(--color-pinned); /* Orange background */
- color: #fff; /* White text */
- }
- /*==== @unpin button ====*/
- .btn-unpin { /* Unpin task button */
- width: 25px; /* Specific smaller fixed width */
- height: 25px; /* Specific smaller fixed height */
- padding: 0; /* Remove padding to fit the icon neatly */
- display: flex; /* Use flexbox to center the emoji */
- justify-content: center; /* Center horizontally */
- align-items: center; /* Center vertically */
- font-size: 0.9rem; /* Slightly larger emoji size */
- flex-shrink: 0; /* Prevents flexbox from squeezing these buttons border-color: var(--color-pinned); /* Orange border */
- border-color: var(--color-pinned); /* Orange border (same as pin) */
- color: var(--color-pinned); /* Orange text */
- }
- /*==== @unpin button hover ====*/
- .btn-unpin:hover { /* Unpin button hover state */
- background: var(--color-pinned); /* Orange background */
- color: #fff; /* White text */
- }
- /*==== @favorite button ====*/
- .btn-favorite { /* Add to favorites button */
- width: 25px; /* Specific smaller fixed width */
- height: 25px; /* Specific smaller fixed height */
- padding: 0; /* Remove padding to fit the icon neatly */
- display: flex; /* Use flexbox to center the emoji */
- justify-content: center; /* Center horizontally */
- align-items: center; /* Center vertically */
- font-size: 0.9rem; /* Slightly larger emoji size */
- flex-shrink: 0; /* Prevents flexbox from squeezing these buttons border-color: var(--color-pinned); /* Orange border */
- border-color: var(--color-favorite); /* Yellow border */
- color: var(--color-favorite); /* Yellow text */
- }
- /*==== @favorite button hover ====*/
- .btn-favorite:hover { /* Favorite button hover state */
- background: var(--color-favorite); /* Yellow background */
- color: #fff; /* White text */
- }
- /*==== @unfavorite button ====*/
- .btn-unfavorite { /* Remove from favorites button */
- width: 25px; /* Specific smaller fixed width */
- height: 25px; /* Specific smaller fixed height */
- padding: 0; /* Remove padding to fit the icon neatly */
- display: flex; /* Use flexbox to center the emoji */
- justify-content: center; /* Center horizontally */
- align-items: center; /* Center vertically */
- font-size: 0.9rem; /* Slightly larger emoji size */
- flex-shrink: 0; /* Prevents flexbox from squeezing these buttons border-color: var(--color-pinned); /* Orange border */
- border-color: var(--color-favorite); /* Yellow border (same as favorite) */
- color: var(--color-favorite); /* Yellow text */
- }
- /*==== @unfavorite button hover ====*/
- .btn-unfavorite:hover { /* Unfavorite button hover state */
- background: var(--color-favorite); /* Yellow background */
- color: #fff; /* White text */
- }
- /*==== @task category badge ====*/
- .task-category-badge { /* Action Status (category) badge */
- display: inline-block; /* Inline block */
- padding: 4px 10px; /* Badge padding */
- border-radius: 12px; /* Rounded pill shape */
- font-size: 0.8rem; /* Small text */
- font-weight: 600; /* Semi-bold */
- color: #fff; /* White text */
- text-transform: capitalize; /* Capitalize status text */
- }
- /* Status badge colors */
- .status-active { background: var(--color-active); } /* Green */
- .status-review { background: var(--color-review); } /* Blue */
- .status-completed { background: var(--color-completed); } /* Bright green */
- .status-future { background: var(--color-future); } /* Blue (same as review) */
- .status-archived { background: var(--color-archived); } /* Gray */
- .status-dump { background: var(--color-dump); } /* Gray (same as archive) */
- .status-deleted { background: var(--color-deleted); } /* Red */
- .status-moo { background: var(--color-moo); } /* Purple */
- .status-pinned { background: var(--color-pinned); } /* Orange */
- .status-favorite { background: var(--color-favorite); } /* Yellow */
- .status-default { background: #7f8c8d; } /* Dark gray for unknown */
- </style>
- </head>
- <body>
- <h1 style="color: #fff; padding: 20px;">BENDS Table Test</h1>
- <div style="padding: 0 20px 20px 20px;">
- <button id="generate-test-data" style="padding: 10px 20px; background: #4a90e2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; margin-right: 10px;">Generate Test Tasks</button>
- <button id="clear-tasks" style="padding: 10px 20px; background: #e74c3c; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem;">Clear All</button>
- </div>
- <!-- @task table -->
- <div class="task-table-container">
- <table class="task-table">
- <thead>
- <tr> <!-- @task list headers -->
- <th class="sortable" data-column="isPinned" data-type="boolean">⭐ <span class="sort-indicator"></span></th>
- <th>Details</th>
- <th class="sortable" data-column="steps" data-type="number">
- Steps <span class="sort-indicator"></span>
- </th>
- <th class="sortable" data-column="priority" data-type="number">
- Score <span class="sort-indicator"></span>
- </th>
- <th class="sortable" data-column="name" data-type="text">
- Task<br>Name <span class="sort-indicator"></span>
- </th>
- <th class="sortable" data-column="status" data-type="text">
- Status <span class="sort-indicator"></span>
- </th>
- <th class="sortable" data-column="category" data-type="text">
- Category <span class="sort-indicator"></span>
- </th>
- <th class="sortable" data-column="dateAdded" data-type="date">
- Date<br>Added <span class="sort-indicator"></span>
- </th>
- <th class="sortable" data-column="dateDue" data-type="date">
- Due<br>Date <span class="sort-indicator"></span>
- </th>
- <th class="sortable" data-column="timesMoved" data-type="number">
- Times<br>Moved <span class="sort-indicator"></span>
- </th>
- <th class="sortable" data-column="lastMovedFrom" data-type="text">
- Last Moved<br>From <span class="sort-indicator"></span>
- </th>
- <th>Actions</th>
- </tr>
- </thead>
- <tbody id="task-table-body">
- <!-- Tasks will be dynamically inserted here -->
- <tr>
- <td colspan="12" class="no-tasks-message">No tasks to display. Create a task to get started!</td>
- </tr>
- </tbody>
- </table>
- <script>
- // Mock TaskManager
- const TaskManager = {
- tasks: []
- };
- // Mock UI object
- const UI = {
- viewTask: (index) => {
- alert(`View task ${index}: ${TaskManager.tasks[index].name}`);
- },
- editTask: (index) => {
- alert(`Edit task ${index}: ${TaskManager.tasks[index].name}`);
- },
- permanentDelete: (index) => {
- if (confirm('Permanently delete this task?')) {
- TaskManager.tasks.splice(index, 1);
- UI.renderTaskTable(TaskManager.tasks);
- }
- },
- /* ================================================================= */
- /* ===================== RENDER TASK TABLE ========================= */
- /* ================================================================= */
- /* @constant variable UI
- @function
- @render @task @table
- */
- /*==== @render task table ====*/
- //render tasks in table
- renderTaskTable(tasks) {
- /*==== @table body @tbody ====*/
- const tbody = document.getElementById('task-table-body');
- //clear existing content
- tbody.innerHTML = '';
- //if no tasks, show empty message
- if (!tasks || tasks.length === 0) {
- tbody.innerHTML =
- `<tr>
- <td colspan="12" class="no-tasks-message">No Tasks to display. Create a task to get started!</td>
- </tr>`;
- return;
- }
- //render each task as a row
- tasks.forEach((task) => {
- /*==== @row ====*/
- // Find the actual index in TaskManager.tasks
- const actualIndex = TaskManager.tasks.indexOf(task);
- const row = this.createTaskRow(task, actualIndex);
- tbody.appendChild(row);
- });
- },
- /* ================================================================= */
- /* ===================== CREATE TASK ROW =========================== */
- /* ================================================================= */
- /* @constant variable UI
- @function
- @create @task @row
- */
- /*==== @create task row ====*/
- //create a table row for tasks
- createTaskRow(task, index) {
- /*==== @tr @table row ====*/
- const tr = document.createElement('tr');
- //format date (handle different date formats)
- const dateAdded = task.dateCreated || task.created || 'N/A';
- const displayDate = dateAdded !== 'N/A' ? dateAdded.split('T')[0] : 'N/A';
- //get status badge color
- const statusColors = {
- 'active': 'status-active',
- 'review': 'status-review',
- 'completed': 'status-completed',
- 'future': 'status-future',
- 'archived': 'status-archived',
- 'dump': 'status-dump',
- 'deleted': 'status-deleted',
- 'moo': 'status-moo',
- 'pinned': 'status-pinned',
- 'favorite': 'status-favorite'
- };
- const statusClass = statusColors[task.status] || 'status-default';
- // Calculate steps progress
- const stepsTotal = task.stepsCount || 0;
- const stepsCompleted = task.stepsCompleted || 0;
- const stepsPercentage = stepsTotal > 0 ? (stepsCompleted / stepsTotal) * 100 : 0;
- // Build entire row using innerHTML
- tr.innerHTML = `
- <td data-col="1" data-col-name="star" class="task-star-cell">
- <button class="task-icon-btn pin-btn ${task.isPinned ? 'btn-unpin' : 'btn-pin'}" onclick="ReasonModal.open(${index}, '${task.isPinned ? 'unpin' : 'pin'}')" title="${task.isPinned ? 'Unpin' : 'Pin'}">${task.isPinned ? '📍' : '⭕'}</button>
- <button class="task-icon-btn star-btn ${task.isFavorite ? 'btn-unfavorite' : 'btn-favorite'}" onclick="ReasonModal.open(${index}, '${task.isFavorite ? 'unfavorite' : 'favorite'}')" title="${task.isFavorite ? 'Remove from Favorites' : 'Add to Favorites'}">${task.isFavorite ? '⭐' : '✰'}</button>
- </td>
- <td data-col="2" data-col-name="details" class="task-details-cell">
- <button class="task-action-btn btn-view" onclick="UI.viewTask(${index})" title="View Task">👁️ View</button>
- <button class="task-action-btn btn-edit" onclick="UI.editTask(${index})" title="Edit Task">✏️ Edit</button>
- </td>
- <td data-col="3" data-col-name="steps">
- <div class="table-steps-progress">
- <div class="table-steps-count">${stepsCompleted}/${stepsTotal}</div>
- <div class="table-progress-bar-track">
- <div class="table-progress-bar-fill" style="width: ${stepsPercentage}%"></div>
- </div>
- </div>
- </td>
- <td data-col="4" data-col-name="score" class="task-score">${task.priority ? task.priority.toFixed(1) : '5.0'}</td>
- <td data-col="5" data-col-name="name" class="task-name">${task.isTestData ? '🧬 ' : ''}${task.name || 'Unnamed Task'}</td>
- <td data-col="6" data-col-name="status"><span class="task-category-badge ${statusClass}">${task.status || 'active'}</span></td>
- <td data-col="7" data-col-name="category"><span class="task-category-badge">${task.category || 'None'}</span></td>
- <td data-col="8" data-col-name="dateAdded">${displayDate}</td>
- <td data-col="9" data-col-name="dateDue">${task.dateDue || 'N/A'}</td>
- <td data-col="10" data-col-name="timesMoved">${task.timesMoved || 0}</td>
- <td data-col="11" data-col-name="lastMovedFrom">${task.lastMovedFrom || '-'}</td>
- <td data-col="12" data-col-name="actions" class="task-actions">
- ${task.status !== 'active' ? `<button class="task-action-btn btn-active" onclick="ReasonModal.open(${index}, 'active')" title="Move to Active">🟢 Active</button>` : ''}
- ${task.status !== 'review' ? `<button class="task-action-btn btn-review" onclick="ReasonModal.open(${index}, 'review')" title="Move to Review">🔍 Review</button>` : ''}
- ${task.status !== 'completed' ? `<button class="task-action-btn btn-completed" onclick="ReasonModal.open(${index}, 'completed')" title="Move to Completed">✅ Done</button>` : ''}
- ${task.status !== 'future' ? `<button class="task-action-btn btn-future" onclick="ReasonModal.open(${index}, 'future')" title="Move to Future">🔮 Future</button>` : ''}
- ${task.status !== 'archived' ? `<button class="task-action-btn btn-archived" onclick="ReasonModal.open(${index}, 'archived')" title="Archive">📦 Archive</button>` : ''}
- ${task.status !== 'dump' ? `<button class="task-action-btn btn-dump" onclick="ReasonModal.open(${index}, 'dump')" title="Move to Dump">🗑️ Dump</button>` : ''}
- ${task.status !== 'deleted' ? `<button class="task-action-btn btn-deleted" onclick="ReasonModal.open(${index}, 'deleted')" title="Delete">❌ Delete</button>` : ''}
- ${task.status !== 'moo' ? `<button class="task-action-btn btn-moo" onclick="ReasonModal.open(${index}, 'moo')" title="Move to Moo">🐄 Moo</button>` : ''}
- ${task.status === 'deleted' ? `<button class="task-action-btn btn-permanent-delete" onclick="UI.permanentDelete(${index})" title="Permanently Delete (Cannot be undone)">💀 Permanent Delete</button>` : ''}
- </td>
- `;
- return tr;
- }
- };
- // Mock ReasonModal
- const ReasonModal = {
- open: (index, action) => {
- const task = TaskManager.tasks[index];
- alert(`Action: ${action}\nTask: ${task.name}`);
- // Simulate status changes
- if (['active', 'review', 'completed', 'future', 'archived', 'dump', 'deleted', 'moo'].includes(action)) {
- task.status = action;
- UI.renderTaskTable(TaskManager.tasks);
- } else if (action === 'pin') {
- task.isPinned = true;
- UI.renderTaskTable(TaskManager.tasks);
- } else if (action === 'unpin') {
- task.isPinned = false;
- UI.renderTaskTable(TaskManager.tasks);
- } else if (action === 'favorite') {
- task.isFavorite = true;
- UI.renderTaskTable(TaskManager.tasks);
- } else if (action === 'unfavorite') {
- task.isFavorite = false;
- UI.renderTaskTable(TaskManager.tasks);
- }
- }
- };
- // Generate test tasks
- function generateTestTasks() {
- TaskManager.tasks = [
- {
- name: "Test Task 1 - Active",
- status: "active",
- category: "Work",
- priority: 7.5,
- stepsCount: 5,
- stepsCompleted: 2,
- isPinned: false,
- isFavorite: true,
- dateCreated: "2025-12-13",
- dateDue: "2025-12-20",
- timesMoved: 0,
- lastMovedFrom: "-",
- isTestData: true
- },
- {
- name: "Test Task 2 - Review",
- status: "review",
- category: "Personal",
- priority: 6.2,
- stepsCount: 3,
- stepsCompleted: 1,
- isPinned: true,
- isFavorite: false,
- dateCreated: "2025-12-12",
- dateDue: "2025-12-18",
- timesMoved: 2,
- lastMovedFrom: "Active",
- isTestData: true
- },
- {
- name: "Test Task 3 - Future",
- status: "future",
- category: "Learning",
- priority: 8.9,
- stepsCount: 10,
- stepsCompleted: 0,
- isPinned: false,
- isFavorite: false,
- dateCreated: "2025-12-11",
- dateDue: "N/A",
- timesMoved: 0,
- lastMovedFrom: "-",
- isTestData: true
- },
- {
- name: "Test Task 4 - Completed",
- status: "completed",
- category: "Work",
- priority: 9.1,
- stepsCount: 8,
- stepsCompleted: 8,
- isPinned: false,
- isFavorite: true,
- dateCreated: "2025-12-10",
- dateDue: "2025-12-15",
- timesMoved: 5,
- lastMovedFrom: "Review",
- isTestData: true
- },
- {
- name: "Test Task 5 - Archived",
- status: "archived",
- category: "Personal",
- priority: 5.0,
- stepsCount: 4,
- stepsCompleted: 4,
- isPinned: false,
- isFavorite: false,
- dateCreated: "2025-12-09",
- dateDue: "2025-12-14",
- timesMoved: 3,
- lastMovedFrom: "Completed",
- isTestData: true
- }
- ];
- UI.renderTaskTable(TaskManager.tasks);
- }
- // Event listeners
- document.getElementById('generate-test-data').addEventListener('click', generateTestTasks);
- document.getElementById('clear-tasks').addEventListener('click', () => {
- TaskManager.tasks = [];
- UI.renderTaskTable(TaskManager.tasks);
- });
- // Initial render
- UI.renderTaskTable(TaskManager.tasks);
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment