Compare commits

..

No commits in common. "7083a55e0333d717f0e25f79b740e79753a00105" and "bd9ddfb0d2da552876686695f9b63ee3d6486a49" have entirely different histories.

24 changed files with 46 additions and 21928 deletions

3
.gitignore vendored
View File

@ -1,5 +1,4 @@
composer.lock
package-lock.json
lib/
downloads/
public/tmp/
@ -7,5 +6,3 @@ storage/
public/test.php
app/config/.env.cfg
app/.env.cfg
app/config/tp_servicedesk.sql
node_modules

View File

@ -61,22 +61,3 @@ POST /project/@id/update=ProjectController->update
GET /users=UserController->index
GET /user/@id/edit=UserController->editForm
POST /user/@id/update=UserController->update
; admin
GET /admin=Admin\HomeController->index
; admin/priority
GET /admin/priority=Admin\TicketOptionsController->listPriorities
GET /admin/priority/create=Admin\TicketOptionsController->createPriorityForm
POST /admin/priority/create=Admin\TicketOptionsController->createPriority
GET /admin/priority/@id/edit=Admin\TicketController->editPriorityForm
POST /admin/priority/@id/update=Admin\TicketController->updatePriority
GET /admin/priority/@id/delete=Admin\TicketController->deletePriority
; admin/status
GET /admin/status=Admin\TicketOptionsController->listStatuses
GET /admin/status/create=Admin\TicketOptionsController->createStatusForm
POST /admin/status/create=Admin\TicketOptionsController->createStatus
GET /admin/status/@id/edit=Admin\TicketController->editStatusForm
POST /admin/status/@id/update=Admin\TicketController->updateStatus
GET /admin/status/@id/delete=Admin\TicketController->deleteStatus

View File

@ -1,11 +0,0 @@
<?php
namespace Admin;
class HomeController extends \BaseController
{
public function index($f3)
{
$this->renderView('/ui/views/admin/index.html');
}
}

View File

@ -1,36 +0,0 @@
<?php
namespace Admin;
class TicketOptionsController extends \BaseController
{
public function listPriorities()
{
$this->requireLogin();
// TODO: check admin
$model = new \TicketPriority($this->getDB());
$priorities = $model->findAll();
$this->renderView('/ui/views/admin/priorities/index.html', [
'priorities' => $priorities
]);
}
public function createPriorityForm()
{
$this->requireLogin();
$this->renderView('/ui/views/admin/priorities/create.html');
}
public function createPriority()
{
$this->requireLogin();
$p = new \TicketPriority($this->getDB());
$p->name = $this->f3->get('POST.name');
$p->sort_order = $this->f3->get('POST.sort_order');
$p->save();
}
// TODO: editPriorityForm(), updatePriorityForm(), deletePriorityForm()
}

View File

@ -3,23 +3,16 @@
class IconsHelper extends \Prefab {
static public $status_icons = [
'New' => ['fas fa-circle-dot has-text-success', "🆕"],
'In Progress' => ['fas fa-circle-play has-text-link', "🔄"],
'On Hold' => ['fas fa-pause-circle has-text-warning',"⏸️"],
'Completed' => ['fas fa-check-circle has-text-danger', ""]
'New' => ['fas fa-plus-circle has-text-warning', "🆕"],
'In Progress' => ['fas fa-repeat has-text-link', "🔄"],
'On Hold' => ['fas fa-pause-circle has-text-danger',"⏸️"],
'Completed' => ['fas fa-check-circle has-text-success', ""]
];
static public $priority_icons = [
'Low' => ['fas fa-circle-down',"🟢"],
'Medium' => ['fas fa-circle-dot', "🟡"],
'High' => ['fas fa-circle-up', "🔴"]
];
static public $priority_colors = [
'Low' => 'success',
'Medium' => 'warning',
'High' => 'danger',
'' => 'info'
'Low' => ['fas fa-arrow-down',"🟢"],
'Medium' => ['fas fa-minus', "🟡"],
'High' => ['fas fa-arrow-up', "🔴"]
];
static public function icons($node){
@ -45,21 +38,13 @@ class IconsHelper extends \Prefab {
break;
case 'priority':
$icon_class = IconsHelper::$priority_icons[$value] ?? ['fas fa-question-circle', "🔲"];
$icon_color = IconsHelper::$priority_colors[$value] ?? 'info';
break;
default:
$icon_class = 'fas fa-question-circle';
}
if($type == 'priority'){
// return '<p class="button"><span class="icon is-small">'
return '<span class="icon is-medium">
<i class="'.$icon_class[0].' fa-lg has-text-'.$icon_color.'"></i>
</span>';
} else {
return '<span class="icon is-medium"><i class="'.$icon_class[0].' fa-lg"></i></span>';
}
return '<span class="is-size-5">'.$icon_class[1].'</span>';
return '<i class="'.$icon_class[0].' is-size-4"></i>';
}

View File

@ -11,11 +11,10 @@ class Ticket extends \DB\SQL\Mapper {
public function findAll(): array
{
return $this->db->exec(
'SELECT t.* , tp.name AS priority_name, ts.name AS status_name, u.display_name
'SELECT t.* , tp.name AS priority_name, ts.name AS status_name
FROM tickets t
LEFT JOIN ticket_priorities tp ON t.priority_id = tp.id
LEFT JOIN ticket_statuses ts ON t.status_id = ts.id
LEFT JOIN users u ON t.created_by = u.id
WHERE t.recycled = 0
ORDER BY t.created_at DESC'
);

View File

@ -1,10 +0,0 @@
{
"dependencies": {
"bulma": "^1.0.3"
},
"scripts": {
"sass": "sass scss/main.scss public/css/main.css",
"sass:min": "sass scss/main.scss public/css/main.min.css --style compressed",
"sass:watch": "sass --watch scss/main.scss:public/css/main.css"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,8 +8,6 @@ i.fa { font-weight: 100 !important ; }
.table th.th-icon { width: 2rem; }
#ticket_list .g-flex-item { border-bottom: 1px solid var(--bulma-text-soft); }
/* List Component */
.list{
--be-list-color:var(--bulma-text);

View File

@ -1,59 +0,0 @@
@use "../vendor/bulma";
.ticket-item {
@extend .is-flex;
@extend .mb-1;
@extend .pt-1;
@extend .pb-2;
@extend .is-align-items-flex-start;
border-bottom: 1px solid var(--bulma-text-90);
.ticket-icon {
@extend .mr-2;
display: flex;
align-items: baseline;
.checkbox {
margin-right: 0.5rem;
}
}
.ticket-content {
@extend .is-flex;
@extend .is-flex-direction-column;
@extend .is-flex-grow-1;
align-self: baseline;
.ticket-header {
@extend .is-flex;
@extend .is-justify-content-flex-start;
@extend .is-flex-wrap-wrap;
align-items: center;
.ticket-title {
@extend .title;
@extend .is-5;
@extend .mb-1;
font-weight: normal;
}
.tags {
@extend .ml-2;
}
}
.ticket-meta {
@extend .is-flex;
align-items: center;
flex-wrap: wrap;
gap: 0.25rem;
p {
@extend .subtitle;
@extend .is-6;
font-weight: 300;
margin: 0;
}
}
}
}

View File

@ -1,5 +0,0 @@
// import bulma
@use "vendor/bulma";
// import custom components
@use "components/ticket-item";

View File

@ -1,3 +0,0 @@
@use "../../node_modules/bulma/sass/utilities/" as bulma-utils;
@use "../../node_modules/bulma/sass/helpers/" as bulma-helpers;
@use "../../node_modules/bulma/sass/elements/" as bulma-elements;

View File

@ -1 +0,0 @@
@forward "../../node_modules/bulma/bulma";

View File

@ -1,34 +0,0 @@
<div class="ticket-item">
<div class="ticket-icon">
<div class="field">
<label class="b-checkbox checkbox">
<input type="checkbox" value="false" />
<span class="check"></span>
<span class="control-label"></span>
</label>
</div>
<span class="icon is-medium"><icons type="status">{{@ticket.status_name}}</icons></span>
</div>
<div class="ticket-content">
<div class="ticket-header">
<span class="ticket-title">
<a href="/ticket/{{ @ticket.id }}">{{ @ticket.title }}</a>
</span>
<div class="tags">
<div class="tags ml-2">
<!-- TODO: get tags -->
<span class="tag is-link">tag</span>
</div>
<?php /*
<repeat group="{{ @ticket.tags }}" value="{{ @tag }}">
<span class="tag is-link">{{ @tag }}</span>
</repeat>
*/ ?>
</div>
</div>
<div class="ticket-meta">
<p>#{{ @ticket.id }} opened {{ @ticket.created_at }} by {{ @ticket.display_name }}</p>
</div>
</div>
</div>

View File

@ -5,16 +5,14 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TP ServiceDesk</title>
<link rel="stylesheet" href="/style.css">
<link rel="stylesheet" href="/css/main.min.css">
<!-- bulma.io-->
<!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.2/css/bulma.min.css"> -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.2/css/bulma.min.css">
<!-- bulma helpers -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma-helpers/0.4.3/css/bulma-helpers.min.css"
integrity="sha512-U6ELnUi7oqVEjkLmFw5r5UR5LEtvpImS/jUykBKneVhD0lxZxfJZ3k3pe003ktrtNZYungd9u3Urp2X09wKwXg=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<!-- bulma-checkbox -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma-checkbox@1.2.1/css/main.min.css" integrity="sha256-wvxLpriInkhouxrLZ5oo74cJpCtZJkR9bRJwFDvdd4w=" crossorigin="anonymous">
<link rel="stylesheet" href="/style.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma-checkradio@2.1/dist/css/bulma-checkradio.min.css">
<!-- font awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"
integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg=="

View File

@ -1,8 +0,0 @@
<h1 class="title">Admin</h1>
<include href="/ui/session/error.html">
<hr>
<section>
<p><a href="/admin/priority">Ticket &gt; Priorities</a></p>
<p><a href="/admin/status">Ticket &gt; Statuses</a></p>
</section>

View File

@ -1,2 +0,0 @@
<h1 class="title">Create Ticket Priority</h1>
<p>TODO:</p>

View File

@ -1,33 +0,0 @@
<h1 class="title">Admin: Ticket Priorities</h1>
<include href="/ui/session/error.html">
<p><a class="button" href="/admin/priority/create">create priority</a></p>
<hr>
<table class="table is-fullwidth is-bordered">
<thead>
<tr class="has-background-grey">
<th class="has-text-light">id</th>
<th class="has-text-light">name</th>
<th class="has-text-light">sort_order</th>
<th class="has-text-light"></th>
</tr>
</thead>
<tbody>
<repeat group="{{@priorities}}" value="{{@priority}}">
<tr>
<td>{{@priority.id}}</td>
<td><a href="/admin/priority/{{@priority.id}}">{{@priority.name}}</a></td>
<td>{{@priority.sort_order}}</td>
<td>
<a class="button is-link is-small" href="/admin/priority/{{@priority.id}}/edit">
<i class="fa fa-edit"></i></a>
<a class="button is-danger is-small"
href="/admin/priority/{{@priority.id}}/delete"
onclick="return confirm('Are you sure you want to delete this ticket?');">
<i class="fa fa-trash-can"></i></a>
</td>
</tr>
</repeat>
</tbody>
</table>

View File

@ -1,38 +1,34 @@
<h1 class="title">Tickets</h1>
<include href="/ui/session/error.html"></include>
</include>
<!-- updated design -- inspiration gitea -->
<div class="field is-grouped">
<div class="control is-expanded">
<div class="field has-addons is-expanded">
<div class="control is-expanded">
<input class="input" type="text" placeholder="Find a ticket">
</div>
<div class="control">
<button class="button is-info"><span class="icon"><i class="fas fa-magnifying-glass"></i></span></button>
</div>
</div>
</div>
<div class="field">
<div class="control">
<p><a class="button is-primary" href="/ticket/create">create ticket</a></p>
</div>
</div>
</div>
<include href="/ui/session/error.html">
<p><a class="button" href="/ticket/create">create ticket</a></p>
<hr>
<div id="ticket_list">
<repeat group="{{@tickets}}" value="{{@ticket}}">
<include href="/ui/partials/ticket_item.html"></include>
</repeat>
</div>
<table class="table is-fullwidth is-bordered">
<thead>
<tr class="has-background-warning">
<th>id</th><th>title</th>
<th>status</th><th>priority</th><th>created_at</th>
<th></th>
</tr>
</thead>
<?php
/*
<div id="ticket_list">
<tbody>
<repeat group="{{@tickets}}" value="{{@ticket}}">
<include href="/ui/views/ticket/index_row.html"></include>
<tr>
<td>{{@ticket.id}}</td>
<td><a href="/ticket/{{@ticket.id}}">{{@ticket.title}}</a></td>
<td><icons type="status">{{@ticket.status_name}}</icons></td>
<td><icons type="priority">{{@ticket.priority_name}}</icons></td>
<td>{{@ticket.created_at}}</td>
<td>
<a class="button is-link is-small" href="/ticket/{{@ticket.id}}/edit">
<i class="fa fa-edit"></i></a>
<a class="button is-danger is-small"
href="/ticket/{{@ticket.id}}/delete"
onclick="return confirm('Are you sure you want to delete this ticket?');">
<i class="fa fa-trash-can"></i></a>
</td>
</tr>
</repeat>
</div>
*/
?>
</tbody>
</table>

View File

@ -1,20 +0,0 @@
<div class="g-flex-item is-flex is-align-items-flex-start mb-1 pt-1 pb-2">
<div class="g-flex-item-icon is-align-self-baseline mr-2">
<label class="checkbox mr-2"><input type="checkbox"></label>
<span class="icon is-medium"><icons type="status">{{@ticket.status_name}}</icons></span>
</div>
<div class="g-flex-item-main is-flex is-flex-direction-column is-flex-grow-1 is-align-self-baseline">
<div class="g-flex-item-header is-flex is-justify-content-flex-start is-flex-wrap-wrap">
<div class="">
<span class="title is-5 has-text-weight-normal"><a href="/ticket/{{@ticket.id}}">{{@ticket.title}}</a></span>
</div>
<div class="tags ml-2">
<!-- TODO: get tags -->
<span class="tag is-link">tag</span>
</div>
</div>
<div class="g-flex-item-body is-flex is-align-items-centre flex-wrap gap ">
<p class="subtitle is-6 has-text-weight-light">#{{@ticket.id}} opened 2025-03-25 by {{@ticket.display_name}}</p>
</div>
</div>
</div>

View File

@ -1,12 +1,6 @@
<!-- Ticket - View -->
<div class="is-flex">
<h1 class="title is-flex-grow-1">{{ @ticket.title }}</h1>
<div class="field is-grouped">
<p class="control"><a class="button" href="/ticket/{{ @ticket.id}}/edit">edit ticket</a></p>
<p class="control"><a class="button is-primary" href="/ticket/create">new ticket</a></p>
</div>
</div>
<h1 class="title">{{ @ticket.title }}</h1>
<p><a href="/ticket/{{ @ticket.id}}/edit">edit ticket</a></p>
<hr>
<div class="content">