moved ui into app folder

This commit is contained in:
tp_dhu 2025-05-03 08:51:33 +01:00
parent 67a35cdf3e
commit 165d4eabe5
32 changed files with 201 additions and 79 deletions

114
app/ui/issues.md Normal file
View File

@ -0,0 +1,114 @@
# MVP Issues
This issue list defines the work required to bring the `tp_servicedesk` Fat-Free PHP application to a beta-ready MVP for personal workload/project tracking.
---
## 🧩 Ticketing System
- [ ] Display assigned user in ticket view
- [ ] Add user assignment capability in ticket create/edit forms
- [ ] Implement ticket filtering (by status, assignee, project)
- [ ] Improve UI feedback for ticket soft-delete
- [ ] Ensure metadata, attachments, and comments update properly on edit
- [ ] Add tag support for tickets (UI and DB updates)
- [ ] Implement ticket history for status/priority changes
- [ ] Add comment thread display on ticket edit view
- [ ] Update "new ticket" template to match the edit form
- [ ] Enable linking tickets using markdown shortcodes (e.g. `#ticket-id` autocomplete)
---
## 📂 Project Management
- [ ] Implement `ProjectController::create()` and `update()` logic
- [ ] Add CRUD for:
- [ ] `project_tasks` (task list under project)
- [ ] `project_links` (related links/resources)
- [ ] `project_events` (project timeline/log)
- [ ] Show tickets related to a project in the project view page
---
## 📚 Knowledge Base (KB)
- [ ] Display and edit tags for each article
- [ ] Show article creator and last updated info
- [ ] Add search suggestions or recent articles on main KB page
---
## 👤 User Management
- [ ] Implement full CRUD in `Admin\UserController`
- [ ] Add role selection to user creation/edit forms
- [ ] Restrict sensitive actions (ticket edit/delete) to owner or admin
---
## ⚙️ Admin Panel
- [ ] Complete admin routes and views for ticket status management
- [ ] Add dashboard widgets (open tickets count, recent updates, etc.)
- [ ] Create settings/config view to manage global app options
---
## 📦 UI & UX Polish
- [ ] Show success/error alerts for all user actions
- [ ] Apply consistent Bulma styling to forms, buttons, and messages
- [ ] Add loading indicators or skeletons on longer actions
- [ ] Embed `/public/test.md.php` JS markdown editor into edit/create ticket templates
- [ ] Add smart shortcuts to markdown editor:
- [ ] `#` opens ticket linking modal
- [ ] `@` opens user tagging modal
- [ ] `!a` opens hyperlink creation modal
---
## 🧪 Quality Assurance
- [ ] Create fake/test data seeder
- [ ] Add DB integrity checks for tickets, users, and project FK links
- [ ] Manually test:
- [ ] Login/logout
- [ ] Ticket create/edit/delete
- [ ] KB CRUD
- [ ] Attachment upload/download
- [ ] Audit all routes and controllers for authentication and access checks
---
## 🔍 Search & Indexing
- [ ] Improve full-text search to be smarter than `LIKE %{query}%`
- [ ] Add partial, fuzzy, and prioritised relevance to results (e.g. `title > tags > content`)
---
## 📅 Timeline & Activity Views
- [ ] Create timeline view per ticket using:
- [ ] status/priority history
- [ ] comments
- [ ] attachments and other actions
- [ ] Build global timeline dashboard to see activity across system
- [ ] Implement calendar heatmap (e.g. GitHub-style) for activity tracking
- [ ] Add drilldown support from calendar to view specific actions on each day
- [ ] Add detailed log/summary of:
- [ ] ticket creation/updates
- [ ] project creation/updates
- [ ] assignments
- [ ] comments
- [ ] closures
---
## 🔐 Security & Session
- [ ] Add CSRF protection for all POST forms
- [ ] Enforce permission checks on:
- [ ] Ticket edits
- [ ] Comment deletion
- [ ] Attachment deletion
- [ ] Add password reset flow or admin-reset function
---
## 📈 Post-MVP (Optional Enhancements)
- [ ] Ticket due dates and reminders
- [ ] Kanban or Gantt-style project view
- [ ] REST API endpoints
---

View File

@ -92,7 +92,7 @@
<!-- Main Content Area --> <!-- Main Content Area -->
<div class="container"> <div class="container">
<include href="ui/session/error.html"> <include href="session/error.html">
</div> </div>
<main class="section" id="page"> <main class="section" id="page">
<div class="container"> <div class="container">

View File

@ -1,9 +1,8 @@
<div class="box"> <div class="block">
<div class="content"> <h4 class="title is-4">Attachments</h4>
<h4 class="title is-4">Attachments</h4> <div class="block">
<div class="block"> <check if="isset( {{@attachments }})">
<check if="isset( {{@attachments }})"> <check if="count({{@attachments}}) > 0">
<check if="count({{@attachments}}) > 0">
<table class="table is-fullwidth is-narrow is-striped is-hoverable"> <table class="table is-fullwidth is-narrow is-striped is-hoverable">
<thead> <thead>
<tr> <tr>
@ -34,23 +33,22 @@
<img src="/attachment/{{@attach.id}}/view"> <img src="/attachment/{{@attach.id}}/view">
</repeat> </repeat>
</div> </div>
</check>
</check> </check>
<div class="block"> </check>
<form action="/ticket/{{@PARAMS.id}}/attachments/upload" method="POST" enctype="multipart/form-data"> <div class="block">
<div class="field has-addons"> <form action="/ticket/{{@PARAMS.id}}/attachments/upload" method="POST" enctype="multipart/form-data">
<div class="control has-icons-left"><!-- is-expanded --> <div class="field has-addons">
<input class="input" type="file" name="attachment" required> <div class="control has-icons-left"><!-- is-expanded -->
<span class="icon is-small is-left"> <input class="input" type="file" name="attachment" required>
<i class="fas fa-file"></i> <span class="icon is-small is-left">
</span> <i class="fas fa-file"></i>
</div> </span>
<div class="control">
<button class="button" type="submit">Upload</button>
</div>
</div> </div>
</form> <div class="control">
</div> <button class="button" type="submit">Upload</button>
</div>
</div>
</form>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,28 +1,27 @@
<hr> <hr>
<div class="box" id="comments"> <div class="block" id="comments">
<h3 class="title is-3">Comments</h3> <h3 class="title is-3">Comments</h3>
<check if="{{ !empty(@comments) }}"> <check if="{{ !empty(@comments) }}">
<div class="list"> <div class="list">
<repeat group="{{ @comments }}" value="{{ @comment}}"> <repeat group="{{ @comments }}" value="{{ @comment}}">
<div class="list-item"> <div class="list-item">
<div class="list-item-image"> <div class="list-item-image">
<figure class="image is-48x48"> <figure class="image is-48x48">
<img class="is-rounded" <img class="is-rounded" src="https://placehold.co/200x200/66d1ff/FFF?text=TP">
src="https://placehold.co/200x200/66d1ff/FFF?text=TP"> <!-- <img class="is-rounded"
<!-- <img class="is-rounded"
src="https://loremflickr.com/200/200/dog?{{ (int)rand()}}">--> src="https://loremflickr.com/200/200/dog?{{ (int)rand()}}">-->
</figure> </figure>
</div>
<div class="list-item-content">
<div class="list-item-title is-flex is-justify-content-space-between">
<span>{{ @comment.author_name}}</span>
<span class="has-text-weight-normal has-text-grey">{{ @comment.created_at }}</span>
</div> </div>
<div class="list-item-description"> <div class="list-item-content">
<parsedown>{{ @comment.comment | raw }}</parsedown> <div class="list-item-title is-flex is-justify-content-space-between">
<span>{{ @comment.author_name}}</span>
<span class="has-text-weight-normal has-text-grey">{{ @comment.created_at }}</span>
</div>
<div class="list-item-description">
<parsedown>{{ @comment.comment | raw }}</parsedown>
</div>
</div> </div>
</div> </div>
</div>
</repeat> </repeat>
</div> </div>
</check> </check>

View File

@ -0,0 +1,3 @@
<h1 class="title">Dashboard</h1>
<parsedown href="issues.md"></parsedown>

View File

@ -61,6 +61,9 @@
options="{{@statuses}}" option_value="id" option_name="name" options="{{@statuses}}" option_value="id" option_name="name"
selected="{{@ticket.status_id}}"></bulma> selected="{{@ticket.status_id}}"></bulma>
</div> </div>
<!-- additional data -->
<div class="block">
</div>
<!-- meta data --> <!-- meta data -->
<div class="block"> <div class="block">
<table class="table is-bordered is-fullwidth"> <table class="table is-bordered is-fullwidth">
@ -128,9 +131,10 @@
<div> <div>
<exclude>
<include href="../ui/views/attachment/index.html"> <include href="views/attachment/index.html"></include>
<include href="../ui/views/comments/view.html"> <include href="views/comments/view.html"></include>
</exclude>
<!-- <!--

View File

@ -15,7 +15,7 @@
options="statuses" option_value="id" option_name="name" options="statuses" option_value="id" option_name="name"
selected="{{@ticket.status_id}}"></bulma> selected="{{@ticket.status_id}}"></bulma>
<include href="/ui/parts/clipboard.html"></include> <include href="parts/clipboard.html"></include>
<div class="block"> <div class="block">
<h3 class="title is-5">Custom Fields</h3> <h3 class="title is-5">Custom Fields</h3>

View File

@ -37,16 +37,14 @@
<div id="ticket_list"> <div id="ticket_list">
<repeat group="{{@tickets}}" value="{{@ticket}}"> <repeat group="{{@tickets}}" value="{{@ticket}}">
<include href="/ui/partials/ticket_item.html"></include> <include href="partials/ticket_item.html"></include>
</repeat> </repeat>
</div> </div>
<?php <exclude>
/* <div id="ticket_list">
<div id="ticket_list"> <repeat group="{{@tickets}}" value="{{@ticket}}">
<repeat group="{{@tickets}}" value="{{@ticket}}"> <include href="views/ticket/index_row.html"></include>
<include href="/ui/views/ticket/index_row.html"></include> </repeat>
</repeat> </div>
</div> </exclude>
*/
?>

View File

@ -13,34 +13,51 @@
<div class="columns"> <div class="columns">
<div class="column is-two-thirds"> <div class="column is-two-thirds">
<!-- content -->
<div class="block"> <div class="block">
<p>{{ @ticket.created_at }}</p> <p>{{ @ticket.created_at }}</p>
<div class="content"> <div class="content">
<parsedown>{{ @ticket.description | raw }}</parsedown> <parsedown>{{ @ticket.description | raw }}</parsedown>
</div> </div>
</div> </div>
<hr>
<include href="views/attachment/index.html">
<include href="views/comments/view.html">
</div> </div>
<div class="column"> <div class="column">
<!-- meta data --> <!-- meta data -->
<div class="block"> <div class="block">
<div class="tags"> <h6 class="title is-6">Tags
<repeat group="{{ @ticket.tags }}" value="{{@tag}}"> <span class="icon"><i class="fas fa-cog"></i></span></h6>
<span class="tag is-{{@tag.color}}">{{@tag.name}}</span>
</repeat> <!-- tags -->
<div class="block">
<div class="tags">
<repeat group="{{ @ticket.tags }}" value="{{@tag}}">
<span class="tag is-{{@tag.color}}">{{@tag.name}}</span>
</repeat>
</div>
</div> </div>
<table class="table is-bordered is-fullwidth"> </div>
<thead> <hr>
<tr><th class="has-width-100">Property</th><th>Value</th></tr> <div class="block">
</thead> <h6 class="title is-6">Projects
<tbody> <span class="icon"><i class="fas fa-cog"></i></span></h6>
<repeat group="{{ @ticket }}" key="{{ @key }}" value="{{ @value }}"> <hr>
<check if="{{ @key !== 'description'}}"> <h6 class="title is-6">Assignees</h6>
<tr><td>{{@key}}</td> <td>{{@value}}</td></tr> <check if="{{ @assigned_user }}">
</check> <div class="block">
</repeat> <h4 class="title">Assigned User</h4>
</tbody> <p>{{ @assigned_user.display_name ?: @assigned_user.username }}</p>
</table> </div>
</check>
<h6 class="title is-6">Participants</h6>
<h6 class="title is-6">Time Tracker?</h6>
<h6 class="title is-6">Dependencies</h6>
<p>Reference:</p>
<a href="#" class="button"><span class="icon">
<i class="fas fa-trash"></i></span><span>Delete</span></a>
</div> </div>
<!-- form to add child ticket relationships --> <!-- form to add child ticket relationships -->
<div class="box"> <div class="box">
@ -85,12 +102,6 @@
</div> </div>
<hr>
<include href="../ui/views/attachment/index.html">
<include href="../ui/views/comments/view.html">
<!-- <!--
<div class="block" id="attachments"></div> <div class="block" id="attachments"></div>
<div class="block" id="comments"></div> <div class="block" id="comments"></div>

View File

@ -1,5 +0,0 @@
<h1 class="title">Dashboard</h1>
<parsedown href="issues.md"></parsedown>
<p>109</p>