From 0046721fde7b8269d328c8824c44f5acec26bfce Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Tue, 20 Jan 2026 21:11:49 -0500 Subject: [PATCH] feat: Add admin navigation, fix modals, clickable stats, update docs - Add admin dropdown menu in dashboard header with links to all admin pages - Fix template modal: larger size (800px), responsive grid, type/priority dropdowns - Fix recurring tickets modal: add Type and Assign To fields, larger size - Make dashboard stat cards clickable for quick filtering - Fix user-activity query (remove is_active requirement) - Add table existence check in ticket_dependencies API - Fix table overflow on dashboard - Update Claude.md and README.md with current project status - Remove migrations directory (all migrations completed) Co-Authored-By: Claude Opus 4.5 --- Claude.md | 771 ++++++--------------------- README.md | 18 +- api/ticket_dependencies.php | 35 +- assets/css/dashboard.css | 76 +++ index.php | 1 - migrations/run_migrations.php | 107 ---- views/DashboardView.php | 54 +- views/admin/RecurringTicketsView.php | 82 ++- views/admin/TemplatesView.php | 13 +- 9 files changed, 406 insertions(+), 751 deletions(-) delete mode 100644 migrations/run_migrations.php diff --git a/Claude.md b/Claude.md index 2998213..490304f 100644 --- a/Claude.md +++ b/Claude.md @@ -2,20 +2,34 @@ ## Project Status (January 2026) -**Current Phase**: All 5 core features implemented and deployed. Ready for ANSI Art redesign. +**Current Phase**: All core features implemented. ANSI Art terminal redesign complete. System is production-ready. -**Recent Completion**: +**Completed Features**: - ✅ Activity Timeline (Feature 1) - ✅ Ticket Assignment (Feature 2) - ✅ Status Transitions with Workflows (Feature 3) - ✅ Ticket Templates (Feature 4) - ✅ Bulk Actions - Admin Only (Feature 5) +- ✅ ANSI Art Terminal Redesign +- ✅ File Attachments +- ✅ Ticket Dependencies +- ✅ @Mentions in Comments +- ✅ Recurring Tickets +- ✅ Custom Fields +- ✅ Advanced Search with Saved Filters +- ✅ Export to CSV/JSON +- ✅ Admin Pages (Templates, Workflow, Recurring, Custom Fields, User Activity, Audit Log) -**Next Priority**: 🎨 ANSI Art Redesign (major visual overhaul) +**Recent Updates** (January 2026): +- Added admin dropdown navigation in dashboard header +- Fixed template/recurring ticket modals (larger size, type/assignee fields) +- Made dashboard stat cards clickable for quick filtering +- Fixed table overflow on dashboard +- Improved error handling for ticket dependencies API ## Project Overview -Tinker Tickets is a feature-rich, self-hosted ticket management system built for managing data center infrastructure issues. It features SSO integration with Authelia/LLDAP, workflow management, Discord notifications, and a comprehensive web interface. +Tinker Tickets is a feature-rich, self-hosted ticket management system built for managing data center infrastructure issues. It features SSO integration with Authelia/LLDAP, workflow management, Discord notifications, and a retro terminal-style web interface. **Tech Stack:** - Backend: PHP 7.4+ with MySQLi @@ -40,57 +54,100 @@ Controllers → Models → Database Views ``` -### Project Structure (Updated) +### Project Structure ``` /tinker_tickets/ ├── api/ # API endpoints │ ├── add_comment.php # POST: Add comment -│ ├── assign_ticket.php # POST: Assign ticket to user (NEW) -│ ├── bulk_operation.php # POST: Bulk operations - admin only (NEW) -│ ├── get_template.php # GET: Fetch ticket template (NEW) -│ ├── get_users.php # GET: Get user list (NEW) -│ └── update_ticket.php # POST: Update ticket (workflow validation) +│ ├── assign_ticket.php # POST: Assign ticket to user +│ ├── bulk_operation.php # POST: Bulk operations - admin only +│ ├── check_duplicates.php # GET: Check for duplicate tickets +│ ├── delete_attachment.php # POST/DELETE: Delete attachment +│ ├── export_tickets.php # GET: Export tickets to CSV/JSON +│ ├── get_template.php # GET: Fetch ticket template +│ ├── get_users.php # GET: Get user list +│ ├── manage_recurring.php # CRUD: Recurring tickets (admin) +│ ├── manage_templates.php # CRUD: Templates (admin) +│ ├── manage_workflows.php # CRUD: Workflow rules (admin) +│ ├── ticket_dependencies.php # GET/POST/DELETE: Ticket dependencies +│ ├── update_ticket.php # POST: Update ticket (workflow validation) +│ └── upload_attachment.php # GET/POST: List or upload attachments ├── assets/ │ ├── css/ -│ │ ├── dashboard.css # Shared + dashboard + bulk actions -│ │ └── ticket.css # Ticket + timeline + dark mode fixes +│ │ ├── dashboard.css # Dashboard + terminal styling +│ │ └── ticket.css # Ticket view styling │ ├── js/ -│ │ ├── dashboard.js # Dashboard + hamburger + bulk actions + templates -│ │ └── ticket.js # Ticket + comments + status updates + assignment +│ │ ├── advanced-search.js # Advanced search modal +│ │ ├── ascii-banner.js # ASCII art banner +│ │ ├── dashboard.js # Dashboard + bulk actions + templates +│ │ ├── keyboard-shortcuts.js # Keyboard shortcuts +│ │ ├── markdown.js # Markdown rendering +│ │ ├── settings.js # User preferences +│ │ ├── ticket.js # Ticket + comments + assignment +│ │ └── toast.js # Toast notifications │ └── images/ │ └── favicon.png ├── config/ │ └── config.php # Config + .env loading -├── controllers/ # MVC Controllers -│ ├── DashboardController.php # Dashboard with assigned_to column +├── controllers/ +│ ├── DashboardController.php # Dashboard with stats + filters │ └── TicketController.php # Ticket CRUD + timeline + templates -├── models/ # Data models +├── cron/ +│ └── create_recurring_tickets.php # Process recurring ticket schedules +├── helpers/ +│ └── ResponseHelper.php # Standardized JSON responses +├── middleware/ +│ ├── AuthMiddleware.php # Authelia SSO integration +│ ├── CsrfMiddleware.php # CSRF protection +│ ├── RateLimitMiddleware.php # API rate limiting +│ └── SecurityHeadersMiddleware.php # Security headers +├── models/ │ ├── AuditLogModel.php # Audit logging + timeline -│ ├── BulkOperationsModel.php # Bulk operations tracking (NEW) +│ ├── BulkOperationsModel.php # Bulk operations tracking │ ├── CommentModel.php # Comment data access -│ ├── TemplateModel.php # Ticket templates (NEW) +│ ├── CustomFieldModel.php # Custom field definitions/values +│ ├── DependencyModel.php # Ticket dependencies +│ ├── RecurringTicketModel.php # Recurring ticket schedules +│ ├── StatsModel.php # Dashboard statistics +│ ├── TemplateModel.php # Ticket templates │ ├── TicketModel.php # Ticket CRUD + assignment -│ ├── UserModel.php # User management (NEW) -│ └── WorkflowModel.php # Status transition workflows (NEW) -├── views/ # PHP templates +│ ├── UserModel.php # User management +│ ├── UserPreferencesModel.php # User preferences +│ └── WorkflowModel.php # Status transition workflows +├── scripts/ +│ └── cleanup_orphan_uploads.php # Clean orphaned uploads +├── uploads/ # File attachment storage +├── views/ +│ ├── admin/ +│ │ ├── AuditLogView.php # Audit log browser +│ │ ├── CustomFieldsView.php # Custom field management +│ │ ├── RecurringTicketsView.php # Recurring ticket management +│ │ ├── TemplatesView.php # Template management +│ │ ├── UserActivityView.php # User activity report +│ │ └── WorkflowDesignerView.php # Workflow transition designer │ ├── CreateTicketView.php # Ticket creation with templates -│ ├── DashboardView.php # Dashboard with bulk actions + assigned column +│ ├── DashboardView.php # Dashboard with stats + bulk actions │ └── TicketView.php # Ticket view with timeline + assignment -├── migrations/ # Database migrations -│ ├── 001_initial_schema.sql -│ ├── 007_add_ticket_assignment.sql # Ticket assignment -│ ├── 008_add_status_workflows.sql # Workflow rules -│ ├── 009_add_ticket_templates.sql # Ticket templates -│ ├── 010_add_bulk_operations.sql # Bulk operations -│ └── 011_remove_view_tracking.sql # Remove view audit logs -├── .env # Environment variables (GITIGNORED) -├── Claude.md # This file -├── README.md # User documentation -├── index.php # Dashboard entry point -└── ticket.php # Ticket view/create router +├── .env # Environment variables (GITIGNORED) +├── Claude.md # This file +├── README.md # User documentation +└── index.php # Main router ``` -## Database Schema (Updated) +## Admin Pages + +All admin pages are accessible via the **Admin dropdown** in the dashboard header (for admin users only). + +| Route | Description | +|-------|-------------| +| `/admin/templates` | Create and edit ticket templates | +| `/admin/workflow` | Visual workflow transition designer | +| `/admin/recurring-tickets` | Manage recurring ticket schedules | +| `/admin/custom-fields` | Define custom fields per category | +| `/admin/user-activity` | View per-user activity statistics | +| `/admin/audit-log` | Browse all audit log entries | + +## Database Schema **Database**: `ticketing_system` at 10.10.10.50 **User**: `tinkertickets` @@ -98,443 +155,63 @@ Controllers → Models → Database ### Core Tables -#### `tickets` Table (Updated) -```sql -CREATE TABLE tickets ( - ticket_id INT AUTO_INCREMENT PRIMARY KEY, - title VARCHAR(255) NOT NULL, - description TEXT, - status VARCHAR(50) DEFAULT 'Open', - priority INT DEFAULT 4, - category VARCHAR(50) DEFAULT 'General', - type VARCHAR(50) DEFAULT 'Issue', - created_by INT, -- User who created - updated_by INT, -- User who last updated - assigned_to INT, -- User assigned to (NEW) - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - FOREIGN KEY (created_by) REFERENCES users(user_id), - FOREIGN KEY (updated_by) REFERENCES users(user_id), - FOREIGN KEY (assigned_to) REFERENCES users(user_id) ON DELETE SET NULL, - INDEX idx_status (status), - INDEX idx_assigned_to (assigned_to) -) ENGINE=InnoDB; -``` +- `tickets` - Core ticket data with assignment +- `ticket_comments` - Markdown-supported comments +- `ticket_attachments` - File attachment metadata +- `ticket_dependencies` - Ticket relationships (blocks/blocked_by/relates_to/duplicates) +- `users` - User accounts synced from LLDAP +- `user_preferences` - User settings and preferences +- `audit_log` - Complete audit trail +- `status_transitions` - Workflow configuration +- `ticket_templates` - Reusable ticket templates +- `recurring_tickets` - Scheduled ticket definitions +- `custom_field_definitions` - Custom field schemas +- `custom_field_values` - Custom field data per ticket +- `saved_filters` - User-saved dashboard filters +- `bulk_operations` - Bulk operation tracking -#### `users` Table (SSO Integration) -```sql -CREATE TABLE users ( - user_id INT AUTO_INCREMENT PRIMARY KEY, - username VARCHAR(100) UNIQUE NOT NULL, - display_name VARCHAR(255), - email VARCHAR(255), - is_admin BOOLEAN DEFAULT FALSE, - last_login TIMESTAMP NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -) ENGINE=InnoDB; -``` - -#### `comments` Table -```sql -CREATE TABLE comments ( - comment_id INT AUTO_INCREMENT PRIMARY KEY, - ticket_id INT NOT NULL, - user_id INT, - comment_text TEXT NOT NULL, - markdown_enabled BOOLEAN DEFAULT FALSE, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (ticket_id) REFERENCES tickets(ticket_id) ON DELETE CASCADE, - FOREIGN KEY (user_id) REFERENCES users(user_id), - INDEX idx_ticket_id (ticket_id) -) ENGINE=InnoDB; -``` - -#### `audit_log` Table (Activity Timeline) -```sql -CREATE TABLE audit_log ( - log_id INT AUTO_INCREMENT PRIMARY KEY, - user_id INT, - action_type VARCHAR(50) NOT NULL, -- 'create', 'update', 'comment', 'assign', etc. - entity_type VARCHAR(50) NOT NULL, -- 'ticket', 'comment' - entity_id INT NOT NULL, -- ticket_id or comment_id - details JSON, -- JSON details of what changed - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (user_id) REFERENCES users(user_id), - INDEX idx_entity (entity_type, entity_id), - INDEX idx_user (user_id), - INDEX idx_action (action_type) -) ENGINE=InnoDB; -``` - -#### `status_transitions` Table (Workflow Rules) -```sql -CREATE TABLE status_transitions ( - transition_id INT AUTO_INCREMENT PRIMARY KEY, - from_status VARCHAR(50) NOT NULL, - to_status VARCHAR(50) NOT NULL, - requires_comment BOOLEAN DEFAULT FALSE, -- Transition requires comment - requires_admin BOOLEAN DEFAULT FALSE, -- Transition requires admin - is_active BOOLEAN DEFAULT TRUE, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - UNIQUE KEY unique_transition (from_status, to_status), - INDEX idx_from_status (from_status) -) ENGINE=InnoDB; -``` - -Default transitions: -```sql --- Open → Pending → In Progress → Closed --- In Progress → Closed, Pending --- Closed → X -``` - -#### `ticket_templates` Table -```sql -CREATE TABLE ticket_templates ( - template_id INT AUTO_INCREMENT PRIMARY KEY, - template_name VARCHAR(100) NOT NULL, - title_template VARCHAR(255) NOT NULL, - description_template TEXT NOT NULL, - category VARCHAR(50), - type VARCHAR(50), - default_priority INT DEFAULT 4, - created_by INT, - is_active BOOLEAN DEFAULT TRUE, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (created_by) REFERENCES users(user_id), - INDEX idx_template_name (template_name) -) ENGINE=InnoDB; -``` - -Default templates: Hardware Failure, Software Installation, Network Issue, Maintenance Request - -#### `bulk_operations` Table -```sql -CREATE TABLE bulk_operations ( - operation_id INT AUTO_INCREMENT PRIMARY KEY, - operation_type VARCHAR(50) NOT NULL, -- 'bulk_close', 'bulk_assign', 'bulk_priority' - ticket_ids TEXT NOT NULL, -- Comma-separated ticket IDs - performed_by INT NOT NULL, - parameters JSON, -- Operation parameters - status VARCHAR(20) DEFAULT 'pending', - total_tickets INT, - processed_tickets INT DEFAULT 0, - failed_tickets INT DEFAULT 0, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - completed_at TIMESTAMP NULL, - FOREIGN KEY (performed_by) REFERENCES users(user_id), - INDEX idx_performed_by (performed_by), - INDEX idx_created_at (created_at) -) ENGINE=InnoDB; -``` - -## API Endpoints (Updated) +## API Endpoints ### Authentication All API endpoints check: `$_SESSION['user']['user_id']` for authentication. Admin-only endpoints check: `$_SESSION['user']['is_admin']`. -### POST `/api/update_ticket.php` -Updates ticket with workflow validation. +### Core Endpoints -**Request:** -```json -{ - "ticket_id": 123, - "status": "In Progress", // Validated against workflow rules - "priority": 2, - "title": "Updated title", - "description": "...", - "category": "Software", - "type": "Task" -} -``` +| Endpoint | Method | Description | +|----------|--------|-------------| +| `/api/update_ticket.php` | POST | Update ticket with workflow validation | +| `/api/assign_ticket.php` | POST | Assign ticket to user | +| `/api/add_comment.php` | POST | Add comment to ticket | +| `/api/get_template.php` | GET | Fetch ticket template | +| `/api/get_users.php` | GET | Get user list for assignments | +| `/api/bulk_operation.php` | POST | Perform bulk operations (admin) | +| `/api/ticket_dependencies.php` | GET/POST/DELETE | Manage ticket dependencies | +| `/api/upload_attachment.php` | GET/POST | List or upload attachments | +| `/api/delete_attachment.php` | POST/DELETE | Delete attachment | +| `/api/export_tickets.php` | GET | Export tickets to CSV/JSON | +| `/api/check_duplicates.php` | GET | Check for duplicate tickets | -**Response:** -```json -{ - "success": true, - "status": "In Progress", - "priority": 2, - "message": "Ticket updated successfully" -} -``` +## Dashboard Features -**Features:** -- Workflow validation via WorkflowModel -- Partial updates (only send changed fields) -- User tracking (updated_by) -- Discord webhook notifications -- Audit logging +- **Stats Widgets**: Clickable cards for quick filtering (Open, Critical, Unassigned, Created Today, Closed Today) +- **Admin Dropdown**: Quick access to all admin pages +- **Sortable Columns**: Click headers to sort +- **Advanced Search**: Date ranges, priority ranges, user filters +- **Saved Filters**: Save and load custom filter combinations +- **Bulk Actions** (admin): Select multiple tickets for bulk close/assign/priority/status +- **Export**: Export selected tickets to CSV or JSON +- **Left Sidebar**: Status, Category, Type filters -### POST `/api/assign_ticket.php` (NEW) -Assigns ticket to a user. +## Terminal UI Design -**Request:** -```json -{ - "ticket_id": 123, - "assigned_to": 5 // user_id, or null to unassign -} -``` - -**Response:** -```json -{ - "success": true -} -``` - -### GET `/api/get_users.php` (NEW) -Returns list of all users for assignment dropdowns. - -**Response:** -```json -{ - "success": true, - "users": [ - { - "user_id": 1, - "username": "jared", - "display_name": "Jared Vititoe", - "is_admin": true - } - ] -} -``` - -### GET `/api/get_template.php?template_id=1` (NEW) -Fetches a ticket template. - -**Response:** -```json -{ - "success": true, - "template": { - "template_id": 1, - "template_name": "Hardware Failure", - "title_template": "Hardware Failure: [Device Name]", - "description_template": "Device: \nIssue: \n...", - "category": "Hardware", - "type": "Problem", - "default_priority": 2 - } -} -``` - -### POST `/api/bulk_operation.php` (NEW - ADMIN ONLY) -Performs bulk operations on tickets. - -**Request:** -```json -{ - "operation_type": "bulk_close", // or 'bulk_assign', 'bulk_priority' - "ticket_ids": [123, 456, 789], - "parameters": { // For bulk_assign or bulk_priority - "assigned_to": 5, // For bulk_assign - "priority": 2 // For bulk_priority - } -} -``` - -**Response:** -```json -{ - "success": true, - "operation_id": 42, - "processed": 3, - "failed": 0, - "message": "Bulk operation completed: 3 succeeded, 0 failed" -} -``` - -### POST `/api/add_comment.php` -Adds comment to ticket. - -**Request:** -```json -{ - "ticket_id": 123, - "comment_text": "Comment content", - "markdown_enabled": true -} -``` - -**Response:** -```json -{ - "success": true, - "user_name": "Jared Vititoe", - "created_at": "Jan 01, 2026 12:00" -} -``` - -## Key Features Implementation - -### Feature 1: Activity Timeline -**Location**: Ticket view → Activity tab - -**Implementation**: -- `AuditLogModel->getTicketTimeline()` - Fetches all events for a ticket -- Shows: creates, updates, comments, assignments, status changes -- Displays: user, action, timestamp, details -- CSS: timeline-content boxes with icons -- Dark mode: Fully supported - -**Code**: `views/TicketView.php:258-282`, `models/AuditLogModel.php:getTicketTimeline()` - -### Feature 2: Ticket Assignment -**Location**: Ticket view → "Assigned to" dropdown, Dashboard → "Assigned To" column - -**Implementation**: -- Database: `tickets.assigned_to` column -- Models: `TicketModel->assignTicket()`, `TicketModel->unassignTicket()` -- API: `api/assign_ticket.php` -- Dashboard: Shows assigned user in table -- Auto-saves on change -- Audit logged - -**Code**: `views/TicketView.php:170-181`, `assets/js/ticket.js:handleAssignmentChange()` - -### Feature 3: Status Transitions with Workflows -**Location**: Ticket view → Status dropdown (header) - -**Implementation**: -- Database: `status_transitions` table defines allowed transitions -- Models: `WorkflowModel->isTransitionAllowed()`, `WorkflowModel->getAllowedTransitions()` -- Dropdown shows only valid transitions for current status -- Server-side validation prevents invalid changes -- Can require comments or admin privileges -- Removed from hamburger menu (was duplicate) - -**Code**: `models/WorkflowModel.php`, `api/update_ticket.php:130-144`, `views/TicketView.php:185-198` - -### Feature 4: Ticket Templates -**Location**: Create ticket page → Template selector - -**Implementation**: -- Database: `ticket_templates` table -- Models: `TemplateModel->getAllTemplates()`, `TemplateModel->getTemplateById()` -- API: `api/get_template.php` -- JavaScript: `loadTemplate()` in dashboard.js -- Auto-fills: title, description, category, type, priority -- 4 default templates included - -**Code**: `views/CreateTicketView.php:27-39`, `assets/js/dashboard.js:loadTemplate()` - -### Feature 5: Bulk Actions (Admin Only) -**Location**: Dashboard → Checkboxes + Toolbar (admins only) - -**Implementation**: -- Database: `bulk_operations` table tracks operations -- Models: `BulkOperationsModel->processBulkOperation()` -- API: `api/bulk_operation.php` -- UI: Toolbar appears when tickets selected -- Operations: Bulk close, bulk assign, bulk priority -- All operations audit logged -- Server-side admin validation - -**Code**: `views/DashboardView.php:176-188`, `assets/js/dashboard.js:bulkClose()`, `models/BulkOperationsModel.php` - -## Authentication & SSO Integration - -### Authelia Integration -User information passed via HTTP headers: -- `Remote-User`: Username -- `Remote-Name`: Display name -- `Remote-Email`: Email -- `Remote-Groups`: Comma-separated groups - -### Session Management -```php -$_SESSION['user'] = [ - 'user_id' => 123, - 'username' => 'jared', - 'display_name' => 'Jared Vititoe', - 'email' => 'jared@lotusguild.org', - 'is_admin' => true // true if 'admins' in Remote-Groups -]; -``` - -### Admin Privileges -- Bulk operations (close, assign, priority) -- Future: Admin-only transitions - -## Frontend Components (Updated) - -### Dashboard (`DashboardView.php` + `dashboard.js`) - -**Features**: -- Sortable columns including new "Assigned To" column -- Search (title, description, ticket_id, category, type) -- Status filtering (default: Open + In Progress) -- Pagination (configurable) -- Dark mode toggle -- **Bulk Actions Toolbar** (admin only): - - Checkboxes on each ticket - - "Select All" checkbox - - Bulk close, assign, priority buttons - - Shows count of selected tickets - -**Hamburger Menu**: -- Category/Type filtering -- Apply/Clear filters -- No status field (removed) - -### Ticket View (`TicketView.php` + `ticket.js`) - -**Features**: -- **Tabbed Interface**: Description, Comments, Activity -- **Activity Timeline**: Complete audit trail with icons -- **Assignment Dropdown**: Assign to users -- **Status Dropdown**: Workflow-validated status changes (header) -- **Hamburger Menu**: Priority, Category, Type editing -- **Edit Button**: Title and description editing -- **Markdown Comments**: With live preview -- **Dark Mode**: Comprehensive support - -**Visual Indicators**: -- Priority colors (P1=Red, P2=Orange, P3=Blue, P4=Green, P5=Gray) -- Status badges (Open=Green, In Progress=Yellow, Closed=Red) -- Priority border colors on ticket container - -### Create Ticket (`CreateTicketView.php`) - -**Features**: -- **Template Selector**: Quick-fill from templates -- Standard fields: title, description, status, priority, category, type -- Form validation -- Discord webhook on creation - -## Dark Mode (Fixed) - -### Comprehensive Dark Mode CSS -**Files**: `assets/css/ticket.css`, `assets/css/dashboard.css` - -**Colors**: -```css -body.dark-mode { - --bg-primary: #1a202c; /* Main background */ - --bg-secondary: #2d3748; /* Cards, inputs */ - --bg-tertiary: #4a5568; /* Hover states */ - --text-primary: #e2e8f0; /* Main text */ - --text-secondary: #cbd5e0; /* Secondary text */ - --text-muted: #a0aec0; /* Muted text */ - --border-color: #4a5568; /* Borders */ -} -``` - -**Fixed Elements**: -- Timeline boxes (background + text) -- Bulk actions toolbar -- Tables and table rows -- Input fields and textareas -- Dropdowns and selects -- Comment boxes -- Modal dialogs -- All text elements - -**Important**: Used `!important` flags to override any conflicting styles. +The application uses a retro terminal aesthetic with: +- **Box-drawing characters**: ╔═╗║╚═╝┌─┐│└─┘ +- **Monospace fonts**: Courier New, Consolas, Monaco +- **Terminal colors**: Green (#00ff41), Amber (#ffb000), Cyan (#00ffff) +- **CRT effects**: Scanlines, subtle flicker +- **Glow effects**: Text shadows for terminal phosphor look +- **ASCII art**: Boot sequence, empty states, headers ## Configuration @@ -549,27 +226,6 @@ DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/... **CRITICAL**: `.env` is gitignored! Never commit this file. -### Apache Configuration -**Virtual Host**: Apache serving from `/root/code/tinker_tickets` - -```apache - - ServerName t.lotusguild.org - DocumentRoot /root/code/tinker_tickets - - - Options -Indexes +FollowSymLinks - AllowOverride All - Require all granted - - RewriteEngine On - RewriteBase / - RewriteRule ^ticket/([0-9]+)$ ticket.php?id=$1 [L,QSA] - RewriteRule ^ticket/create$ ticket.php?action=create [L,QSA] - - -``` - ## Deployment ### Git Auto-Deploy @@ -579,17 +235,6 @@ DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/... 1. Push to `main` branch 2. Auto-deploys to `/root/code/tinker_tickets` on 10.10.10.45 3. `.env` is preserved -4. Migrations must be run manually - -### Running Migrations -```bash -cd /root/code/tinker_tickets/migrations -mysql -h 10.10.10.50 -u tinkertickets -p'pass' ticketing_system < 007_add_ticket_assignment.sql -mysql -h 10.10.10.50 -u tinkertickets -p'pass' ticketing_system < 008_add_status_workflows.sql -mysql -h 10.10.10.50 -u tinkertickets -p'pass' ticketing_system < 009_add_ticket_templates.sql -mysql -h 10.10.10.50 -u tinkertickets -p'pass' ticketing_system < 010_add_bulk_operations.sql -mysql -h 10.10.10.50 -u tinkertickets -p'pass' ticketing_system < 011_remove_view_tracking.sql -``` ## Development Guidelines @@ -601,123 +246,45 @@ mysql -h 10.10.10.50 -u tinkertickets -p'pass' ticketing_system < 011_remove_vie ### Error Handling - APIs return JSON with `{success: bool, error: string}` -- Debug logging to `/tmp/api_debug.log` (update_ticket.php) +- Debug logging to `/tmp/api_debug.log` - User-friendly error messages ### Adding New Features -1. **Database**: Create migration in `migrations/` -2. **Model**: Add methods to relevant Model class -3. **API**: Create API endpoint in `api/` (with auth check) -4. **Controller**: Update controller to load data -5. **View**: Add UI elements -6. **JavaScript**: Add interactivity -7. **CSS**: Style for light + dark mode -8. **Test**: Test thoroughly before pushing - -## ANSI Art Redesign (Next Priority) - -### Goal -Transform Tinker Tickets into a retro terminal aesthetic using ANSI art and ASCII characters. - -### Design Concept -- **Terminal-style borders**: Use box-drawing characters (┌─┐│└─┘) -- **Monospace fonts**: Courier New, Consolas, Monaco -- **ASCII art headers**: Stylized "TINKER TICKETS" banner -- **Retro color palette**: Green terminal, amber terminal, or custom -- **Template objects**: Reusable border/box components - -### Implementation Approach -1. **CSS Variables**: Define ANSI color palette -2. **Border Components**: Create CSS classes for boxes with ASCII borders -3. **Typography**: Monospace fonts throughout -4. **Icons**: Replace emoji with ASCII art -5. **Dashboard**: Terminal-style table with borders -6. **Tickets**: Box-drawing characters for sections -7. **Forms**: Terminal-style input boxes - -### Reference Colors (Classic Terminal) -```css -:root { - --ansi-black: #000000; - --ansi-green: #00ff00; - --ansi-amber: #ffb000; - --ansi-blue: #0000ff; - --ansi-cyan: #00ffff; - --ansi-white: #ffffff; - --ansi-bg: #000000; -} -``` - -### Example Box Template -``` -┌─────────────────────────────┐ -│ TICKET #123 │ -├─────────────────────────────┤ -│ Title: Hardware Failure │ -│ Status: [OPEN] │ -│ Priority: P1 (CRITICAL) │ -└─────────────────────────────┘ -``` - -## Debugging - -### Common Issues -```bash -# API debug logs -tail -f /tmp/api_debug.log - -# Database connection -mysql -h 10.10.10.50 -u tinkertickets -p ticketing_system - -# JavaScript console -# Open browser DevTools (F12) → Console tab - -# Check dark mode -# localStorage.getItem('theme') -``` - -### Known Behaviors -- Ticket viewing no longer tracked (011 migration removes view logs) -- Status can only be changed via header dropdown (removed from hamburger) -- Bulk actions only visible to admins -- Templates are optional when creating tickets -- Workflow validation prevents invalid status transitions +1. **Model**: Add methods to relevant Model class +2. **API**: Create API endpoint in `api/` (with auth check) +3. **Controller**: Update controller to load data +4. **View**: Add UI elements +5. **JavaScript**: Add interactivity +6. **CSS**: Style with terminal aesthetic +7. **Test**: Test thoroughly before pushing ## Important Notes for AI Assistants -1. **All 5 features are complete and deployed** -2. **Dark mode is fixed** with comprehensive CSS -3. **Next priority is ANSI Art redesign** (major visual overhaul) -4. **Database at 10.10.10.50**, can't access directly from dev machine -5. **Auto-deploy is active**, test carefully before pushing -6. **Session format**: `$_SESSION['user']['user_id']` (not `$_SESSION['user_id']`) -7. **API auth**: Check `$_SESSION['user']['user_id']` exists -8. **Admin check**: `$_SESSION['user']['is_admin'] ?? false` -9. **Config path**: `config/config.php` (not `config/db.php`) -10. **Migrations**: Must be run manually on database server +1. **All features are complete and deployed** +2. **Terminal UI redesign is complete** - maintain the aesthetic +3. **Database at 10.10.10.50**, can't access directly from dev machine +4. **Auto-deploy is active**, test carefully before pushing +5. **Session format**: `$_SESSION['user']['user_id']` (not `$_SESSION['user_id']`) +6. **API auth**: Check `$_SESSION['user']['user_id']` exists +7. **Admin check**: `$_SESSION['user']['is_admin'] ?? false` +8. **Config path**: `config/config.php` (not `config/db.php`) +9. **Comments table**: `ticket_comments` (not `comments`) +10. **CSRF**: Required for POST/DELETE requests via `X-CSRF-Token` header ## File Reference Quick Guide -| File | Purpose | Key Functions | -|------|---------|---------------| -| `index.php` | Dashboard router | Database connection, routing | -| `ticket.php` | Ticket router | View/create ticket routing | -| `api/update_ticket.php` | Update API | Workflow validation, partial updates | -| `api/assign_ticket.php` | Assignment API | Assign/unassign tickets | -| `api/bulk_operation.php` | Bulk ops API | Admin bulk operations | -| `api/get_template.php` | Template API | Fetch ticket templates | -| `api/get_users.php` | Users API | Get user list | -| `models/TicketModel.php` | Ticket data | CRUD, assignment, filtering | -| `models/WorkflowModel.php` | Workflow rules | Status transition validation | -| `models/AuditLogModel.php` | Audit logging | Timeline, activity tracking | -| `models/TemplateModel.php` | Templates | Template CRUD | -| `models/BulkOperationsModel.php` | Bulk ops | Process bulk operations | -| `controllers/DashboardController.php` | Dashboard logic | Pagination, filters, assigned column | -| `controllers/TicketController.php` | Ticket logic | CRUD, timeline, templates | -| `assets/js/dashboard.js` | Dashboard UI | Filters, bulk actions, templates | -| `assets/js/ticket.js` | Ticket UI | Status updates, assignment, comments | -| `assets/css/dashboard.css` | Dashboard styles | Layout, table, bulk toolbar, dark mode | -| `assets/css/ticket.css` | Ticket styles | Timeline, ticket view, dark mode | +| File | Purpose | +|------|---------| +| `index.php` | Main router for all routes | +| `api/update_ticket.php` | Ticket updates with workflow validation | +| `api/ticket_dependencies.php` | Manage ticket dependencies | +| `models/TicketModel.php` | Ticket CRUD, assignment, filtering | +| `models/WorkflowModel.php` | Status transition validation | +| `models/DependencyModel.php` | Ticket dependency management | +| `controllers/DashboardController.php` | Dashboard logic, stats, filters | +| `assets/js/dashboard.js` | Dashboard UI, bulk actions, templates | +| `assets/js/ticket.js` | Ticket UI, comments, assignment | +| `assets/css/dashboard.css` | Terminal styling, layout, components | ## Repository & Contact diff --git a/README.md b/README.md index f55c0d4..f56419a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ # Tinker Tickets -A feature-rich PHP-based ticketing system designed for tracking and managing data center infrastructure issues with enterprise-grade workflow management. +A feature-rich PHP-based ticketing system designed for tracking and managing data center infrastructure issues with enterprise-grade workflow management and a retro terminal aesthetic. ## Core Features ### Dashboard & Ticket Management - **Smart Dashboard**: Sortable columns, advanced filtering by status/priority/category/type +- **Stats Widgets**: Clickable cards for quick filtering (Open, Critical, Unassigned, Today's tickets) - **Full-Text Search**: Search across tickets, descriptions, and metadata +- **Advanced Search**: Date ranges, priority ranges, user filters with saved filter support - **Ticket Assignment**: Assign tickets to specific users with quick-assign from dashboard - **Priority Tracking**: P1 (Critical) to P5 (Minimal Impact) with color-coded indicators - **Custom Categories**: Hardware, Software, Network, Security, General @@ -57,14 +59,16 @@ A feature-rich PHP-based ticketing system designed for tracking and managing dat - **Bulk Status**: Change status for multiple tickets ### Admin Pages +Access all admin pages via the **Admin dropdown** in the dashboard header. + | Route | Description | |-------|-------------| +| `/admin/templates` | Create and edit ticket templates | +| `/admin/workflow` | Visual workflow transition designer | | `/admin/recurring-tickets` | Manage recurring ticket schedules | | `/admin/custom-fields` | Define custom fields per category | -| `/admin/workflow` | Visual workflow transition designer | -| `/admin/templates` | Create and edit ticket templates | -| `/admin/audit-log` | Browse all audit log entries | | `/admin/user-activity` | View per-user activity statistics | +| `/admin/audit-log` | Browse all audit log entries | ### Notifications - **Discord Integration**: Webhook notifications for ticket creation and updates @@ -86,9 +90,10 @@ A feature-rich PHP-based ticketing system designed for tracking and managing dat - **Architecture**: MVC pattern with models, views, controllers ### Frontend -- **HTML5/CSS3**: Semantic markup with modern CSS +- **HTML5/CSS3**: Semantic markup with retro terminal styling - **JavaScript**: Vanilla JS with Fetch API for AJAX - **Markdown**: Custom markdown parser with toolbar +- **Terminal UI**: Box-drawing characters, monospace fonts, CRT effects ### Database Tables | Table | Purpose | @@ -137,7 +142,7 @@ DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/... ### 2. Database Setup -The database schema is managed through migrations. For a fresh install, run all migrations in order using the migration runner. +The database schema should already be configured. For a fresh install, contact the system administrator for database setup instructions. ### 3. Cron Jobs @@ -188,7 +193,6 @@ tinker_tickets/ ├── uploads/ # File upload storage ├── views/ # View templates │ └── admin/ # Admin panel views -├── migrations/ # Database migrations ├── index.php # Main router └── .env # Environment configuration ``` diff --git a/api/ticket_dependencies.php b/api/ticket_dependencies.php index 89eeb71..0bd0c39 100644 --- a/api/ticket_dependencies.php +++ b/api/ticket_dependencies.php @@ -1,18 +1,34 @@ false, + 'error' => 'Fatal: ' . $error['message'], + 'file' => basename($error['file']), + 'line' => $error['line'] + ]); + } +}); + ini_set('display_errors', 0); error_reporting(E_ALL); -// Custom error handler to return JSON errors +// Custom error handler set_error_handler(function($errno, $errstr, $errfile, $errline) { + ob_end_clean(); http_response_code(500); header('Content-Type: application/json'); echo json_encode([ @@ -26,6 +42,7 @@ set_error_handler(function($errno, $errstr, $errfile, $errline) { // Custom exception handler set_exception_handler(function($e) { + ob_end_clean(); http_response_code(500); header('Content-Type: application/json'); echo json_encode([ @@ -81,6 +98,12 @@ if ($conn->connect_error) { ResponseHelper::serverError('Database connection failed'); } +// Check if ticket_dependencies table exists +$tableCheck = $conn->query("SHOW TABLES LIKE 'ticket_dependencies'"); +if ($tableCheck->num_rows === 0) { + ResponseHelper::serverError('Ticket dependencies feature not available. The ticket_dependencies table does not exist. Please run the migration.'); +} + try { $dependencyModel = new DependencyModel($conn); $auditLog = new AuditLogModel($conn); diff --git a/assets/css/dashboard.css b/assets/css/dashboard.css index 9bf7d28..9cb5c63 100644 --- a/assets/css/dashboard.css +++ b/assets/css/dashboard.css @@ -3167,3 +3167,79 @@ tr:hover .quick-actions { background: rgba(0, 255, 65, 0.1); color: var(--terminal-amber); } + +/* ===== ADMIN DROPDOWN ===== */ +.admin-dropdown { + position: relative; + display: inline-block; +} + +.admin-dropdown .admin-badge { + cursor: pointer; + padding: 0.3rem 0.6rem; +} + +.admin-dropdown-content { + display: none; + position: absolute; + top: 100%; + right: 0; + background: var(--bg-primary); + border: 2px solid var(--priority-1); + min-width: 180px; + z-index: 1000; + box-shadow: 0 0 15px rgba(255, 77, 77, 0.3); +} + +.admin-dropdown-content.show { + display: block; +} + +.admin-dropdown-content a { + display: block; + padding: 0.6rem 1rem; + color: var(--terminal-green); + text-decoration: none; + font-family: var(--font-mono); + font-size: 0.85rem; + transition: all 0.2s ease; + border-bottom: 1px solid var(--bg-tertiary); +} + +.admin-dropdown-content a:last-child { + border-bottom: none; +} + +.admin-dropdown-content a:hover { + background: rgba(255, 77, 77, 0.1); + color: var(--priority-1); + text-shadow: var(--glow-red); +} + +/* ===== CLICKABLE STAT CARDS ===== */ +.stat-card:hover { + transform: translateY(-2px); +} + +.stat-card:active { + transform: translateY(0); +} + +/* ===== TABLE OVERFLOW FIX ===== */ +.ascii-content { + overflow-x: auto; +} + +/* Reduce column widths for better fit */ +table th, +table td { + padding: 8px 10px; + font-size: 0.85rem; +} + +/* Make title column wrap if needed */ +table td:nth-child(4) { + max-width: 180px; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/index.php b/index.php index 73b90f0..97ad2df 100644 --- a/index.php +++ b/index.php @@ -224,7 +224,6 @@ switch (true) { (SELECT COUNT(*) FROM tickets t WHERE t.assigned_to = u.user_id AND DATE(t.created_at) BETWEEN ? AND ?) as tickets_assigned, (SELECT MAX(al.created_at) FROM audit_log al WHERE al.user_id = u.user_id) as last_activity FROM users u - WHERE u.is_active = 1 ORDER BY tickets_created DESC, tickets_resolved DESC"; $stmt = $conn->prepare($sql); diff --git a/migrations/run_migrations.php b/migrations/run_migrations.php deleted file mode 100644 index 786683f..0000000 --- a/migrations/run_migrations.php +++ /dev/null @@ -1,107 +0,0 @@ -connect_error) { - die("Database connection failed: " . $conn->connect_error . "\n"); -} - -echo "Connected to database: {$envVars['DB_NAME']}\n\n"; - -// Get all migration files -$migrationFiles = glob(__DIR__ . '/*.sql'); -sort($migrationFiles); - -// Filter out rollback script -$migrationFiles = array_filter($migrationFiles, function($file) { - return !strpos($file, 'rollback'); -}); - -if (empty($migrationFiles)) { - echo "No migration files found.\n"; - exit(0); -} - -echo "Found " . count($migrationFiles) . " migration(s):\n"; -foreach ($migrationFiles as $file) { - echo " - " . basename($file) . "\n"; -} -echo "\n"; - -// Execute each migration -$successCount = 0; -$errorCount = 0; - -foreach ($migrationFiles as $file) { - $filename = basename($file); - echo "Executing: $filename... "; - - $sql = file_get_contents($file); - - // Split SQL into individual statements - // This handles multi-statement migrations - if ($conn->multi_query($sql)) { - do { - // Store first result set - if ($result = $conn->store_result()) { - $result->free(); - } - // Check for errors - if ($conn->errno) { - echo "FAILED\n"; - echo " Error: " . $conn->error . "\n"; - $errorCount++; - break; - } - } while ($conn->more_results() && $conn->next_result()); - - // If we got through all results without error - if (!$conn->errno) { - echo "OK\n"; - $successCount++; - } - } else { - echo "FAILED\n"; - echo " Error: " . $conn->error . "\n"; - $errorCount++; - } -} - -echo "\n"; -echo "Migration Summary:\n"; -echo " Success: $successCount\n"; -echo " Errors: $errorCount\n"; - -if ($errorCount > 0) { - echo "\nSome migrations failed. Please review errors above.\n"; - exit(1); -} else { - echo "\nAll migrations completed successfully!\n"; - exit(0); -} - -$conn->close(); diff --git a/views/DashboardView.php b/views/DashboardView.php index 69942ca..6e41ede 100644 --- a/views/DashboardView.php +++ b/views/DashboardView.php @@ -79,7 +79,17 @@ 👤 - Admin + @@ -667,5 +677,47 @@ + \ No newline at end of file diff --git a/views/admin/RecurringTicketsView.php b/views/admin/RecurringTicketsView.php index 7577fc2..884b09f 100644 --- a/views/admin/RecurringTicketsView.php +++ b/views/admin/RecurringTicketsView.php @@ -108,7 +108,7 @@