31 Commits

Author SHA1 Message Date
johnnyq
6df101c217 Css fixes 2026-08-16 22:25:05 -04:00
johnnyq
92377b918a Dark Mode Patches across the board for Calendar TinyMCE additonal dark mode css fixed and fixing autofocus on modal close when modal is open without a form autofocus 2026-08-16 15:57:37 -04:00
johnnyq
0f69ef8e19 Fix Dark mode bg-light and btn-light and multi select box table checkboxes 2026-08-16 13:27:27 -04:00
johnnyq
35ddd1a64d Feature: Designate a client record as your organization currently only provdes a direct link when you click company name in top of the side nav 2026-08-15 20:36:56 -04:00
johnnyq
1514934726 Update DB Structure 2026-08-15 19:56:38 -04:00
johnnyq
6af0634f47 Ticket SLA: Fix on hold to pause only after first reply, show resolved closed and onhold as fixed on paused sla in the list 2026-08-15 19:55:40 -04:00
johnnyq
bcc73737e4 Apply custom css across the board including client portal and guest 2026-08-15 17:53:10 -04:00
johnnyq
6ef84c4547 Feature: Add Ticket Canned Responses 2026-08-15 17:29:17 -04:00
johnnyq
4c4c172f59 Feature: queued Updates which now eliminates the need for shell_exec from the webui, but if enabled you can still update from the webui the old way too 2026-08-15 16:41:42 -04:00
johnnyq
d5ee0bff74 update_cli.php now does both db and forces app updates all in one go no more switches 2026-08-15 15:25:14 -04:00
johnnyq
77319f8fc1 update_cli.php now updates both the app and all database updates in one go and the switches --update only updates the app --db_update only updates the db 2026-08-15 15:12:45 -04:00
johnnyq
bdab434707 Fix Margins in various areas 2026-08-15 13:34:38 -04:00
johnnyq
56d9e04eac Update Theme select to use new bootstrap 5 radio button 2026-08-15 13:17:32 -04:00
johnnyq
72c037c581 Fix Date Range FlatPickr defaulting to 1970 for All time now default to current month 2026-08-15 13:04:55 -04:00
johnnyq
2375e69f2d Update badge classes to bg 2026-08-15 13:00:41 -04:00
johnnyq
73e10e72f2 Update filter bar, increase height on top navbar, primary buttons now inherit theme color 2026-08-15 12:55:24 -04:00
johnnyq
c44fa30792 Fix Mail settings tabs regression and user menu coloring 2026-08-15 12:29:39 -04:00
johnnyq
8c0e5246b4 Fix Card Margin bottoms client header and ticket cards on the right 2026-08-14 19:08:15 -04:00
johnnyq
35239b563d Resize top nav and compoents 2026-08-14 18:53:20 -04:00
johnnyq
e2512b0f86 Fixed Side nav titles, Fixed ajax on bootstrap modals, fixed pagination all regressions 2026-08-14 18:32:33 -04:00
johnnyq
1c5803dc12 Removed dead libs pdfmake dropzone and popper, fixed missing label for ids and migrated datatables to use bootstrap 5 libs instead of of 4 2026-08-14 17:50:17 -04:00
johnnyq
6fc94d9733 Migrated confirm modal to sweetalert2 lib 2026-08-14 17:38:21 -04:00
johnnyq
bbbfff7413 All Jquery removed replaced with stand JS and non jqery dependent libs 2026-08-14 17:28:06 -04:00
johnnyq
2354dd1511 Migrate fully away from Jquery Stage 1 2026-08-14 17:11:01 -04:00
johnnyq
dc6b191eed Update Font, Migrated away from JQUERY dependent libs: toastr to bootstrap5 toasts, daterangepicker to flatpickr, select2 to Tom Select, InputMask to IMask 2026-08-14 17:08:40 -04:00
johnnyq
0fe6d51bdb Theme Fixes for adminlte 4 2026-08-14 14:11:13 -04:00
johnnyq
e6da3fd0e3 Remove script 2026-08-14 13:22:47 -04:00
johnnyq
a084e37c39 Initial migration from AdminLTE 3 to 4, bootstrap 4 to 5 2026-08-14 13:22:11 -04:00
wrongecho
691059aab2 Debug - bump php memory flag to 512M 2026-08-13 09:45:01 +01:00
wrongecho
eda32f7d57 Update security 2026-08-12 15:27:40 +01:00
wrongecho
c44ae74557 Update readme 2026-08-12 15:20:48 +01:00
606 changed files with 16747 additions and 18489 deletions

View File

@@ -27,7 +27,7 @@
· ·
<a href="https://forum.itflow.org/t/bug">Report Bug</a> <a href="https://forum.itflow.org/t/bug">Report Bug</a>
· ·
<a href="https://forum.itflow.org/t/features">Request Feature</a> <a href="https://forum.itflow.org/t/features">Suggest Feature</a>
· ·
<a href="https://github.com/itflow-org/itflow/security/policy">Security</a> <a href="https://github.com/itflow-org/itflow/security/policy">Security</a>
</p> </p>
@@ -44,16 +44,16 @@
### The Problem ### The Problem
- You're a small but busy managed service provider with 101 things to do. Information about your clients is unorganised, unstructured and outdated. - You're a small but busy managed service provider with 101 things to do. Information about your clients is unorganised, unstructured and outdated.
- For some work, you seem to spend longer looking for the relevant documentation than actually working on the issue/project. - For some work, you seem to spend longer looking for the relevant documentation than actually working on the issue/project.
- On top of the technical day to day, you also have to take care of the financial side of the business - consistent pricing, quotes/invoicing, and accounting. - MSP tools can be expensive, with recurring licensing costs adding up quickly.
- On top of the technical day-to-day, you also have to take care of the financial side of the business - consistent pricing, quotes/invoicing, and accounting.
### The Solution: ITFlow ### The Solution: ITFlow
- ITFlow consolidates common MSP needs (documentation, ticketing and billing) into one unified system. - ITFlow consolidates common MSP needs (documentation, ticketing and billing) into one unified, free platform that you control.
<!-- GETTING STARTED -->
## Getting Started ## Getting Started
### Self Hosting ### Self Hosting
- The best installation method is to use the [install script](https://docs.itflow.org/installation_script) on Ubuntu/Debian. A video walk through is available [here](https://www.youtube.com/watch?v=kKz9NOU_1XE). - The best installation method is to use the [install script](https://docs.itflow.org/installation_script) on Ubuntu/Debian. See the [video](https://www.youtube.com/watch?v=kKz9NOU_1XE) walk through.
``` ```
wget -O itflow_install.sh https://github.com/itflow-org/itflow-install-script/raw/main/itflow_install.sh wget -O itflow_install.sh https://github.com/itflow-org/itflow-install-script/raw/main/itflow_install.sh
bash itflow_install.sh bash itflow_install.sh
@@ -61,25 +61,25 @@
- Other manual installation methods are available in the [docs](https://docs.itflow.org/installation). - Other manual installation methods are available in the [docs](https://docs.itflow.org/installation).
### Managed Hosting ### Managed Hosting
- If you'd prefer, we can [host ITFlow for you](https://services.itflow.org/hosting.php). - If you'd prefer, we can [host ITFlow for you](https://services.itflow.org/hosting.php) (coming soon).
<!-- FEATURES --> <!-- FEATURES -->
## Key Features ## Key Features
* Client documentation - assets, contacts, domains, docs, files, passwords, and more * Client documentation - assets, contacts, domains, docs/files, passwords, tickets, and more
* Accounting / Billing - finance dashboard, quotes, invoices, accounting, expenses, etc * Billing - quotes, invoices and expenses, with Stripe integration for online payments
* Client Portal - self service quote/invoice/ticket management for clients * Alerting - domain and SSL expiry/renewals
* Alerting - account balance, invoices, domain/SSL renewals * Client Portal - self service quote, invoice, and ticket management for clients
* Completely free & open-source alternative to ITGlue and Hudu
<!-- ROADMAP --> <!-- ROADMAP -->
## Roadmap / Future to-do ## Roadmap / Future to-do
We track the implementation of confirmed features and bugs via [TaskFlow](https://tasks.dev.itflow.org/tasks.php). Use the [forum](https://forum.itflow.org) to request features or raise bug reports. We track the implementation of confirmed features and bugs via [TaskFlow](https://tasks.dev.itflow.org/tasks.php). Use the [forum](https://forum.itflow.org) to suggest new features or report bugs.
<!-- CONTRIBUTING --> <!-- CONTRIBUTING -->
## Support & Contributions ## Support & Contributions
### Forum ### Forum
For help using ITFlow, bugs, feature requests, and general ideas / discussions please use the community [forum](https://forum.itflow.org). For help using ITFlow, bugs, feature suggestions, and other general ideas or discussions, please use the community [forum](https://forum.itflow.org).
### Contributing ### Contributing
We have temporarily paused PRs from the community. We have temporarily paused PRs from the community.
@@ -90,17 +90,16 @@ We have temporarily paused PRs from the community.
</a> </a>
### Supporters ### Supporters
Were incredibly grateful to the organizations and individuals who support the project - a big thank you to: Were incredibly grateful to the organizations and individuals who [sponsor](https://services.itflow.org) the project - a big thank you to:
- CompuMatter - CompuMatter
- F1 for HELP - F1 for HELP
- digiBandit - digiBandit
- JetBrains (PhpStorm)
## License ## License
ITFlow is distributed "as is" under the GPL License, WITHOUT WARRANTY OF ANY KIND. See [`LICENSE`](https://github.com/itflow-org/itflow/blob/master/LICENSE) for details. ITFlow is distributed "as is" under the GPL License, WITHOUT WARRANTY OF ANY KIND. See [`LICENSE`](https://github.com/itflow-org/itflow/blob/master/LICENSE) for details.
## Security ## Security
* As of 2025, we now have a stable release of the project. * We've had a stable release of the project since Jan 2025.
* Whilst we are confident in the safety of the code, no system is risk-free. Nearly all software has bugs. Use your best judgement before storing highly confidential information in ITFlow. * Whilst we are confident in the safety of the code, no system is risk-free. Nearly all software has bugs. Use your best judgement before storing highly confidential information in ITFlow.
* If you have a security concern, privately report it [here](https://github.com/itflow-org/itflow/security/policy). * If you have a security concern, privately report it [here](https://github.com/itflow-org/itflow/security/policy).

View File

@@ -1,12 +1,12 @@
# Security Policy # Security Policy
## **Please do NOT report security concerns/vulnerabilities publicly (Issues/forum)** ## **Please do NOT report security concerns/vulnerabilities publicly**
**We take security seriously** **ITFlow stores important information, so we take security seriously**
- Whilst we are confident in the safety of the code, no system is risk-free. Nearly all software has bugs. Use your best judgement before storing highly confidential information in ITFlow. - Whilst we are confident in the safety of the code, no system is risk-free. Nearly all software has bugs.
- We attempt to follow security best practices where possible, including [automated code scanning](https://sonarcloud.io/component_measures?id=itflow-org_itflow&metric=security_rating&view=list). - Use your best judgement before storing highly confidential information in ITFlow.
- [![Security](https://sonarcloud.io/api/project_badges/measure?project=itflow-org_itflow&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=itflow-org_itflow) - We attempt to follow security best practices where possible, including automated code scanning.
## Supported Versions ## Supported Versions
We operate a rolling release model. Any bug fixes will be released into latest version of ITFlow, so you must stay up-to-date. We operate a rolling release model. Any bug fixes will be released into latest version of ITFlow, so you must stay up-to-date.
@@ -19,6 +19,8 @@ We operate a rolling release model. Any bug fixes will be released into latest v
**Security contact: [GitHub Security Advisories](https://github.com/itflow-org/itflow/security/advisories/new)** **Security contact: [GitHub Security Advisories](https://github.com/itflow-org/itflow/security/advisories/new)**
If you have discovered a security issue, please **[report it](https://github.com/itflow-org/itflow/security/advisories/new)** to us in as much detail as possible, so we can fix it. If you have discovered a security issue, please **[report it](https://github.com/itflow-org/itflow/security/advisories/new)** to us so we can fix it.
You should expect to receive an initial acknowledgement within 72 hours. If you don't receive any feedback, we may have missed the initial email from GitHub (we're human!). Please raise a forum discussion quoting ONLY the assigned GHSA ref. You should expect to receive an initial acknowledgement within 7 days. If you don't receive any feedback, we may have missed the initial email from GitHub (we're human!). Please raise a forum discussion quoting ONLY the assigned GHSA ref.
Note: Please don't submit AI slop. AI can be useful for drafting and research, but you are responsible for reviewing and validating anything you submit. We reserve the right to restrict repository access if you repeatedly ignore this requirement.

View File

@@ -25,9 +25,9 @@ $num_rows = mysqli_num_rows($sql);
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-2"> <div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-robot mr-2"></i>AI Models</h3> <h3 class="card-title mt-2"><i class="fas fa-fw fa-robot me-2"></i>AI Models</h3>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/ai/ai_model_add.php"><i class="fas fa-plus mr-2"></i>Add Model</button> <button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/ai/ai_model_add.php"><i class="fas fa-plus me-2"></i>Add Model</button>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-body">
@@ -79,18 +79,18 @@ $num_rows = mysqli_num_rows($sql);
<td><?= $use_case ?></td> <td><?= $use_case ?></td>
<td><?= $prompt ?></td> <td><?= $prompt ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" <a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/ai/ai_model_edit.php?id=<?= $model_id ?>"> data-modal-url="modals/ai/ai_model_edit.php?id=<?= $model_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit me-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_ai_model=<?= $model_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger confirm-link" href="post.php?delete_ai_model=<?= $model_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</a> </a>
</div> </div>
</div> </div>

View File

@@ -14,9 +14,9 @@ $num_rows = mysqli_num_rows($sql);
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-2"> <div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-robot mr-2"></i>AI Providers</h3> <h3 class="card-title mt-2"><i class="fas fa-fw fa-robot me-2"></i>AI Providers</h3>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/ai/ai_provider_add.php"><i class="fas fa-plus mr-2"></i>Add Provider</button> <button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/ai/ai_provider_add.php"><i class="fas fa-plus me-2"></i>Add Provider</button>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-body">
@@ -68,20 +68,20 @@ $num_rows = mysqli_num_rows($sql);
<td><?= $url ?></td> <td><?= $url ?></td>
<td><?= $key ?></td> <td><?= $key ?></td>
<td class="text-center"> <td class="text-center">
<a class="badge badge-dark badge-pill p-2" href="ai_models.php"><?= $ai_model_count ?></a> <a class="badge bg-dark rounded-pill p-2" href="ai_models.php"><?= $ai_model_count ?></a>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" <a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/ai/ai_provider_edit.php?id=<?= $provider_id ?>"> data-modal-url="modals/ai/ai_provider_edit.php?id=<?= $provider_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit me-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_ai_provider=<?= $provider_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger confirm-link" href="post.php?delete_ai_provider=<?= $provider_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</a> </a>
</div> </div>
</div> </div>

View File

@@ -18,38 +18,36 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<div class="card card-dark"> <div class="card">
<div class="card-header py-2"> <div class="card-header bg-dark py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-key mr-2"></i>API Keys</h3> <h3 class="card-title mt-2"><i class="fas fa-fw fa-key me-2"></i>API Keys</h3>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/api/api_key_add.php"><i class="fas fa-plus mr-2"></i>New API Key</button> <button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/api/api_key_add.php"><i class="fas fa-plus me-2"></i>New API Key</button>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-header py-3">
<form autocomplete="off"> <form autocomplete="off">
<div class="row"> <div class="row g-2 align-items-center">
<div class="col-md-4"> <div class="col-md-4">
<div class="input-group mb-3 mb-md-0"> <div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search keys"> <input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search keys">
<div class="input-group-append">
<button class="btn btn-primary"><i class="fa fa-search"></i></button> <button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div> </div>
</div> </div>
</div>
<div class="col-md-8"> <div class="col-md-8">
<div class="btn-group float-right"> <div class="btn-group float-end">
<div class="dropdown ml-2" id="bulkActionButton" hidden> <div class="dropdown ms-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>) <i class="fas fa-fw fa-layer-group me-2"></i>Bulk Action (<span id="selectedCount">0</span>)
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<button class="dropdown-item text-danger text-bold" <button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_api_keys"> type="submit" form="bulkActions" name="bulk_delete_api_keys">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</button> </button>
</div> </div>
</div> </div>
@@ -59,17 +57,17 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
</form> </form>
<hr> </div>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<form id="bulkActions" action="post.php" method="post"> <form id="bulkActions" action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<table class="table table-striped table-borderless table-hover"> <table class="table table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr> <tr>
<td class="pr-0"> <td class="pe-0">
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" onclick="checkAll(this)"> <input class="form-check-input" type="checkbox" onclick="checkAll(this)">
</div> </div>
@@ -119,7 +117,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<tr> <tr>
<td class="pr-0"> <td class="pe-0">
<div class="form-check"> <div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="api_key_ids[]" value="<?= $api_key_id ?>"> <input class="form-check-input bulk-select" type="checkbox" name="api_key_ids[]" value="<?= $api_key_id ?>">
</div> </div>
@@ -130,22 +128,22 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<td><?= $api_key_created_at ?></td> <td><?= $api_key_created_at ?></td>
<td><?= $api_key_expire ?></td> <td><?= $api_key_expire ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/api/api_key_edit.php?id=<?= $api_key_id ?>"> <a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/api/api_key_edit.php?id=<?= $api_key_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit me-2"></i>Edit
</a> </a>
<?php if ($api_key_expire > date("Y-m-d H:i:s")) { ?> <?php if ($api_key_expire > date("Y-m-d H:i:s")) { ?>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?revoke_api_key=<?= $api_key_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?revoke_api_key=<?= $api_key_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-times mr-2"></i>Revoke <i class="fas fa-fw fa-times me-2"></i>Revoke
</a> </a>
<?php } ?> <?php } ?>
<?php if ($api_key_expire < date("Y-m-d H:i:s")) { ?> <?php if ($api_key_expire < date("Y-m-d H:i:s")) { ?>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_api_key=<?= $api_key_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_api_key=<?= $api_key_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-times mr-2"></i>Delete <i class="fas fa-fw fa-times me-2"></i>Delete
</a> </a>
<?php } ?> <?php } ?>
</div> </div>
@@ -164,7 +162,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
<?php require_once "../includes/filter_footer.php"; ?> <?php require_once "../includes/filter_footer.php"; ?>
</div> </div>
</div>
<script src="../js/bulk_actions.js"></script> <script src="../js/bulk_actions.js"></script>

View File

@@ -40,28 +40,26 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<div class="card card-dark"> <div class="card">
<div class="card-header py-3"> <div class="card-header bg-dark py-2">
<h3 class="card-title"><i class="fas fa-fw fa-history mr-2"></i>App Logs</h3> <h3 class="card-title"><i class="fas fa-fw fa-history me-2"></i>App Logs</h3>
</div> </div>
<div class="card-body"> <div class="card-header py-3">
<form autocomplete="off"> <form autocomplete="off">
<div class="row"> <div class="row g-2 align-items-end">
<div class="col-sm-4"> <div class="col-sm-4">
<div class="form-group"> <div>
<div class="input-group"> <div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search app logs"> <input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search app logs">
<div class="input-group-append"> <button class="btn btn-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#advancedFilter"><i class="fas fa-filter"></i></button>
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#advancedFilter"><i class="fas fa-filter"></i></button>
<button class="btn btn-primary"><i class="fa fa-search"></i></button> <button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="col-sm-2"> <div class="col-sm-2">
<div class="form-group"> <div>
<select class="form-control select2" name="type" onchange="this.form.submit()"> <select class="form-select select2" name="type" onchange="this.form.submit()">
<option value="">- All Types -</option> <option value="">- All Types -</option>
<?php <?php
@@ -79,8 +77,8 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
<div class="form-group"> <div>
<select class="form-control select2" name="category" onchange="this.form.submit()"> <select class="form-select select2" name="category" onchange="this.form.submit()">
<option value="">- All Categories -</option> <option value="">- All Categories -</option>
<?php <?php
@@ -98,10 +96,10 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
</div> </div>
<div class="collapse mt-3 <?php if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') { echo "show"; } ?>" id="advancedFilter"> <div class="collapse mt-3 <?php if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') { echo "show"; } ?>" id="advancedFilter">
<div class="row"> <div class="row g-3">
<div class="col-md-3"> <div class="col-md-3">
<div class="form-group"> <div>
<label>Date range</label> <label class="form-label">Date range</label>
<input type="text" id="dateFilter" class="form-control" autocomplete="off"> <input type="text" id="dateFilter" class="form-control" autocomplete="off">
<input type="hidden" name="canned_date" id="canned_date" value="<?= escapeHtml($_GET['canned_date']) ?? '' ?>"> <input type="hidden" name="canned_date" id="canned_date" value="<?= escapeHtml($_GET['canned_date']) ?? '' ?>">
<input type="hidden" name="dtf" id="dtf" value="<?= escapeHtml($dtf ?? '') ?>"> <input type="hidden" name="dtf" id="dtf" value="<?= escapeHtml($dtf ?? '') ?>">
@@ -111,9 +109,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
</div> </div>
</form> </form>
<hr> </div>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-sm table-striped table-borderless table-hover"> <table class="table table-sm table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr> <tr>
<th> <th>
@@ -151,7 +149,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<tr> <tr>
<td class="text-monospace"><?= $log_created_at ?></td> <td class="font-monospace"><?= $log_created_at ?></td>
<td><?= $log_type ?></td> <td><?= $log_type ?></td>
<td><?= $log_category ?></td> <td><?= $log_category ?></td>
<td><?= $log_details ?></td> <td><?= $log_details ?></td>
@@ -167,7 +165,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php require_once "../includes/filter_footer.php"; <?php require_once "../includes/filter_footer.php";
?> ?>
</div> </div>
</div>
<?php <?php
require_once "../includes/footer.php"; require_once "../includes/footer.php";

View File

@@ -65,26 +65,24 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<div class="card card-dark"> <div class="card">
<div class="card-header bg-dark py-2">
<h3 class="card-title"><i class="fas fa-fw fa-history me-2"></i>Audit Logs</h3>
</div>
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-history mr-2"></i>Audit Logs</h3> <form autocomplete="off">
</div> <div class="row g-2 align-items-end">
<div class="card-body">
<form class="mb-4" autocomplete="off">
<div class="row">
<div class="col-sm-4"> <div class="col-sm-4">
<div class="input-group mb-3 mb-md-0"> <div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search audit logs"> <input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search audit logs">
<div class="input-group-append"> <button class="btn btn-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#advancedFilter"><i class="fas fa-filter"></i></button>
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#advancedFilter"><i class="fas fa-filter"></i></button>
<button class="btn btn-primary"><i class="fa fa-search"></i></button> <button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div> </div>
</div> </div>
</div>
<div class="col-sm-2"> <div class="col-sm-2">
<div class="input-group mb-3 mb-md-0"> <div class="input-group">
<select class="form-control select2" name="client" onchange="this.form.submit()"> <select class="form-select select2" name="client" onchange="this.form.submit()">
<option value="">- All Clients -</option> <option value="">- All Clients -</option>
<?php <?php
@@ -103,8 +101,8 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
<div class="input-group mb-3 mb-md-0"> <div class="input-group">
<select class="form-control select2" name="user" onchange="this.form.submit()"> <select class="form-select select2" name="user" onchange="this.form.submit()">
<option value="">- All Users -</option> <option value="">- All Users -</option>
<?php <?php
@@ -123,8 +121,8 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
<div class="input-group mb-3 mb-md-0"> <div class="input-group">
<select class="form-control select2" name="type" onchange="this.form.submit()"> <select class="form-select select2" name="type" onchange="this.form.submit()">
<option value="">- All Types -</option> <option value="">- All Types -</option>
<?php <?php
@@ -142,8 +140,8 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
<div class="input-group mb-3 mb-md-0"> <div class="input-group">
<select class="form-control select2" name="action" onchange="this.form.submit()"> <select class="form-select select2" name="action" onchange="this.form.submit()">
<option value="">- All Actions -</option> <option value="">- All Actions -</option>
<?php <?php
@@ -161,10 +159,10 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
</div> </div>
<div class="collapse mt-3 <?php if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') { echo"show"; } ?>" id="advancedFilter"> <div class="collapse mt-3 <?php if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') { echo"show"; } ?>" id="advancedFilter">
<div class="row"> <div class="row g-3">
<div class="col-md-3"> <div class="col-md-3">
<div class="form-group"> <div>
<label>Date range</label> <label class="form-label">Date range</label>
<input type="text" id="dateFilter" class="form-control" autocomplete="off"> <input type="text" id="dateFilter" class="form-control" autocomplete="off">
<input type="hidden" name="canned_date" id="canned_date" value="<?= escapeHtml($_GET['canned_date']) ?? '' ?>"> <input type="hidden" name="canned_date" id="canned_date" value="<?= escapeHtml($_GET['canned_date']) ?? '' ?>">
<input type="hidden" name="dtf" id="dtf" value="<?= escapeHtml($dtf ?? '') ?>"> <input type="hidden" name="dtf" id="dtf" value="<?= escapeHtml($dtf ?? '') ?>">
@@ -174,9 +172,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
</div> </div>
</form> </form>
<hr> </div>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-sm table-striped table-borderless table-hover"> <table class="table table-sm table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?> text-nowrap"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?> text-nowrap">
<tr> <tr>
<th> <th>
@@ -255,7 +253,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<tr> <tr>
<td class="text-monospace"><?= $log_created_at ?></td> <td class="font-monospace"><?= $log_created_at ?></td>
<td><?= $user_name_display ?></td> <td><?= $user_name_display ?></td>
<?php if(empty($client)) { ?> <?php if(empty($client)) { ?>
<td><?= $client_name_display ?></td> <td><?= $client_name_display ?></td>
@@ -263,7 +261,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<td><?= $log_type ?></td> <td><?= $log_type ?></td>
<td><?= $log_action ?></td> <td><?= $log_action ?></td>
<td><?= $log_description ?></td> <td><?= $log_description ?></td>
<td class="text-monospace"><?= $log_ip ?></td> <td class="font-monospace"><?= $log_ip ?></td>
<td><?= "$log_user_os<div class='text-secondary'>$log_user_browser</div>" ?></td> <td><?= "$log_user_os<div class='text-secondary'>$log_user_browser</div>" ?></td>
</tr> </tr>
@@ -277,7 +275,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php require_once "../includes/filter_footer.php"; <?php require_once "../includes/filter_footer.php";
?> ?>
</div> </div>
</div>
<?php <?php
require_once "../includes/footer.php"; require_once "../includes/footer.php";

View File

@@ -33,15 +33,15 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
unset($_SESSION['backup_master_key_reveal']); unset($_SESSION['backup_master_key_reveal']);
?> ?>
<div class="alert alert-warning"> <div class="alert alert-warning">
<h5><i class="fas fa-fw fa-key mr-2"></i>Master encryption key</h5> <h5><i class="fas fa-fw fa-key me-2"></i>Master encryption key</h5>
<p class="mb-2">Shown once. Refreshing this page will not show it again.</p> <p class="mb-2">Shown once. Refreshing this page will not show it again.</p>
<input type="text" class="form-control text-monospace" value="<?= escapeHtml($master_key_reveal) ?>" readonly onclick="this.select();"> <input type="text" class="form-control font-monospace" value="<?= escapeHtml($master_key_reveal) ?>" readonly onclick="this.select();">
</div> </div>
<?php } ?> <?php } ?>
<?php if ($backup_key === '') { ?> <?php if ($backup_key === '') { ?>
<div class="alert alert-danger"> <div class="alert alert-danger">
<h5><i class="fas fa-fw fa-exclamation-triangle mr-2"></i>No backup encryption key</h5> <h5><i class="fas fa-fw fa-exclamation-triangle me-2"></i>No backup encryption key</h5>
ITFlow could not write a backup encryption key to <strong>config.php</strong>, so it cannot produce an encrypted backup. ITFlow could not write a backup encryption key to <strong>config.php</strong>, so it cannot produce an encrypted backup.
Make config.php writable by the web server user and reload this page, or add a line like Make config.php writable by the web server user and reload this page, or add a line like
<code>$config_backup_key = '&lt;32 random characters&gt;';</code> to it yourself. <code>$config_backup_key = '&lt;32 random characters&gt;';</code> to it yourself.
@@ -50,26 +50,26 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<?php if (!$cron_is_running) { ?> <?php if (!$cron_is_running) { ?>
<div class="alert alert-danger"> <div class="alert alert-danger">
<h5><i class="fas fa-fw fa-exclamation-triangle mr-2"></i>Cron is not running</h5> <h5><i class="fas fa-fw fa-exclamation-triangle me-2"></i>Cron is not running</h5>
Backups are built by the cron dispatcher, not by your browser. Until cron is running, anything you Backups are built by the cron dispatcher, not by your browser. Until cron is running, anything you
start here will sit in the queue. See <a href="cron.php">Maintenance &gt; Cron</a>. start here will sit in the queue. See <a href="cron.php">Maintenance &gt; Cron</a>.
</div> </div>
<?php } elseif ($config_enable_cron == 0) { ?> <?php } elseif ($config_enable_cron == 0) { ?>
<div class="alert alert-warning"> <div class="alert alert-warning">
<i class="fas fa-fw fa-exclamation-circle mr-2"></i>Cron is switched off in <i class="fas fa-fw fa-exclamation-circle me-2"></i>Cron is switched off in
<a href="cron.php">Maintenance &gt; Cron</a>. <a href="cron.php">Maintenance &gt; Cron</a>.
</div> </div>
<?php } ?> <?php } ?>
<div class="card card-dark mb-3"> <div class="card card-dark mb-3">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-cloud-upload-alt mr-2"></i>Create a Backup</h3> <h3 class="card-title"><i class="fas fa-fw fa-cloud-upload-alt me-2"></i>Create a Backup</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<?php if ($pending_count > 0) { ?> <?php if ($pending_count > 0) { ?>
<div class="alert alert-info"> <div class="alert alert-info">
<i class="fas fa-fw fa-spinner mr-2"></i><strong><?= $pending_count ?></strong> backup<?= $pending_count == 1 ? ' is' : 's are' ?> <i class="fas fa-fw fa-spinner me-2"></i><strong><?= $pending_count ?></strong> backup<?= $pending_count == 1 ? ' is' : 's are' ?>
queued or building. You will get a notification when ready - this page does not refresh itself. queued or building. You will get a notification when ready - this page does not refresh itself.
</div> </div>
<?php } ?> <?php } ?>
@@ -81,7 +81,7 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<h5>Full Backup</h5> <h5>Full Backup</h5>
<p class="text-muted small">The database and everything in the uploads folder. This is the one to keep.</p> <p class="text-muted small">The database and everything in the uploads folder. This is the one to keep.</p>
<a class="btn btn-primary <?= $backup_key === '' ? 'disabled' : '' ?>" href="post.php?queue_backup=full&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="btn btn-primary <?= $backup_key === '' ? 'disabled' : '' ?>" href="post.php?queue_backup=full&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-play mr-2"></i>Start <i class="fas fa-fw fa-play me-2"></i>Start
</a> </a>
</div> </div>
</div> </div>
@@ -91,7 +91,7 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<h5>Database Only</h5> <h5>Database Only</h5>
<p class="text-muted small">Just the SQL dump. Much smaller and much quicker, but no attachments or documents.</p> <p class="text-muted small">Just the SQL dump. Much smaller and much quicker, but no attachments or documents.</p>
<a class="btn btn-primary <?= $backup_key === '' ? 'disabled' : '' ?>" href="post.php?queue_backup=database&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="btn btn-primary <?= $backup_key === '' ? 'disabled' : '' ?>" href="post.php?queue_backup=database&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-play mr-2"></i>Start <i class="fas fa-fw fa-play me-2"></i>Start
</a> </a>
</div> </div>
</div> </div>
@@ -100,8 +100,8 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<i class="fas fa-fw fa-3x fa-key text-dark mb-3"></i> <i class="fas fa-fw fa-3x fa-key text-dark mb-3"></i>
<h5>Master Key</h5> <h5>Master Key</h5>
<p class="text-muted small">The credential vault key. Only needed if every user password is lost - a normal restore recovers the vault on its own.</p> <p class="text-muted small">The credential vault key. Only needed if every user password is lost - a normal restore recovers the vault on its own.</p>
<button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#masterKeyModal"> <button type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#masterKeyModal">
<i class="fas fa-fw fa-key mr-2"></i>Export <i class="fas fa-fw fa-key me-2"></i>Export
</button> </button>
</div> </div>
</div> </div>
@@ -112,7 +112,7 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<div class="card card-dark mb-3"> <div class="card card-dark mb-3">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-archive mr-2"></i>Backups</h3> <h3 class="card-title"><i class="fas fa-fw fa-archive me-2"></i>Backups</h3>
</div> </div>
<div class="card-body p-0"> <div class="card-body p-0">
<div class="table-responsive"> <div class="table-responsive">
@@ -124,7 +124,7 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<th>Size</th> <th>Size</th>
<th>Source</th> <th>Source</th>
<th>Status</th> <th>Status</th>
<th class="text-right">Action</th> <th class="text-end">Action</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -148,12 +148,12 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<td><?= $backup['backup_size'] > 0 ? escapeHtml(backupFormatBytes($backup['backup_size'])) : '-' ?></td> <td><?= $backup['backup_size'] > 0 ? escapeHtml(backupFormatBytes($backup['backup_size'])) : '-' ?></td>
<td><?= escapeHtml($backup['backup_source']) ?></td> <td><?= escapeHtml($backup['backup_source']) ?></td>
<td> <td>
<span class="badge badge-<?= $badge ?>"><?= escapeHtml($status) ?></span> <span class="badge text-bg-<?= $badge ?>"><?= escapeHtml($status) ?></span>
<?php if (!empty($backup['backup_error'])) { ?> <?php if (!empty($backup['backup_error'])) { ?>
<br><small class="text-danger"><?= escapeHtml($backup['backup_error']) ?></small> <br><small class="text-danger"><?= escapeHtml($backup['backup_error']) ?></small>
<?php } ?> <?php } ?>
</td> </td>
<td class="text-right"> <td class="text-end">
<?php if ($status === 'Complete') { ?> <?php if ($status === 'Complete') { ?>
<a class="btn btn-sm btn-primary" href="backup_download.php?backup_id=<?= $backup_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="btn btn-sm btn-primary" href="backup_download.php?backup_id=<?= $backup_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-download"></i> <i class="fas fa-fw fa-download"></i>
@@ -173,11 +173,11 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<div class="card card-dark mb-3"> <div class="card card-dark mb-3">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-lock mr-2"></i>Encryption Key</h3> <h3 class="card-title"><i class="fas fa-fw fa-lock me-2"></i>Encryption Key</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="alert alert-warning mb-3"> <div class="alert alert-warning mb-3">
<i class="fas fa-fw fa-exclamation-triangle mr-2"></i> <i class="fas fa-fw fa-exclamation-triangle me-2"></i>
<strong>Write this down and keep it somewhere other than this server.</strong> <strong>Write this down and keep it somewhere other than this server.</strong>
Every backup is encrypted with it, and without it a backup cannot be restored - not by you, Every backup is encrypted with it, and without it a backup cannot be restored - not by you,
not by anyone. It is stored in config.php and never in the database, which is what stops a not by anyone. It is stored in config.php and never in the database, which is what stops a
@@ -186,13 +186,11 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<?php if ($backup_key !== '') { ?> <?php if ($backup_key !== '') { ?>
<div class="input-group col-md-6 px-0"> <div class="input-group col-md-6 px-0">
<input type="text" class="form-control text-monospace" value="<?= escapeHtml($backup_key) ?>" readonly onclick="this.select();"> <input type="text" class="form-control font-monospace" value="<?= escapeHtml($backup_key) ?>" readonly onclick="this.select();">
<div class="input-group-append">
<button class="btn btn-secondary" type="button" onclick="navigator.clipboard.writeText('<?= escapeHtml($backup_key) ?>');"> <button class="btn btn-secondary" type="button" onclick="navigator.clipboard.writeText('<?= escapeHtml($backup_key) ?>');">
<i class="fas fa-fw fa-copy"></i> <i class="fas fa-fw fa-copy"></i>
</button> </button>
</div> </div>
</div>
<?php } ?> <?php } ?>
<p class="text-muted small mt-3 mb-0"> <p class="text-muted small mt-3 mb-0">
@@ -204,43 +202,43 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<div class="card card-dark mb-3"> <div class="card card-dark mb-3">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-clock mr-2"></i>Scheduled Backups &amp; Retention</h3> <h3 class="card-title"><i class="fas fa-fw fa-clock me-2"></i>Scheduled Backups &amp; Retention</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="POST" autocomplete="off"> <form action="post.php" method="POST" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-4"> <div class="mb-3 col-md-4">
<label>Scheduled backup type</label> <label>Scheduled backup type</label>
<select class="form-control" name="config_backup_cron_type"> <select class="form-select" name="config_backup_cron_type">
<option <?= $config_backup_cron_type === 'full' ? 'selected' : '' ?> value="full">Full Backup</option> <option <?= $config_backup_cron_type === 'full' ? 'selected' : '' ?> value="full">Full Backup</option>
<option <?= $config_backup_cron_type === 'database' ? 'selected' : '' ?> value="database">Database Only</option> <option <?= $config_backup_cron_type === 'database' ? 'selected' : '' ?> value="database">Database Only</option>
</select> </select>
</div> </div>
<div class="form-group col-md-4"> <div class="mb-3 col-md-4">
<label>Keep backups for (days)</label> <label>Keep backups for (days)</label>
<input type="number" class="form-control" name="config_backup_retention_days" min="0" value="<?= intval($config_backup_retention_days) ?>"> <input type="number" class="form-control" name="config_backup_retention_days" min="0" value="<?= intval($config_backup_retention_days) ?>">
<small class="text-muted">0 disables age-based deletion.</small> <small class="text-muted">0 disables age-based deletion.</small>
</div> </div>
<div class="form-group col-md-4"> <div class="mb-3 col-md-4">
<label>Keep at most (per type)</label> <label>Keep at most (per type)</label>
<input type="number" class="form-control" name="config_backup_retention_count" min="1" value="<?= intval($config_backup_retention_count) ?>"> <input type="number" class="form-control" name="config_backup_retention_count" min="1" value="<?= intval($config_backup_retention_count) ?>">
<small class="text-muted">Counted separately for each type. The newest of each is never deleted.</small> <small class="text-muted">Counted separately for each type. The newest of each is never deleted.</small>
</div> </div>
</div> </div>
<button type="submit" name="edit_backup_settings" class="btn btn-primary"><i class="fas fa-fw fa-check mr-2"></i>Save</button> <button type="submit" name="edit_backup_settings" class="btn btn-primary"><i class="fas fa-fw fa-check me-2"></i>Save</button>
</form> </form>
<hr> <hr>
<p class="mb-0"> <p class="mb-0">
<?php if (!empty($backup_job) && intval($backup_job['cron_job_enabled']) === 1) { ?> <?php if (!empty($backup_job) && intval($backup_job['cron_job_enabled']) === 1) { ?>
<i class="fas fa-fw fa-check text-success mr-2"></i>Scheduled backups run daily at <i class="fas fa-fw fa-check text-success me-2"></i>Scheduled backups run daily at
<strong><?= escapeHtml(substr((string)$backup_job['cron_job_daily_at'], 0, 5)) ?></strong>. <strong><?= escapeHtml(substr((string)$backup_job['cron_job_daily_at'], 0, 5)) ?></strong>.
<?php } else { ?> <?php } else { ?>
<i class="fas fa-fw fa-times text-danger mr-2"></i>Scheduled backups are switched off. <i class="fas fa-fw fa-times text-danger me-2"></i>Scheduled backups are switched off.
<?php } ?> <?php } ?>
Turn them on or change the time in <a href="cron.php">Maintenance &gt; Cron</a>. Turn them on or change the time in <a href="cron.php">Maintenance &gt; Cron</a>.
</p> </p>
@@ -253,7 +251,7 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-undo mr-2"></i>Restoring</h3> <h3 class="card-title"><i class="fas fa-fw fa-undo me-2"></i>Restoring</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<p>Restoring replaces the database and the uploads folder with what is in the archive. It cannot be done from here, on purpose - a running install is the wrong place to be dropping its own tables from a browser.</p> <p>Restoring replaces the database and the uploads folder with what is in the archive. It cannot be done from here, on purpose - a running install is the wrong place to be dropping its own tables from a browser.</p>
@@ -267,8 +265,8 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title"><i class="fas fa-fw fa-key mr-2"></i>Export Master Key</h5> <h5 class="modal-title"><i class="fas fa-fw fa-key me-2"></i>Export Master Key</h5>
<button type="button" class="close" data-dismiss="modal"><span>&times;</span></button> <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div> </div>
<form action="post.php" method="POST" autocomplete="off"> <form action="post.php" method="POST" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -276,13 +274,13 @@ if (!empty($_SESSION['backup_master_key_reveal'])) {
<div class="alert alert-warning"> <div class="alert alert-warning">
This key decrypts every credential in this install. It is shown on screen and is not written anywhere. This key decrypts every credential in this install. It is shown on screen and is not written anywhere.
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Confirm your account password</label> <label>Confirm your account password</label>
<input type="password" class="form-control" name="password" autocomplete="new-password" required> <input type="password" class="form-control" name="password" autocomplete="new-password" required>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="backup_master_key" class="btn btn-primary"><i class="fas fa-fw fa-key mr-2"></i>Show Master Key</button> <button type="submit" name="backup_master_key" class="btn btn-primary"><i class="fas fa-fw fa-key me-2"></i>Show Master Key</button>
</div> </div>
</form> </form>
</div> </div>

134
admin/canned_responses.php Normal file
View File

@@ -0,0 +1,134 @@
<?php
// Default Column Sortby Filter
$sort = "canned_response_name";
$order = "ASC";
require_once "includes/inc_all_admin.php";
/*
* A canned response either belongs to one ticket category or, with category id 0, offers
* itself on every ticket. The LEFT JOIN is what puts the category name on the row; a
* response whose category was deleted since falls back to the general case below.
*/
$sql = mysqli_query(
$mysqli,
"SELECT SQL_CALC_FOUND_ROWS canned_response_id, canned_response_name, canned_response_body,
canned_response_category_id, category_name
FROM canned_responses
LEFT JOIN categories ON canned_response_category_id = category_id AND category_type = 'Ticket'
WHERE (canned_response_name LIKE '%$q%' OR canned_response_body LIKE '%$q%')
AND canned_response_archived_at IS NULL
ORDER BY $sort $order
LIMIT $record_from, $record_to"
);
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?>
<div class="card">
<div class="card-header bg-dark py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-comment-dots me-2"></i>Canned Responses</h3>
<div class="card-tools">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/canned_response/canned_response_add.php" data-modal-size="lg"><i class="fas fa-plus me-2"></i>New Canned Response</button>
</div>
</div>
<div class="card-header py-3">
<form autocomplete="off">
<div class="row g-2 align-items-center">
<div class="col-md-4">
<div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if(isset($q)){ echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search Canned Responses">
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
</div>
</div>
<div class="col-md-8">
</div>
</div>
</form>
</div>
<div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr>
<th>
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=canned_response_name&order=<?= $disp ?>">
Response <?php if ($sort == 'canned_response_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=category_name&order=<?= $disp ?>">
Ticket Category <?php if ($sort == 'category_name') { echo $order_icon; } ?>
</a>
</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<?php
while($row = mysqli_fetch_assoc($sql)){
$canned_response_id = intval($row['canned_response_id']);
$canned_response_name = escapeHtml($row['canned_response_name']);
$canned_response_category_id = intval($row['canned_response_category_id']);
$canned_response_category_name = escapeHtml($row['category_name']);
// The body is HTML from TinyMCE. This is a preview, not a render - tags
// are stripped rather than escaped so the column reads as the sentence
// the agent will actually be inserting
$canned_response_preview = escapeHtml(mb_strimwidth(trim(html_entity_decode(strip_tags($row['canned_response_body']), ENT_QUOTES, 'UTF-8')), 0, 120, '...'));
?>
<tr>
<td>
<div class="d-flex">
<i class="fa fa-fw fa-2x fa-comment-dots me-3"></i>
<div class="flex-grow-1">
<div>
<a class="ajax-modal" href="#" data-modal-url="modals/canned_response/canned_response_edit.php?id=<?= $canned_response_id ?>" data-modal-size="lg">
<?= $canned_response_name ?>
</a>
</div>
<div><small class="text-secondary"><?= $canned_response_preview ?></small></div>
</div>
</div>
</td>
<td>
<?php if ($canned_response_category_id && $canned_response_category_name) { ?>
<span class="badge bg-secondary"><?= $canned_response_category_name ?></span>
<?php } else { ?>
<span class="badge bg-dark">All ticket categories</span>
<?php } ?>
</td>
<td>
<div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/canned_response/canned_response_edit.php?id=<?= $canned_response_id ?>" data-modal-size="lg">
<i class="fas fa-fw fa-edit me-2"></i>Edit
</a>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_canned_response=<?= $canned_response_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash me-2"></i>Delete
</a>
</div>
</div>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<?php require_once "../includes/filter_footer.php";
?>
</div>
<?php
require_once "../includes/footer.php";

View File

@@ -67,7 +67,7 @@ $archive_toggle_url = '?' . http_build_query($archive_toggle_query);
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-2"> <div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-list-ul mr-2"></i> <h3 class="card-title mt-2"><i class="fa fa-fw fa-list-ul me-2"></i>
<?= escapeHtml($category_label) ?> Categories <?= escapeHtml($category_label) ?> Categories
</h3> </h3>
<?php <?php
@@ -75,7 +75,7 @@ $archive_toggle_url = '?' . http_build_query($archive_toggle_query);
?> ?>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/category/category_add.php?category=<?= escapeHtml($category) ?>"><i <button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/category/category_add.php?category=<?= escapeHtml($category) ?>"><i
class="fas fa-plus mr-2"></i>New <?= escapeHtml($category_label) ?> Category</button> class="fas fa-plus me-2"></i>New <?= escapeHtml($category_label) ?> Category</button>
</div> </div>
<?php <?php
} }
@@ -85,15 +85,15 @@ $archive_toggle_url = '?' . http_build_query($archive_toggle_query);
<div class="row"> <div class="row">
<!-- Category types --> <!-- Category types -->
<div class="col-md-3 border-right mb-3"> <div class="col-md-3 border-end mb-3">
<ul class="nav nav-pills flex-column bg-light"> <ul class="nav nav-pills flex-column bg-light">
<?php foreach ($category_types as $category_type => $category_type_details) { ?> <?php foreach ($category_types as $category_type => $category_type_details) { ?>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link<?php if ($category == $category_type) { <a class="nav-link<?php if ($category == $category_type) {
echo ' active'; echo ' active';
} ?>" href="?category=<?= urlencode($category_type) ?>"> } ?>" href="?category=<?= urlencode($category_type) ?>">
<i class="fa fa-fw <?= $category_type_details['icon'] ?> mr-2"></i><?= escapeHtml($category_type_details['label']) ?> <i class="fa fa-fw <?= $category_type_details['icon'] ?> me-2"></i><?= escapeHtml($category_type_details['label']) ?>
<span class="badge badge-pill badge-dark float-right mt-1"><?= $category_type_counts[$category_type] ?? 0 ?></span> <span class="badge rounded-pill bg-dark float-end mt-1"><?= $category_type_counts[$category_type] ?? 0 ?></span>
</a> </a>
</li> </li>
<?php } ?> <?php } ?>
@@ -115,25 +115,23 @@ $archive_toggle_url = '?' . http_build_query($archive_toggle_query);
echo stripslashes(escapeHtml($q)); echo stripslashes(escapeHtml($q));
} ?>" } ?>"
placeholder="Search <?= escapeHtml($category_label) ?> Categories "> placeholder="Search <?= escapeHtml($category_label) ?> Categories ">
<div class="input-group-append">
<button class="btn btn-primary"><i class="fa fa-search"></i></button> <button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div> </div>
</div> </div>
</div>
<div class="col-sm-6 mb-2"> <div class="col-sm-6 mb-2">
<a href="<?= $archive_toggle_url ?>" <a href="<?= $archive_toggle_url ?>"
class="btn float-right <?php if ($archived) { class="btn float-end <?php if ($archived) {
echo 'btn-primary'; echo 'btn-primary';
} else { } else {
echo 'btn-default'; echo 'btn-default';
} ?>"><i } ?>"><i
class="fas fa-fw fa-archive mr-2"></i>Archived</a> class="fas fa-fw fa-archive me-2"></i>Archived</a>
</div> </div>
</div> </div>
</form> </form>
<hr> <hr>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover"> <table class="table table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr> <tr>
<th> <th>
@@ -165,8 +163,8 @@ $archive_toggle_url = '?' . http_build_query($archive_toggle_query);
</td> </td>
<td><i class="fa fa-3x fa-circle" style="color:<?= $category_color ?>;"></i></td> <td><i class="fa fa-3x fa-circle" style="color:<?= $category_color ?>;"></i></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
@@ -175,22 +173,22 @@ $archive_toggle_url = '?' . http_build_query($archive_toggle_query);
?> ?>
<a class="dropdown-item text-info confirm-link" <a class="dropdown-item text-info confirm-link"
href="post.php?restore_category=<?= $category_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> href="post.php?restore_category=<?= $category_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-redo mr-2"></i>Restore <i class="fas fa-fw fa-redo me-2"></i>Restore
</a> </a>
<a class="dropdown-item text-danger confirm-link" <a class="dropdown-item text-danger confirm-link"
href="post.php?delete_category=<?= $category_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> href="post.php?delete_category=<?= $category_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</a> </a>
<?php <?php
} else { } else {
?> ?>
<a class="dropdown-item ajax-modal" href="#" <a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/category/category_edit.php?id=<?= $category_id ?>"> data-modal-url="modals/category/category_edit.php?id=<?= $category_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit me-2"></i>Edit
</a> </a>
<a class="dropdown-item text-danger confirm-link" <a class="dropdown-item text-danger confirm-link"
href="post.php?archive_category=<?= $category_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> href="post.php?archive_category=<?= $category_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive <i class="fas fa-fw fa-archive me-2"></i>Archive
</a> </a>
<?php <?php
} }

View File

@@ -18,29 +18,27 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<div class="card card-dark"> <div class="card">
<div class="card-header py-2"> <div class="card-header bg-dark py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file-contract mr-2"></i>Contract Templates</h3> <h3 class="card-title mt-2"><i class="fa fa-fw fa-file-contract me-2"></i>Contract Templates</h3>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/contract_template/contract_template_add.php" data-modal-size="lg"> <button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/contract_template/contract_template_add.php" data-modal-size="lg">
<i class="fas fa-plus mr-2"></i>New Template <i class="fas fa-plus me-2"></i>New Template
</button> </button>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-header py-3">
<form autocomplete="off"> <form autocomplete="off">
<div class="input-group"> <div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search templates"> <input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search templates">
<div class="input-group-append">
<button class="btn btn-secondary"><i class="fa fa-search"></i></button> <button class="btn btn-secondary"><i class="fa fa-search"></i></button>
</div> </div>
</div>
</form> </form>
<hr> </div>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover"> <table class="table table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr> <tr>
<th>Template Name</th> <th>Template Name</th>
@@ -95,19 +93,19 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<td><?= $created ?></td> <td><?= $created ?></td>
<td><?= $updated ?></td> <td><?= $updated ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" <a class="dropdown-item ajax-modal" href="#"
data-modal-size="xl" data-modal-size="xl"
data-modal-url="modals/contract_template/contract_template_edit.php?id=<?= $id ?>"> data-modal-url="modals/contract_template/contract_template_edit.php?id=<?= $id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit me-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold" href="post.php?delete_contract_template=<?= $id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger text-bold" href="post.php?delete_contract_template=<?= $id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</a> </a>
</div> </div>
</div> </div>
@@ -120,6 +118,5 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
<?php require_once "../includes/filter_footer.php"; ?> <?php require_once "../includes/filter_footer.php"; ?>
</div> </div>
</div>
<?php require_once "../includes/footer.php"; ?> <?php require_once "../includes/footer.php"; ?>

View File

@@ -35,13 +35,13 @@ while ($job_row = mysqli_fetch_assoc($sql)) {
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-clock mr-2"></i>Cron</h3> <h3 class="card-title"><i class="fas fa-fw fa-clock me-2"></i>Cron</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<?php if (!$cron_is_running) { ?> <?php if (!$cron_is_running) { ?>
<div class="alert alert-danger"> <div class="alert alert-danger">
<h5><i class="fas fa-fw fa-exclamation-triangle mr-2"></i>Cron is not running</h5> <h5><i class="fas fa-fw fa-exclamation-triangle me-2"></i>Cron is not running</h5>
ITFlow last heard from cron <strong><?= escapeHtml(strtolower(cronJobTimeAgo($cron_last_dispatch_at))) ?></strong>. ITFlow last heard from cron <strong><?= escapeHtml(strtolower(cronJobTimeAgo($cron_last_dispatch_at))) ?></strong>.
Nothing below will run - no mail is being sent, no email is being turned into tickets, and invoices are not being generated. Nothing below will run - no mail is being sent, no email is being turned into tickets, and invoices are not being generated.
Add this line to the crontab of the user that owns the ITFlow files: Add this line to the crontab of the user that owns the ITFlow files:
@@ -49,26 +49,26 @@ while ($job_row = mysqli_fetch_assoc($sql)) {
</div> </div>
<?php } else { ?> <?php } else { ?>
<div class="alert alert-success"> <div class="alert alert-success">
<i class="fas fa-fw fa-check mr-2"></i>Cron last checked in <strong><?= escapeHtml(strtolower(cronJobTimeAgo($cron_last_dispatch_at))) ?></strong>. <i class="fas fa-fw fa-check me-2"></i>Cron last checked in <strong><?= escapeHtml(strtolower(cronJobTimeAgo($cron_last_dispatch_at))) ?></strong>.
<span class="text-muted ml-2"><?= escapeHtml($cron_command) ?></span> <span class="text-muted ms-2"><?= escapeHtml($cron_command) ?></span>
</div> </div>
<?php } ?> <?php } ?>
<?php if ($config_enable_cron == 0) { ?> <?php if ($config_enable_cron == 0) { ?>
<div class="alert alert-warning"> <div class="alert alert-warning">
<div class="float-right"> <div class="float-end">
<a class="btn btn-sm btn-warning" href="post.php?enable_cron=1&amp;csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="btn btn-sm btn-warning" href="post.php?enable_cron=1&amp;csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-power-off mr-2"></i>Turn cron on <i class="fas fa-fw fa-power-off me-2"></i>Turn cron on
</a> </a>
</div> </div>
<h5><i class="fas fa-fw fa-exclamation-circle mr-2"></i>Cron is switched off</h5> <h5><i class="fas fa-fw fa-exclamation-circle me-2"></i>Cron is switched off</h5>
The dispatcher is running, but every job below stops itself immediately while this is off - The dispatcher is running, but every job below stops itself immediately while this is off -
no mail is sent, no email becomes a ticket, and nothing is invoiced. no mail is sent, no email becomes a ticket, and nothing is invoiced.
</div> </div>
<?php } else { ?> <?php } else { ?>
<p class="text-muted"> <p class="text-muted">
<small> <small>
<i class="fas fa-fw fa-power-off mr-1"></i>The master switch is <strong>on</strong>. Turning it off <i class="fas fa-fw fa-power-off me-1"></i>The master switch is <strong>on</strong>. Turning it off
stops every job at once without touching their schedules, which is what you want on a restored stops every job at once without touching their schedules, which is what you want on a restored
backup or a staging clone - those come up with every job enabled and will otherwise email clients backup or a staging clone - those come up with every job enabled and will otherwise email clients
and charge cards. Switching back on returns you to exactly this configuration. and charge cards. Switching back on returns you to exactly this configuration.
@@ -112,24 +112,24 @@ while ($job_row = mysqli_fetch_assoc($sql)) {
$next_run = $job_row ? cronJobNextRun($job_row) : null; $next_run = $job_row ? cronJobNextRun($job_row) : null;
if ($run_now) { if ($run_now) {
$status_badge = '<span class="badge badge-warning">Queued</span>'; $status_badge = '<span class="badge bg-warning text-dark">Queued</span>';
} elseif ($last_status === 'Running') { } elseif ($last_status === 'Running') {
$status_badge = '<span class="badge badge-info">Running</span>'; $status_badge = '<span class="badge bg-info text-dark">Running</span>';
} elseif ($last_status === 'Completed') { } elseif ($last_status === 'Completed') {
$status_badge = '<span class="badge badge-success">Completed</span>'; $status_badge = '<span class="badge bg-success">Completed</span>';
} elseif ($last_status === 'Failed') { } elseif ($last_status === 'Failed') {
$status_badge = '<span class="badge badge-danger">Failed</span>'; $status_badge = '<span class="badge bg-danger">Failed</span>';
} elseif ($last_status !== null) { } elseif ($last_status !== null) {
$status_badge = '<span class="badge badge-secondary">Stopped</span>'; $status_badge = '<span class="badge bg-secondary">Stopped</span>';
} else { } else {
$status_badge = '<span class="badge badge-light">Never run</span>'; $status_badge = '<span class="badge bg-light text-dark">Never run</span>';
} }
?> ?>
<tr class="<?= $enabled ? '' : 'text-muted' ?>"> <tr class="<?= $enabled ? '' : 'text-muted' ?>">
<td> <td>
<strong><?= escapeHtml($job['label']) ?></strong> <strong><?= escapeHtml($job['label']) ?></strong>
<?php if (!$enabled) { ?><span class="badge badge-secondary ml-1">Disabled</span><?php } ?> <?php if (!$enabled) { ?><span class="badge bg-secondary ms-1">Disabled</span><?php } ?>
<br><small class="text-secondary"><?= escapeHtml($job['description']) ?></small> <br><small class="text-secondary"><?= escapeHtml($job['description']) ?></small>
<br><small class="text-muted"><code>cron/<?= escapeHtml($job['script']) ?></code></small> <br><small class="text-muted"><code>cron/<?= escapeHtml($job['script']) ?></code></small>
</td> </td>
@@ -147,25 +147,25 @@ while ($job_row = mysqli_fetch_assoc($sql)) {
</td> </td>
<td><?= $next_run === null ? '-' : escapeHtml(cronJobTimeAgo($next_run)) ?></td> <td><?= $next_run === null ? '-' : escapeHtml(cronJobTimeAgo($next_run)) ?></td>
<td class="text-center"> <td class="text-center">
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i> <i class="fas fa-ellipsis-v"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item <?= $cron_job_id === 0 ? 'disabled' : '' ?>" href="post.php?run_cron_job=<?= $cron_job_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item <?= $cron_job_id === 0 ? 'disabled' : '' ?>" href="post.php?run_cron_job=<?= $cron_job_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-play mr-2"></i>Run Now <i class="fas fa-fw fa-play me-2"></i>Run Now
</a> </a>
<button class="dropdown-item ajax-modal <?= $cron_job_id === 0 ? 'disabled' : '' ?>" type="button" data-toggle="ajax-modal" <button class="dropdown-item ajax-modal <?= $cron_job_id === 0 ? 'disabled' : '' ?>" type="button" data-toggle="ajax-modal"
data-modal-url="modals/cron/cron_edit.php?id=<?= $cron_job_id ?>"> data-modal-url="modals/cron/cron_edit.php?id=<?= $cron_job_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit Schedule <i class="fas fa-fw fa-edit me-2"></i>Edit Schedule
</button> </button>
<?php if ($enabled) { ?> <?php if ($enabled) { ?>
<a class="dropdown-item text-danger" href="post.php?disable_cron_job=<?= $cron_job_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger" href="post.php?disable_cron_job=<?= $cron_job_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-pause mr-2"></i>Disable <i class="fas fa-fw fa-pause me-2"></i>Disable
</a> </a>
<?php } else { ?> <?php } else { ?>
<a class="dropdown-item text-success" href="post.php?enable_cron_job=<?= $cron_job_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-success" href="post.php?enable_cron_job=<?= $cron_job_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-play-circle mr-2"></i>Enable <i class="fas fa-fw fa-play-circle me-2"></i>Enable
</a> </a>
<?php } ?> <?php } ?>
</div> </div>
@@ -176,13 +176,13 @@ while ($job_row = mysqli_fetch_assoc($sql)) {
<tr> <tr>
<td colspan="7" class="pt-0"> <td colspan="7" class="pt-0">
<div class="alert alert-danger mb-0 py-2"> <div class="alert alert-danger mb-0 py-2">
<div class="float-right"> <div class="float-end">
<a class="text-danger" href="post.php?clear_cron_error=<?= $cron_job_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>" title="Dismiss"> <a class="text-danger" href="post.php?clear_cron_error=<?= $cron_job_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>" title="Dismiss">
<i class="fas fa-fw fa-times"></i> <i class="fas fa-fw fa-times"></i>
</a> </a>
</div> </div>
<strong><i class="fas fa-fw fa-exclamation-triangle mr-2"></i>Last error</strong> <strong><i class="fas fa-fw fa-exclamation-triangle me-2"></i>Last error</strong>
<small class="text-muted ml-2"><?= escapeHtml(cronJobTimeAgo($last_error_at)) ?></small> <small class="text-muted ms-2"><?= escapeHtml(cronJobTimeAgo($last_error_at)) ?></small>
<div class="mt-1"><small><?= escapeHtml($last_error) ?></small></div> <div class="mt-1"><small><?= escapeHtml($last_error) ?></small></div>
</div> </div>
</td> </td>
@@ -195,7 +195,7 @@ while ($job_row = mysqli_fetch_assoc($sql)) {
<p class="text-muted mb-0"> <p class="text-muted mb-0">
<small> <small>
<i class="fas fa-fw fa-info-circle mr-1"></i>Run Now does not start the job in your browser - it asks the <i class="fas fa-fw fa-info-circle me-1"></i>Run Now does not start the job in your browser - it asks the
dispatcher to pick it up on its next pass, so a job starts within a minute and still runs on the command dispatcher to pick it up on its next pass, so a job starts within a minute and still runs on the command
line with the same locking as a scheduled run. Detailed per-job output is in line with the same locking as a scheduled run. Detailed per-job output is in
<a href="app_logs.php">App Logs</a>. <a href="app_logs.php">App Logs</a>.

View File

@@ -20,9 +20,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-2"> <div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-external-link-alt mr-2"></i>Custom Links</h3> <h3 class="card-title mt-2"><i class="fas fa-fw fa-external-link-alt me-2"></i>Custom Links</h3>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/custom_link/custom_link_add.php"><i class="fas fa-plus mr-2"></i>New Link</button> <button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/custom_link/custom_link_add.php"><i class="fas fa-plus me-2"></i>New Link</button>
</div> </div>
</div> </div>
@@ -32,10 +32,8 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<form autocomplete="off"> <form autocomplete="off">
<div class="input-group"> <div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search Links"> <input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search Links">
<div class="input-group-append">
<button class="btn btn-primary"><i class="fa fa-search"></i></button> <button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div> </div>
</div>
</form> </form>
</div> </div>
<div class="col-sm-8"> <div class="col-sm-8">
@@ -44,7 +42,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<hr> <hr>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover"> <table class="table table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr> <tr>
<th> <th>
@@ -108,24 +106,24 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<td> <td>
<a class="ajax-modal" href="#" <a class="ajax-modal" href="#"
data-modal-url="modals/custom_link/custom_link_edit.php?id=<?= $custom_link_id ?>"> data-modal-url="modals/custom_link/custom_link_edit.php?id=<?= $custom_link_id ?>">
<i class="fa fa-fw fa-<?= $custom_link_icon ?> mr-2"></i><?= $custom_link_name ?> <i class="fa fa-fw fa-<?= $custom_link_icon ?> me-2"></i><?= $custom_link_name ?>
</a> </a>
</td> </td>
<td><?= $custom_link_order_display ?></td> <td><?= $custom_link_order_display ?></td>
<td><?= "$custom_link_uri $custom_link_new_tab_display" ?></td> <td><?= "$custom_link_uri $custom_link_new_tab_display" ?></td>
<td><?= $custom_link_location_display ?></td> <td><?= $custom_link_location_display ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/custom_link/custom_link_edit.php?id=<?= $custom_link_id ?>"> <a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/custom_link/custom_link_edit.php?id=<?= $custom_link_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit me-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_custom_link=<?= $custom_link_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_custom_link=<?= $custom_link_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</a> </a>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,20 @@
<?php
/*
* ITFlow - Database update to version 2.6.8 (from 2.6.7)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Maintenance > Update can now hand an update to cron rather than running it inside the
// request: the page stamps this column and cron/app_update.php takes it and runs
// scripts/update_cli.php in its own process. NULL means nothing is queued, which is why
// the job cannot update an install that did not ask for one.
mysqli_query($mysqli, "ALTER TABLE `settings` ADD COLUMN IF NOT EXISTS `config_update_queued_at` datetime DEFAULT NULL");
// Seeded here as well as by the dispatcher, which only creates rows on its next pass -
// without this, an update queued in the minutes after an upgrade would have no row to
// set cron_job_run_now on and would wait for that pass instead of starting.
mysqli_query($mysqli, "INSERT IGNORE INTO cron_jobs SET cron_job_name = 'app_update', cron_job_enabled = 0, cron_job_schedule = 'Daily', cron_job_daily_at = '05:00'");

View File

@@ -0,0 +1,27 @@
<?php
/*
* ITFlow - Database update to version 2.6.9 (from 2.6.8)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Canned responses for ticket replies, managed from Admin > Canned Responses and
// picked from a dropdown on the ticket reply form.
//
// canned_response_category_id is a ticket category (categories.category_id where
// category_type = 'Ticket'), or 0 for one that offers itself on every ticket
// whatever its category.
mysqli_query($mysqli, "CREATE TABLE IF NOT EXISTS `canned_responses` (
`canned_response_id` int(11) NOT NULL AUTO_INCREMENT,
`canned_response_name` varchar(200) NOT NULL,
`canned_response_body` longtext DEFAULT NULL,
`canned_response_category_id` int(11) NOT NULL DEFAULT 0,
`canned_response_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`canned_response_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`canned_response_archived_at` datetime DEFAULT NULL,
PRIMARY KEY (`canned_response_id`),
KEY `canned_response_category_id` (`canned_response_category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci");

View File

@@ -0,0 +1,39 @@
<?php
/*
* ITFlow - Database update to version 2.7.0 (from 2.6.9)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// The five built-in ticket statuses now have fixed SLA clock behaviour, matching
// getTicketStatusSlaLock() in functions/app.php: On Hold, Resolved and Closed
// pause the resolution clock, New and Open run it. Admin > Ticket Statuses no
// longer offers the choice on these five - only on custom statuses.
//
// On Hold shipped with the column defaulting to 0, so a stock install breached
// the resolution SLA on tickets parked waiting for a client or a vendor. Every
// install had to find the toggle themselves; this sets it for them.
//
// Resolved and Closed are set for consistency across the SLA surfaces, not to
// change behaviour - both already stopped the clocks via ticket_resolved_at and
// ticket_closed_at, which is what the cron and syncTicketSlaClock() actually read.
mysqli_query($mysqli, "UPDATE ticket_statuses SET ticket_status_pauses_sla = 1 WHERE ticket_status_id IN (3, 4, 5)");
mysqli_query($mysqli, "UPDATE ticket_statuses SET ticket_status_pauses_sla = 0 WHERE ticket_status_id IN (1, 2)");
/*
* Tickets already parked in On Hold are still holding an open sla_history
* interval, so their paused time would keep counting as consumed. Closing those
* intervals needs business-hours maths in the app timezone, and this file also
* runs from scripts/update_cli.php, which sets neither - so the first
* cron/ticket_sla.php run after the upgrade reconciles them instead, where the
* timezone is set. Nothing is lost by waiting a minute: the same cron no longer
* warns or breaches a paused ticket the moment the flag above lands.
*
* Breach verdicts already recorded against on-hold tickets are deliberately left
* alone. They were recorded by a clock that really was running under the old
* rules, and rewriting a stored miss is exactly what the reopen-integrity rules
* in functions/sla.php exist to prevent. Re-stamp an individual ticket (change
* its priority or its SLA) if you want it re-judged.
*/

View File

@@ -0,0 +1,17 @@
<?php
/*
* ITFlow - Database update to version 2.7.1 (from 2.7.0)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Which client record, if any, is the MSP's own company. Most installs create one to
// hold their internal tickets, documentation, assets and credentials, but nothing in
// the app knew that record was special. Admin > Settings > Company Details sets it.
//
// 0 means no client is designated, which is every existing install - nothing changes
// until an administrator chooses one.
mysqli_query($mysqli, "ALTER TABLE `settings`
ADD COLUMN `config_internal_client_id` int(11) NOT NULL DEFAULT 0");

View File

@@ -114,12 +114,12 @@ $phpConfig[] = [
'value' => $post_max_size, 'value' => $post_max_size,
]; ];
// PHP Memory Limit >= 128M // PHP Memory Limit >= 512M
$memoryLimit = ini_get('memory_limit'); $memoryLimit = ini_get('memory_limit');
$memoryLimitBytes = toBytes($memoryLimit); $memoryLimitBytes = toBytes($memoryLimit);
$memoryLimitPassed = $memoryLimitBytes >= (128 * 1024 * 1024); $memoryLimitPassed = $memoryLimitBytes >= (512 * 1024 * 1024);
$phpConfig[] = [ $phpConfig[] = [
'name' => 'PHP Memory Limit >= 128M', 'name' => 'PHP Memory Limit >= 512M',
'passed' => $memoryLimitPassed, 'passed' => $memoryLimitPassed,
'value' => $memoryLimit, 'value' => $memoryLimit,
]; ];
@@ -508,7 +508,7 @@ $mysqli->close();
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-bug mr-2"></i>Debug</h3> <h3 class="card-title"><i class="fas fa-fw fa-bug me-2"></i>Debug</h3>
</div> </div>
<div class="card-body"> <div class="card-body">

View File

@@ -44,19 +44,19 @@ $document_template_updated_at = escapeHtml($row['document_template_updated_at'])
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="document_templates.php">Document Templates</a> <a href="document_templates.php">Document Templates</a>
</li> </li>
<li class="breadcrumb-item active"><i class="fas fa-file-alt mr-2"></i><?= $document_template_name ?></li> <li class="breadcrumb-item active"><i class="fas fa-file-alt me-2"></i><?= $document_template_name ?></li>
</ol> </ol>
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header"> <div class="card-header">
<h3 class="card-title mt-1"><i class="fa fa-fw fa-file-alt mr-2"></i><?= $document_template_name ?></h3> <h3 class="card-title mt-1"><i class="fa fa-fw fa-file-alt me-2"></i><?= $document_template_name ?></h3>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-tool ajax-modal" <button type="button" class="btn btn-tool ajax-modal"
data-modal-size="xl" data-modal-size="xl"
data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_id ?>"> data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_id ?>">
<i class="fas fa-edit mr-2"></i> <i class="fas fa-edit me-2"></i>
</button> </button>
</div> </div>
</div> </div>

View File

@@ -19,29 +19,27 @@
?> ?>
<div class="card card-dark"> <div class="card">
<div class="card-header py-2"> <div class="card-header bg-dark py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file-alt mr-2"></i>Document Templates</h3> <h3 class="card-title mt-2"><i class="fa fa-fw fa-file-alt me-2"></i>Document Templates</h3>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/document_template/document_template_add.php" data-modal-size="xl"> <button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/document_template/document_template_add.php" data-modal-size="xl">
<i class="fas fa-plus mr-2"></i>New Template <i class="fas fa-plus me-2"></i>New Template
</button> </button>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-header py-3">
<form autocomplete="off"> <form autocomplete="off">
<div class="input-group"> <div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search templates"> <input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search templates">
<div class="input-group-append">
<button class="btn btn-secondary"><i class="fa fa-search"></i></button> <button class="btn btn-secondary"><i class="fa fa-search"></i></button>
</div> </div>
</div>
</form> </form>
<hr> </div>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover"> <table class="table table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr> <tr>
<th> <th>
@@ -83,9 +81,9 @@
<a class="text-dark ajax-modal" href="#" <a class="text-dark ajax-modal" href="#"
data-modal-size="xl" data-modal-size="xl"
data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_id ?>"> data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_id ?>">
<div class="media"> <div class="d-flex">
<i class="fas fa-fw fa-2x fa-file-alt mr-2"></i> <i class="fas fa-fw fa-2x fa-file-alt me-2"></i>
<div class="media-body"> <div class="flex-grow-1">
<div><?= $document_template_name ?></div> <div><?= $document_template_name ?></div>
<div><small class="text-secondary"><?= $document_template_description ?></small></div> <div><small class="text-secondary"><?= $document_template_description ?></small></div>
</div> </div>
@@ -98,23 +96,23 @@
</td> </td>
<td><?= $document_template_updated_at ?></td> <td><?= $document_template_updated_at ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item" href="document_template.php?document_template_id=<?= $document_template_id ?>"> <a class="dropdown-item" href="document_template.php?document_template_id=<?= $document_template_id ?>">
<i class="fas fa-fw fa-eye mr-2"></i>View <i class="fas fa-fw fa-eye me-2"></i>View
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item ajax-modal" href="#" <a class="dropdown-item ajax-modal" href="#"
data-modal-size="xl" data-modal-size="xl"
data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_id ?>"> data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit me-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold" href="post.php?delete_document_template=<?= $document_template_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger text-bold" href="post.php?delete_document_template=<?= $document_template_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</a> </a>
</div> </div>
</div> </div>
@@ -133,6 +131,5 @@
</div> </div>
<?php require_once "../includes/filter_footer.php"; ?> <?php require_once "../includes/filter_footer.php"; ?>
</div> </div>
</div>
<?php require_once "../includes/footer.php"; <?php require_once "../includes/footer.php";

View File

@@ -4,7 +4,7 @@ require_once "includes/inc_all_admin.php";
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-fingerprint mr-2"></i>Identity Providers</h3> <h3 class="card-title"><i class="fas fa-fw fa-fingerprint me-2"></i>Identity Providers</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
@@ -12,13 +12,11 @@ require_once "includes/inc_all_admin.php";
<h4>Client Portal SSO via Microsoft Entra</h4> <h4>Client Portal SSO via Microsoft Entra</h4>
<div class="form-group"> <div class="mb-3">
<label>Identity Provider <small class='text-secondary'>(Currently only works with Microsoft Entra ID/AAD)</small></label> <label>Identity Provider <small class='text-secondary'>(Currently only works with Microsoft Entra ID/AAD)</small></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-fingerprint"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-fingerprint"></i></span>
</div> <select class="form-select select2" readonly>
<select class="form-control select2" readonly>
<option <?php if (empty($config_azure_client_id)) { echo "selected"; } ?>>Disabled</option> <option <?php if (empty($config_azure_client_id)) { echo "selected"; } ?>>Disabled</option>
<option <?php if ($config_azure_client_id) { echo "selected"; } ?>>Microsoft Entra</option> <option <?php if ($config_azure_client_id) { echo "selected"; } ?>>Microsoft Entra</option>
<option>Google (WIP)</option> <option>Google (WIP)</option>
@@ -27,29 +25,25 @@ require_once "includes/inc_all_admin.php";
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>MS Entra OAuth App (Client) ID</label> <label>MS Entra OAuth App (Client) ID</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<input type="text" class="form-control" name="azure_client_id" placeholder="e721e3b6-01d6-50e8-7f22-c84d951a52e7" maxlength="200" value="<?= escapeHtml($config_azure_client_id) ?>"> <input type="text" class="form-control" name="azure_client_id" placeholder="e721e3b6-01d6-50e8-7f22-c84d951a52e7" maxlength="200" value="<?= escapeHtml($config_azure_client_id) ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>MS Entra OAuth Secret</label> <label>MS Entra OAuth Secret</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div>
<input type="password" class="form-control" name="azure_client_secret" placeholder="Auto-generated from App Registration" maxlength="200" value="<?= escapeHtml($config_azure_client_secret) ?>" autocomplete="new-password"> <input type="password" class="form-control" name="azure_client_secret" placeholder="Auto-generated from App Registration" maxlength="200" value="<?= escapeHtml($config_azure_client_secret) ?>" autocomplete="new-password">
</div> </div>
</div> </div>
<hr> <hr>
<button type="submit" name="edit_identity_provider" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_identity_provider" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
</form> </form>
</div> </div>

View File

@@ -1,19 +1,17 @@
<!-- Main Sidebar Container --> <!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-<?= escapeHtml($config_theme) ?> d-print-none"> <aside class="app-sidebar shadow d-print-none" data-bs-theme="dark">
<a class="brand-link pb-1 mt-1" href="/agent/<?= $config_start_page ?>"> <div class="sidebar-brand">
<p class="h6"> <a class="brand-link" href="/agent/<?= $config_start_page ?>">
<i class="nav-icon fas fa-arrow-left ml-3 mr-2"></i> <i class="fas fa-arrow-left me-2"></i>
<span class="brand-text"> <span class="brand-text h6 mb-0">Back | <strong>Administration</strong></span>
Back | <strong>Administration</strong>
</span>
</p>
</a> </a>
</div>
<!-- Sidebar --> <!-- Sidebar -->
<div class="sidebar"> <div class="sidebar-wrapper">
<!-- Sidebar Menu --> <!-- Sidebar Menu -->
<nav> <nav>
<ul class="nav nav-pills nav-sidebar flex-column mt-2" data-widget="treeview" data-accordion="false"> <ul class="nav nav-pills sidebar-menu flex-column mt-2" data-lte-toggle="treeview" data-accordion="false">
<li class="nav-header">ACCESS</li> <li class="nav-header">ACCESS</li>
<li class="nav-item"> <li class="nav-item">
<a href="/admin/users.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "users.php") {echo "active";} ?>"> <a href="/admin/users.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "users.php") {echo "active";} ?>">
@@ -126,6 +124,12 @@
<p>Ticket Templates</p> <p>Ticket Templates</p>
</a> </a>
</li> </li>
<li class="nav-item">
<a href="/admin/canned_responses.php" class="nav-link <?= (basename($_SERVER['PHP_SELF']) == 'canned_responses.php' ? 'active' : '') ?>">
<i class="nav-icon fas fa-comment-dots"></i>
<p>Canned Responses</p>
</a>
</li>
<?php } ?> <?php } ?>
<?php if ($config_module_enable_itdoc) { ?> <?php if ($config_module_enable_itdoc) { ?>
<!-- 2025-11-16 JQ - Hide Contracts not yet ready <!-- 2025-11-16 JQ - Hide Contracts not yet ready
@@ -211,7 +215,7 @@
</li> </li>
<!-- SETTINGS Section --> <!-- SETTINGS Section -->
<li class="nav-item has-treeview mt-2 <?= (in_array(basename($_SERVER['PHP_SELF']), ['settings_company.php', 'settings_localization.php', 'settings_theme.php', 'settings_security.php', 'settings_mail.php', 'settings_notification.php', 'settings_default.php', 'settings_invoice.php', 'settings_quote.php', 'settings_online_payment.php', 'settings_online_payment_clients.php', 'settings_project.php', 'settings_ticket.php', 'settings_ai.php', 'identity_providers.php', 'settings_telemetry.php', 'settings_module.php']) ? 'menu-open' : '') ?>"> <li class="nav-item mt-2 <?= (in_array(basename($_SERVER['PHP_SELF']), ['settings_company.php', 'settings_localization.php', 'settings_theme.php', 'settings_security.php', 'settings_mail.php', 'settings_notification.php', 'settings_default.php', 'settings_invoice.php', 'settings_quote.php', 'settings_online_payment.php', 'settings_online_payment_clients.php', 'settings_project.php', 'settings_ticket.php', 'settings_ai.php', 'identity_providers.php', 'settings_telemetry.php', 'settings_module.php']) ? 'menu-open' : '') ?>">
<a href="#" class="nav-link"> <a href="#" class="nav-link">
<p> <p>
SETTINGS SETTINGS
@@ -336,7 +340,7 @@
<a href="<?= $custom_link_uri ?>" <?= $target ?> class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == basename($custom_link_uri)) { echo "active"; } ?>"> <a href="<?= $custom_link_uri ?>" <?= $target ?> class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == basename($custom_link_uri)) { echo "active"; } ?>">
<i class="fas fa-<?= $custom_link_icon ?> nav-icon"></i> <i class="fas fa-<?= $custom_link_icon ?> nav-icon"></i>
<p><?= $custom_link_name ?></p> <p><?= $custom_link_name ?></p>
<i class="fas fa-angle-right nav-icon float-right"></i> <i class="fas fa-angle-right nav-icon float-end"></i>
</a> </a>
</li> </li>

View File

@@ -19,46 +19,44 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<div class="card card-dark"> <div class="card">
<div class="card-header py-3"> <div class="card-header bg-dark py-2">
<h3 class="card-title"><i class="fas fa-fw fa-inbox mr-2"></i>Email Queue</h3> <h3 class="card-title"><i class="fas fa-fw fa-inbox me-2"></i>Email Queue</h3>
</div> </div>
<div class="card-body"> <div class="card-header py-3">
<form class="mb-4" autocomplete="off"> <form autocomplete="off">
<div class="row"> <div class="row g-2 align-items-end">
<div class="col-sm-4"> <div class="col-sm-4">
<div class="input-group"> <div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search mail queue"> <input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search mail queue">
<div class="input-group-append"> <button class="btn btn-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#advancedFilter"><i class="fas fa-filter"></i></button>
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#advancedFilter"><i class="fas fa-filter"></i></button>
<button class="btn btn-primary"><i class="fa fa-search"></i></button> <button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div> </div>
</div> </div>
</div>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="dropdown float-right" id="bulkActionButton" hidden> <div class="dropdown float-end" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>) <i class="fas fa-fw fa-layer-group me-2"></i>Bulk Action (<span id="selectedCount">0</span>)
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<button class="dropdown-item" <button class="dropdown-item"
type="submit" form="bulkActions" name="bulk_cancel_emails"> type="submit" form="bulkActions" name="bulk_cancel_emails">
<i class="fas fa-fw fa-ban mr-2"></i>Cancel <i class="fas fa-fw fa-ban me-2"></i>Cancel
</button> </button>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold" <button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_emails"> type="submit" form="bulkActions" name="bulk_delete_emails">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="collapse mt-3 <?php if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') { echo"show"; } ?>" id="advancedFilter"> <div class="collapse mt-3 <?php if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') { echo"show"; } ?>" id="advancedFilter">
<div class="row"> <div class="row g-3">
<div class="col-md-3"> <div class="col-md-3">
<div class="form-group"> <div>
<label>Date range</label> <label class="form-label">Date range</label>
<input type="text" id="dateFilter" class="form-control" autocomplete="off"> <input type="text" id="dateFilter" class="form-control" autocomplete="off">
<input type="hidden" name="canned_date" id="canned_date" value="<?= escapeHtml($_GET['canned_date']) ?? '' ?>"> <input type="hidden" name="canned_date" id="canned_date" value="<?= escapeHtml($_GET['canned_date']) ?? '' ?>">
<input type="hidden" name="dtf" id="dtf" value="<?= escapeHtml($dtf ?? '') ?>"> <input type="hidden" name="dtf" id="dtf" value="<?= escapeHtml($dtf ?? '') ?>">
@@ -68,15 +66,15 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
</div> </div>
</form> </form>
<hr> </div>
<form id="bulkActions" action="post.php" method="post"> <form id="bulkActions" action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-sm table-striped table-borderless table-hover"> <table class="table table-sm table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr> <tr>
<td class="bg-light pr-0"> <td class="bg-light pe-0">
<div class="form-check"> <div class="form-check">
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)"> <input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
</div> </div>
@@ -134,22 +132,22 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
} elseif($email_status == 1) { } elseif($email_status == 1) {
$email_status_display = "<div class='text-warning'>Sending</div>"; $email_status_display = "<div class='text-warning'>Sending</div>";
} elseif($email_status == 2) { } elseif($email_status == 2) {
$email_status_display = "<div class='text-danger'>Failed</div><small class='text-secondary text-monospace'>$email_failed_at</small>"; $email_status_display = "<div class='text-danger'>Failed</div><small class='text-secondary font-monospace'>$email_failed_at</small>";
} else { } else {
$email_status_display = "<div class='text-success'>Sent</div><small class='text-secondary text-monospace'>$email_sent_at</small>"; $email_status_display = "<div class='text-success'>Sent</div><small class='text-secondary font-monospace'>$email_sent_at</small>";
} }
?> ?>
<tr> <tr>
<td class="pr-0 bg-light"> <td class="pe-0 bg-light">
<?php if ($email_status !== 3) { ?> <?php if ($email_status !== 3) { ?>
<div class="form-check"> <div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="email_ids[]" value="<?= $email_id ?>"> <input class="form-check-input bulk-select" type="checkbox" name="email_ids[]" value="<?= $email_id ?>">
</div> </div>
<?php } ?> <?php } ?>
</td> </td>
<td class="text-monospace"><?= $email_queued_at ?></td> <td class="font-monospace"><?= $email_queued_at ?></td>
<td><?= "$email_from<br><small class='text-secondary'>$email_from_name</small>" ?></td> <td><?= "$email_from<br><small class='text-secondary'>$email_from_name</small>" ?></td>
<td><?= "$email_recipient<br><small class='text-secondary'>$email_recipient_name</small>" ?></td> <td><?= "$email_recipient<br><small class='text-secondary'>$email_recipient_name</small>" ?></td>
<td><?= $email_subject ?></td> <td><?= $email_subject ?></td>
@@ -186,7 +184,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php require_once "../includes/filter_footer.php"; ?> <?php require_once "../includes/filter_footer.php"; ?>
</div> </div>
</div>
<script src="../js/bulk_actions.js"></script> <script src="../js/bulk_actions.js"></script>

View File

@@ -7,23 +7,19 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-robot mr-2"></i>Add AI Model</h5> <h5 class="modal-title"><i class="fa fa-fw fa-robot me-2"></i>Add AI Model</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Provider <strong class="text-danger">*</strong></label> <label>Provider <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span>
</div> <select class="form-select select2" name="provider" required>
<select class="form-control select2" name="provider" required>
<option value="">- Select an AI Provider -</option> <option value="">- Select an AI Provider -</option>
<?php <?php
$sql_ai_providers = mysqli_query($mysqli, "SELECT ai_provider_id, ai_provider_name FROM ai_providers"); $sql_ai_providers = mysqli_query($mysqli, "SELECT ai_provider_id, ai_provider_name FROM ai_providers");
@@ -38,23 +34,19 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Model Name <strong class="text-danger">*</strong></label> <label>Model Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span>
</div>
<input type="text" class="form-control" name="model" placeholder="ex gpt-4" maxlength="200"> <input type="text" class="form-control" name="model" placeholder="ex gpt-4" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Use Case <strong class="text-danger">*</strong></label> <label>Use Case <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-th-list"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-th-list"></i></span>
</div> <select class="form-select select2" name="use_case">
<select class="form-control select2" name="use_case">
<option>General</option> <option>General</option>
<option>Tickets</option> <option>Tickets</option>
<option>Documentation</option> <option>Documentation</option>
@@ -62,25 +54,23 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Temperature</label> <label>Temperature</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
</div>
<input type="number" class="form-control" name="temperature" step="0.1" min="0" max="2" value="" placeholder="Provider default"> <input type="number" class="form-control" name="temperature" step="0.1" min="0" max="2" value="" placeholder="Provider default">
</div> </div>
<small class="form-text text-muted">Optional. Leave blank to let the provider use its default - some newer models reject every other value.</small> <small class="form-text text-muted">Optional. Leave blank to let the provider use its default - some newer models reject every other value.</small>
</div> </div>
<div class="form-group"> <div class="mb-3">
<textarea class="form-control" rows="8" name="prompt" placeholder="Enter a model prompt:"></textarea> <textarea class="form-control" rows="8" name="prompt" placeholder="Enter a model prompt:"></textarea>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_ai_model" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button> <button type="submit" name="add_ai_model" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -19,10 +19,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-robot mr-2"></i>Editing: <strong><?= $model_name ?></strong></h5> <h5 class="modal-title"><i class="fa fa-fw fa-robot me-2"></i>Editing: <strong><?= $model_name ?></strong></h5>
<button type="button" class="close text-light" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -30,13 +28,11 @@ ob_start();
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Provider <strong class="text-danger">*</strong></label> <label>Provider <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span>
</div> <select class="form-select select2" name="provider" required>
<select class="form-control select2" name="provider" required>
<option value="">- Select an AI Provider -</option> <option value="">- Select an AI Provider -</option>
<?php <?php
$sql_ai_providers = mysqli_query($mysqli, "SELECT ai_provider_id, ai_provider_name FROM ai_providers"); $sql_ai_providers = mysqli_query($mysqli, "SELECT ai_provider_id, ai_provider_name FROM ai_providers");
@@ -51,23 +47,19 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Model Name <strong class="text-danger">*</strong></label> <label>Model Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span>
</div>
<input type="text" class="form-control" name="model" value="<?= $model_name ?>" placeholder="ex gpt-4" maxlength="200"> <input type="text" class="form-control" name="model" value="<?= $model_name ?>" placeholder="ex gpt-4" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Use Case <strong class="text-danger">*</strong></label> <label>Use Case <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-th-list"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-th-list"></i></span>
</div> <select class="form-select select2" name="use_case">
<select class="form-control select2" name="use_case">
<option <?php if ($use_case == 'General') { echo "selected"; } ?>>General</option> <option <?php if ($use_case == 'General') { echo "selected"; } ?>>General</option>
<option <?php if ($use_case == 'Tickets') { echo "selected"; } ?>>Tickets</option> <option <?php if ($use_case == 'Tickets') { echo "selected"; } ?>>Tickets</option>
<option <?php if ($use_case == 'Documentation') { echo "selected"; } ?>>Documentation</option> <option <?php if ($use_case == 'Documentation') { echo "selected"; } ?>>Documentation</option>
@@ -75,24 +67,22 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Temperature</label> <label>Temperature</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
</div>
<input type="number" class="form-control" name="temperature" step="0.1" min="0" max="2" value="<?= $temperature ?>" placeholder="Provider default"> <input type="number" class="form-control" name="temperature" step="0.1" min="0" max="2" value="<?= $temperature ?>" placeholder="Provider default">
</div> </div>
<small class="form-text text-muted">Optional. Leave blank to let the provider use its default - some newer models reject every other value.</small> <small class="form-text text-muted">Optional. Leave blank to let the provider use its default - some newer models reject every other value.</small>
</div> </div>
<div class="form-group"> <div class="mb-3">
<textarea class="form-control" rows="8" name="prompt" placeholder="Enter a model prompt:"><?= $prompt ?></textarea> <textarea class="form-control" rows="8" name="prompt" placeholder="Enter a model prompt:"><?= $prompt ?></textarea>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_ai_model" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_ai_model" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -7,50 +7,42 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-robot mr-2"></i>New AI Provider</h5> <h5 class="modal-title"><i class="fa fa-fw fa-robot me-2"></i>New AI Provider</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Provider Name <strong class="text-danger">*</strong></label> <label>Provider Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span>
</div>
<input type="text" class="form-control" name="provider" placeholder="ex OpenAI" maxlength="200"> <input type="text" class="form-control" name="provider" placeholder="ex OpenAI" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>URL <strong class="text-danger">*</strong></label> <label>URL <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="url" class="form-control" name="url" placeholder="ex https://ai.company.ext/api" maxlength="200"> <input type="url" class="form-control" name="url" placeholder="ex https://ai.company.ext/api" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>API Key</label> <label>API Key</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div>
<input type="text" class="form-control" name="api_key" placeholder="Enter API key here" maxlength="200"> <input type="text" class="form-control" name="api_key" placeholder="Enter API key here" maxlength="200">
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_ai_provider" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button> <button type="submit" name="add_ai_provider" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -16,10 +16,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-robot mr-2"></i>Editing: <strong><?= $provider_name ?></strong></h5> <h5 class="modal-title"><i class="fa fa-fw fa-robot me-2"></i>Editing: <strong><?= $provider_name ?></strong></h5>
<button type="button" class="close text-light" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -27,40 +25,34 @@ ob_start();
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Provider Name <strong class="text-danger">*</strong></label> <label>Provider Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span>
</div>
<input type="text" class="form-control" name="provider" value="<?= $provider_name ?>" placeholder="ex OpenAI" maxlength="200"> <input type="text" class="form-control" name="provider" value="<?= $provider_name ?>" placeholder="ex OpenAI" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>URL <strong class="text-danger">*</strong></label> <label>URL <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="url" class="form-control" name="url" value="<?= $url ?>" placeholder="ex https://ai.company.ext/api" maxlength="200"> <input type="url" class="form-control" name="url" value="<?= $url ?>" placeholder="ex https://ai.company.ext/api" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>API Key</label> <label>API Key</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div>
<input type="text" class="form-control" name="api_key" value="<?= $key ?>" placeholder="Enter API key here" maxlength="200"> <input type="text" class="form-control" name="api_key" value="<?= $key ?>" placeholder="Enter API key here" maxlength="200">
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_ai_provider" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_ai_provider" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -10,20 +10,18 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-key mr-2"></i>New Key</h5> <h5 class="modal-title"><i class="fas fa-fw fa-key me-2"></i>New Key</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<div class="modal-body"> <div class="modal-body">
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-api-details">Details</a> <a class="nav-link active" data-bs-toggle="pill" href="#pills-api-details">Details</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-api-keys">Keys</a> <a class="nav-link" data-bs-toggle="pill" href="#pills-api-keys">Keys</a>
</li> </li>
</ul> </ul>
<hr> <hr>
@@ -35,33 +33,27 @@ ob_start();
<input type="hidden" name="key" value="<?= $key ?>"> <input type="hidden" name="key" value="<?= $key ?>">
<input type="hidden" name="password" value="<?= $decryptPW ?>"> <input type="hidden" name="password" value="<?= $decryptPW ?>">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-sticky-note"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-sticky-note"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Key Name" maxlength="255" required autofocus> <input type="text" class="form-control" name="name" placeholder="Key Name" maxlength="255" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Expiration Date <strong class="text-danger">*</strong></label> <label>Expiration Date <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="expire" min="<?= date('Y-m-d') ?>" max="2999-12-31" required> <input type="date" class="form-control" name="expire" min="<?= date('Y-m-d') ?>" max="2999-12-31" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Run as User <strong class="text-danger">*</strong></label> <label>Run as User <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
</div> <select class="form-select select2" name="run_as_user" required>
<select class="form-control select2" name="run_as_user" required>
<option value="">- Select a user -</option> <option value="">- Select a user -</option>
<?php <?php
$sql_run_users = mysqli_query($mysqli, "SELECT user_id, user_name FROM users WHERE user_type = 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"); $sql_run_users = mysqli_query($mysqli, "SELECT user_id, user_name FROM users WHERE user_type = 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC");
@@ -77,38 +69,28 @@ ob_start();
</div> </div>
<div class="tab-pane fade" id="pills-api-keys"> <div class="tab-pane fade" id="pills-api-keys">
<div class="form-group"> <div class="mb-3">
<label>API Key <strong class="text-danger">*</strong></label> <label>API Key <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div>
<input type="text" class="form-control" value="<?= $key ?>" required disabled> <input type="text" class="form-control" value="<?= $key ?>" required disabled>
<div class="input-group-append">
<button class="btn btn-default clipboardjs" type="button" data-clipboard-text="<?= $key ?>"><i class="fa fa-fw fa-copy"></i></button> <button class="btn btn-default clipboardjs" type="button" data-clipboard-text="<?= $key ?>"><i class="fa fa-fw fa-copy"></i></button>
</div> </div>
</div> </div>
</div>
<div class="form-group"> <div class="mb-3">
<label>Login credential decryption password <strong class="text-danger">*</strong></label> <label>Login credential decryption password <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-unlock-alt"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-unlock-alt"></i></span>
</div>
<input type="text" class="form-control" value="<?= $decryptPW ?>" required disabled> <input type="text" class="form-control" value="<?= $decryptPW ?>" required disabled>
<div class="input-group-append">
<button class="btn btn-default clipboardjs" type="button" data-clipboard-text="<?= $decryptPW ?>"><i class="fa fa-fw fa-copy"></i></button> <button class="btn btn-default clipboardjs" type="button" data-clipboard-text="<?= $decryptPW ?>"><i class="fa fa-fw fa-copy"></i></button>
</div> </div>
</div> </div>
</div>
<br> <br>
<div class="form-group"> <div class="mb-3">
<label>I have made a copy of the key(s)<strong class="text-danger">*</strong></label> <label>I have made a copy of the key(s)<strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <input class="form-check-input" type="checkbox" name="ack" value="1" required>
<input type="checkbox" name="ack" value="1" required>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -117,8 +99,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_api_key" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button> <button type="submit" name="add_api_key" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -14,11 +14,9 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-key mr-2"></i>Editing API Key: <h5 class="modal-title"><i class="fas fa-fw fa-key me-2"></i>Editing API Key:
<strong><?= $api_key_name ?></strong></h5> <strong><?= $api_key_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<div class="modal-body"> <div class="modal-body">
@@ -26,35 +24,29 @@ ob_start();
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="api_key_id" value="<?= $api_key_id ?>"> <input type="hidden" name="api_key_id" value="<?= $api_key_id ?>">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-sticky-note"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-sticky-note"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Key Name" maxlength="255" <input type="text" class="form-control" name="name" placeholder="Key Name" maxlength="255"
value="<?= $api_key_name ?>" required autofocus> value="<?= $api_key_name ?>" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Expiration Date <strong class="text-danger">*</strong></label> <label>Expiration Date <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="expire" min="<?= date('Y-m-d') ?>" max="2999-12-31" <input type="date" class="form-control" name="expire" min="<?= date('Y-m-d') ?>" max="2999-12-31"
value="<?= $api_key_expire ?>" required> value="<?= $api_key_expire ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Run as User <strong class="text-danger">*</strong></label> <label>Run as User <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
</div> <select class="form-select select2" name="run_as_user" required>
<select class="form-control select2" name="run_as_user" required>
<option value="">- Select a user -</option> <option value="">- Select a user -</option>
<?php <?php
$sql_run_users = mysqli_query($mysqli, "SELECT user_id, user_name FROM users WHERE user_type = 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"); $sql_run_users = mysqli_query($mysqli, "SELECT user_id, user_name FROM users WHERE user_type = 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC");
@@ -70,8 +62,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_api_key" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_api_key" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -0,0 +1,58 @@
<?php
require_once '../../includes/modal_header.php';
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-comment-dots me-2"></i>New Canned Response</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body">
<div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-fw fa-comment-dots"></i></span>
<input type="text" class="form-control" name="name" placeholder="What an agent picks it by" maxlength="200" required autofocus>
</div>
</div>
<div class="mb-3">
<label>Ticket Category</label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
<select class="form-select select2" name="category">
<option value="0">- All ticket categories -</option>
<?php
$sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND category_archived_at IS NULL ORDER BY category_name ASC");
while ($row = mysqli_fetch_assoc($sql_categories)) {
$category_id_select = intval($row['category_id']);
$category_name_select = escapeHtml($row['category_name']); ?>
<option value="<?= $category_id_select ?>"><?= $category_name_select ?></option>
<?php } ?>
</select>
</div>
<small class="text-secondary">Leave this on all categories for a response that should be offered on every ticket.</small>
</div>
<div class="mb-3">
<label>Response</label>
<textarea class="form-control tinymceTicket" name="body"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="add_canned_response" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Create Canned Response</button>
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -0,0 +1,72 @@
<?php
require_once '../../includes/modal_header.php';
$canned_response_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT canned_response_name, canned_response_body, canned_response_category_id
FROM canned_responses WHERE canned_response_id = $canned_response_id LIMIT 1");
$row = mysqli_fetch_assoc($sql);
$canned_response_name = escapeHtml($row['canned_response_name']);
$canned_response_category_id = intval($row['canned_response_category_id']);
// Into a textarea, so escaped rather than purified - it is markup being edited, not rendered
$canned_response_body = escapeHtml($row['canned_response_body']);
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-comment-dots me-2"></i>Editing Canned Response: <strong><?= $canned_response_name ?></strong></h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="canned_response_id" value="<?= $canned_response_id ?>">
<div class="modal-body">
<div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-fw fa-comment-dots"></i></span>
<input type="text" class="form-control" name="name" maxlength="200" value="<?= $canned_response_name ?>" required>
</div>
</div>
<div class="mb-3">
<label>Ticket Category</label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
<select class="form-select select2" name="category">
<option value="0" <?php if ($canned_response_category_id == 0) { echo "selected"; } ?>>- All ticket categories -</option>
<?php
$sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND category_archived_at IS NULL ORDER BY category_name ASC");
while ($category_row = mysqli_fetch_assoc($sql_categories)) {
$category_id_select = intval($category_row['category_id']);
$category_name_select = escapeHtml($category_row['category_name']); ?>
<option value="<?= $category_id_select ?>" <?php if ($canned_response_category_id == $category_id_select) { echo "selected"; } ?>><?= $category_name_select ?></option>
<?php } ?>
</select>
</div>
<small class="text-secondary">Leave this on all categories for a response that should be offered on every ticket.</small>
</div>
<div class="mb-3">
<label>Response</label>
<textarea class="form-control tinymceTicket" name="body"><?= $canned_response_body ?></textarea>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="edit_canned_response" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -9,10 +9,8 @@ $category_types_array = ['Expense', 'Income', 'Referral', 'Ticket'];
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-list-ul mr-2"></i>New <strong><?= escapeHtml(ucwords(str_replace('_', ' ', $category))); ?></strong> Category</h5> <h5 class="modal-title"><i class="fa fa-fw fa-list-ul me-2"></i>New <strong><?= escapeHtml(ucwords(str_replace('_', ' ', $category))); ?></strong> Category</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -23,13 +21,11 @@ $category_types_array = ['Expense', 'Income', 'Referral', 'Ticket'];
<input type="hidden" name="type" value="<?= $category ?>"> <input type="hidden" name="type" value="<?= $category ?>">
<?php } else { ?> <?php } else { ?>
<div class="form-group"> <div class="mb-3">
<label>Type <strong class="text-danger">*</strong></label> <label>Type <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div> <select class="form-select select2" name="type" required>
<select class="form-control select2" name="type" required>
<option value="">- Select Type -</option> <option value="">- Select Type -</option>
<?php foreach ($category_types_array as $type_select) { ?> <?php foreach ($category_types_array as $type_select) { ?>
<option><?= $type_select ?></option> <option><?= $type_select ?></option>
@@ -40,40 +36,34 @@ $category_types_array = ['Expense', 'Income', 'Referral', 'Ticket'];
<?php } ?> <?php } ?>
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-list-ul"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-list-ul"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Category name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" placeholder="Category name" maxlength="200" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Color <strong class="text-danger">*</strong></label> <label>Color <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span>
</div>
<input type="color" class="form-control col-3" name="color" required> <input type="color" class="form-control col-3" name="color" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description</label> <label>Description</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-fw fa-align-left"></i></span> <span class="input-group-text"><i class="fas fa-fw fa-align-left"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Enter a description" maxlength="200"> <input type="text" class="form-control" name="description" placeholder="Enter a description" maxlength="200">
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_category" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create Category</button> <button type="submit" name="add_category" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Create Category</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -16,10 +16,8 @@ $category_type = escapeHtml($row['category_type']);
ob_start(); ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-list-ul mr-2"></i>Editing category: <strong><?= $category_name ?></strong></h5> <h5 class="modal-title"><i class="fa fa-fw fa-list-ul me-2"></i>Editing category: <strong><?= $category_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -27,40 +25,34 @@ ob_start();
<input type="hidden" name="type" value="<?= $category_type ?>"> <input type="hidden" name="type" value="<?= $category_type ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-list-ul"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-list-ul"></i></span>
</div>
<input type="text" class="form-control" name="name" maxlength="200" value="<?= $category_name ?>" required> <input type="text" class="form-control" name="name" maxlength="200" value="<?= $category_name ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Color <strong class="text-danger">*</strong></label> <label>Color <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span>
</div>
<input type="color" class="form-control col-3" name="color" value="<?= $category_color ?>" required> <input type="color" class="form-control col-3" name="color" value="<?= $category_color ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description</label> <label>Description</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-fw fa-align-left"></i></span> <span class="input-group-text"><i class="fas fa-fw fa-align-left"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Enter a description" maxlength="200" value="<?= $category_description ?>"> <input type="text" class="form-control" name="description" placeholder="Enter a description" maxlength="200" value="<?= $category_description ?>">
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_category" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_category" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -9,23 +9,23 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-file-contract mr-2"></i>New Contract Template</h5> <h5 class="modal-title"><i class="fa fa-fw fa-file-contract me-2"></i>New Contract Template</h5>
<button type="button" class="close text-white" data-dismiss="modal"><span>&times;</span></button> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div> </div>
<!-- Tabs Navigation --> <!-- Tabs Navigation -->
<ul class="modal-header nav nav-pills nav-justified"> <ul class="modal-header nav nav-pills nav-justified">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" id="general-tab" data-toggle="tab" href="#general" role="tab">General Info</a> <a class="nav-link active" id="general-tab" data-bs-toggle="tab" href="#general" role="tab">General Info</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="sla-tab" data-toggle="tab" href="#sla" role="tab">SLA</a> <a class="nav-link" id="sla-tab" data-bs-toggle="tab" href="#sla" role="tab">SLA</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="rates-tab" data-toggle="tab" href="#rates" role="tab">Rates & Support</a> <a class="nav-link" id="rates-tab" data-bs-toggle="tab" href="#rates" role="tab">Rates & Support</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="details-tab" data-toggle="tab" href="#details" role="tab">Details</a> <a class="nav-link" id="details-tab" data-bs-toggle="tab" href="#details" role="tab">Details</a>
</li> </li>
</ul> </ul>
@@ -37,34 +37,28 @@ ob_start();
<!-- General Info Tab --> <!-- General Info Tab -->
<div class="tab-pane fade show active" id="general" role="tabpanel"> <div class="tab-pane fade show active" id="general" role="tabpanel">
<div class="form-group"> <div class="mb-3">
<label>Template Name <strong class="text-danger">*</strong></label> <label>Template Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-file-contract"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-file-contract"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Contract Template Name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" placeholder="Contract Template Name" maxlength="200" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Template Description <strong class="text-danger">*</strong></label> <label>Template Description <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-align-left"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-align-left"></i></span>
</div>
<input type="text" class="form-control" name="description" <input type="text" class="form-control" name="description"
placeholder="Contract Template Description" maxlength="200" required> placeholder="Contract Template Description" maxlength="200" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Contract Type <strong class="text-danger">*</strong></label> <label>Contract Type <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-list"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-list"></i></span>
</div> <select class="form-select select2" name="type" required>
<select class="form-control select2" name="type" required>
<option value="">- Select Type -</option> <option value="">- Select Type -</option>
<?php foreach ($contract_types_array as $type) { ?> <?php foreach ($contract_types_array as $type) { ?>
<option><?= $type ?></option> <option><?= $type ?></option>
@@ -73,13 +67,11 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Renewal Frequency</label> <label>Renewal Frequency</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-sync-alt"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-sync-alt"></i></span>
</div> <select class="form-select select2" name="renewal_frequency">
<select class="form-control select2" name="renewal_frequency">
<option value="">- Select Frequency -</option> <option value="">- Select Frequency -</option>
<?php foreach ($renewal_frequency_array as $renewal_frequency) { ?> <?php foreach ($renewal_frequency_array as $renewal_frequency) { ?>
<option><?= $renewal_frequency ?></option> <option><?= $renewal_frequency ?></option>
@@ -91,64 +83,52 @@ ob_start();
<!-- SLA Tab --> <!-- SLA Tab -->
<div class="tab-pane fade" id="sla" role="tabpanel"> <div class="tab-pane fade" id="sla" role="tabpanel">
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>Low Priority Response (hrs)</label> <label>Low Priority Response (hrs)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div>
<input type="number" class="form-control" name="sla_low_response_time" placeholder="e.g., 24"> <input type="number" class="form-control" name="sla_low_response_time" placeholder="e.g., 24">
</div> </div>
</div> </div>
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>Low Priority Resolution (hrs)</label> <label>Low Priority Resolution (hrs)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
</div>
<input type="number" class="form-control" name="sla_low_resolution_time" placeholder="e.g., 48"> <input type="number" class="form-control" name="sla_low_resolution_time" placeholder="e.g., 48">
</div> </div>
</div> </div>
</div> </div>
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>Medium Priority Response (hrs)</label> <label>Medium Priority Response (hrs)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div>
<input type="number" class="form-control" name="sla_medium_response_time" placeholder="e.g., 12"> <input type="number" class="form-control" name="sla_medium_response_time" placeholder="e.g., 12">
</div> </div>
</div> </div>
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>Medium Priority Resolution (hrs)</label> <label>Medium Priority Resolution (hrs)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
</div>
<input type="number" class="form-control" name="sla_medium_resolution_time" placeholder="e.g., 24"> <input type="number" class="form-control" name="sla_medium_resolution_time" placeholder="e.g., 24">
</div> </div>
</div> </div>
</div> </div>
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>High Priority Response (hrs)</label> <label>High Priority Response (hrs)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-bolt"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-bolt"></i></span>
</div>
<input type="number" class="form-control" name="sla_high_response_time" placeholder="e.g., 1"> <input type="number" class="form-control" name="sla_high_response_time" placeholder="e.g., 1">
</div> </div>
</div> </div>
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>High Priority Resolution (hrs)</label> <label>High Priority Resolution (hrs)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span>
</div>
<input type="number" class="form-control" name="sla_high_resolution_time" placeholder="e.g., 4"> <input type="number" class="form-control" name="sla_high_resolution_time" placeholder="e.g., 4">
</div> </div>
</div> </div>
@@ -157,42 +137,34 @@ ob_start();
<!-- Rates & Support Tab --> <!-- Rates & Support Tab -->
<div class="tab-pane fade" id="rates" role="tabpanel"> <div class="tab-pane fade" id="rates" role="tabpanel">
<div class="form-group"> <div class="mb-3">
<label>Standard Hourly Rate</label> <label>Standard Hourly Rate</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
</div>
<input type="text" class="form-control" name="rate_standard" placeholder="e.g., 100"> <input type="text" class="form-control" name="rate_standard" placeholder="e.g., 100">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>After Hours Hourly Rate</label> <label>After Hours Hourly Rate</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-moon"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-moon"></i></span>
</div>
<input type="text" class="form-control" name="rate_after_hours" placeholder="e.g., 150"> <input type="text" class="form-control" name="rate_after_hours" placeholder="e.g., 150">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Support Hours</label> <label>Support Hours</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="text" class="form-control" name="support_hours" placeholder="e.g., Mon-Fri 9am-5pm" maxlength="100"> <input type="text" class="form-control" name="support_hours" placeholder="e.g., Mon-Fri 9am-5pm" maxlength="100">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Net Terms</label> <label>Net Terms</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-file-invoice-dollar"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-file-invoice-dollar"></i></span>
</div>
<input type="text" class="form-control" name="net_terms" placeholder="e.g., Net 30" maxlength="50"> <input type="text" class="form-control" name="net_terms" placeholder="e.g., Net 30" maxlength="50">
</div> </div>
</div> </div>
@@ -200,7 +172,7 @@ ob_start();
<!-- Details Tab --> <!-- Details Tab -->
<div class="tab-pane fade" id="details" role="tabpanel"> <div class="tab-pane fade" id="details" role="tabpanel">
<div class="form-group"> <div class="mb-3">
<textarea class="form-control tinymce" rows="6" name="details" placeholder="Enter Contract Details"></textarea> <textarea class="form-control tinymce" rows="6" name="details" placeholder="Enter Contract Details"></textarea>
</div> </div>
</div> </div>
@@ -210,10 +182,10 @@ ob_start();
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_contract_template" class="btn btn-primary text-bold"> <button type="submit" name="add_contract_template" class="btn btn-primary text-bold">
<i class="fa fa-check mr-2"></i>Create Template <i class="fa fa-check me-2"></i>Create Template
</button> </button>
<button type="button" class="btn btn-light" data-dismiss="modal"> <button type="button" class="btn btn-light" data-bs-dismiss="modal">
<i class="fa fa-times mr-2"></i>Cancel <i class="fa fa-times me-2"></i>Cancel
</button> </button>
</div> </div>
</form> </form>

View File

@@ -37,23 +37,23 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-file-contract mr-2"></i>Edit Contract Template</h5> <h5 class="modal-title"><i class="fa fa-fw fa-file-contract me-2"></i>Edit Contract Template</h5>
<button type="button" class="close text-white" data-dismiss="modal"><span>&times;</span></button> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div> </div>
<!-- Tabs Navigation --> <!-- Tabs Navigation -->
<ul class="modal-header nav nav-pills nav-justified"> <ul class="modal-header nav nav-pills nav-justified">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" id="general-tab" data-toggle="tab" href="#general" role="tab">General Info</a> <a class="nav-link active" id="general-tab" data-bs-toggle="tab" href="#general" role="tab">General Info</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="sla-tab" data-toggle="tab" href="#sla" role="tab">SLA</a> <a class="nav-link" id="sla-tab" data-bs-toggle="tab" href="#sla" role="tab">SLA</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="rates-tab" data-toggle="tab" href="#rates" role="tab">Rates & Support</a> <a class="nav-link" id="rates-tab" data-bs-toggle="tab" href="#rates" role="tab">Rates & Support</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="details-tab" data-toggle="tab" href="#details" role="tab">Details</a> <a class="nav-link" id="details-tab" data-bs-toggle="tab" href="#details" role="tab">Details</a>
</li> </li>
</ul> </ul>
@@ -66,37 +66,31 @@ ob_start();
<!-- General Info Tab --> <!-- General Info Tab -->
<div class="tab-pane fade show active" id="general" role="tabpanel"> <div class="tab-pane fade show active" id="general" role="tabpanel">
<div class="form-group"> <div class="mb-3">
<label>Template Name <strong class="text-danger">*</strong></label> <label>Template Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-file-contract"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-file-contract"></i></span>
</div>
<input type="text" class="form-control" name="name" <input type="text" class="form-control" name="name"
placeholder="Contract Template Name" maxlength="200" required autofocus placeholder="Contract Template Name" maxlength="200" required autofocus
value="<?= $name ?>"> value="<?= $name ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Template Description <strong class="text-danger">*</strong></label> <label>Template Description <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-align-left"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-align-left"></i></span>
</div>
<input type="text" class="form-control" name="description" <input type="text" class="form-control" name="description"
placeholder="Contract Template Description" maxlength="200" required placeholder="Contract Template Description" maxlength="200" required
value="<?= $description ?>"> value="<?= $description ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Contract Type <strong class="text-danger">*</strong></label> <label>Contract Type <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-list"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-list"></i></span>
</div> <select class="form-select select2" name="type" required>
<select class="form-control select2" name="type" required>
<option value="">- Select Type -</option> <option value="">- Select Type -</option>
<?php foreach ($contract_types_array as $type_select) { ?> <?php foreach ($contract_types_array as $type_select) { ?>
<option <?php if ($type == $type_select) { echo "selected"; } ?>><?= $type_select ?></option> <option <?php if ($type == $type_select) { echo "selected"; } ?>><?= $type_select ?></option>
@@ -105,13 +99,11 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Renewal Frequency</label> <label>Renewal Frequency</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-sync-alt"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-sync-alt"></i></span>
</div> <select class="form-select select2" name="renewal_frequency">
<select class="form-control select2" name="renewal_frequency">
<option value="">- Select Frequency -</option> <option value="">- Select Frequency -</option>
<?php foreach ($renewal_frequency_array as $renewal_frequency_select) { ?> <?php foreach ($renewal_frequency_array as $renewal_frequency_select) { ?>
<option <?php if ($renewal_frequency == $renewal_frequency_select) { echo "selected"; } ?>><?= $renewal_frequency_select ?></option> <option <?php if ($renewal_frequency == $renewal_frequency_select) { echo "selected"; } ?>><?= $renewal_frequency_select ?></option>
@@ -123,69 +115,57 @@ ob_start();
<!-- SLA Tab --> <!-- SLA Tab -->
<div class="tab-pane fade" id="sla" role="tabpanel"> <div class="tab-pane fade" id="sla" role="tabpanel">
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>Low Priority Response (hrs)</label> <label>Low Priority Response (hrs)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div>
<input type="number" class="form-control" name="sla_low_response_time" placeholder="e.g., 24" <input type="number" class="form-control" name="sla_low_response_time" placeholder="e.g., 24"
value="<?= $sla_low_resp ?>"> value="<?= $sla_low_resp ?>">
</div> </div>
</div> </div>
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>Low Priority Resolution (hrs)</label> <label>Low Priority Resolution (hrs)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
</div>
<input type="number" class="form-control" name="sla_low_resolution_time" placeholder="e.g., 48" <input type="number" class="form-control" name="sla_low_resolution_time" placeholder="e.g., 48"
value="<?= $sla_low_res ?>"> value="<?= $sla_low_res ?>">
</div> </div>
</div> </div>
</div> </div>
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>Medium Priority Response (hrs)</label> <label>Medium Priority Response (hrs)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div>
<input type="number" class="form-control" name="sla_medium_response_time" placeholder="e.g., 12" <input type="number" class="form-control" name="sla_medium_response_time" placeholder="e.g., 12"
value="<?= $sla_med_resp ?>"> value="<?= $sla_med_resp ?>">
</div> </div>
</div> </div>
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>Medium Priority Resolution (hrs)</label> <label>Medium Priority Resolution (hrs)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
</div>
<input type="number" class="form-control" name="sla_medium_resolution_time" placeholder="e.g., 24" <input type="number" class="form-control" name="sla_medium_resolution_time" placeholder="e.g., 24"
value="<?= $sla_med_res ?>"> value="<?= $sla_med_res ?>">
</div> </div>
</div> </div>
</div> </div>
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>High Priority Response (hrs)</label> <label>High Priority Response (hrs)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-bolt"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-bolt"></i></span>
</div>
<input type="number" class="form-control" name="sla_high_response_time" placeholder="e.g., 1" <input type="number" class="form-control" name="sla_high_response_time" placeholder="e.g., 1"
value="<?= $sla_high_resp ?>"> value="<?= $sla_high_resp ?>">
</div> </div>
</div> </div>
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>High Priority Resolution (hrs)</label> <label>High Priority Resolution (hrs)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span>
</div>
<input type="number" class="form-control" name="sla_high_resolution_time" placeholder="e.g., 4" <input type="number" class="form-control" name="sla_high_resolution_time" placeholder="e.g., 4"
value="<?= $sla_high_res ?>"> value="<?= $sla_high_res ?>">
</div> </div>
@@ -195,45 +175,37 @@ ob_start();
<!-- Rates & Support Tab --> <!-- Rates & Support Tab -->
<div class="tab-pane fade" id="rates" role="tabpanel"> <div class="tab-pane fade" id="rates" role="tabpanel">
<div class="form-group"> <div class="mb-3">
<label>Standard Hourly Rate</label> <label>Standard Hourly Rate</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
</div>
<input type="text" class="form-control" name="rate_standard" placeholder="e.g., 100" <input type="text" class="form-control" name="rate_standard" placeholder="e.g., 100"
value="<?= $rate_standard ?>"> value="<?= $rate_standard ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>After Hours Hourly Rate</label> <label>After Hours Hourly Rate</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-moon"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-moon"></i></span>
</div>
<input type="text" class="form-control" name="rate_after_hours" placeholder="e.g., 150" <input type="text" class="form-control" name="rate_after_hours" placeholder="e.g., 150"
value="<?= $rate_after_hours ?>"> value="<?= $rate_after_hours ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Support Hours</label> <label>Support Hours</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="text" class="form-control" name="support_hours" placeholder="e.g., Mon-Fri 9am-5pm" maxlength="100" <input type="text" class="form-control" name="support_hours" placeholder="e.g., Mon-Fri 9am-5pm" maxlength="100"
value="<?= $support_hours ?>"> value="<?= $support_hours ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Net Terms</label> <label>Net Terms</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-file-invoice-dollar"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-file-invoice-dollar"></i></span>
</div>
<input type="text" class="form-control" name="net_terms" placeholder="e.g., Net 30" maxlength="50" <input type="text" class="form-control" name="net_terms" placeholder="e.g., Net 30" maxlength="50"
value="<?= $net_terms ?>"> value="<?= $net_terms ?>">
</div> </div>
@@ -242,12 +214,10 @@ ob_start();
<!-- Details Tab --> <!-- Details Tab -->
<div class="tab-pane fade" id="details" role="tabpanel"> <div class="tab-pane fade" id="details" role="tabpanel">
<div class="form-group"> <div class="mb-3">
<label>Contract Details</label> <label>Contract Details</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-align-left"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-align-left"></i></span>
</div>
<textarea class="form-control tinymce" rows="6" name="details" <textarea class="form-control tinymce" rows="6" name="details"
placeholder="Enter Contract Details"><?= $details ?></textarea> placeholder="Enter Contract Details"><?= $details ?></textarea>
</div> </div>
@@ -259,10 +229,10 @@ ob_start();
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_contract_template" class="btn btn-primary text-bold"> <button type="submit" name="edit_contract_template" class="btn btn-primary text-bold">
<i class="fa fa-check mr-2"></i>Save Changes <i class="fa fa-check me-2"></i>Save Changes
</button> </button>
<button type="button" class="btn btn-light" data-dismiss="modal"> <button type="button" class="btn btn-light" data-bs-dismiss="modal">
<i class="fa fa-times mr-2"></i>Cancel <i class="fa fa-times me-2"></i>Cancel
</button> </button>
</div> </div>
</form> </form>

View File

@@ -27,31 +27,27 @@ if (empty($cron_job_daily_at)) {
ob_start(); ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-clock mr-2"></i>Editing: <strong><?= $cron_job_label ?></strong></h5> <h5 class="modal-title"><i class="fa fa-fw fa-clock me-2"></i>Editing: <strong><?= $cron_job_label ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="cron_job_id" value="<?= $cron_job_id ?>"> <input type="hidden" name="cron_job_id" value="<?= $cron_job_id ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="enabled" value="1" id="cronJobEnabledSwitch" <?= $cron_job_enabled == 1 ? 'checked' : '' ?>> <input type="checkbox" class="form-check-input" name="enabled" value="1" id="cronJobEnabledSwitch" <?= $cron_job_enabled == 1 ? 'checked' : '' ?>>
<label class="custom-control-label" for="cronJobEnabledSwitch">Enabled</label> <label class="form-check-label" for="cronJobEnabledSwitch">Enabled</label>
</div> </div>
<small class="text-muted">A disabled job never runs on its schedule, but Run Now still works.</small> <small class="text-muted">A disabled job never runs on its schedule, but Run Now still works.</small>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Schedule</label> <label>Schedule</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div> <select class="form-select" name="schedule" id="cronJobSchedule">
<select class="form-control" name="schedule" id="cronJobSchedule">
<?php if ($cron_job_interval_safe) { ?> <?php if ($cron_job_interval_safe) { ?>
<option value="Interval" <?= $cron_job_schedule === 'Interval' ? 'selected' : '' ?>>Every so many minutes</option> <option value="Interval" <?= $cron_job_schedule === 'Interval' ? 'selected' : '' ?>>Every so many minutes</option>
<?php } ?> <?php } ?>
@@ -63,26 +59,20 @@ ob_start();
<?php } ?> <?php } ?>
</div> </div>
<div class="form-group" id="cronJobIntervalGroup"> <div class="mb-3" id="cronJobIntervalGroup">
<label>Run every</label> <label>Run every</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-redo"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-redo"></i></span>
</div>
<input type="number" class="form-control" name="interval_minutes" value="<?= $cron_job_interval_minutes ?>" min="1" max="1440"> <input type="number" class="form-control" name="interval_minutes" value="<?= $cron_job_interval_minutes ?>" min="1" max="1440">
<div class="input-group-append">
<span class="input-group-text">minutes</span> <span class="input-group-text">minutes</span>
</div> </div>
</div>
<small class="text-muted">Cron wakes once a minute, so 1 is as often as anything can run.</small> <small class="text-muted">Cron wakes once a minute, so 1 is as often as anything can run.</small>
</div> </div>
<div class="form-group" id="cronJobDailyGroup"> <div class="mb-3" id="cronJobDailyGroup">
<label>Run at</label> <label>Run at</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div>
<input type="time" class="form-control" name="daily_at" value="<?= $cron_job_daily_at ?>"> <input type="time" class="form-control" name="daily_at" value="<?= $cron_job_daily_at ?>">
</div> </div>
<small class="text-muted">Your ITFlow timezone. A run missed because the server was off happens at the next opportunity instead of waiting a day.</small> <small class="text-muted">Your ITFlow timezone. A run missed because the server was off happens at the next opportunity instead of waiting a day.</small>
@@ -90,8 +80,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_cron_job" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_cron_job" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -2,10 +2,8 @@
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-th-list mr-2"></i>Create <?= escapeHtml($table) ?> field</h5> <h5 class="modal-title"><i class="fa fa-fw fa-th-list me-2"></i>Create <?= escapeHtml($table) ?> field</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -13,18 +11,16 @@
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Label <strong class="text-danger">*</strong></label> <label>Label <strong class="text-danger">*</strong></label>
<input type="text" class="form-control" name="label" placeholder="Enter a custom field label" maxlength="255" required autofocus> <input type="text" class="form-control" name="label" placeholder="Enter a custom field label" maxlength="255" required autofocus>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Type <strong class="text-danger">*</strong></label> <label>Type <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-th"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-th"></i></span>
</div> <select class="form-select select2" name="type" required>
<select class="form-control select2" name="type" required>
<option value="">- Select a field type -</option> <option value="">- Select a field type -</option>
<option>Text</option> <option>Text</option>
</select> </select>
@@ -33,8 +29,8 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="create_custom_field" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button> <button type="submit" name="create_custom_field" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>
</div> </div>

View File

@@ -2,28 +2,24 @@
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-th-list mr-2"></i>Editing custom field: <strong><?= $custom_field_label ?></strong></h5> <h5 class="modal-title"><i class="fa fa-fw fa-th-list me-2"></i>Editing custom field: <strong><?= $custom_field_label ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="custom_field_id" value="<?= $custom_field_id ?>"> <input type="hidden" name="custom_field_id" value="<?= $custom_field_id ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Label <strong class="text-danger">*</strong></label> <label>Label <strong class="text-danger">*</strong></label>
<input type="text" class="form-control" name="label" maxlength="255" value="<?= $custom_field_label ?>" required> <input type="text" class="form-control" name="label" maxlength="255" value="<?= $custom_field_label ?>" required>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Type <strong class="text-danger">*</strong></label> <label>Type <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-th"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-th"></i></span>
</div> <select class="form-select select2" name="type" required>
<select class="form-control select2" name="type" required>
<option value="">- Select a field type -</option> <option value="">- Select a field type -</option>
<option <?php if ($custom_field_type == 'text') { echo "selected"; } ?> value="text">Text</option> <option <?php if ($custom_field_type == 'text') { echo "selected"; } ?> value="text">Text</option>
</select> </select>
@@ -32,8 +28,8 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_custom_field" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_custom_field" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>
</div> </div>

View File

@@ -7,68 +7,54 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-external-link-alt mr-2"></i>New Custom Link</h5> <h5 class="modal-title"><i class="fas fa-fw fa-external-link-alt me-2"></i>New Custom Link</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-list-ul"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-list-ul"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Link name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" placeholder="Link name" maxlength="200" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Order</label> <label>Order</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-sort-numeric-down"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-sort-numeric-down"></i></span>
</div>
<input type="number" class="form-control" name="order" placeholder="Leave blank for no order"> <input type="number" class="form-control" name="order" placeholder="Leave blank for no order">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>URI <strong class="text-danger">*</strong></label> / <span class="text-secondary">Open New Tab</span> <label>URI <strong class="text-danger">*</strong></label> / <span class="text-secondary">Open New Tab</span>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-external-link-alt"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-external-link-alt"></i></span>
</div>
<input type="text" class="form-control" name="uri" placeholder="Enter Link" maxlength="500" required> <input type="text" class="form-control" name="uri" placeholder="Enter Link" maxlength="500" required>
<div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="new_tab" value="1"> <input class="form-check-input" type="checkbox" name="new_tab" value="1">
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Icon</label> <label>Icon</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-image"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-image"></i></span>
</div>
<input type="text" class="form-control" name="icon" placeholder="Icon ex handshake" maxlength="200"> <input type="text" class="form-control" name="icon" placeholder="Icon ex handshake" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Location <strong class="text-danger">*</strong></label> <label>Location <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-home"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-home"></i></span>
</div> <select class="form-select select2" name="location" required>
<select class="form-control select2" name="location" required>
<option value="1">Main Side Nav</option> <option value="1">Main Side Nav</option>
<option value="2">Top Nav (Icon Required)</option> <option value="2">Top Nav (Icon Required)</option>
<option value="3">Client Portal Nav</option> <option value="3">Client Portal Nav</option>
@@ -80,8 +66,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_custom_link" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button> <button type="submit" name="add_custom_link" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -19,10 +19,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-external-link-alt mr-2"></i>Editing link: <strong><?= $custom_link_name ?></strong></h5> <h5 class="modal-title"><i class="fas fa-fw fa-external-link-alt me-2"></i>Editing link: <strong><?= $custom_link_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -30,58 +28,46 @@ ob_start();
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-list-ul"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-list-ul"></i></span>
</div>
<input type="text" class="form-control" name="name" value="<?= $custom_link_name ?>" maxlength="200" required> <input type="text" class="form-control" name="name" value="<?= $custom_link_name ?>" maxlength="200" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Order</label> <label>Order</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-sort-numeric-down"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-sort-numeric-down"></i></span>
</div>
<input type="number" class="form-control" name="order" placeholder="Leave blank for no order" value="<?= $custom_link_order ?>"> <input type="number" class="form-control" name="order" placeholder="Leave blank for no order" value="<?= $custom_link_order ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>URI <strong class="text-danger">*</strong></label> / <span class="text-secondary">Open New Tab</span> <label>URI <strong class="text-danger">*</strong></label> / <span class="text-secondary">Open New Tab</span>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-external-link-alt"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-external-link-alt"></i></span>
</div>
<input type="text" class="form-control" name="uri" placeholder="Enter Link" maxlength="500" value="<?= $custom_link_uri ?>" required> <input type="text" class="form-control" name="uri" placeholder="Enter Link" maxlength="500" value="<?= $custom_link_uri ?>" required>
<div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="new_tab" value="1" <?php if ($custom_link_new_tab == 1) { echo "checked"; } ?>> <input class="form-check-input" type="checkbox" name="new_tab" value="1" <?php if ($custom_link_new_tab == 1) { echo "checked"; } ?>>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Icon</label> <label>Icon</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-image"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-image"></i></span>
</div>
<input type="text" class="form-control" name="icon" placeholder="Icon ex handshake" maxlength="200" value="<?= $custom_link_icon ?>"> <input type="text" class="form-control" name="icon" placeholder="Icon ex handshake" maxlength="200" value="<?= $custom_link_icon ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Location <strong class="text-danger">*</strong></label> <label>Location <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-home"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-home"></i></span>
</div> <select class="form-select select2" name="location" required>
<select class="form-control select2" name="location" required>
<option value="1" <?php if ($custom_link_location === 1) { echo "selected"; } ?> >Main Side Nav</option> <option value="1" <?php if ($custom_link_location === 1) { echo "selected"; } ?> >Main Side Nav</option>
<option value="2" <?php if ($custom_link_location === 2) { echo "selected"; } ?> >Top Nav (Icon Required)</option> <option value="2" <?php if ($custom_link_location === 2) { echo "selected"; } ?> >Top Nav (Icon Required)</option>
<option value="3" <?php if ($custom_link_location === 3) { echo "selected"; } ?> >Client Portal Nav</option> <option value="3" <?php if ($custom_link_location === 3) { echo "selected"; } ?> >Client Portal Nav</option>
@@ -93,8 +79,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_custom_link" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_custom_link" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -7,38 +7,34 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-file-alt mr-2"></i>Creating Document Template</h5> <h5 class="modal-title"><i class="fa fa-fw fa-file-alt me-2"></i>Creating Document Template</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<input type="text" class="form-control" name="name" placeholder="Template name" maxlength="200"> <input type="text" class="form-control" name="name" placeholder="Template name" maxlength="200">
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Enter a prompt for the type of IT documentation you want to generate:</label> <label>Enter a prompt for the type of IT documentation you want to generate:</label>
<div class="input-group mb-3"> <div class="input-group mb-3">
<input type="text" class="form-control" id="aiPrompt" placeholder="e.g. 'A network troubleshooting guide for junior technicians'"> <input type="text" class="form-control" id="aiPrompt" placeholder="e.g. 'A network troubleshooting guide for junior technicians'">
<div class="input-group-append">
<button class="btn btn-info" type="button" id="generateAIContent"> <button class="btn btn-info" type="button" id="generateAIContent">
<i class="fa fa-fw fa-magic mr-1"></i>Generate with AI <i class="fa fa-fw fa-magic me-1"></i>Generate with AI
</button> </button>
</div> </div>
</div> </div>
</div>
<!-- TinyMCE Content --> <!-- TinyMCE Content -->
<div class="form-group"> <div class="mb-3">
<textarea class="form-control tinymce" name="content"></textarea> <textarea class="form-control tinymce" name="content"></textarea>
</div> </div>
<div class="form-group"> <div class="mb-3">
<input type="text" class="form-control" name="description" placeholder="Enter a short summary"> <input type="text" class="form-control" name="description" placeholder="Enter a short summary">
</div> </div>
@@ -46,40 +42,54 @@ ob_start();
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_document_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save template</button> <button type="submit" name="add_document_template" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save template</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>
<script> <script>
$(document).ready(function(){ document.addEventListener('DOMContentLoaded', function () {
$('#generateAIContent').on('click', function(){ var button = document.getElementById('generateAIContent');
var prompt = $('#aiPrompt').val().trim(); var promptField = document.getElementById('aiPrompt');
if (!button || !promptField) {
return;
}
button.addEventListener('click', function () {
var prompt = promptField.value.trim();
if (prompt === '') { if (prompt === '') {
alert('Please enter a prompt.'); alert('Please enter a prompt.');
return; return;
} }
$('#generateAIContent').prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> Generating...'); button.disabled = true;
button.innerHTML = '<i class="fa fa-spinner fa-spin"></i> Generating...';
$.ajax({ fetch('/agent/ajax.php?ai_create_document_template', {
url: '/agent/ajax.php?ai_create_document_template', // The PHP script that calls the OpenAI API
method: 'POST', method: 'POST',
data: { prompt: prompt }, headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
dataType: 'html', credentials: 'same-origin',
success: function(response) { body: new URLSearchParams({ prompt: prompt }).toString()
})
.then(function (res) {
if (!res.ok) {
throw new Error('HTTP ' + res.status);
}
return res.text();
})
.then(function (response) {
// Assuming you have exactly one TinyMCE instance on the page // Assuming you have exactly one TinyMCE instance on the page
// and it's targeting the .tinymce textarea: // and it's targeting the .tinymce textarea:
tinymce.activeEditor.setContent(response); tinymce.activeEditor.setContent(response);
}, })
error: function() { .catch(function () {
alert('Error generating content. Please try again.'); alert('Error generating content. Please try again.');
}, })
complete: function() { .finally(function () {
$('#generateAIContent').prop('disabled', false).html('<i class="fa fa-fw fa-magic mr-1"></i>Generate with AI'); button.disabled = false;
} button.innerHTML = '<i class="fa fa-fw fa-magic me-1"></i>Generate with AI';
}); });
}); });
}); });

View File

@@ -14,10 +14,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-file-alt mr-2"></i>Editing template: <strong><?= $document_template_name ?></strong></h5> <h5 class="modal-title"><i class="fa fa-fw fa-file-alt me-2"></i>Editing template: <strong><?= $document_template_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -25,22 +23,22 @@ ob_start();
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<input type="text" class="form-control" name="name" maxlength="200" value="<?= $document_template_name ?>" placeholder="Name" required> <input type="text" class="form-control" name="name" maxlength="200" value="<?= $document_template_name ?>" placeholder="Name" required>
</div> </div>
<div class="form-group"> <div class="mb-3">
<textarea class="form-control tinymce" name="content"><?= $document_template_content ?></textarea> <textarea class="form-control tinymce" name="content"><?= $document_template_content ?></textarea>
</div> </div>
<div class="form-group"> <div class="mb-3">
<input type="text" class="form-control" name="description" value="<?= $document_template_description ?>" placeholder="Short summary"> <input type="text" class="form-control" name="description" value="<?= $document_template_description ?>" placeholder="Short summary">
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_document_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save template</button> <button type="submit" name="edit_document_template" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save template</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -42,10 +42,8 @@ if ($email_status == 0) {
ob_start(); ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class='fas fa-fw fa-envelope-open mr-2'></i><strong><?= $email_subject ?></strong></h5> <h5 class="modal-title"><i class='fas fa-fw fa-envelope-open me-2'></i><strong><?= $email_subject ?></strong></h5>
<button type="button" class="close text-light" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="row"> <div class="row">

View File

@@ -7,34 +7,30 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i>Creating: <strong>Payment Method</strong></h5> <h5 class="modal-title"><i class="fa fa-fw fa-credit-card me-2"></i>Creating: <strong>Payment Method</strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Payment method name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" placeholder="Payment method name" maxlength="200" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<textarea class="form-control" rows="3" name="description" placeholder="Enter a description..." maxlength="250"></textarea> <textarea class="form-control" rows="3" name="description" placeholder="Enter a description..." maxlength="250"></textarea>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_payment_method" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button> <button type="submit" name="add_payment_method" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -15,34 +15,30 @@ $payment_method_description = escapeHtml($row['payment_method_description']);
ob_start(); ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i>Editing: <strong><?= $payment_method_name ?></strong></h5> <h5 class="modal-title"><i class="fa fa-fw fa-credit-card me-2"></i>Editing: <strong><?= $payment_method_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="payment_method_id" value="<?= $payment_method_id ?>"> <input type="hidden" name="payment_method_id" value="<?= $payment_method_id ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span>
</div>
<input type="text" class="form-control" name="name" value="<?= $payment_method_name ?>" placeholder="Payment method name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" value="<?= $payment_method_name ?>" placeholder="Payment method name" maxlength="200" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<textarea class="form-control" rows="3" name="description" placeholder="Enter a description..." maxlength="250"><?= $payment_method_description ?></textarea> <textarea class="form-control" rows="3" name="description" placeholder="Enter a description..." maxlength="250"><?= $payment_method_description ?></textarea>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_payment_method" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_payment_method" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -6,10 +6,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i>Add Payment Provider</h5> <h5 class="modal-title"><i class="fa fa-fw fa-credit-card me-2"></i>Add Payment Provider</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -18,10 +16,10 @@ ob_start();
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-details">Details</a> <a class="nav-link active" data-bs-toggle="pill" href="#pills-details">Details</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-expense">Expense</a> <a class="nav-link" data-bs-toggle="pill" href="#pills-expense">Expense</a>
</li> </li>
</ul> </ul>
@@ -31,45 +29,37 @@ ob_start();
<div class="tab-pane fade show active" id="pills-details"> <div class="tab-pane fade show active" id="pills-details">
<div class="form-group"> <div class="mb-3">
<label>Provider <strong class="text-danger">*</strong></label> <label>Provider <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span>
</div> <select class="form-select select2" name="provider">
<select class="form-control select2" name="provider">
<option>Stripe</option> <option>Stripe</option>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Publishable key <strong class="text-danger">*</strong></label> <label>Publishable key <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
</div>
<input type="text" class="form-control" name="public_key" placeholder="Publishable API Key (pk_...)" maxlength="250"> <input type="text" class="form-control" name="public_key" placeholder="Publishable API Key (pk_...)" maxlength="250">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Secret key <strong class="text-danger">*</strong></label> <label>Secret key <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div>
<input type="text" class="form-control" name="private_key" placeholder="Secret API Key (sk_...)" maxlength="250"> <input type="text" class="form-control" name="private_key" placeholder="Secret API Key (sk_...)" maxlength="250">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Income / Expense Account <strong class="text-danger">*</strong></label> <label>Income / Expense Account <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-piggy-bank"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-piggy-bank"></i></span>
</div> <select class="form-select select2" name="account" required>
<select class="form-control select2" name="account" required>
<option value="">- Select an Account -</option> <option value="">- Select an Account -</option>
<?php <?php
@@ -88,12 +78,10 @@ ob_start();
<small class="form-text text-muted">Should have a seperate account created off the payment provider's name e.g. Stripe</small> <small class="form-text text-muted">Should have a seperate account created off the payment provider's name e.g. Stripe</small>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Threshold</label> <label>Threshold</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
</div>
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="threshold" placeholder="1000.00"> <input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="threshold" placeholder="1000.00">
</div> </div>
<small class="form-text text-muted">Will not show as an option at Checkout if invoice amount is above this number, 0 disables the threshold check.</small> <small class="form-text text-muted">Will not show as an option at Checkout if invoice amount is above this number, 0 disables the threshold check.</small>
@@ -107,20 +95,18 @@ ob_start();
Payment Processing Fee Expenses get reconciled nighly via the cron Payment Processing Fee Expenses get reconciled nighly via the cron
</div> </div>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="enable_expense" checked value="1" id="enableExpenseSwitch"> <input type="checkbox" class="form-check-input" name="enable_expense" checked value="1" id="enableExpenseSwitch">
<label class="custom-control-label" for="enableExpenseSwitch">Enable Expense</label> <label class="form-check-label" for="enableExpenseSwitch">Enable Expense</label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Payment Provider Vendor <strong class="text-danger">*</strong></label> <label>Payment Provider Vendor <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-building"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
</div> <select class="form-select select2" name="expense_vendor" required>
<select class="form-control select2" name="expense_vendor" required>
<option value="0">Expense Disabled</option> <option value="0">Expense Disabled</option>
<?php <?php
@@ -139,13 +125,11 @@ ob_start();
<small class="form-text text-muted">Payment Privider name e.g. Stripe</small> <small class="form-text text-muted">Payment Privider name e.g. Stripe</small>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Expense Category <strong class="text-danger">*</strong></label> <label>Expense Category <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-list"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-list"></i></span>
</div> <select class="form-select select2" name="expense_category" required>
<select class="form-control select2" name="expense_category" required>
<option value="">- Select a Category -</option> <option value="">- Select a Category -</option>
<?php <?php
@@ -160,13 +144,11 @@ ob_start();
} }
?> ?>
</select> </select>
<div class="input-group-append">
<button class="btn btn-secondary ajax-modal" type="button" <button class="btn btn-secondary ajax-modal" type="button"
data-modal-url="../admin/modals/category/category_add.php?category=Expense"> data-modal-url="../admin/modals/category/category_add.php?category=Expense">
<i class="fas fa-plus"></i> <i class="fas fa-plus"></i>
</button> </button>
</div> </div>
</div>
<small class="form-text text-muted">Processing Fee, Credit Card Fee etc</small> <small class="form-text text-muted">Processing Fee, Credit Card Fee etc</small>
</div> </div>
@@ -174,8 +156,8 @@ ob_start();
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_payment_provider" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Add</button> <button type="submit" name="add_payment_provider" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Add</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -22,10 +22,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i>Editing: <strong><?= $provider_name ?></strong></h5> <h5 class="modal-title"><i class="fa fa-fw fa-credit-card me-2"></i>Editing: <strong><?= $provider_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -35,10 +33,10 @@ ob_start();
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-details">Details</a> <a class="nav-link active" data-bs-toggle="pill" href="#pills-details">Details</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-expense">Expense</a> <a class="nav-link" data-bs-toggle="pill" href="#pills-expense">Expense</a>
</li> </li>
</ul> </ul>
@@ -48,33 +46,27 @@ ob_start();
<div class="tab-pane fade show active" id="pills-details"> <div class="tab-pane fade show active" id="pills-details">
<div class="form-group"> <div class="mb-3">
<label>Publishable key <strong class="text-danger">*</strong></label> <label>Publishable key <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
</div>
<input type="text" class="form-control" name="public_key" placeholder="Publishable API Key (pk_...)" maxlength="250" value="<?= $public_key ?>"> <input type="text" class="form-control" name="public_key" placeholder="Publishable API Key (pk_...)" maxlength="250" value="<?= $public_key ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Secret key <strong class="text-danger">*</strong></label> <label>Secret key <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div>
<input type="text" class="form-control" name="private_key" placeholder="Secret API Key (sk_...)" maxlength="250" value="<?= $private_key ?>"> <input type="text" class="form-control" name="private_key" placeholder="Secret API Key (sk_...)" maxlength="250" value="<?= $private_key ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Income / Expense Account <strong class="text-danger">*</strong></label> <label>Income / Expense Account <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-piggy-bank"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-piggy-bank"></i></span>
</div> <select class="form-select select2" name="account" required>
<select class="form-control select2" name="account" required>
<option value="">- Select an Account -</option> <option value="">- Select an Account -</option>
<?php <?php
@@ -93,12 +85,10 @@ ob_start();
<small class="form-text text-muted">Should have a seperate account created off the payment provider's name e.g. Stripe</small> <small class="form-text text-muted">Should have a seperate account created off the payment provider's name e.g. Stripe</small>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Threshold</label> <label>Threshold</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
</div>
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="threshold" placeholder="1000.00" value="<?= $threshold ?>"> <input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="threshold" placeholder="1000.00" value="<?= $threshold ?>">
</div> </div>
<small class="form-text text-muted">Will not show as an option at Checkout if above this number</small> <small class="form-text text-muted">Will not show as an option at Checkout if above this number</small>
@@ -112,13 +102,11 @@ ob_start();
Payment Processing Fee Expenses get reconciled nighly via the cron Payment Processing Fee Expenses get reconciled nighly via the cron
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Payment Provider Vendor <strong class="text-danger">*</strong></label> <label>Payment Provider Vendor <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-building"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
</div> <select class="form-select select2" name="expense_vendor" required>
<select class="form-control select2" name="expense_vendor" required>
<option value="0">Expense Disabled</option> <option value="0">Expense Disabled</option>
<?php <?php
@@ -139,13 +127,11 @@ ob_start();
<small class="form-text text-muted">Payment Privider name e.g. Stripe</small> <small class="form-text text-muted">Payment Privider name e.g. Stripe</small>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Expense Category <strong class="text-danger">*</strong></label> <label>Expense Category <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-list"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-list"></i></span>
</div> <select class="form-select select2" name="expense_category" required>
<select class="form-control select2" name="expense_category" required>
<option value="">- Select a Category -</option> <option value="">- Select a Category -</option>
<?php <?php
@@ -160,21 +146,19 @@ ob_start();
} }
?> ?>
</select> </select>
<div class="input-group-append">
<button class="btn btn-secondary ajax-modal" type="button" <button class="btn btn-secondary ajax-modal" type="button"
data-modal-url="../admin/modals/category/category_add.php?category=Expense"> data-modal-url="../admin/modals/category/category_add.php?category=Expense">
<i class="fas fa-plus"></i> <i class="fas fa-plus"></i>
</button> </button>
</div> </div>
</div>
<small class="form-text text-muted">Processing Fee, Credit Card Fee etc</small> <small class="form-text text-muted">Processing Fee, Credit Card Fee etc</small>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_payment_provider" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_payment_provider" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -6,39 +6,33 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-project-diagram mr-2"></i>Creating Project Template</h5> <h5 class="modal-title"><i class="fas fa-fw fa-project-diagram me-2"></i>Creating Project Template</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Project Template Name <strong class="text-danger">*</strong></label> <label>Project Template Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-project-diagram"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-project-diagram"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Project Template Name" maxlength="255" required autofocus> <input type="text" class="form-control" name="name" placeholder="Project Template Name" maxlength="255" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description</label> <label>Description</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Description"> <input type="text" class="form-control" name="description" placeholder="Description">
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_project_template" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button> <button type="submit" name="add_project_template" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -14,32 +14,26 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-project-diagram mr-2"></i>Editing Project Template: <strong><?= $project_template_name ?></strong></h5> <h5 class="modal-title"><i class="fas fa-fw fa-project-diagram me-2"></i>Editing Project Template: <strong><?= $project_template_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="project_template_id" value="<?= $project_template_id ?>"> <input type="hidden" name="project_template_id" value="<?= $project_template_id ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Project Template Name <strong class="text-danger">*</strong></label> <label>Project Template Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-project-diagram"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-project-diagram"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Project Template Name" maxlength="255" value="<?= $project_template_name ?>" required autofocus> <input type="text" class="form-control" name="name" placeholder="Project Template Name" maxlength="255" value="<?= $project_template_name ?>" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description</label> <label>Description</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Description" value="<?= $project_template_description ?>"> <input type="text" class="form-control" name="description" placeholder="Description" value="<?= $project_template_description ?>">
</div> </div>
</div> </div>
@@ -47,8 +41,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_project_template" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_project_template" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -9,10 +9,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-life-ring mr-2"></i>Adding Ticket Template</h5> <h5 class="modal-title"><i class="fas fa-fw fa-life-ring me-2"></i>Adding Ticket Template</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -20,13 +18,11 @@ ob_start();
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Ticket Template <strong class="text-danger">*</strong></label> <label>Ticket Template <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-life-ring"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-life-ring"></i></span>
</div> <select class="form-select select2" name="ticket_template_id" required>
<select class="form-control select2" name="ticket_template_id" required>
<option value="">- Select a Ticket Template -</option> <option value="">- Select a Ticket Template -</option>
<?php <?php
@@ -51,12 +47,10 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Order</label> <label>Order</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-sort-numeric-down"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-sort-numeric-down"></i></span>
</div>
<input type="text" class="form-control" name="order" value="1"> <input type="text" class="form-control" name="order" value="1">
</div> </div>
</div> </div>
@@ -64,8 +58,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_ticket_template_to_project_template" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Add</button> <button type="submit" name="add_ticket_template_to_project_template" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Add</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -6,10 +6,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>New Role</h5> <h5 class="modal-title"><i class="fas fa-fw fa-user-shield me-2"></i>New Role</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> <form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
@@ -19,10 +17,10 @@ ob_start();
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-role-details">Details</a> <a class="nav-link active" data-bs-toggle="pill" href="#pills-role-details">Details</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-role-permissions">Permissions</a> <a class="nav-link" data-bs-toggle="pill" href="#pills-role-permissions">Permissions</a>
</li> </li>
</ul> </ul>
@@ -33,39 +31,35 @@ ob_start();
<!-- DETAILS TAB --> <!-- DETAILS TAB -->
<div class="tab-pane fade show active" id="pills-role-details"> <div class="tab-pane fade show active" id="pills-role-details">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
</div>
<input type="text" class="form-control" name="role_name" placeholder="Role Name" maxlength="200" required> <input type="text" class="form-control" name="role_name" placeholder="Role Name" maxlength="200" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description <strong class="text-danger">*</strong></label> <label>Description <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-chevron-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-chevron-right"></i></span>
</div>
<input type="text" class="form-control" name="role_description" placeholder="Role Description" maxlength="200" required> <input type="text" class="form-control" name="role_description" placeholder="Role Description" maxlength="200" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Admin Access <strong class="text-danger">*</strong></label> <label>Admin Access <strong class="text-danger">*</strong></label>
<div class="custom-control custom-radio mb-2"> <div class="form-check mb-2">
<input type="radio" class="custom-control-input" id="admin_no" name="role_is_admin" value="0" checked required> <input type="radio" class="form-check-input" id="admin_no" name="role_is_admin" value="0" checked required>
<label class="custom-control-label" for="admin_no"> <label class="form-check-label" for="admin_no">
No - use permissions on the next tab No - use permissions on the next tab
</label> </label>
</div> </div>
<div class="custom-control custom-radio"> <div class="form-check">
<input type="radio" class="custom-control-input" id="admin_yes" name="role_is_admin" value="1" required> <input type="radio" class="form-check-input" id="admin_yes" name="role_is_admin" value="1" required>
<label class="custom-control-label" for="admin_yes"> <label class="form-check-label" for="admin_yes">
Yes - this role should have full admin access Yes - this role should have full admin access
</label> </label>
</div> </div>
@@ -98,14 +92,13 @@ ob_start();
$group_id = "perm_group_$module_id"; $group_id = "perm_group_$module_id";
?> ?>
<div class="form-group"> <div class="mb-3">
<label><?= $module_name_display_safe ?> <strong class="text-danger">*</strong></label> <label><?= $module_name_display_safe ?> <strong class="text-danger">*</strong></label>
<div class="btn-group btn-group-toggle btn-block" data-toggle="buttons" role="group" <div class="btn-group w-100" role="group"
aria-label="Permissions for <?= $module_name_display_safe ?>"> aria-label="Permissions for <?= $module_name_display_safe ?>">
<label class="btn btn-outline-secondary btn-sm active" title="No Access"> <input class="btn-check"
<input
type="radio" type="radio"
name="<?= $field_name ?>" name="<?= $field_name ?>"
id="<?= $group_id ?>_0" id="<?= $group_id ?>_0"
@@ -114,41 +107,34 @@ ob_start();
checked checked
required required
> >
None <label class="btn btn-outline-secondary btn-sm" title="No Access" for="<?= $group_id ?>_0">None</label>
</label>
<label class="btn btn-outline-primary btn-sm" title="Viewing Only"> <input class="btn-check"
<input
type="radio" type="radio"
name="<?= $field_name ?>" name="<?= $field_name ?>"
id="<?= $group_id ?>_1" id="<?= $group_id ?>_1"
value="1" value="1"
autocomplete="off" autocomplete="off"
> >
<i class="fas fa-fw fa-eye mr-1"></i>Read <label class="btn btn-outline-primary btn-sm" title="Viewing Only" for="<?= $group_id ?>_1"><i class="fas fa-fw fa-eye me-1"></i>Read</label>
</label>
<label class="btn btn-outline-warning btn-sm" title="Read, Edit, Archive"> <input class="btn-check"
<input
type="radio" type="radio"
name="<?= $field_name ?>" name="<?= $field_name ?>"
id="<?= $group_id ?>_2" id="<?= $group_id ?>_2"
value="2" value="2"
autocomplete="off" autocomplete="off"
> >
<i class="fas fa-fw fa-edit mr-1"></i>Modify <label class="btn btn-outline-warning btn-sm" title="Read, Edit, Archive" for="<?= $group_id ?>_2"><i class="fas fa-fw fa-edit me-1"></i>Modify</label>
</label>
<label class="btn btn-outline-danger btn-sm" title="Read, Edit, Archive, Delete"> <input class="btn-check"
<input
type="radio" type="radio"
name="<?= $field_name ?>" name="<?= $field_name ?>"
id="<?= $group_id ?>_3" id="<?= $group_id ?>_3"
value="3" value="3"
autocomplete="off" autocomplete="off"
> >
<i class="fas fa-fw fa-trash mr-1"></i>Full <label class="btn btn-outline-danger btn-sm" title="Read, Edit, Archive, Delete" for="<?= $group_id ?>_3"><i class="fas fa-fw fa-trash me-1"></i>Full</label>
</label>
</div> </div>
@@ -164,10 +150,10 @@ ob_start();
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_role" class="btn btn-primary text-bold"> <button type="submit" name="add_role" class="btn btn-primary text-bold">
<i class="fas fa-check mr-2"></i>Create <i class="fas fa-check me-2"></i>Create
</button> </button>
<button type="button" class="btn btn-light" data-dismiss="modal"> <button type="button" class="btn btn-light" data-bs-dismiss="modal">
<i class="fas fa-times mr-2"></i>Cancel <i class="fas fa-times me-2"></i>Cancel
</button> </button>
</div> </div>
</form> </form>

View File

@@ -35,11 +35,9 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>Editing role: <h5 class="modal-title"><i class="fas fa-fw fa-user-shield me-2"></i>Editing role:
<strong><?= $role_name ?></strong></h5> <strong><?= $role_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> <form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -47,11 +45,11 @@ ob_start();
<div class="modal-body"> <div class="modal-body">
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-role-details">Details</a> <a class="nav-link active" data-bs-toggle="pill" href="#pills-role-details">Details</a>
</li> </li>
<?php if (!$role_admin) { ?> <?php if (!$role_admin) { ?>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-role-permissions">Permissions</a> <a class="nav-link" data-bs-toggle="pill" href="#pills-role-permissions">Permissions</a>
</li> </li>
<?php } ?> <?php } ?>
</ul> </ul>
@@ -62,41 +60,37 @@ ob_start();
<div class="tab-pane fade show active" id="pills-role-details"> <div class="tab-pane fade show active" id="pills-role-details">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
</div>
<input type="text" class="form-control" name="role_name" placeholder="Role Name" maxlength="200" value="<?= $role_name ?>" required> <input type="text" class="form-control" name="role_name" placeholder="Role Name" maxlength="200" value="<?= $role_name ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description <strong class="text-danger">*</strong></label> <label>Description <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-chevron-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-chevron-right"></i></span>
</div>
<input type="text" class="form-control" name="role_description" placeholder="Role Description" maxlength="200" value="<?= $role_description ?>" required> <input type="text" class="form-control" name="role_description" placeholder="Role Description" maxlength="200" value="<?= $role_description ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Admin Access <strong class="text-danger">*</strong></label> <label>Admin Access <strong class="text-danger">*</strong></label>
<div class="custom-control custom-radio mb-2"> <div class="form-check mb-2">
<input type="radio" class="custom-control-input" id="admin_yes" name="role_is_admin" value="1" <input type="radio" class="form-check-input" id="admin_yes" name="role_is_admin" value="1"
<?php if ($role_admin) { echo 'checked'; } ?> required> <?php if ($role_admin) { echo 'checked'; } ?> required>
<label class="custom-control-label" for="admin_yes"> <label class="form-check-label" for="admin_yes">
Yes - this role should have full admin access Yes - this role should have full admin access
</label> </label>
</div> </div>
<div class="custom-control custom-radio"> <div class="form-check">
<input type="radio" class="custom-control-input" id="admin_no" name="role_is_admin" value="0" <input type="radio" class="form-check-input" id="admin_no" name="role_is_admin" value="0"
<?php if (!$role_admin) { echo 'checked'; } ?> required> <?php if (!$role_admin) { echo 'checked'; } ?> required>
<label class="custom-control-label" for="admin_no"> <label class="form-check-label" for="admin_no">
No - use permissions on the next tab No - use permissions on the next tab
</label> </label>
</div> </div>
@@ -128,17 +122,16 @@ ob_start();
} }
?> ?>
<div class="form-group"> <div class="mb-3">
<label> <?= $module_name_display ?> <strong class="text-danger">*</strong></label> <label> <?= $module_name_display ?> <strong class="text-danger">*</strong></label>
<?php <?php
$field_name = "$module_id##$module_name"; $field_name = "$module_id##$module_name";
$group_id = "perm_group_$module_id"; $group_id = "perm_group_$module_id";
?> ?>
<div class="btn-group btn-group-toggle btn-block" data-toggle="buttons" role="group" aria-label="Permissions for <?= $module_name_display ?>"> <div class="btn-group w-100" role="group" aria-label="Permissions for <?= $module_name_display ?>">
<label class="btn btn-outline-secondary btn-sm <?php if ($module_permission == 0) { echo 'active'; } ?>" title="No Access"> <input class="btn-check"
<input
type="radio" type="radio"
name="<?= $field_name ?>" name="<?= $field_name ?>"
id="<?= $group_id ?>_0" id="<?= $group_id ?>_0"
@@ -147,11 +140,9 @@ ob_start();
<?php if ($module_permission == 0) { echo 'checked'; } ?> <?php if ($module_permission == 0) { echo 'checked'; } ?>
required required
> >
None <label class="btn btn-outline-secondary btn-sm" title="No Access" for="<?= $group_id ?>_0">None</label>
</label>
<label class="btn btn-outline-primary btn-sm <?php if ($module_permission == 1) { echo 'active'; } ?>" title="Viewing Only"> <input class="btn-check"
<input
type="radio" type="radio"
name="<?= $field_name ?>" name="<?= $field_name ?>"
id="<?= $group_id ?>_1" id="<?= $group_id ?>_1"
@@ -159,11 +150,9 @@ ob_start();
autocomplete="off" autocomplete="off"
<?php if ($module_permission == 1) { echo 'checked'; } ?> <?php if ($module_permission == 1) { echo 'checked'; } ?>
> >
<i class="fas fa-fw fa-eye mr-1"></i>Read <label class="btn btn-outline-primary btn-sm" title="Viewing Only" for="<?= $group_id ?>_1"><i class="fas fa-fw fa-eye me-1"></i>Read</label>
</label>
<label class="btn btn-outline-warning btn-sm <?php if ($module_permission == 2) { echo 'active'; } ?>" title="Read, Edit, Archive"> <input class="btn-check"
<input
type="radio" type="radio"
name="<?= $field_name ?>" name="<?= $field_name ?>"
id="<?= $group_id ?>_2" id="<?= $group_id ?>_2"
@@ -171,11 +160,9 @@ ob_start();
autocomplete="off" autocomplete="off"
<?php if ($module_permission == 2) { echo 'checked'; } ?> <?php if ($module_permission == 2) { echo 'checked'; } ?>
> >
<i class="fas fa-fw fa-edit mr-1"></i>Modify <label class="btn btn-outline-warning btn-sm" title="Read, Edit, Archive" for="<?= $group_id ?>_2"><i class="fas fa-fw fa-edit me-1"></i>Modify</label>
</label>
<label class="btn btn-outline-danger btn-sm <?php if ($module_permission == 3) { echo 'active'; } ?>" title="Read, Edit, Archive, Delete"> <input class="btn-check"
<input
type="radio" type="radio"
name="<?= $field_name ?>" name="<?= $field_name ?>"
id="<?= $group_id ?>_3" id="<?= $group_id ?>_3"
@@ -183,8 +170,7 @@ ob_start();
autocomplete="off" autocomplete="off"
<?php if ($module_permission == 3) { echo 'checked'; } ?> <?php if ($module_permission == 3) { echo 'checked'; } ?>
> >
<i class="fas fa-fw fa-trash mr-1"></i>Full <label class="btn btn-outline-danger btn-sm" title="Read, Edit, Archive, Delete" for="<?= $group_id ?>_3"><i class="fas fa-fw fa-trash me-1"></i>Full</label>
</label>
</div> </div>
@@ -201,8 +187,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_role" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_role" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -4,59 +4,49 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-stopwatch mr-2"></i>New SLA</h5> <h5 class="modal-title"><i class="fas fa-fw fa-stopwatch me-2"></i>New SLA</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="SLA name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" placeholder="SLA name" maxlength="200" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description</label> <label>Description</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-comment"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-comment"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Short description" maxlength="500"> <input type="text" class="form-control" name="description" placeholder="Short description" maxlength="500">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Response target (business minutes) <strong class="text-danger">*</strong></label> <label>Response target (business minutes) <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-reply"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-reply"></i></span>
</div>
<input type="number" class="form-control" name="response_minutes" min="1" placeholder="e.g. 60" required> <input type="number" class="form-control" name="response_minutes" min="1" placeholder="e.g. 60" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Resolution target (business minutes)</label> <label>Resolution target (business minutes)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-flag-checkered"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-flag-checkered"></i></span>
</div>
<input type="number" class="form-control" name="resolution_minutes" min="1" placeholder="Leave empty for response-only"> <input type="number" class="form-control" name="resolution_minutes" min="1" placeholder="Leave empty for response-only">
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_sla" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button> <button type="submit" name="add_sla" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -14,52 +14,42 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-stopwatch mr-2"></i>Editing SLA: <strong><?= $sla_name ?></strong></h5> <h5 class="modal-title"><i class="fas fa-fw fa-stopwatch me-2"></i>Editing SLA: <strong><?= $sla_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="sla_id" value="<?= $sla_id ?>"> <input type="hidden" name="sla_id" value="<?= $sla_id ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span>
</div>
<input type="text" class="form-control" name="name" value="<?= $sla_name ?>" maxlength="200" required> <input type="text" class="form-control" name="name" value="<?= $sla_name ?>" maxlength="200" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description</label> <label>Description</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-comment"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-comment"></i></span>
</div>
<input type="text" class="form-control" name="description" value="<?= $sla_description ?>" maxlength="500"> <input type="text" class="form-control" name="description" value="<?= $sla_description ?>" maxlength="500">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Response target (business minutes) <strong class="text-danger">*</strong></label> <label>Response target (business minutes) <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-reply"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-reply"></i></span>
</div>
<input type="number" class="form-control" name="response_minutes" min="1" value="<?= $sla_response_minutes ?>" required> <input type="number" class="form-control" name="response_minutes" min="1" value="<?= $sla_response_minutes ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Resolution target (business minutes)</label> <label>Resolution target (business minutes)</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-flag-checkered"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-flag-checkered"></i></span>
</div>
<input type="number" class="form-control" name="resolution_minutes" min="1" value="<?= $sla_resolution_minutes ?: '' ?>" placeholder="Leave empty for response-only"> <input type="number" class="form-control" name="resolution_minutes" min="1" value="<?= $sla_resolution_minutes ?: '' ?>" placeholder="Leave empty for response-only">
</div> </div>
<small class="text-muted">Saving recalculates targets on open tickets using this SLA.</small> <small class="text-muted">Saving recalculates targets on open tickets using this SLA.</small>
@@ -67,8 +57,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_sla" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_sla" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -17,53 +17,43 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-cube mr-2"></i>New License Template</h5> <h5 class="modal-title"><i class="fa fa-fw fa-cube me-2"></i>New License Template</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Template Name <strong class="text-danger">*</strong></label> <label>Template Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Software name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" placeholder="Software name" maxlength="200" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Version</label> <label>Version</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span>
</div>
<input type="text" class="form-control" name="version" placeholder="Software version" maxlength="200"> <input type="text" class="form-control" name="version" placeholder="Software version" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description</label> <label>Description</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Short description"> <input type="text" class="form-control" name="description" placeholder="Short description">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Type <strong class="text-danger">*</strong></label> <label>Type <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div> <select class="form-select select2" name="type" required>
<select class="form-control select2" name="type" required>
<option value="">- Select Type -</option> <option value="">- Select Type -</option>
<<?php <<?php
$sql_software_types_select = mysqli_query($mysqli, " $sql_software_types_select = mysqli_query($mysqli, "
@@ -81,13 +71,11 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>License Type</label> <label>License Type</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span>
</div> <select class="form-select select2" name="license_type">
<select class="form-control select2" name="license_type">
<option value="">- Select a License Type -</option> <option value="">- Select a License Type -</option>
<?php foreach($license_types_array as $license_type) { ?> <?php foreach($license_types_array as $license_type) { ?>
<option><?= $license_type ?></option> <option><?= $license_type ?></option>
@@ -100,8 +88,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_software_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button> <button type="submit" name="add_software_template" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -29,10 +29,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-cube mr-2"></i>Editing template: <strong><?= $software_name ?></strong></h5> <h5 class="modal-title"><i class="fa fa-fw fa-cube me-2"></i>Editing template: <strong><?= $software_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -40,43 +38,35 @@ ob_start();
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Template Name <strong class="text-danger">*</strong></label> <label>Template Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Software name" maxlength="200" value="<?= $software_name ?>" required> <input type="text" class="form-control" name="name" placeholder="Software name" maxlength="200" value="<?= $software_name ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Version</label> <label>Version</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span>
</div>
<input type="text" class="form-control" name="version" placeholder="Software version" maxlength="200" value="<?= $software_version ?>"> <input type="text" class="form-control" name="version" placeholder="Software version" maxlength="200" value="<?= $software_version ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description</label> <label>Description</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Short description" value="<?= $software_description ?>"> <input type="text" class="form-control" name="description" placeholder="Short description" value="<?= $software_description ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Type <strong class="text-danger">*</strong></label> <label>Type <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div> <select class="form-select select2" name="type" required>
<select class="form-control select2" name="type" required>
<option value="">- Select Type -</option> <option value="">- Select Type -</option>
<<?php <<?php
$sql_software_types_select = mysqli_query($mysqli, " $sql_software_types_select = mysqli_query($mysqli, "
@@ -96,13 +86,11 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>License Type</label> <label>License Type</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span>
</div> <select class="form-select select2" name="license_type">
<select class="form-control select2" name="license_type">
<option value="">- Select a License Type -</option> <option value="">- Select a License Type -</option>
<?php foreach($license_types_array as $license_type_select) { ?> <?php foreach($license_types_array as $license_type_select) { ?>
<option <?php if($license_type_select == $software_license_type){ echo "selected"; } ?>><?= $license_type_select ?></option> <option <?php if($license_type_select == $software_license_type){ echo "selected"; } ?>><?= $license_type_select ?></option>
@@ -115,8 +103,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_software_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_software_template" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -24,22 +24,18 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-tag mr-2"></i>New <strong><?= $type_display ?></strong> Tag</h5> <h5 class="modal-title"><i class="fas fa-fw fa-tag me-2"></i>New <strong><?= $type_display ?></strong> Tag</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="type" value="<?= $type ?>"> <input type="hidden" name="type" value="<?= $type ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Tag name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" placeholder="Tag name" maxlength="200" required autofocus>
</div> </div>
</div> </div>
@@ -50,13 +46,11 @@ ob_start();
<?php } else { ?> <?php } else { ?>
<div class="form-group"> <div class="mb-3">
<label>Type <strong class="text-danger">*</strong></label> <label>Type <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-th"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-th"></i></span>
</div> <select class="form-select select2" name="type" required>
<select class="form-control select2" name="type" required>
<option value="">- Type -</option> <option value="">- Type -</option>
<option value="1">Client Tag</option> <option value="1">Client Tag</option>
<option value="2">Location Tag</option> <option value="2">Location Tag</option>
@@ -69,30 +63,26 @@ ob_start();
<?php } ?> <?php } ?>
<div class="form-group"> <div class="mb-3">
<label>Color <strong class="text-danger">*</strong></label> <label>Color <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span>
</div>
<input type="color" class="form-control col-3" name="color" required> <input type="color" class="form-control col-3" name="color" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Icon</label> <label>Icon</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-image"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-image"></i></span>
</div>
<input type="text" class="form-control" name="icon" placeholder="Icon ex handshake" maxlength="200"> <input type="text" class="form-control" name="icon" placeholder="Icon ex handshake" maxlength="200">
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_tag" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create Tag</button> <button type="submit" name="add_tag" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Create Tag</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -29,10 +29,8 @@ if ($tag_type == 1) {
ob_start(); ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-tag mr-2"></i><?= $tag_type_display ?> Tag: <strong><?= $tag_name ?></strong></h5> <h5 class="modal-title"><i class="fas fa-fw fa-tag me-2"></i><?= $tag_type_display ?> Tag: <strong><?= $tag_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -40,40 +38,34 @@ ob_start();
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input type="text" class="form-control" name="name" maxlength="200" value="<?= $tag_name ?>" required> <input type="text" class="form-control" name="name" maxlength="200" value="<?= $tag_name ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Color <strong class="text-danger">*</strong></label> <label>Color <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span>
</div>
<input type="color" class="form-control col-3" name="color" value="<?= $tag_color ?>" required> <input type="color" class="form-control col-3" name="color" value="<?= $tag_color ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Icon</label> <label>Icon</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-image"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-image"></i></span>
</div>
<input type="text" class="form-control" name="icon" placeholder="Icon ex handshake" maxlength="200" value="<?= $tag_icon ?>"> <input type="text" class="form-control" name="icon" placeholder="Icon ex handshake" maxlength="200" value="<?= $tag_icon ?>">
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_tag" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save changes</button> <button type="submit" name="edit_tag" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save changes</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -7,27 +7,25 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-balance-scale mr-2"></i>New Tax</h5> <h5 class="modal-title"><i class="fas fa-fw fa-balance-scale me-2"></i>New Tax</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span aria-hidden="true">&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<input type="text" class="form-control" name="name" placeholder="Tax name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" placeholder="Tax name" maxlength="200" required autofocus>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Percent <strong class="text-danger">*</strong></label> <label>Percent <strong class="text-danger">*</strong></label>
<input type="number" min="0" step="any" class="form-control col-md-4" name="percent"> <input type="number" min="0" step="any" class="form-control col-md-4" name="percent">
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_tax" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button> <button type="submit" name="add_tax" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -14,10 +14,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-balance-scale mr-2"></i>Editing tax: <strong><?= $tax_name ?></strong></h5> <h5 class="modal-title"><i class="fas fa-fw fa-balance-scale me-2"></i>Editing tax: <strong><?= $tax_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -25,20 +23,20 @@ ob_start();
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<input type="text" class="form-control" name="name" maxlength="200" value="<?= $tax_name ?>" required> <input type="text" class="form-control" name="name" maxlength="200" value="<?= $tax_name ?>" required>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Percent <strong class="text-danger">*</strong></label> <label>Percent <strong class="text-danger">*</strong></label>
<input type="number" min="0" step="any" class="form-control col-md-4" name="percent" value="<?= $tax_percent ?>"> <input type="number" min="0" step="any" class="form-control col-md-4" name="percent" value="<?= $tax_percent ?>">
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_tax" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_tax" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -4,43 +4,35 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-info-circle mr-2"></i>New Ticket Status</h5> <h5 class="modal-title"><i class="fas fa-fw fa-info-circle me-2"></i>New Ticket Status</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-info-circle"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-info-circle"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Ticket Status name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" placeholder="Ticket Status name" maxlength="200" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Color <strong class="text-danger">*</strong></label> <label>Color <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span>
</div>
<input type="color" class="form-control col-3" name="color" required> <input type="color" class="form-control col-3" name="color" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>SLA</label> <label>SLA</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span>
</div> <select class="form-select select2" name="pauses_sla">
<select class="form-control select2" name="pauses_sla">
<option value="0">Resolution clock keeps running</option> <option value="0">Resolution clock keeps running</option>
<option value="1">Pause the resolution clock</option> <option value="1">Pause the resolution clock</option>
</select> </select>
@@ -49,8 +41,8 @@ ob_start();
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_ticket_status" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button> <button type="submit" name="add_ticket_status" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -12,16 +12,16 @@ $ticket_status_color = escapeHtml($row['ticket_status_color']);
$ticket_status_order = intval($row['ticket_status_order']); $ticket_status_order = intval($row['ticket_status_order']);
$ticket_status_active = intval($row['ticket_status_active']); $ticket_status_active = intval($row['ticket_status_active']);
$ticket_status_pauses_sla = intval($row['ticket_status_pauses_sla']); $ticket_status_pauses_sla = intval($row['ticket_status_pauses_sla']);
// Null for a custom status (the admin picks), 1 or 0 for the five built-in ones
$ticket_status_sla_lock = getTicketStatusSlaLock($ticket_status_id);
// Generate the HTML form content using output buffering. // Generate the HTML form content using output buffering.
ob_start(); ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-info-circle mr-2"></i>Editing Ticket Status: <strong><?= $ticket_status_name ?></strong></h5> <h5 class="modal-title"><i class="fas fa-fw fa-info-circle me-2"></i>Editing Ticket Status: <strong><?= $ticket_status_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -29,67 +29,67 @@ ob_start();
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input type="text" class="form-control" name="name" maxlength="200" value="<?= $ticket_status_name ?>" required <?php if ($ticket_status_id <= 5) { echo "readonly"; } ?>> <input type="text" class="form-control" name="name" maxlength="200" value="<?= $ticket_status_name ?>" required <?php if ($ticket_status_id <= 5) { echo "readonly"; } ?>>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Color <strong class="text-danger">*</strong></label> <label>Color <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span>
</div>
<input type="color" class="form-control col-3" name="color" value="<?= $ticket_status_color ?>" required> <input type="color" class="form-control col-3" name="color" value="<?= $ticket_status_color ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Order</label> <label>Order</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-sort-numeric-down"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-sort-numeric-down"></i></span>
</div>
<input type="number" class="form-control" name="order" placeholder="Leave blank for no order" value="<?= $ticket_status_order ?>"> <input type="number" class="form-control" name="order" placeholder="Leave blank for no order" value="<?= $ticket_status_order ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Status <strong class="text-danger">*</strong></label> <label>Status <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-info-circle"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-info-circle"></i></span>
</div> <select class="form-select select2" name="status" required>
<select class="form-control select2" name="status" required>
<option <?php if ($ticket_status_active == 1) { echo "selected"; } ?> value="1">Active</option> <option <?php if ($ticket_status_active == 1) { echo "selected"; } ?> value="1">Active</option>
<option <?php if ($ticket_status_active == 0) { echo "selected"; } ?> value="0" <?php if ($ticket_status_id <= 5) { echo "disabled"; } ?>>Inactive</option> <option <?php if ($ticket_status_active == 0) { echo "selected"; } ?> value="0" <?php if ($ticket_status_id <= 5) { echo "disabled"; } ?>>Inactive</option>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>SLA</label> <label>SLA</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span>
</div> <?php if (is_null($ticket_status_sla_lock)) { ?>
<select class="form-control select2" name="pauses_sla"> <select class="form-select select2" name="pauses_sla">
<option <?php if ($ticket_status_pauses_sla == 0) { echo "selected "; } ?>value="0">Resolution clock keeps running</option> <option <?php if ($ticket_status_pauses_sla == 0) { echo "selected "; } ?>value="0">Resolution clock keeps running</option>
<option <?php if ($ticket_status_pauses_sla == 1) { echo "selected "; } ?>value="1">Pause the resolution clock</option> <option <?php if ($ticket_status_pauses_sla == 1) { echo "selected "; } ?>value="1">Pause the resolution clock</option>
</select> </select>
<?php } else { ?>
<input type="text" class="form-control" value="<?= $ticket_status_sla_lock ? 'Pause the resolution clock' : 'Resolution clock keeps running' ?>" readonly>
<?php } ?>
</div> </div>
<?php if (is_null($ticket_status_sla_lock)) { ?>
<small class="text-muted">Tickets sitting in a paused status never warn or breach on resolution. Time already spent is kept and the deadline moves out when the ticket comes back.</small> <small class="text-muted">Tickets sitting in a paused status never warn or breach on resolution. Time already spent is kept and the deadline moves out when the ticket comes back.</small>
<?php } elseif ($ticket_status_sla_lock) { ?>
<small class="text-muted">Fixed for built-in statuses. Tickets here never warn or breach on resolution - time already spent is kept and the deadline moves out when the ticket comes back.</small>
<?php } else { ?>
<small class="text-muted">Fixed for built-in statuses. Tickets here are being worked, so their resolution clock runs.</small>
<?php } ?>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_ticket_status" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_ticket_status" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -6,57 +6,47 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-life-ring mr-2"></i>New Ticket Template</h5> <h5 class="modal-title"><i class="fa fa-fw fa-life-ring me-2"></i>New Ticket Template</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Template Name <strong class="text-danger">*</strong></label> <label>Template Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-life-ring"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-life-ring"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Template name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" placeholder="Template name" maxlength="200" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Subject</label> <label>Subject</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="subject" placeholder="Subject" maxlength="500"> <input type="text" class="form-control" name="subject" placeholder="Subject" maxlength="500">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<textarea class="form-control tinymceTicket" name="details"></textarea> <textarea class="form-control tinymceTicket" name="details"></textarea>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description</label> <label>Description</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Short description"> <input type="text" class="form-control" name="description" placeholder="Short description">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Add it to a Project Template?</label> <label>Add it to a Project Template?</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-project-diagram"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-project-diagram"></i></span>
</div> <select class="form-select select2" name="project_template">
<select class="form-control select2" name="project_template">
<option value="0">- No -</option> <option value="0">- No -</option>
<?php <?php
@@ -72,8 +62,8 @@ ob_start();
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_ticket_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create Template</button> <button type="submit" name="add_ticket_template" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Create Template</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -3,10 +3,8 @@
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-life-ring mr-2"></i>Editing Ticket Template: <?= $ticket_template_name ?></h5> <h5 class="modal-title"><i class="fa fa-fw fa-life-ring me-2"></i>Editing Ticket Template: <?= $ticket_template_name ?></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -14,44 +12,38 @@
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Template Name <strong class="text-danger">*</strong></label> <label>Template Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-life-ring"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-life-ring"></i></span>
</div>
<input type="text" class="form-control" name="name" maxlength="200" value="<?= $ticket_template_name ?>" placeholder="Template name" required autofocus> <input type="text" class="form-control" name="name" maxlength="200" value="<?= $ticket_template_name ?>" placeholder="Template name" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Subject</label> <label>Subject</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="subject" maxlength="500" value="<?= $ticket_template_subject ?>" placeholder="Subject"> <input type="text" class="form-control" name="subject" maxlength="500" value="<?= $ticket_template_subject ?>" placeholder="Subject">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<textarea class="form-control tinymceTicket" name="details"><?= $ticket_template_details ?></textarea> <textarea class="form-control tinymceTicket" name="details"><?= $ticket_template_details ?></textarea>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description</label> <label>Description</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" value="<?= $ticket_template_description ?>" placeholder="Short description"> <input type="text" class="form-control" name="description" value="<?= $ticket_template_description ?>" placeholder="Short description">
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_ticket_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_ticket_template" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>
</div> </div>

View File

@@ -18,10 +18,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-tasks mr-2"></i>Editing task</h5> <h5 class="modal-title"><i class="fa fa-fw fa-tasks me-2"></i>Editing task</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -29,22 +27,18 @@ ob_start();
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Name the task" maxlength="255" value="<?= $task_template_name ?>" required autofocus> <input type="text" class="form-control" name="name" placeholder="Name the task" maxlength="255" value="<?= $task_template_name ?>" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Estimated Completion Time <span class="text-secondary">(Minutes)</span></label> <label>Estimated Completion Time <span class="text-secondary">(Minutes)</span></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div>
<input type="number" class="form-control" name="completion_estimate" placeholder="Estimated time to complete task in mins" value="<?= $task_template_completion_estimate ?>"> <input type="number" class="form-control" name="completion_estimate" placeholder="Estimated time to complete task in mins" value="<?= $task_template_completion_estimate ?>">
</div> </div>
</div> </div>
@@ -52,8 +46,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_ticket_template_task" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_ticket_template_task" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -6,10 +6,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-user-plus mr-2"></i>New User</h5> <h5 class="modal-title"><i class="fas fa-fw fa-user-plus me-2"></i>New User</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> <form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -17,10 +15,10 @@ ob_start();
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-user-details">Details</a> <a class="nav-link active" data-bs-toggle="pill" href="#pills-user-details">Details</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-user-access">Restrict Access</a> <a class="nav-link" data-bs-toggle="pill" href="#pills-user-access">Restrict Access</a>
</li> </li>
</ul> </ul>
@@ -30,49 +28,37 @@ ob_start();
<div class="tab-pane fade show active" id="pills-user-details"> <div class="tab-pane fade show active" id="pills-user-details">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Full Name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" placeholder="Full Name" maxlength="200" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Email <strong class="text-danger">*</strong></label> <label>Email <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span>
</div>
<input type="email" class="form-control" name="email" placeholder="Email Address" maxlength="200" required> <input type="email" class="form-control" name="email" placeholder="Email Address" maxlength="200" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Password <strong class="text-danger">*</strong></label> <label>Password <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
</div>
<input type="password" class="form-control" data-toggle="password" name="password" id="password" placeholder="Enter a Password" autocomplete="new-password" minlength="8" required> <input type="password" class="form-control" data-toggle="password" name="password" id="password" placeholder="Enter a Password" autocomplete="new-password" minlength="8" required>
<div class="input-group-append">
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
</div>
<div class="input-group-append">
<span class="btn btn-default"><i class="fa fa-fw fa-question" onclick="generatePassword()"></i></span> <span class="btn btn-default"><i class="fa fa-fw fa-question" onclick="generatePassword()"></i></span>
</div> </div>
</div> </div>
</div>
<div class="form-group"> <div class="mb-3">
<label>Role <strong class="text-danger">*</strong></label> <label>Role <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
</div> <select class="form-select select2" name="role" required>
<select class="form-control select2" name="role" required>
<option value="">- Role -</option> <option value="">- Role -</option>
<?php <?php
$sql_user_roles = mysqli_query($mysqli, "SELECT role_id, role_name FROM user_roles WHERE role_archived_at IS NULL"); $sql_user_roles = mysqli_query($mysqli, "SELECT role_id, role_name FROM user_roles WHERE role_archived_at IS NULL");
@@ -87,24 +73,24 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Avatar</label> <label>Avatar</label>
<input type="file" class="form-control-file" accept="image/*" name="file"> <input type="file" class="form-control" accept="image/*" name="file">
</div> </div>
<div class="form-group" <?php if(empty($config_smtp_host)) { echo "hidden"; } ?>> <div class="mb-3" <?php if(empty($config_smtp_host)) { echo "hidden"; } ?>>
<div class="custom-control custom-checkbox"> <div class="form-check">
<input class="custom-control-input" type="checkbox" id="sendEmailCheckBox" name="send_email" value="" checked> <input class="form-check-input" type="checkbox" id="sendEmailCheckBox" name="send_email" value="" checked>
<label for="sendEmailCheckBox" class="custom-control-label"> <label for="sendEmailCheckBox" class="form-check-label">
Send user e-mail with login details? Send user e-mail with login details?
</label> </label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-checkbox"> <div class="form-check">
<input class="custom-control-input" type="checkbox" id="forceMFACheckBox" name="force_mfa" value=1> <input class="form-check-input" type="checkbox" id="forceMFACheckBox" name="force_mfa" value=1>
<label for="forceMFACheckBox" class="custom-control-label"> <label for="forceMFACheckBox" class="form-check-label">
Force MFA Force MFA
</label> </label>
</div> </div>
@@ -119,7 +105,7 @@ ob_start();
</div> </div>
<div class="mb-2"> <div class="mb-2">
<small class="text-muted mr-2">Set all:</small> <small class="text-muted me-2">Set all:</small>
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.querySelectorAll('#accessTable .perm-none').forEach(r => r.checked = true);">No Rule</button> <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.querySelectorAll('#accessTable .perm-none').forEach(r => r.checked = true);">No Rule</button>
<button type="button" class="btn btn-sm btn-outline-success" onclick="document.querySelectorAll('#accessTable .perm-allow').forEach(r => r.checked = true);">Allow</button> <button type="button" class="btn btn-sm btn-outline-success" onclick="document.querySelectorAll('#accessTable .perm-allow').forEach(r => r.checked = true);">Allow</button>
<button type="button" class="btn btn-sm btn-outline-danger" onclick="document.querySelectorAll('#accessTable .perm-deny').forEach(r => r.checked = true);">Deny</button> <button type="button" class="btn btn-sm btn-outline-danger" onclick="document.querySelectorAll('#accessTable .perm-deny').forEach(r => r.checked = true);">Deny</button>
@@ -147,13 +133,13 @@ ob_start();
<tr> <tr>
<td class="align-middle"><?= $client_name ?></td> <td class="align-middle"><?= $client_name ?></td>
<td class="text-center align-middle"> <td class="text-center align-middle">
<input type="radio" class="perm-none" name="client_permission[<?= $client_id ?>]" value="" checked> <input type="radio" class="form-check-input perm-none" name="client_permission[<?= $client_id ?>]" value="" checked>
</td> </td>
<td class="text-center align-middle"> <td class="text-center align-middle">
<input type="radio" class="perm-allow" name="client_permission[<?= $client_id ?>]" value="allow"> <input type="radio" class="form-check-input perm-allow" name="client_permission[<?= $client_id ?>]" value="allow">
</td> </td>
<td class="text-center align-middle"> <td class="text-center align-middle">
<input type="radio" class="perm-deny" name="client_permission[<?= $client_id ?>]" value="deny"> <input type="radio" class="form-check-input perm-deny" name="client_permission[<?= $client_id ?>]" value="deny">
</td> </td>
</tr> </tr>
@@ -169,15 +155,15 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_user" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button> <button type="submit" name="add_user" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>
<script> <script>
function generatePassword() { function generatePassword() {
jQuery.get( itflowGet(
"/agent/ajax.php", { "/agent/ajax.php", {
get_readable_pass: 'true' get_readable_pass: 'true'
}, },

View File

@@ -18,16 +18,14 @@ ob_start();
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="row col-7 offset-4"> <div class="row col-7 offset-4">
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<input type="password" class="form-control" placeholder="Enter your account password to continue" name="admin_password" required> <input type="password" class="form-control" placeholder="Enter your account password to continue" name="admin_password" required>
</div> </div>
</div> </div>
</div>
<br> <br>
<button class="btn btn-danger" type="submit" name="ir_reset_user_password"><i class="fas fa-fw fa-key mr-2"></i>Reset passwords</button> <button class="btn btn-danger" type="submit" name="ir_reset_user_password"><i class="fas fa-fw fa-key me-2"></i>Reset passwords</button>
</form> </form>
</div> </div>
<button type="button" class="btn btn-outline-secondary btn-lg px-5 mr-4" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-outline-secondary btn-lg px-5 me-4" data-bs-dismiss="modal">Cancel</button>
</div> </div>

View File

@@ -26,11 +26,9 @@ $recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets);
ob_start(); ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-user-slash mr-2"></i>Archiving user: <h5 class="modal-title"><i class="fas fa-fw fa-user-slash me-2"></i>Archiving user:
<strong><?= $user_name ?></strong></h5> <strong><?= $user_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -50,13 +48,11 @@ ob_start();
</center> </center>
<div class="form-group"> <div class="mb-3">
<label>Reassign <?= $ticket_count ?> Open Tickets and <?= $recurring_ticket_count ?> Recurring Tickets To:</label> <label>Reassign <?= $ticket_count ?> Open Tickets and <?= $recurring_ticket_count ?> Recurring Tickets To:</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div> <select class="form-select select2" name="ticket_assign" required>
<select class="form-control select2" name="ticket_assign" required>
<option value="0">No one</option> <option value="0">No one</option>
<?php <?php
$sql_users = mysqli_query($mysqli, "SELECT user_id, user_name FROM users WHERE user_type = 1 AND user_archived_at IS NULL"); $sql_users = mysqli_query($mysqli, "SELECT user_id, user_name FROM users WHERE user_type = 1 AND user_archived_at IS NULL");
@@ -74,8 +70,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="archive_user" class="btn btn-danger text-bold"><i class="fas fa-archive mr-2"></i>Archive</button> <button type="submit" name="archive_user" class="btn btn-danger text-bold"><i class="fas fa-archive me-2"></i>Archive</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -35,11 +35,9 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-user-edit mr-2"></i>Editing user: <h5 class="modal-title"><i class="fas fa-fw fa-user-edit me-2"></i>Editing user:
<strong><?= $user_name ?></strong></h5> <strong><?= $user_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> <form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -48,10 +46,10 @@ ob_start();
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-user-details<?= $user_id ?>">Details</a> <a class="nav-link active" data-bs-toggle="pill" href="#pills-user-details<?= $user_id ?>">Details</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-user-access<?= $user_id ?>">Restrict Access</a> <a class="nav-link" data-bs-toggle="pill" href="#pills-user-access<?= $user_id ?>">Restrict Access</a>
</li> </li>
</ul> </ul>
@@ -72,52 +70,40 @@ ob_start();
<?php } ?> <?php } ?>
</center> </center>
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Full Name" maxlength="200" <input type="text" class="form-control" name="name" placeholder="Full Name" maxlength="200"
value="<?= $user_name ?>" required> value="<?= $user_name ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Email <strong class="text-danger">*</strong></label> <label>Email <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span>
</div>
<input type="email" class="form-control" name="email" placeholder="Email Address" maxlength="200" <input type="email" class="form-control" name="email" placeholder="Email Address" maxlength="200"
value="<?= $user_email ?>" required> value="<?= $user_email ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>New Password</label> <label>New Password</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
</div>
<input type="password" class="form-control" data-toggle="password" name="new_password" id="password" <input type="password" class="form-control" data-toggle="password" name="new_password" id="password"
placeholder="Leave Blank For No Password Change" autocomplete="new-password"> placeholder="Leave Blank For No Password Change" autocomplete="new-password">
<div class="input-group-append">
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
</div>
<div class="input-group-append">
<span class="btn btn-default"><i class="fa fa-fw fa-question" onclick="generatePassword()"></i></span> <span class="btn btn-default"><i class="fa fa-fw fa-question" onclick="generatePassword()"></i></span>
</div> </div>
</div> </div>
</div>
<div class="form-group"> <div class="mb-3">
<label>Role <strong class="text-danger">*</strong></label> <label>Role <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
</div> <select class="form-select select2" name="role" required>
<select class="form-control select2" name="role" required>
<?php <?php
$sql_user_roles = mysqli_query($mysqli, "SELECT role_id, role_name FROM user_roles WHERE role_archived_at IS NULL"); $sql_user_roles = mysqli_query($mysqli, "SELECT role_id, role_name FROM user_roles WHERE role_archived_at IS NULL");
while ($row = mysqli_fetch_assoc($sql_user_roles)) { while ($row = mysqli_fetch_assoc($sql_user_roles)) {
@@ -132,15 +118,15 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Avatar</label> <label>Avatar</label>
<input type="file" class="form-control-file" accept="image/*" name="file"> <input type="file" class="form-control" accept="image/*" name="file">
</div> </div>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-checkbox"> <div class="form-check">
<input class="custom-control-input" type="checkbox" id="forceMFACheckBox<?= $user_id ?>" name="force_mfa" value="1" <?php if($user_config_force_mfa == 1){ echo "checked"; } ?>> <input class="form-check-input" type="checkbox" id="forceMFACheckBox<?= $user_id ?>" name="force_mfa" value="1" <?php if($user_config_force_mfa == 1){ echo "checked"; } ?>>
<label for="forceMFACheckBox<?= $user_id ?>" class="custom-control-label"> <label for="forceMFACheckBox<?= $user_id ?>" class="form-check-label">
Force MFA Force MFA
</label> </label>
</div> </div>
@@ -148,13 +134,11 @@ ob_start();
<?php if (!empty($user_token)) { ?> <?php if (!empty($user_token)) { ?>
<div class="form-group"> <div class="mb-3">
<label>2FA</label> <label>2FA</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-id-card"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-id-card"></i></span>
</div> <select class="form-select" name="2fa">
<select class="form-control" name="2fa">
<option value="">Keep enabled</option> <option value="">Keep enabled</option>
<option value="disable">Disable</option> <option value="disable">Disable</option>
</select> </select>
@@ -171,7 +155,7 @@ ob_start();
</div> </div>
<div class="mb-2"> <div class="mb-2">
<small class="text-muted mr-2">Set all:</small> <small class="text-muted me-2">Set all:</small>
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.querySelectorAll('#accessTable<?= $user_id ?> .perm-none').forEach(r => r.checked = true);">No Rule</button> <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.querySelectorAll('#accessTable<?= $user_id ?> .perm-none').forEach(r => r.checked = true);">No Rule</button>
<button type="button" class="btn btn-sm btn-outline-success" onclick="document.querySelectorAll('#accessTable<?= $user_id ?> .perm-allow').forEach(r => r.checked = true);">Allow</button> <button type="button" class="btn btn-sm btn-outline-success" onclick="document.querySelectorAll('#accessTable<?= $user_id ?> .perm-allow').forEach(r => r.checked = true);">Allow</button>
<button type="button" class="btn btn-sm btn-outline-danger" onclick="document.querySelectorAll('#accessTable<?= $user_id ?> .perm-deny').forEach(r => r.checked = true);">Deny</button> <button type="button" class="btn btn-sm btn-outline-danger" onclick="document.querySelectorAll('#accessTable<?= $user_id ?> .perm-deny').forEach(r => r.checked = true);">Deny</button>
@@ -201,13 +185,13 @@ ob_start();
<tr> <tr>
<td class="align-middle"><?= $client_name_select ?></td> <td class="align-middle"><?= $client_name_select ?></td>
<td class="text-center align-middle"> <td class="text-center align-middle">
<input type="radio" class="perm-none" name="client_permission[<?= $client_id_select ?>]" value="" <?php if (!$client_is_allow && !$client_is_deny) { echo "checked"; } ?>> <input type="radio" class="form-check-input perm-none" name="client_permission[<?= $client_id_select ?>]" value="" <?php if (!$client_is_allow && !$client_is_deny) { echo "checked"; } ?>>
</td> </td>
<td class="text-center align-middle"> <td class="text-center align-middle">
<input type="radio" class="perm-allow" name="client_permission[<?= $client_id_select ?>]" value="allow" <?php if ($client_is_allow) { echo "checked"; } ?>> <input type="radio" class="form-check-input perm-allow" name="client_permission[<?= $client_id_select ?>]" value="allow" <?php if ($client_is_allow) { echo "checked"; } ?>>
</td> </td>
<td class="text-center align-middle"> <td class="text-center align-middle">
<input type="radio" class="perm-deny" name="client_permission[<?= $client_id_select ?>]" value="deny" <?php if ($client_is_deny) { echo "checked"; } ?>> <input type="radio" class="form-check-input perm-deny" name="client_permission[<?= $client_id_select ?>]" value="deny" <?php if ($client_is_deny) { echo "checked"; } ?>>
</td> </td>
</tr> </tr>
@@ -222,8 +206,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="edit_user" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_user" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>
@@ -231,7 +215,7 @@ ob_start();
function generatePassword() { function generatePassword() {
// Send a GET request to ajax.php as ajax.php?get_readable_pass=true // Send a GET request to ajax.php as ajax.php?get_readable_pass=true
jQuery.get( itflowGet(
"/agent/ajax.php", { "/agent/ajax.php", {
get_readable_pass: 'true' get_readable_pass: 'true'
}, },

View File

@@ -22,10 +22,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Users</h5> <h5 class="modal-title"><i class="fas fa-fw fa-download me-2"></i>Export Users</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<?php exportTabsNav(); ?> <?php exportTabsNav(); ?>
@@ -37,23 +35,19 @@ ob_start();
<?php exportTabsFiltersOpen(); ?> <?php exportTabsFiltersOpen(); ?>
<div class="form-group"> <div class="mb-3">
<label>Search</label> <label>Search</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name or email"> <input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name or email">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Archived</label> <label>Archived</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
</div> <select class="form-select select2" name="archived">
<select class="form-control select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option> <option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option> <option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select> </select>

View File

@@ -7,31 +7,25 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-user-plus"></i>Invite User</h5> <h5 class="modal-title"><i class="fas fa-fw fa-user-plus"></i>Invite User</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> <form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="mb-3">
<label>Email <strong class="text-danger">*</strong></label> <label>Email <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span>
</div>
<input type="email" class="form-control" name="email" placeholder="Email Address" maxlength="200" required> <input type="email" class="form-control" name="email" placeholder="Email Address" maxlength="200" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Role <strong class="text-danger">*</strong></label> <label>Role <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
</div> <select class="form-select select2" name="role" required>
<select class="form-control select2" name="role" required>
<option value="">- Role -</option> <option value="">- Role -</option>
<!-- //TODO: Pull from roles --> <!-- //TODO: Pull from roles -->
</select> </select>
@@ -40,8 +34,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="invite_user" class="btn btn-primary text-bold"><i class="fas fa-paper-plane mr-2"></i>Send Invite</button> <button type="submit" name="invite_user" class="btn btn-primary text-bold"><i class="fas fa-paper-plane me-2"></i>Send Invite</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -18,11 +18,9 @@ $user_role_id = intval($row['user_role_id']);
ob_start(); ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-redo-alt mr-2"></i>Restoring user: <h5 class="modal-title"><i class="fas fa-fw fa-redo-alt me-2"></i>Restoring user:
<strong><?= $user_name ?></strong></h5> <strong><?= $user_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -41,27 +39,21 @@ ob_start();
<?php } ?> <?php } ?>
</center> </center>
<div class="form-group"> <div class="mb-3">
<label>Set a New Password</label> <label>Set a New Password</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
</div>
<input type="password" class="form-control" data-toggle="password" name="new_password" <input type="password" class="form-control" data-toggle="password" name="new_password"
placeholder="Enter a new password" autocomplete="new-password" required> placeholder="Enter a new password" autocomplete="new-password" required>
<div class="input-group-append">
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
</div> </div>
</div> </div>
</div>
<div class="form-group"> <div class="mb-3">
<label>Role <strong class="text-danger">*</strong></label> <label>Role <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
</div> <select class="form-select select2" name="role" required>
<select class="form-control select2" name="role" required>
<?php <?php
$sql_user_roles = mysqli_query($mysqli, "SELECT role_id, role_name FROM user_roles WHERE role_archived_at IS NULL"); $sql_user_roles = mysqli_query($mysqli, "SELECT role_id, role_name FROM user_roles WHERE role_archived_at IS NULL");
while ($row = mysqli_fetch_assoc($sql_user_roles)) { while ($row = mysqli_fetch_assoc($sql_user_roles)) {
@@ -78,8 +70,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="restore_user" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Restore</button> <button type="submit" name="restore_user" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Restore</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -7,10 +7,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-building mr-2"></i>New Vendor Template</h5> <h5 class="modal-title"><i class="fas fa-fw fa-building me-2"></i>New Vendor Template</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -19,13 +17,13 @@ ob_start();
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-details">Details</a> <a class="nav-link active" data-bs-toggle="pill" href="#pills-details">Details</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-support">Support</a> <a class="nav-link" data-bs-toggle="pill" href="#pills-support">Support</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-notes">Notes</a> <a class="nav-link" data-bs-toggle="pill" href="#pills-notes">Notes</a>
</li> </li>
</ul> </ul>
@@ -35,42 +33,34 @@ ob_start();
<div class="tab-pane fade show active" id="pills-details"> <div class="tab-pane fade show active" id="pills-details">
<div class="form-group"> <div class="mb-3">
<label>Vendor Name <strong class="text-danger">*</strong></label> <label>Vendor Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-building"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Vendor Name" maxlength="200" required autofocus> <input type="text" class="form-control" name="name" placeholder="Vendor Name" maxlength="200" required autofocus>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description</label> <label>Description</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Description" maxlength="200"> <input type="text" class="form-control" name="description" placeholder="Description" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Account Number</label> <label>Account Number</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-fingerprint"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-fingerprint"></i></span>
</div>
<input type="text" class="form-control" name="account_number" placeholder="Account number" maxlength="200"> <input type="text" class="form-control" name="account_number" placeholder="Account number" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Account Manager</label> <label>Account Manager</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<input type="text" class="form-control" name="contact_name" placeholder="Account manager's name" maxlength="200"> <input type="text" class="form-control" name="contact_name" placeholder="Account manager's name" maxlength="200">
</div> </div>
</div> </div>
@@ -80,71 +70,59 @@ ob_start();
<div class="tab-pane fade" id="pills-support"> <div class="tab-pane fade" id="pills-support">
<label>Support Phone / <span class="text-secondary">Extension</span></label> <label>Support Phone / <span class="text-secondary">Extension</span></label>
<div class="form-row"> <div class="row g-2">
<div class="col-9"> <div class="col-9">
<div class="form-group"> <div class="mb-3">
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-phone"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-phone"></i></span>
</div>
<input type="tel" class="form-control col-2" name="phone_country_code" placeholder="+" maxlength="4"> <input type="tel" class="form-control col-2" name="phone_country_code" placeholder="+" maxlength="4">
<input type="tel" class="form-control" name="phone" placeholder="Phone Number" maxlength="200"> <input type="tel" class="form-control" name="phone" placeholder="Phone Number" maxlength="200">
</div> </div>
</div> </div>
</div> </div>
<div class="col-3"> <div class="col-3">
<div class="form-group"> <div class="mb-3">
<input type="text" class="form-control" name="extension" placeholder="ext." maxlength="200"> <input type="text" class="form-control" name="extension" placeholder="ext." maxlength="200">
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Support Hours</label> <label>Support Hours</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="text" class="form-control" name="hours" placeholder="Support Hours" maxlength="200"> <input type="text" class="form-control" name="hours" placeholder="Support Hours" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Support Email</label> <label>Support Email</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span>
</div>
<input type="email" class="form-control" name="email" placeholder="Support Email" maxlength="200"> <input type="email" class="form-control" name="email" placeholder="Support Email" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Support Website URL</label> <label>Support Website URL</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="text" class="form-control" name="website" placeholder="Do not include http(s)://" maxlength="200"> <input type="text" class="form-control" name="website" placeholder="Do not include http(s)://" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Pin/Code</label> <label>Pin/Code</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div>
<input type="text" class="form-control" name="code" placeholder="Access Code or Pin" maxlength="200"> <input type="text" class="form-control" name="code" placeholder="Access Code or Pin" maxlength="200">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>SLA</label> <label>SLA</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-handshake"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-handshake"></i></span>
</div>
<input type="text" class="form-control" name="sla" placeholder="SLA Response Time" maxlength="200"> <input type="text" class="form-control" name="sla" placeholder="SLA Response Time" maxlength="200">
</div> </div>
</div> </div>
@@ -153,7 +131,7 @@ ob_start();
<div class="tab-pane fade" id="pills-notes"> <div class="tab-pane fade" id="pills-notes">
<div class="form-group"> <div class="mb-3">
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"></textarea> <textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"></textarea>
</div> </div>
@@ -163,8 +141,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_vendor_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create Template</button> <button type="submit" name="add_vendor_template" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Create Template</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -28,10 +28,8 @@ ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-building mr-2"></i>Editing vendor template: <strong><?= $vendor_name ?></strong></h5> <h5 class="modal-title"><i class="fas fa-fw fa-building me-2"></i>Editing vendor template: <strong><?= $vendor_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<span>&times;</span>
</button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
@@ -41,13 +39,13 @@ ob_start();
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-details<?= $vendor_template_id ?>">Details</a> <a class="nav-link active" data-bs-toggle="pill" href="#pills-details<?= $vendor_template_id ?>">Details</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-support<?= $vendor_template_id ?>">Support</a> <a class="nav-link" data-bs-toggle="pill" href="#pills-support<?= $vendor_template_id ?>">Support</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-notes<?= $vendor_template_id ?>">Notes</a> <a class="nav-link" data-bs-toggle="pill" href="#pills-notes<?= $vendor_template_id ?>">Notes</a>
</li> </li>
</ul> </ul>
@@ -60,70 +58,54 @@ ob_start();
<div class="tab-pane fade show active" id="pills-details<?= $vendor_template_id ?>"> <div class="tab-pane fade show active" id="pills-details<?= $vendor_template_id ?>">
<div class="form-group"> <div class="mb-3">
<label>Vendor Name <strong class="text-danger">*</strong></label> <label>Vendor Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-building"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Vendor Name" maxlength="200" value="<?= "$vendor_name" ?>" required> <input type="text" class="form-control" name="name" placeholder="Vendor Name" maxlength="200" value="<?= "$vendor_name" ?>" required>
<div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="global_update_vendor_name" value="1"> <input class="form-check-input" type="checkbox" name="global_update_vendor_name" value="1">
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Description</label> <label>Description</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Description" maxlength="200" value="<?= $vendor_description ?>"> <input type="text" class="form-control" name="description" placeholder="Description" maxlength="200" value="<?= $vendor_description ?>">
<div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="global_update_vendor_description" value="1"> <input class="form-check-input" type="checkbox" name="global_update_vendor_description" value="1">
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Account Number</label> <label>Account Number</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-fingerprint"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-fingerprint"></i></span>
</div>
<input type="text" class="form-control" name="account_number" placeholder="Account number" maxlength="200" value="<?= $vendor_account_number ?>"> <input type="text" class="form-control" name="account_number" placeholder="Account number" maxlength="200" value="<?= $vendor_account_number ?>">
<div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="global_update_vendor_account_number" value="1"> <input class="form-check-input" type="checkbox" name="global_update_vendor_account_number" value="1">
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Account Manager</label> <label>Account Manager</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<input type="text" class="form-control" name="contact_name" maxlength="200" value="<?= $vendor_contact_name ?>" placeholder="Vendor contact name"> <input type="text" class="form-control" name="contact_name" maxlength="200" value="<?= $vendor_contact_name ?>" placeholder="Vendor contact name">
<div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="global_update_vendor_contact_name" value="1"> <input class="form-check-input" type="checkbox" name="global_update_vendor_contact_name" value="1">
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-checkbox"> <div class="form-check">
<input type="checkbox" class="custom-control-input" id="updateVendorsCheckbox<?= $vendor_template_id ?>" name="update_base_vendors" value="1" > <input type="checkbox" class="form-check-input" id="updateVendorsCheckbox<?= $vendor_template_id ?>" name="update_base_vendors" value="1" >
<label class="custom-control-label" for="updateVendorsCheckbox<?= $vendor_template_id ?>">Update All Base Vendors</label> <label class="form-check-label" for="updateVendorsCheckbox<?= $vendor_template_id ?>">Update All Base Vendors</label>
</div> </div>
</div> </div>
@@ -132,13 +114,11 @@ ob_start();
<div class="tab-pane fade" id="pills-support<?= $vendor_template_id ?>"> <div class="tab-pane fade" id="pills-support<?= $vendor_template_id ?>">
<label>Support Phone</label> <label>Support Phone</label>
<div class="form-row"> <div class="row g-2">
<div class="col-8"> <div class="col-8">
<div class="form-group"> <div class="mb-3">
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-phone"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-phone"></i></span>
</div>
<input type="tel" class="form-control col-2" name="phone_country_code" placeholder="+" maxlength="4" value="<?= $vendor_phone_country_code ?>"> <input type="tel" class="form-control col-2" name="phone_country_code" placeholder="+" maxlength="4" value="<?= $vendor_phone_country_code ?>">
<input type="tel" class="form-control" name="phone" maxlength="200" value="<?= $vendor_phone ?>"> <input type="tel" class="form-control" name="phone" maxlength="200" value="<?= $vendor_phone ?>">
</div> </div>
@@ -147,86 +127,64 @@ ob_start();
<div class="col-4"> <div class="col-4">
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" name="extension" placeholder="Prompts" maxlength="200" value="<?= $vendor_extension ?>"> <input type="text" class="form-control" name="extension" placeholder="Prompts" maxlength="200" value="<?= $vendor_extension ?>">
<div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="global_update_vendor_phone" value="1"> <input class="form-check-input" type="checkbox" name="global_update_vendor_phone" value="1">
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Support Hours</label> <label>Support Hours</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="text" class="form-control" name="hours" placeholder="Support Hours" maxlength="200" value="<?= $vendor_hours ?>"> <input type="text" class="form-control" name="hours" placeholder="Support Hours" maxlength="200" value="<?= $vendor_hours ?>">
<div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="global_update_vendor_hours" value="1"> <input class="form-check-input" type="checkbox" name="global_update_vendor_hours" value="1">
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Support Email</label> <label>Support Email</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span>
</div>
<input type="email" class="form-control" name="email" placeholder="Support Email" maxlength="200" value="<?= $vendor_email ?>"> <input type="email" class="form-control" name="email" placeholder="Support Email" maxlength="200" value="<?= $vendor_email ?>">
<div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="global_update_vendor_email" value="1"> <input class="form-check-input" type="checkbox" name="global_update_vendor_email" value="1">
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Support Website URL</label> <label>Support Website URL</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="text" class="form-control" name="website" placeholder="Do not include http(s)://" maxlength="200" value="<?= $vendor_website ?>"> <input type="text" class="form-control" name="website" placeholder="Do not include http(s)://" maxlength="200" value="<?= $vendor_website ?>">
<div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="global_update_vendor_website" value="1"> <input class="form-check-input" type="checkbox" name="global_update_vendor_website" value="1">
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>SLA</label> <label>SLA</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-handshake"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-handshake"></i></span>
</div>
<input type="text" class="form-control" name="sla" placeholder="SLA Response Time" maxlength="200" value="<?= $vendor_sla ?>"> <input type="text" class="form-control" name="sla" placeholder="SLA Response Time" maxlength="200" value="<?= $vendor_sla ?>">
<div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="global_update_vendor_sla" value="1"> <input class="form-check-input" type="checkbox" name="global_update_vendor_sla" value="1">
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Pin/Code</label> <label>Pin/Code</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div>
<input type="text" class="form-control" name="code" placeholder="Access Code or Pin" maxlength="200" value="<?= $vendor_code ?>"> <input type="text" class="form-control" name="code" placeholder="Access Code or Pin" maxlength="200" value="<?= $vendor_code ?>">
<div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="global_update_vendor_code" value="1"> <input class="form-check-input" type="checkbox" name="global_update_vendor_code" value="1">
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -235,13 +193,13 @@ ob_start();
<div class="tab-pane fade" id="pills-notes<?= $vendor_template_id ?>"> <div class="tab-pane fade" id="pills-notes<?= $vendor_template_id ?>">
<div class="form-group"> <div class="mb-3">
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?= $vendor_notes ?></textarea> <textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?= $vendor_notes ?></textarea>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Update Notes Globally?</label> <label>Update Notes Globally?</label>
<input type="checkbox" name="global_update_vendor_notes" value="1"> <input class="form-check-input" type="checkbox" name="global_update_vendor_notes" value="1">
</div> </div>
</div> </div>
@@ -250,8 +208,8 @@ ob_start();
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" class="btn btn-primary text-bold" name="edit_vendor_template"><i class="fa fa-check mr-2"></i>Update Template</button> <button type="submit" class="btn btn-primary text-bold" name="edit_vendor_template"><i class="fa fa-check me-2"></i>Update Template</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@@ -17,33 +17,31 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<div class="card card-dark"> <div class="card">
<div class="card-header py-2"> <div class="card-header bg-dark py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-puzzle-piece mr-2"></i>Access Modules</h3> <h3 class="card-title mt-2"><i class="fas fa-fw fa-puzzle-piece me-2"></i>Access Modules</h3>
<div class="card-tools"> <div class="card-tools">
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/module/module_add.php"> <button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/module/module_add.php">
<i class="fas fa-fw fa-plus mr-2"></i>New Module <i class="fas fa-fw fa-plus me-2"></i>New Module
</button> </button>
</div> </div>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-header py-3">
<form class="mb-4" autocomplete="off"> <form autocomplete="off">
<div class="row"> <div class="row g-2 align-items-center">
<div class="col-md-4"> <div class="col-md-4">
<div class="input-group"> <div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) {echo stripslashes(escapeHtml($q));} ?>" placeholder="Search Modules"> <input type="search" class="form-control" name="q" value="<?php if (isset($q)) {echo stripslashes(escapeHtml($q));} ?>" placeholder="Search Modules">
<div class="input-group-append">
<button class="btn btn-primary"><i class="fa fa-search"></i></button> <button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div> </div>
</div> </div>
</div> </div>
</div>
</form> </form>
<hr> </div>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover"> <table class="table table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?> text-nowrap"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?> text-nowrap">
<tr> <tr>
<th> <th>
@@ -72,20 +70,20 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</td> </td>
<td> <td>
<?php if ($module_id > 6) { ?> <?php if ($module_id > 6) { ?>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" <a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/module/module_edit.php?id=<?= $module_id ?>"> data-modal-url="modals/module/module_edit.php?id=<?= $module_id ?>">
<i class="fas fa-fw fa-user-edit mr-2"></i>Edit <i class="fas fa-fw fa-user-edit me-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_module=<?= $module_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger confirm-link" href="post.php?delete_module=<?= $module_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Delete <i class="fas fa-fw fa-archive me-2"></i>Delete
</a> </a>
</div> </div>
@@ -106,7 +104,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php require_once "../includes/filter_footer.php"; <?php require_once "../includes/filter_footer.php";
?> ?>
</div> </div>
</div>
<?php <?php

View File

@@ -15,9 +15,9 @@ $num_rows = mysqli_num_rows($sql);
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-2"> <div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-credit-card mr-2"></i>Payment Methods</h3> <h3 class="card-title mt-2"><i class="fas fa-fw fa-credit-card me-2"></i>Payment Methods</h3>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/payment_method/payment_method_add.php"><i class="fas fa-plus mr-2"></i>Add Payment Method</button> <button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/payment_method/payment_method_add.php"><i class="fas fa-plus me-2"></i>Add Payment Method</button>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-body">
@@ -63,18 +63,18 @@ $num_rows = mysqli_num_rows($sql);
<td><?= $payment_method_description ?></td> <td><?= $payment_method_description ?></td>
<td><?= $payment_method_created_at ?></td> <td><?= $payment_method_created_at ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" <a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/payment_method/payment_method_edit.php?id=<?= $payment_method_id ?>"> data-modal-url="modals/payment_method/payment_method_edit.php?id=<?= $payment_method_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit me-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_payment_method=<?= $payment_method_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger confirm-link" href="post.php?delete_payment_method=<?= $payment_method_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</a> </a>
</div> </div>
</div> </div>

View File

@@ -20,9 +20,9 @@ $num_rows = mysqli_num_rows($sql);
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-2"> <div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-credit-card mr-2"></i>Payment Providers</h3> <h3 class="card-title mt-2"><i class="fas fa-fw fa-credit-card me-2"></i>Payment Providers</h3>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/payment_provider/payment_provider_add.php"><i class="fas fa-plus mr-2"></i>Add Provider</button> <button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/payment_provider/payment_provider_add.php"><i class="fas fa-plus me-2"></i>Add Provider</button>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-body">
@@ -95,21 +95,21 @@ $num_rows = mysqli_num_rows($sql);
<td><?= $vendor_name ?></td> <td><?= $vendor_name ?></td>
<td><?= $category ?></td> <td><?= $category ?></td>
<td class="text-center"> <td class="text-center">
<a class="badge badge-dark badge-pill p-2" href="saved_payment_methods.php"><?= $saved_payment_count ?></a> <a class="badge bg-dark rounded-pill p-2" href="saved_payment_methods.php"><?= $saved_payment_count ?></a>
</td> </td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" <a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/payment_provider/payment_provider_edit.php?id=<?= $provider_id ?>"> data-modal-url="modals/payment_provider/payment_provider_edit.php?id=<?= $provider_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit me-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_payment_provider=<?= $provider_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger confirm-link" href="post.php?delete_payment_provider=<?= $provider_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i><strong>Delete Provider and</strong> <i class="fas fa-fw fa-trash me-2"></i><strong>Delete Provider and</strong>
<ul class="text-xs"> <ul class="text-xs">
<li>Related Recurring Payments</li> <li>Related Recurring Payments</li>
<li>Related Saved cards</li> <li>Related Saved cards</li>

View File

@@ -0,0 +1,67 @@
<?php
// Canned Responses
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
if (isset($_POST['add_canned_response'])) {
validateCSRFToken();
$name = escapeSql($_POST['name']);
// The body is TinyMCE HTML, so it goes in the way ticket replies and ticket template
// details do - escaped for the query only, and purified where it is rendered
$body = mysqli_real_escape_string($mysqli, $_POST['body']);
// 0 is the general case: offered on every ticket whatever its category
$category_id = intval($_POST['category']);
mysqli_query($mysqli, "INSERT INTO canned_responses SET canned_response_name = '$name', canned_response_body = '$body', canned_response_category_id = $category_id");
$canned_response_id = mysqli_insert_id($mysqli);
logAudit("Canned Response", "Create", "$session_name created canned response $name", 0, $canned_response_id);
flashAlert("Canned Response <strong>$name</strong> created");
redirect();
}
if (isset($_POST['edit_canned_response'])) {
validateCSRFToken();
$canned_response_id = intval($_POST['canned_response_id']);
$name = escapeSql($_POST['name']);
$body = mysqli_real_escape_string($mysqli, $_POST['body']);
$category_id = intval($_POST['category']);
mysqli_query($mysqli, "UPDATE canned_responses SET canned_response_name = '$name', canned_response_body = '$body', canned_response_category_id = $category_id WHERE canned_response_id = $canned_response_id");
logAudit("Canned Response", "Edit", "$session_name edited canned response $name", 0, $canned_response_id);
flashAlert("Canned Response <strong>$name</strong> edited");
redirect();
}
if (isset($_GET['delete_canned_response'])) {
validateCSRFToken();
$canned_response_id = intval($_GET['delete_canned_response']);
$name = escapeSql(getFieldById('canned_responses', $canned_response_id, 'canned_response_name'));
mysqli_query($mysqli, "DELETE FROM canned_responses WHERE canned_response_id = $canned_response_id");
logAudit("Canned Response", "Delete", "$session_name deleted canned response $name", 0, $canned_response_id);
flashAlert("Canned Response <strong>$name</strong> deleted", 'error');
redirect();
}

View File

@@ -42,8 +42,18 @@ if (isset($_POST['edit_company'])) {
} }
} }
// The client record standing in for this company. Verified against the clients table
// rather than trusted from the POST, so a stale or hand-made value cannot leave the
// sidebar pointing at a client that no longer exists. 0 clears the designation.
$internal_client_id = intval($_POST['internal_client_id'] ?? 0);
if ($internal_client_id !== 0 && !mysqli_num_rows(mysqli_query($mysqli, "SELECT client_id FROM clients WHERE client_id = $internal_client_id LIMIT 1"))) {
$internal_client_id = 0;
}
mysqli_query($mysqli,"UPDATE companies SET company_name = '$name', company_address = '$address', company_city = '$city', company_state = '$state', company_zip = '$zip', company_country = '$country', company_phone_country_code = '$phone_country_code', company_phone = '$phone', company_email = '$email', company_website = '$website', company_tax_id = '$tax_id' WHERE company_id = 1"); mysqli_query($mysqli,"UPDATE companies SET company_name = '$name', company_address = '$address', company_city = '$city', company_state = '$state', company_zip = '$zip', company_country = '$country', company_phone_country_code = '$phone_country_code', company_phone = '$phone', company_email = '$email', company_website = '$website', company_tax_id = '$tax_id' WHERE company_id = 1");
mysqli_query($mysqli,"UPDATE settings SET config_internal_client_id = $internal_client_id WHERE company_id = 1");
logAudit("Settings", "Edit", "$session_name edited company details"); logAudit("Settings", "Edit", "$session_name edited company details");
flashAlert("Company <strong>$name</strong> edited"); flashAlert("Company <strong>$name</strong> edited");

View File

@@ -3,7 +3,7 @@
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed"); defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
// Saves and tests return to the tab they were submitted from (see settings_mail.php) // Saves and tests return to the tab they were submitted from (see settings_mail.php)
$mail_tabs = ['smtp', 'imap', 'oauth', 'from', 'tests']; $mail_tabs = ['sending', 'receiving', 'oauth', 'from', 'tests'];
$mail_tab_redirect = 'settings_mail.php'; $mail_tab_redirect = 'settings_mail.php';
if (isset($_POST['tab']) && in_array($_POST['tab'], $mail_tabs, true)) { if (isset($_POST['tab']) && in_array($_POST['tab'], $mail_tabs, true)) {
$mail_tab_redirect .= '?tab=' . $_POST['tab']; $mail_tab_redirect .= '?tab=' . $_POST['tab'];
@@ -249,7 +249,7 @@ if (isset($_POST['test_email_smtp'])) {
$mail = addToMailQueue($data); $mail = addToMailQueue($data);
if ($mail === true) { if ($mail === true) {
flashAlert("Test email queued! <a class='text-bold text-light' href='mail_queue.php'>Check Admin > Mail queue</a>"); flashAlert("Test email queued! Check <strong>Admin &gt; Mail queue</strong>");
} else { } else {
flashAlert("Failed to add test mail to queue", 'error'); flashAlert("Failed to add test mail to queue", 'error');
} }

View File

@@ -33,7 +33,13 @@ if (isset($_POST['edit_ticket_status'])) {
$order = intval($_POST['order']); $order = intval($_POST['order']);
$status = intval($_POST['status']); $status = intval($_POST['status']);
// Built-in statuses have fixed SLA behaviour. The modal renders it read-only, and a
// read-only field submits nothing - so the value is decided here rather than taken
// from the POST, which also means a hand-made request cannot change it.
$pauses_sla = getTicketStatusSlaLock($ticket_status_id);
if (is_null($pauses_sla)) {
$pauses_sla = intval($_POST['pauses_sla'] ?? 0); $pauses_sla = intval($_POST['pauses_sla'] ?? 0);
}
mysqli_query($mysqli, "UPDATE ticket_statuses SET ticket_status_name = '$name', ticket_status_color = '$color', ticket_status_order = $order, ticket_status_active = $status, ticket_status_pauses_sla = $pauses_sla WHERE ticket_status_id = $ticket_status_id"); mysqli_query($mysqli, "UPDATE ticket_statuses SET ticket_status_name = '$name', ticket_status_color = '$color', ticket_status_order = $order, ticket_status_active = $status, ticket_status_pauses_sla = $pauses_sla WHERE ticket_status_id = $ticket_status_id");

View File

@@ -2,12 +2,53 @@
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed"); defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
/*
* Hands the update to cron instead of running it in this request. scripts/update_cli.php
* replaces the files this request is executing from and then applies the migrations that
* came with them, which is not something to do half way through a page load - and on a host
* where PHP cannot run external commands it is the only way to update the application at all.
*
* The row is written as well as the settings column: config_update_queued_at is what
* cron/app_update.php acts on, and cron_job_run_now is what gets the dispatcher to look
* before the job's own schedule comes round.
*/
if (isset($_GET['queue_update'])) {
validateCSRFToken();
enforceAdminPermission();
// The files can be newer than the schema - that is the window this whole page exists to
// close - and the column the queue is written to arrives with a migration
if (!settingsColumnExists($mysqli, 'config_update_queued_at')) {
flashAlert("Apply the database update first - queueing needs a schema change this install has not caught up with yet.", 'error');
redirect();
}
mysqli_query($mysqli, "UPDATE settings SET config_update_queued_at = '" . date('Y-m-d H:i:s') . "' WHERE company_id = 1");
mysqli_query($mysqli, "UPDATE cron_jobs SET cron_job_run_now = 1 WHERE cron_job_name = 'app_update'");
logAudit("App", "Update", "$session_name queued an update to be applied by cron");
flashAlert("Update queued - cron will start it within a minute.");
redirect();
}
if (isset($_GET['update'])) { if (isset($_GET['update'])) {
validateCSRFToken(); validateCSRFToken();
enforceAdminPermission(); enforceAdminPermission();
// Reached only from buttons this install cannot draw without a shell, so anything
// arriving here without one is a crafted request rather than somebody's mistake
if (!shellCommandsAvailable()) {
flashAlert("PHP on this server cannot run Git. Queue the update instead and cron will apply it.", 'error');
redirect();
}
// git fetch downloads the latest from the remote without merging or rebasing anything. // git fetch downloads the latest from the remote without merging or rebasing anything.
// The hard reset then throws away every local change and makes the working tree match // The hard reset then throws away every local change and makes the working tree match
// the tracked branch exactly. // the tracked branch exactly.

View File

@@ -60,22 +60,22 @@ if (isset($_GET['project_template_id'])) {
</ol> </ol>
<!-- Project Header --> <!-- Project Header -->
<div class="card card-body"> <div class="card card-body mb-3">
<div class="row"> <div class="row">
<div class="col-sm-4"> <div class="col-sm-4">
<div class="media"> <div class="d-flex">
<i class="fa fa-fw fa-2x fa-project-diagram text-secondary mr-3"></i> <i class="fa fa-fw fa-2x fa-project-diagram text-secondary me-3"></i>
<div class="media-body"> <div class="flex-grow-1">
<h3 class="mb-0"><?= $project_template_name ?><span class='badge badge-pill badge-info ml-2'>Template</span></h3> <h3 class="mb-0"><?= $project_template_name ?><span class='badge rounded-pill bg-info ms-2'>Template</span></h3>
<div><small class="text-secondary"><?= $project_template_description ?></small></div> <div><small class="text-secondary"><?= $project_template_description ?></small></div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm-3"> <div class="col-sm-3">
<div class="media"> <div class="d-flex">
<i class="fa fa-fw fa-2x fa-life-ring text-secondary mr-3"></i> <i class="fa fa-fw fa-2x fa-life-ring text-secondary me-3"></i>
<div class="media-body"> <div class="flex-grow-1">
<div>Ticket Templates</div> <div>Ticket Templates</div>
<h3 class="mb-0"><?= $ticket_template_count ?></h3> <h3 class="mb-0"><?= $ticket_template_count ?></h3>
</div> </div>
@@ -83,9 +83,9 @@ if (isset($_GET['project_template_id'])) {
</div> </div>
<div class="col-sm-3"> <div class="col-sm-3">
<div class="media"> <div class="d-flex">
<i class="fa fa-fw fa-2x fa-tasks text-secondary mr-3"></i> <i class="fa fa-fw fa-2x fa-tasks text-secondary me-3"></i>
<div class="media-body"> <div class="flex-grow-1">
<div>Task Templates</div> <div>Task Templates</div>
<h3 class="mb-0"><?= $task_template_count ?></h3> <h3 class="mb-0"><?= $task_template_count ?></h3>
</div> </div>
@@ -93,28 +93,28 @@ if (isset($_GET['project_template_id'])) {
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
<div class="btn-group float-right"> <div class="btn-group float-end">
<button type="button" class="btn btn-primary btn-sm ajax-modal" href="#" data-modal-url="modals/project_template/project_template_ticket_template_add.php?project_template_id=<?= $project_template_id ?>"> <button type="button" class="btn btn-primary btn-sm ajax-modal" href="#" data-modal-url="modals/project_template/project_template_ticket_template_add.php?project_template_id=<?= $project_template_id ?>">
<i class="fas fa-fw fa-plus mr-2"></i>Add Ticket Template <i class="fas fa-fw fa-plus me-2"></i>Add Ticket Template
</button> </button>
<div class="dropdown dropleft text-center ml-3"> <div class="dropdown dropstart text-center ms-3">
<button class="btn btn-secondary btn-sm" type="button" id="dropdownMenuButton" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown">
<i class="fas fa-fw fa-ellipsis-v"></i> <i class="fas fa-fw fa-ellipsis-v"></i>
</button> </button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/project_template/project_template_edit.php?project_template_id=<?= $project_template_id ?>"> <a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/project_template/project_template_edit.php?project_template_id=<?= $project_template_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit Template <i class="fas fa-fw fa-edit me-2"></i>Edit Template
</a> </a>
<?php if ($session_user_role == 3) { ?> <?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?archive_project_template=<?= $project_template_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?archive_project_template=<?= $project_template_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive (not yet implemented) <i class="fas fa-fw fa-archive me-2"></i>Archive (not yet implemented)
</a> </a>
<?php } ?> <?php } ?>
<?php if ($session_user_role == 3) { ?> <?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_project_template=<?= $project_template_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger confirm-link" href="post.php?delete_project_template=<?= $project_template_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</a> </a>
<?php } ?> <?php } ?>
</div> </div>
@@ -131,7 +131,7 @@ if (isset($_GET['project_template_id'])) {
<?php if (mysqli_num_rows($sql_ticket_templates) > 0) { ?> <?php if (mysqli_num_rows($sql_ticket_templates) > 0) { ?>
<div class="card card-body card-outline card-dark mb-3"> <div class="card card-body card-outline card-dark mb-3">
<h5 class="text-secondary"><i class="fa fa-fw fa-life-ring mr-2"></i>Project Ticket Templates</h5> <h5 class="text-secondary"><i class="fa fa-fw fa-life-ring me-2"></i>Project Ticket Templates</h5>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover" id="ticket_templates"> <table class="table table-striped table-borderless table-hover" id="ticket_templates">
<thead class="text-dark"> <thead class="text-dark">
@@ -158,7 +158,7 @@ if (isset($_GET['project_template_id'])) {
<tr data-task-id="<?= $ticket_template_id ?>"> <tr data-task-id="<?= $ticket_template_id ?>">
<td> <td>
<a href="#" class="drag-handle"><i class="fas fa-bars text-muted mr-2"></i></a> <a href="#" class="drag-handle"><i class="fas fa-bars text-muted me-2"></i></a>
<a href="ticket_template.php?ticket_template_id=<?= $ticket_template_id ?>"> <a href="ticket_template.php?ticket_template_id=<?= $ticket_template_id ?>">
<?= $ticket_template_name ?> <?= $ticket_template_name ?>
</a> </a>
@@ -192,7 +192,7 @@ if (isset($_GET['project_template_id'])) {
<!-- Task Templates Card --> <!-- Task Templates Card -->
<?php if (mysqli_num_rows($sql_task_templates) > 0) { ?> <?php if (mysqli_num_rows($sql_task_templates) > 0) { ?>
<div class="card card-body card-outline card-dark"> <div class="card card-body card-outline card-dark">
<h5 class="text-secondary"><i class="fas fa-fw fa-tasks mr-2"></i>Project Task Templates</h5> <h5 class="text-secondary"><i class="fas fa-fw fa-tasks me-2"></i>Project Task Templates</h5>
<table class="table"> <table class="table">
<?php <?php
while($row = mysqli_fetch_assoc($sql_task_templates)){ while($row = mysqli_fetch_assoc($sql_task_templates)){
@@ -201,7 +201,7 @@ if (isset($_GET['project_template_id'])) {
?> ?>
<tr> <tr>
<td> <td>
<i class="far fa-fw fa-check-square text-primary mr-3"></i> <i class="far fa-fw fa-check-square text-primary me-3"></i>
<?= $task_template_name ?> <?= $task_template_name ?>
</td> </td>
</tr> </tr>
@@ -227,7 +227,7 @@ new Sortable(document.querySelector('table#ticket_templates tbody'), {
order: index order: index
})); }));
$.post('/agent/ajax.php', { itflowPostForm('/agent/ajax.php', {
update_project_template_ticket_order: true, update_project_template_ticket_order: true,
csrf_token: '<?= $_SESSION['csrf_token'] ?>', csrf_token: '<?= $_SESSION['csrf_token'] ?>',
project_template_id: <?= $project_template_id ?>, project_template_id: <?= $project_template_id ?>,

View File

@@ -19,34 +19,32 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<div class="card card-dark"> <div class="card">
<div class="card-header py-2"> <div class="card-header bg-dark py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-project-diagram mr-2"></i>Project Templates</h3> <h3 class="card-title mt-2"><i class="fas fa-fw fa-project-diagram me-2"></i>Project Templates</h3>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/project_template/project_template_add.php"><i class="fas fa-plus mr-2"></i>New Project Template</button> <button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/project_template/project_template_add.php"><i class="fas fa-plus me-2"></i>New Project Template</button>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-header py-3">
<form autocomplete="off"> <form autocomplete="off">
<div class="row"> <div class="row g-2 align-items-center">
<div class="col-md-4"> <div class="col-md-4">
<div class="input-group mb-3 mb-md-0"> <div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if(isset($q)){ echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search Project Templates"> <input type="search" class="form-control" name="q" value="<?php if(isset($q)){ echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search Project Templates">
<div class="input-group-append">
<button class="btn btn-dark"><i class="fa fa-search"></i></button> <button class="btn btn-dark"><i class="fa fa-search"></i></button>
</div> </div>
</div> </div>
</div>
<div class="col-md-8"> <div class="col-md-8">
</div> </div>
</div> </div>
</form> </form>
<hr> </div>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover"> <table class="table table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if($num_rows[0] == 0){ echo "d-none"; } ?>"> <thead class="text-dark <?php if($num_rows[0] == 0){ echo "d-none"; } ?>">
<tr> <tr>
<th> <th>
@@ -89,9 +87,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tr> <tr>
<td> <td>
<a class="text-dark" href="project_template.php?project_template_id=<?= $project_template_id ?>"> <a class="text-dark" href="project_template.php?project_template_id=<?= $project_template_id ?>">
<div class="media"> <div class="d-flex">
<i class="fa fa-fw fa-2x fa-project-diagram mr-3"></i> <i class="fa fa-fw fa-2x fa-project-diagram me-3"></i>
<div class="media-body"> <div class="flex-grow-1">
<div> <div>
<?= $project_template_name ?> <?= $project_template_name ?>
</div> </div>
@@ -105,18 +103,18 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<td><?= $ticket_template_count ?></td> <td><?= $ticket_template_count ?></td>
<td><?= $task_template_count ?></td> <td><?= $task_template_count ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/project_template/project_template_edit.php?project_template_id=<?= $project_template_id ?>"> <a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/project_template/project_template_edit.php?project_template_id=<?= $project_template_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit me-2"></i>Edit
</a> </a>
<?php if($session_user_role == 3) { ?> <?php if($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_project_template=<?= $project_template_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_project_template=<?= $project_template_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</a> </a>
<?php } ?> <?php } ?>
</div> </div>
@@ -135,7 +133,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
<?php require_once "../includes/filter_footer.php"; ?> <?php require_once "../includes/filter_footer.php"; ?>
</div> </div>
</div>
<?php <?php
require_once "../includes/footer.php"; require_once "../includes/footer.php";

View File

@@ -18,33 +18,31 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<div class="card card-dark"> <div class="card">
<div class="card-header py-2"> <div class="card-header bg-dark py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-user-shield mr-2"></i>Roles</h3> <h3 class="card-title mt-2"><i class="fas fa-fw fa-user-shield me-2"></i>Roles</h3>
<div class="card-tools"> <div class="card-tools">
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/role/role_add.php"> <button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/role/role_add.php">
<i class="fas fa-fw fa-user-plus mr-2"></i>New Role <i class="fas fa-fw fa-user-plus me-2"></i>New Role
</button> </button>
</div> </div>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-header py-3">
<form class="mb-4" autocomplete="off"> <form autocomplete="off">
<div class="row"> <div class="row g-2 align-items-center">
<div class="col-md-4"> <div class="col-md-4">
<div class="input-group"> <div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) {echo stripslashes(escapeHtml($q));} ?>" placeholder="Search Roles"> <input type="search" class="form-control" name="q" value="<?php if (isset($q)) {echo stripslashes(escapeHtml($q));} ?>" placeholder="Search Roles">
<div class="input-group-append">
<button class="btn btn-primary"><i class="fa fa-search"></i></button> <button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div> </div>
</div> </div>
</div> </div>
</div>
</form> </form>
<hr> </div>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover"> <table class="table table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?> text-nowrap"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?> text-nowrap">
<tr> <tr>
<th> <th>
@@ -95,9 +93,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tr> <tr>
<td> <td>
<a class="<?php if ($role_id !== 3) { ?> ajax-modal" data-modal-url="modals/role/role_edit.php?id=<?= $role_id ?>" <?php } ?> href="#"> <a class="<?php if ($role_id !== 3) { ?> ajax-modal" data-modal-url="modals/role/role_edit.php?id=<?= $role_id ?>" <?php } ?> href="#">
<div class="media"> <div class="d-flex">
<i class="fas fa-fw fa-2x fa-user-shield text-dark mr-2"></i> <i class="fas fa-fw fa-2x fa-user-shield text-dark me-2"></i>
<div class="media-body"> <div class="flex-grow-1">
<div><?= $role_name ?></div> <div><?= $role_name ?></div>
<div><small class="text-secondary"><?= $role_description ?></small></div> <div><small class="text-secondary"><?= $role_description ?></small></div>
</div> </div>
@@ -108,21 +106,21 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<td><?= $role_admin ? 'Yes' : 'No' ?></td> <td><?= $role_admin ? 'Yes' : 'No' ?></td>
<td> <td>
<?php if ($role_id !== 3) { ?> <?php if ($role_id !== 3) { ?>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" <a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/role/role_edit.php?id=<?= $role_id ?>"> data-modal-url="modals/role/role_edit.php?id=<?= $role_id ?>">
<i class="fas fa-fw fa-user-edit mr-2"></i>Edit <i class="fas fa-fw fa-user-edit me-2"></i>Edit
</a> </a>
<?php if (empty($role_archived_at) && $role_user_count == 0) { ?> <?php if (empty($role_archived_at) && $role_user_count == 0) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_role=<?= $role_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger confirm-link" href="post.php?archive_role=<?= $role_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive <i class="fas fa-fw fa-archive me-2"></i>Archive
</a> </a>
<?php } ?> <?php } ?>
@@ -144,7 +142,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php require_once "../includes/filter_footer.php"; <?php require_once "../includes/filter_footer.php";
?> ?>
</div> </div>
</div>
<?php <?php
require_once "../includes/footer.php"; require_once "../includes/footer.php";

View File

@@ -43,28 +43,26 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<li class="breadcrumb-item active">Saved Payment Methods (Stripe)</li> <li class="breadcrumb-item active">Saved Payment Methods (Stripe)</li>
</ol> </ol>
<div class="card card-dark"> <div class="card">
<div class="card-header"> <div class="card-header bg-dark py-2">
<h3 class="card-title"><i class="fas fa-fw fa-credit-card mr-2"></i>Saved Payment Methods</h3> <h3 class="card-title"><i class="fas fa-fw fa-credit-card me-2"></i>Saved Payment Methods</h3>
</div> </div>
<div class="card-body"> <div class="card-header py-3">
<form class="mb-4" autocomplete="off"> <form autocomplete="off">
<div class="row"> <div class="row g-2 align-items-center">
<div class="col-md-4"> <div class="col-md-4">
<div class="input-group"> <div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) {echo stripslashes(escapeHtml($q));} ?>" placeholder="Search Saved Payment Methods"> <input type="search" class="form-control" name="q" value="<?php if (isset($q)) {echo stripslashes(escapeHtml($q));} ?>" placeholder="Search Saved Payment Methods">
<div class="input-group-append">
<button class="btn btn-primary"><i class="fa fa-search"></i></button> <button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div> </div>
</div> </div>
</div>
<div class="col-md-8"> <div class="col-md-8">
</div> </div>
</div> </div>
</form> </form>
<hr> </div>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover"> <table class="table table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if ($num_rows == 0) { echo "d-none"; } ?>"> <thead class="text-dark <?php if ($num_rows == 0) { echo "d-none"; } ?>">
<tr> <tr>
<th> <th>
@@ -133,7 +131,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<td><?= $saved_payment_created_at ?></td> <td><?= $saved_payment_created_at ?></td>
<td> <td>
<a class="btn btn-outline-danger confirm-link" href="post.php?delete_saved_payment=<?= $saved_payment_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="btn btn-outline-danger confirm-link" href="post.php?delete_saved_payment=<?= $saved_payment_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</a> </a>
</td> </td>
</tr> </tr>
@@ -150,7 +148,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
<?php require_once "../includes/filter_footer.php"; ?> <?php require_once "../includes/filter_footer.php"; ?>
</div> </div>
</div>
<?php <?php
require_once "../includes/footer.php"; require_once "../includes/footer.php";

View File

@@ -29,7 +29,7 @@ $company_initials = escapeHtml(initials($company_name));
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header"> <div class="card-header">
<h3 class="card-title"><i class="fas fa-fw fa-briefcase mr-2"></i>Company Details</h3> <h3 class="card-title"><i class="fas fa-fw fa-briefcase me-2"></i>Company Details</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> <form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
@@ -39,73 +39,61 @@ $company_initials = escapeHtml(initials($company_name));
<div class="col-md-3 text-center"> <div class="col-md-3 text-center">
<?php if ($company_logo) { ?> <?php if ($company_logo) { ?>
<img class="img-thumbnail" src="<?= "../uploads/settings/$company_logo" ?>"> <img class="img-thumbnail" src="<?= "../uploads/settings/$company_logo" ?>">
<a href="post.php?remove_company_logo&csrf_token=<?= $_SESSION['csrf_token'] ?>" class="btn btn-outline-danger btn-block">Remove Logo</a> <a href="post.php?remove_company_logo&csrf_token=<?= $_SESSION['csrf_token'] ?>" class="btn btn-outline-danger w-100">Remove Logo</a>
<hr> <hr>
<?php } ?> <?php } ?>
<div class="form-group"> <div class="mb-3">
<label>Upload company logo</label> <label>Upload company logo</label>
<input type="file" class="form-control-file" name="file" accept=".jpg, .jpeg, .png"> <input type="file" class="form-control" name="file" accept=".jpg, .jpeg, .png">
</div> </div>
</div> </div>
<div class="col-md-9"> <div class="col-md-9">
<div class="form-group"> <div class="mb-3">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-building"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Company Name" maxlength="200" value="<?= $company_name ?>" required> <input type="text" class="form-control" name="name" placeholder="Company Name" maxlength="200" value="<?= $company_name ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Address</label> <label>Address</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<input type="text" class="form-control" name="address" placeholder="Street Address" maxlength="200" value="<?= $company_address ?>"> <input type="text" class="form-control" name="address" placeholder="Street Address" maxlength="200" value="<?= $company_address ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>City</label> <label>City</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-city"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-city"></i></span>
</div>
<input type="text" class="form-control" name="city" placeholder="City" maxlength="200" value="<?= $company_city ?>"> <input type="text" class="form-control" name="city" placeholder="City" maxlength="200" value="<?= $company_city ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>State / Province</label> <label>State / Province</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-flag"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-flag"></i></span>
</div>
<input type="text" class="form-control" name="state" placeholder="State or Province" maxlength="200" value="<?= $company_state ?>"> <input type="text" class="form-control" name="state" placeholder="State or Province" maxlength="200" value="<?= $company_state ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Postal Code</label> <label>Postal Code</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fab fa-fw fa-usps"></i></span> <span class="input-group-text"><i class="fab fa-fw fa-usps"></i></span>
</div>
<input type="text" class="form-control" name="zip" placeholder="Zip or Postal Code" maxlength="200" value="<?= $company_zip ?>"> <input type="text" class="form-control" name="zip" placeholder="Zip or Postal Code" maxlength="200" value="<?= $company_zip ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Country</label> <label>Country</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe-americas"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-globe-americas"></i></span>
</div> <select class="form-select select2" name="country">
<select class="form-control select2" name="country">
<option value="">- Country -</option> <option value="">- Country -</option>
<?php foreach($countries_array as $country_name) { ?> <?php foreach($countries_array as $country_name) { ?>
<option <?php if ($company_country == $country_name) { echo "selected"; } ?>><?= $country_name ?></option> <option <?php if ($company_country == $country_name) { echo "selected"; } ?>><?= $country_name ?></option>
@@ -115,13 +103,11 @@ $company_initials = escapeHtml(initials($company_name));
</div> </div>
<label>Phone</label> <label>Phone</label>
<div class="form-row"> <div class="row g-2">
<div class="col-md-9"> <div class="col-md-9">
<div class="form-group"> <div class="mb-3">
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-phone"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-phone"></i></span>
</div>
<input type="tel" class="form-control col-2" name="phone_country_code" value="<?= $company_phone_country_code ?>" placeholder="+" maxlength="4"> <input type="tel" class="form-control col-2" name="phone_country_code" value="<?= $company_phone_country_code ?>" placeholder="+" maxlength="4">
<input type="tel" class="form-control" name="phone" value="<?= $company_phone ?>" placeholder="Phone Number" maxlength="200"> <input type="tel" class="form-control" name="phone" value="<?= $company_phone ?>" placeholder="Phone Number" maxlength="200">
</div> </div>
@@ -129,39 +115,54 @@ $company_initials = escapeHtml(initials($company_name));
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Email</label> <label>Email</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span>
</div>
<input type="email" class="form-control" name="email" placeholder="Email address" maxlength="200" value="<?= $company_email ?>"> <input type="email" class="form-control" name="email" placeholder="Email address" maxlength="200" value="<?= $company_email ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Website</label> <label>Website</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="text" class="form-control" name="website" placeholder="Website address" maxlength="200" value="<?= $company_website ?>"> <input type="text" class="form-control" name="website" placeholder="Website address" maxlength="200" value="<?= $company_website ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Tax ID</label> <label>Tax ID</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-balance-scale"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-balance-scale"></i></span>
</div>
<input type="text" class="form-control" name="tax_id" value="<?= $company_tax_id ?>" placeholder="Tax ID" maxlength="200"> <input type="text" class="form-control" name="tax_id" value="<?= $company_tax_id ?>" placeholder="Tax ID" maxlength="200">
</div> </div>
</div> </div>
<hr> <hr>
<button type="submit" name="edit_company" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <div class="mb-3">
<label>My Company's Client Record</label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-fw fa-house-user"></i></span>
<select class="form-select select2" name="internal_client_id">
<option value="0">None</option>
<?php
$sql_internal_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
while ($row_internal_client = mysqli_fetch_assoc($sql_internal_clients)) {
$internal_client_id_select = intval($row_internal_client['client_id']);
$internal_client_name_select = escapeHtml($row_internal_client['client_name']);
?>
<option <?php if ($config_internal_client_id == $internal_client_id_select) { echo "selected"; } ?> value="<?= $internal_client_id_select ?>"><?= $internal_client_name_select ?></option>
<?php } ?>
</select>
</div>
<small class="text-muted">If you keep a client record for your own company - for internal tickets, documentation, assets and credentials - point it out here. Your company name in the sidebar then links straight to it.</small>
</div>
<hr>
<button type="submit" name="edit_company" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -26,36 +26,34 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<div class="card card-dark"> <div class="card">
<div class="card-header py-2"> <div class="card-header bg-dark py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-th-list mr-2"></i><?= escapeHtml($table) ?> Fields</h3> <h3 class="card-title mt-2"><i class="fa fa-fw fa-th-list me-2"></i><?= escapeHtml($table) ?> Fields</h3>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#createCustomFieldModal"><i class="fas fa-plus mr-2"></i>Create</button> <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#createCustomFieldModal"><i class="fas fa-plus me-2"></i>Create</button>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-header py-3">
<form autocomplete="off"> <form autocomplete="off">
<input type="hidden" name="table" value="<?= escapeHtml($table) ?>"> <input type="hidden" name="table" value="<?= escapeHtml($table) ?>">
<div class="row"> <div class="row g-2 align-items-center">
<div class="col-sm-4 mb-2"> <div class="col-sm-4">
<div class="input-group"> <div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search"> <input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search">
<div class="input-group-append">
<button class="btn btn-primary"><i class="fa fa-search"></i></button> <button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div> </div>
</div> </div>
</div>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="btn-group float-right"> <div class="btn-group float-end">
<a href="?table=client_assets" class="btn <?php if ($table == 'client_assets') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>">Assets</a> <a href="?table=client_assets" class="btn <?php if ($table == 'client_assets') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>">Assets</a>
<a href="?table=clients" class="btn <?php if ($table == 'clients') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>">Clients</a> <a href="?table=clients" class="btn <?php if ($table == 'clients') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>">Clients</a>
</div> </div>
</div> </div>
</div> </div>
</form> </form>
<hr> </div>
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover"> <table class="table table-striped table-borderless table-hover mb-0">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr> <tr>
<th><a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=custom_field_label&order=<?= $disp ?>">Label</a></th> <th><a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=custom_field_label&order=<?= $disp ?>">Label</a></th>
@@ -75,20 +73,20 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<tr> <tr>
<td><a class="text-dark" href="#" data-toggle="modal" data-target="#editCustomFieldModal<?= $custom_field_id ?>"><?= $custom_field_label ?></a></td> <td><a class="text-dark" href="#" data-bs-toggle="modal" data-bs-target="#editCustomFieldModal<?= $custom_field_id ?>"><?= $custom_field_label ?></a></td>
<td><?= $custom_field_type ?></td> <td><?= $custom_field_type ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editCustomFieldModal<?= $custom_field_id ?>"> <a class="dropdown-item" href="#" data-bs-toggle="modal" data-bs-target="#editCustomFieldModal<?= $custom_field_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit me-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_custom_field=<?= $custom_field_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_custom_field=<?= $custom_field_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash me-2"></i>Delete
</a> </a>
</div> </div>
</div> </div>
@@ -112,7 +110,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php require_once "../includes/filter_footer.php"; <?php require_once "../includes/filter_footer.php";
?> ?>
</div> </div>
</div>
<?php <?php
require_once "custom_field_create_modal.php"; require_once "custom_field_create_modal.php";

View File

@@ -23,19 +23,17 @@ $net_terms_array = array (
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-cogs mr-2"></i>Defaults</h3> <h3 class="card-title"><i class="fas fa-fw fa-cogs me-2"></i>Defaults</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="form-group"> <div class="mb-3">
<label>Start Page</label> <label>Start Page</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-home"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-home"></i></span>
</div> <select class="form-select select2" name="start_page" data-tags="true" required>
<select class="form-control select2" name="start_page" data-tags="true" required>
<?php if (!in_array($config_start_page, array_keys($start_page_select_array))) { ?> <?php if (!in_array($config_start_page, array_keys($start_page_select_array))) { ?>
<option selected> <?= escapeHtml($config_start_page) ?></option> <option selected> <?= escapeHtml($config_start_page) ?></option>
<?php } ?> <?php } ?>
@@ -49,13 +47,11 @@ $net_terms_array = array (
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Calendar</label> <label>Calendar</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div> <select class="form-select select2" name="calendar">
<select class="form-control select2" name="calendar">
<option value="0">- None -</option> <option value="0">- None -</option>
<?php <?php
@@ -72,13 +68,11 @@ $net_terms_array = array (
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Transfer From Account</label> <label>Transfer From Account</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-exchange-alt"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-exchange-alt"></i></span>
</div> <select class="form-select select2" name="transfer_from_account">
<select class="form-control select2" name="transfer_from_account">
<option value="0">- None -</option> <option value="0">- None -</option>
<?php <?php
@@ -95,13 +89,11 @@ $net_terms_array = array (
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Transfer To Account</label> <label>Transfer To Account</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-exchange-alt"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-exchange-alt"></i></span>
</div> <select class="form-select select2" name="transfer_to_account">
<select class="form-control select2" name="transfer_to_account">
<option value="0">- None -</option> <option value="0">- None -</option>
<?php <?php
@@ -118,13 +110,11 @@ $net_terms_array = array (
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Payment Account</label> <label>Payment Account</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span>
</div> <select class="form-select select2" name="payment_account">
<select class="form-control select2" name="payment_account">
<option value="0">- None -</option> <option value="0">- None -</option>
<?php <?php
@@ -143,13 +133,11 @@ $net_terms_array = array (
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Expense Account</label> <label>Expense Account</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
</div> <select class="form-select select2" name="expense_account">
<select class="form-control select2" name="expense_account">
<option value="0">- None -</option> <option value="0">- None -</option>
<?php <?php
@@ -166,13 +154,11 @@ $net_terms_array = array (
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Payment Method</label> <label>Payment Method</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span>
</div> <select class="form-select select2" name="payment_method">
<select class="form-control select2" name="payment_method">
<option value="">- None -</option> <option value="">- None -</option>
<?php <?php
@@ -188,13 +174,11 @@ $net_terms_array = array (
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Expense Payment Method</label> <label>Expense Payment Method</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span>
</div> <select class="form-select select2" name="expense_payment_method">
<select class="form-control select2" name="expense_payment_method">
<option value="">- None -</option> <option value="">- None -</option>
<?php <?php
@@ -210,13 +194,11 @@ $net_terms_array = array (
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Net Terms</label> <label>Net Terms</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div> <select class="form-select select2" name="net_terms">
<select class="form-control select2" name="net_terms">
<?php foreach ($net_terms_array as $net_term_value => $net_term_name) { ?> <?php foreach ($net_terms_array as $net_term_value => $net_term_name) { ?>
<option <?php if ($config_default_net_terms == $net_term_value) { <option <?php if ($config_default_net_terms == $net_term_value) {
echo "selected"; echo "selected";
@@ -226,19 +208,17 @@ $net_terms_array = array (
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Client Hourly Rate</label> <label>Client Hourly Rate</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div>
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="hourly_rate" value="<?= number_format($config_default_hourly_rate, 2, '.', '') ?>" placeholder="0.00" required> <input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="hourly_rate" value="<?= number_format($config_default_hourly_rate, 2, '.', '') ?>" placeholder="0.00" required>
</div> </div>
</div> </div>
<hr> <hr>
<button type="submit" name="edit_default_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_default_settings" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
</form> </form>
</div> </div>

View File

@@ -4,7 +4,7 @@ require_once "includes/inc_all_admin.php";
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-file-invoice mr-2"></i>Invoice Settings</h3> <h3 class="card-title"><i class="fas fa-fw fa-file-invoice me-2"></i>Invoice Settings</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
@@ -12,66 +12,58 @@ require_once "includes/inc_all_admin.php";
<h4>Invoice</h4> <h4>Invoice</h4>
<div class="form-group"> <div class="mb-3">
<label>Invoice Prefix</label> <label>Invoice Prefix</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div>
<input type="text" class="form-control" name="config_invoice_prefix" placeholder="Invoice Prefix" maxlength="200" value="<?= escapeHtml($config_invoice_prefix) ?>" required> <input type="text" class="form-control" name="config_invoice_prefix" placeholder="Invoice Prefix" maxlength="200" value="<?= escapeHtml($config_invoice_prefix) ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Next Number</label> <label>Next Number</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div>
<input type="number" min="0" class="form-control" name="config_invoice_next_number" placeholder="Next Invoice Number" value="<?= intval($config_invoice_next_number) ?>" required> <input type="number" min="0" class="form-control" name="config_invoice_next_number" placeholder="Next Invoice Number" value="<?= intval($config_invoice_next_number) ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Invoice Footer</label> <label>Invoice Footer</label>
<textarea class="form-control" rows="4" name="config_invoice_footer"><?= escapeHtml($config_invoice_footer) ?></textarea> <textarea class="form-control" rows="4" name="config_invoice_footer"><?= escapeHtml($config_invoice_footer) ?></textarea>
</div> </div>
<h5>Show Tax ID On Invoices</h5> <h5>Show Tax ID On Invoices</h5>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_invoice_show_tax_id" <?php if ($config_invoice_show_tax_id == 1) { echo "checked"; } ?> value="1" id="customSwitch1"> <input type="checkbox" class="form-check-input" name="config_invoice_show_tax_id" <?php if ($config_invoice_show_tax_id == 1) { echo "checked"; } ?> value="1" id="customSwitch1">
<label class="custom-control-label" for="customSwitch1">Show Tax ID</label> <label class="form-check-label" for="customSwitch1">Show Tax ID</label>
</div> </div>
</div> </div>
<h5>Invoice Late Fees</h5> <h5>Invoice Late Fees</h5>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_invoice_late_fee_enable" <?php if ($config_invoice_late_fee_enable == 1) { echo "checked"; } ?> value="1" id="customSwitch2"> <input type="checkbox" class="form-check-input" name="config_invoice_late_fee_enable" <?php if ($config_invoice_late_fee_enable == 1) { echo "checked"; } ?> value="1" id="customSwitch2">
<label class="custom-control-label" for="customSwitch2">Enable Late Fee</label> <label class="form-check-label" for="customSwitch2">Enable Late Fee</label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Late Fee %</label> <label>Late Fee %</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-percent"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-percent"></i></span>
</div>
<input type="number" class="form-control" min="0" max="100" step="0.01" name="config_invoice_late_fee_percent" value="<?= $config_invoice_late_fee_percent ?>"> <input type="number" class="form-control" min="0" max="100" step="0.01" name="config_invoice_late_fee_percent" value="<?= $config_invoice_late_fee_percent ?>">
</div> </div>
<small class="text-secondary">We recommend updating the invoice footer to include policies on your late charges. This will be applied every 30 days after the invoice Due Date.</small> <small class="text-secondary">We recommend updating the invoice footer to include policies on your late charges. This will be applied every 30 days after the invoice Due Date.</small>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Email address to notify when invoices are paid online <small class="text-secondary">(Ideally a distribution list/shared mailbox)</small></label> <label>Email address to notify when invoices are paid online <small class="text-secondary">(Ideally a distribution list/shared mailbox)</small></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-bell"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-bell"></i></span>
</div>
<input type="email" class="form-control" name="config_invoice_paid_notification_email" placeholder="Address to notify for paid invoices, leave blank for none" maxlength="200" value="<?= escapeHtml($config_invoice_paid_notification_email) ?>"> <input type="email" class="form-control" name="config_invoice_paid_notification_email" placeholder="Address to notify for paid invoices, leave blank for none" maxlength="200" value="<?= escapeHtml($config_invoice_paid_notification_email) ?>">
</div> </div>
</div> </div>
@@ -80,22 +72,18 @@ require_once "includes/inc_all_admin.php";
<h4>Recurring Invoice</h4> <h4>Recurring Invoice</h4>
<div class="form-group"> <div class="mb-3">
<label>Recurring Prefix</label> <label>Recurring Prefix</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div>
<input type="text" class="form-control" name="config_recurring_invoice_prefix" placeholder="Recurring Invoice Prefix" maxlength="200" value="<?= escapeHtml($config_recurring_invoice_prefix) ?>" required> <input type="text" class="form-control" name="config_recurring_invoice_prefix" placeholder="Recurring Invoice Prefix" maxlength="200" value="<?= escapeHtml($config_recurring_invoice_prefix) ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Next Number</label> <label>Next Number</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div>
<input type="number" min="0" class="form-control" name="config_recurring_invoice_next_number" placeholder="Next Recurring Invoice Number" value="<?= intval($config_recurring_invoice_next_number) ?>" required> <input type="number" min="0" class="form-control" name="config_recurring_invoice_next_number" placeholder="Next Recurring Invoice Number" value="<?= intval($config_recurring_invoice_next_number) ?>" required>
</div> </div>
</div> </div>
@@ -104,7 +92,7 @@ require_once "includes/inc_all_admin.php";
<hr> <hr>
<button type="submit" name="edit_invoice_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_invoice_settings" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
</form> </form>
</div> </div>

View File

@@ -15,19 +15,17 @@ $timezones = DateTimeZone::listIdentifiers();
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-globe mr-2"></i>Localization</h3> <h3 class="card-title"><i class="fas fa-fw fa-globe me-2"></i>Localization</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="form-group"> <div class="mb-3">
<label>Language <strong class="text-danger">*</strong></label> <label>Language <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-language"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-language"></i></span>
</div> <select class="form-select select2" name="locale" required>
<select class="form-control select2" name="locale" required>
<option value="">- Select a Locale -</option> <option value="">- Select a Locale -</option>
<?php foreach($locales_array as $locale_code => $locale_name) { ?> <?php foreach($locales_array as $locale_code => $locale_name) { ?>
<option <?php if ($company_locale == $locale_code) { echo "selected"; } ?> value="<?= $locale_code ?>"><?= $locale_name ?></option> <option <?php if ($company_locale == $locale_code) { echo "selected"; } ?> value="<?= $locale_code ?>"><?= $locale_name ?></option>
@@ -36,13 +34,11 @@ $timezones = DateTimeZone::listIdentifiers();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Currency <strong class="text-danger">*</strong></label> <label>Currency <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-money-bill"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-money-bill"></i></span>
</div> <select class="form-select select2" name="currency_code" required>
<select class="form-control select2" name="currency_code" required>
<option value="">- Currency -</option> <option value="">- Currency -</option>
<?php foreach($currencies_array as $currency_code => $currency_name) { ?> <?php foreach($currencies_array as $currency_code => $currency_name) { ?>
<option <?php if ($company_currency == $currency_code) { echo "selected"; } ?> value="<?= $currency_code ?>"><?= "$currency_code - $currency_name" ?></option> <option <?php if ($company_currency == $currency_code) { echo "selected"; } ?> value="<?= $currency_code ?>"><?= "$currency_code - $currency_name" ?></option>
@@ -51,13 +47,11 @@ $timezones = DateTimeZone::listIdentifiers();
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Timezone <strong class="text-danger">*</strong></label> <label>Timezone <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-business-time"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-business-time"></i></span>
</div> <select class="form-select select2" name="timezone" required>
<select class="form-control select2" name="timezone" required>
<option value="">- Select a Timezone -</option> <option value="">- Select a Timezone -</option>
<?php foreach ($timezones as $tz) { ?> <?php foreach ($timezones as $tz) { ?>
<option <?php if ($config_timezone == $tz) { echo "selected"; } ?> value="<?= $tz ?>"><?= $tz ?></option> <option <?php if ($config_timezone == $tz) { echo "selected"; } ?> value="<?= $tz ?>"><?= $tz ?></option>
@@ -68,7 +62,7 @@ $timezones = DateTimeZone::listIdentifiers();
<hr> <hr>
<button type="submit" name="edit_localization" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_localization" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
</form> </form>
</div> </div>

View File

@@ -4,8 +4,8 @@ require_once "includes/inc_all_admin.php";
// ---- Tiny status dot for tab labels ---------------------------------------- // ---- Tiny status dot for tab labels ----------------------------------------
function renderMailStatusDot($on) { function renderMailStatusDot($on) {
return $on return $on
? '<i class="fas fa-circle text-success ml-2" style="font-size:.5rem;vertical-align:middle;" title="Configured"></i>' ? '<i class="fas fa-circle text-success ms-2" style="font-size:.5rem;vertical-align:middle;" title="Configured"></i>'
: '<i class="far fa-circle text-muted ml-2" style="font-size:.5rem;vertical-align:middle;" title="Not configured"></i>'; : '<i class="far fa-circle text-muted ms-2" style="font-size:.5rem;vertical-align:middle;" title="Not configured"></i>';
} }
$smtp_on = !empty($config_smtp_provider); $smtp_on = !empty($config_smtp_provider);
@@ -14,10 +14,10 @@ $oauth_needed = in_array($config_smtp_provider, ['google_oauth', 'microsoft_oaut
|| in_array($config_imap_provider, ['google_oauth', 'microsoft_oauth'], true); || in_array($config_imap_provider, ['google_oauth', 'microsoft_oauth'], true);
// ---- Active tab ------------------------------------------------------------- // ---- Active tab -------------------------------------------------------------
// The tab lives in the URL (?tab=imap) so it can be linked, bookmarked, survives a // The tab lives in the URL (?tab=receiving) so it can be linked, bookmarked, survives a
// reload, and lets the POST handlers send you back to the tab you saved from // reload, and lets the POST handlers send you back to the tab you saved from
$mail_tabs = ['smtp', 'imap', 'oauth', 'from', 'tests']; $mail_tabs = ['sending', 'receiving', 'oauth', 'from', 'tests'];
$active_tab = isset($_GET['tab']) && in_array($_GET['tab'], $mail_tabs, true) ? $_GET['tab'] : 'smtp'; $active_tab = isset($_GET['tab']) && in_array($_GET['tab'], $mail_tabs, true) ? $_GET['tab'] : 'sending';
// A direct link to the OAuth tab reveals it even when no OAuth provider is selected yet // A direct link to the OAuth tab reveals it even when no OAuth provider is selected yet
if ($active_tab === 'oauth') { if ($active_tab === 'oauth') {
@@ -68,34 +68,34 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-envelope mr-2"></i>Mail Configuration</h3> <h3 class="card-title"><i class="fas fa-fw fa-envelope me-2"></i>Mail Configuration</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<ul class="nav nav-tabs" id="mailTabs" role="tablist"> <ul class="nav nav-tabs" id="mailTabs" role="tablist">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link <?php if ($active_tab === 'smtp') { echo 'active'; } ?>" href="?tab=smtp" data-target="#tab-smtp"> <a class="nav-link <?php if ($active_tab === 'sending') { echo 'active'; } ?>" href="?tab=sending" data-bs-target="#tab-sending">
<i class="fas fa-fw fa-paper-plane mr-1"></i>Sending<?= renderMailStatusDot($smtp_on) ?> <i class="fas fa-fw fa-paper-plane me-1"></i>Sending<?= renderMailStatusDot($smtp_on) ?>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link <?php if ($active_tab === 'imap') { echo 'active'; } ?>" href="?tab=imap" data-target="#tab-imap"> <a class="nav-link <?php if ($active_tab === 'receiving') { echo 'active'; } ?>" href="?tab=receiving" data-bs-target="#tab-receiving">
<i class="fas fa-fw fa-inbox mr-1"></i>Receiving<?= renderMailStatusDot($imap_on) ?> <i class="fas fa-fw fa-inbox me-1"></i>Receiving<?= renderMailStatusDot($imap_on) ?>
</a> </a>
</li> </li>
<li class="nav-item" id="tabitem-oauth" style="<?= $oauth_needed ? '' : 'display:none;' ?>"> <li class="nav-item" id="tabitem-oauth" style="<?= $oauth_needed ? '' : 'display:none;' ?>">
<a class="nav-link <?php if ($active_tab === 'oauth') { echo 'active'; } ?>" href="?tab=oauth" data-target="#tab-oauth"> <a class="nav-link <?php if ($active_tab === 'oauth') { echo 'active'; } ?>" href="?tab=oauth" data-bs-target="#tab-oauth">
<i class="fas fa-fw fa-key mr-1"></i>OAuth <i class="fas fa-fw fa-key me-1"></i>OAuth
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link <?php if ($active_tab === 'from') { echo 'active'; } ?>" href="?tab=from" data-target="#tab-from"> <a class="nav-link <?php if ($active_tab === 'from') { echo 'active'; } ?>" href="?tab=from" data-bs-target="#tab-from">
<i class="fas fa-fw fa-at mr-1"></i>From Addresses <i class="fas fa-fw fa-at me-1"></i>From Addresses
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link <?php if ($active_tab === 'tests') { echo 'active'; } ?>" href="?tab=tests" data-target="#tab-tests"> <a class="nav-link <?php if ($active_tab === 'tests') { echo 'active'; } ?>" href="?tab=tests" data-bs-target="#tab-tests">
<i class="fas fa-fw fa-vial mr-1"></i>Tests <i class="fas fa-fw fa-vial me-1"></i>Tests
</a> </a>
</li> </li>
</ul> </ul>
@@ -103,16 +103,15 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
<div class="tab-content pt-4"> <div class="tab-content pt-4">
<!-- ============================ SENDING / SMTP ============================ --> <!-- ============================ SENDING / SMTP ============================ -->
<div class="tab-pane fade <?php if ($active_tab === 'smtp') { echo 'show active'; } ?>" id="tab-smtp" role="tabpanel"> <div class="tab-pane fade <?php if ($active_tab === 'sending') { echo 'show active'; } ?>" id="tab-sending" role="tabpanel">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="tab" value="smtp"> <input type="hidden" name="tab" value="sending">
<div class="form-group"> <div class="mb-3">
<label>SMTP Provider <small class="text-muted">— outbound</small></label> <label>SMTP Provider <small class="text-muted">— outbound</small></label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-cloud"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-cloud"></i></span></div> <select class="form-select" name="config_smtp_provider" id="config_smtp_provider">
<select class="form-control" name="config_smtp_provider" id="config_smtp_provider">
<option value="" <?php if (empty($config_smtp_provider)) { echo 'selected'; } ?>>None (Disabled)</option> <option value="" <?php if (empty($config_smtp_provider)) { echo 'selected'; } ?>>None (Disabled)</option>
<option value="standard_smtp" <?php if ($config_smtp_provider === 'standard_smtp') { echo 'selected'; } ?>>Standard SMTP (Username/Password)</option> <option value="standard_smtp" <?php if ($config_smtp_provider === 'standard_smtp') { echo 'selected'; } ?>>Standard SMTP (Username/Password)</option>
<option value="google_oauth" <?php if ($config_smtp_provider === 'google_oauth') { echo 'selected'; } ?>>Google Workspace (OAuth)</option> <option value="google_oauth" <?php if ($config_smtp_provider === 'google_oauth') { echo 'selected'; } ?>>Google Workspace (OAuth)</option>
@@ -123,26 +122,23 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
</div> </div>
<div id="smtp_conn_fields"> <div id="smtp_conn_fields">
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>SMTP Host</label> <label>SMTP Host</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-server"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-server"></i></span></div>
<input type="text" class="form-control" name="config_smtp_host" placeholder="smtp.yourcompany.com" maxlength="200" value="<?= escapeHtml($config_smtp_host) ?>" required> <input type="text" class="form-control" name="config_smtp_host" placeholder="smtp.yourcompany.com" maxlength="200" value="<?= escapeHtml($config_smtp_host) ?>" required>
</div> </div>
</div> </div>
<div class="form-group col-md-3"> <div class="mb-3 col-md-3">
<label>Port</label> <label>Port</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span></div>
<input type="text" class="form-control numeric-only" inputmode="numeric" pattern="[0-9]*" maxlength="5" name="config_smtp_port" placeholder="587 / 465 / 25" value="<?= !empty($config_smtp_port) ? intval($config_smtp_port) : '' ?>" required> <input type="text" class="form-control numeric-only" inputmode="numeric" pattern="[0-9]*" maxlength="5" name="config_smtp_port" placeholder="587 / 465 / 25" value="<?= !empty($config_smtp_port) ? intval($config_smtp_port) : '' ?>" required>
</div> </div>
</div> </div>
<div class="form-group col-md-3"> <div class="mb-3 col-md-3">
<label>Encryption</label> <label>Encryption</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span></div> <select class="form-select" name="config_smtp_encryption">
<select class="form-control" name="config_smtp_encryption">
<option value="">None</option> <option value="">None</option>
<option <?php if ($config_smtp_encryption == 'tls') { echo "selected"; } ?> value="tls">TLS</option> <option <?php if ($config_smtp_encryption == 'tls') { echo "selected"; } ?> value="tls">TLS</option>
<option <?php if ($config_smtp_encryption == 'ssl') { echo "selected"; } ?> value="ssl">SSL</option> <option <?php if ($config_smtp_encryption == 'ssl') { echo "selected"; } ?> value="ssl">SSL</option>
@@ -152,48 +148,44 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
</div> </div>
</div> </div>
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-6" id="smtp_user_group"> <div class="mb-3 col-md-6" id="smtp_user_group">
<label id="smtp_user_label">SMTP Username</label> <label id="smtp_user_label">SMTP Username</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-user"></i></span></div>
<input type="text" class="form-control" name="config_smtp_username" id="config_smtp_username" placeholder="usually your full email address" maxlength="200" value="<?= escapeHtml($config_smtp_username) ?>"> <input type="text" class="form-control" name="config_smtp_username" id="config_smtp_username" placeholder="usually your full email address" maxlength="200" value="<?= escapeHtml($config_smtp_username) ?>">
</div> </div>
<small class="form-text text-muted" id="smtp_user_hint">Leave blank if no authentication is required.</small> <small class="form-text text-muted" id="smtp_user_hint">Leave blank if no authentication is required.</small>
</div> </div>
<div class="form-group col-md-6" id="smtp_pass_group"> <div class="mb-3 col-md-6" id="smtp_pass_group">
<label>SMTP Password</label> <label>SMTP Password</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-key"></i></span></div> <input type="password" class="form-control" data-toggle="password" name="config_smtp_password" placeholder="mailbox or app password" maxlength="200" value="<?= escapeHtml($config_smtp_password) ?>" autocomplete="new-password"><span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
<input type="password" class="form-control" data-toggle="password" name="config_smtp_password" placeholder="mailbox or app password" maxlength="200" value="<?= escapeHtml($config_smtp_password) ?>" autocomplete="new-password">
<div class="input-group-append"><span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span></div>
</div> </div>
</div> </div>
</div> </div>
<div class="alert alert-info" id="smtp_oauth_pointer" style="display:none;"> <div class="alert alert-info" id="smtp_oauth_pointer" style="display:none;">
<div class="d-flex align-items-center justify-content-between"> <div class="d-flex align-items-center justify-content-between">
<span><i class="fas fa-fw fa-info-circle mr-2"></i>This provider uses OAuth — the password is ignored. Enter app credentials in the OAuth tab.</span> <span><i class="fas fa-fw fa-info-circle me-2"></i>This provider uses OAuth — the password is ignored. Enter app credentials in the OAuth tab.</span>
<button type="button" class="btn btn-sm btn-outline-primary goto-oauth ml-3 text-nowrap"><i class="fas fa-fw fa-key mr-1"></i>Open OAuth</button> <button type="button" class="btn btn-sm btn-outline-primary goto-oauth ms-3 text-nowrap"><i class="fas fa-fw fa-key me-1"></i>Open OAuth</button>
</div> </div>
</div> </div>
<hr> <hr>
<button type="submit" name="edit_mail_smtp_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save Sending Settings</button> <button type="submit" name="edit_mail_smtp_settings" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save Sending Settings</button>
</form> </form>
</div> </div>
<!-- ============================ RECEIVING / IMAP ============================ --> <!-- ============================ RECEIVING / IMAP ============================ -->
<div class="tab-pane fade <?php if ($active_tab === 'imap') { echo 'show active'; } ?>" id="tab-imap" role="tabpanel"> <div class="tab-pane fade <?php if ($active_tab === 'receiving') { echo 'show active'; } ?>" id="tab-receiving" role="tabpanel">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="tab" value="imap"> <input type="hidden" name="tab" value="receiving">
<div class="form-group"> <div class="mb-3">
<label>IMAP Provider <small class="text-muted">— inbound ticket inbox</small></label> <label>IMAP Provider <small class="text-muted">— inbound ticket inbox</small></label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-cloud"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-cloud"></i></span></div> <select class="form-select" name="config_imap_provider" id="config_imap_provider">
<select class="form-control" name="config_imap_provider" id="config_imap_provider">
<option value="" <?php if (empty($config_imap_provider)) { echo 'selected'; } ?>>None (Disabled)</option> <option value="" <?php if (empty($config_imap_provider)) { echo 'selected'; } ?>>None (Disabled)</option>
<option value="standard_imap" <?php if ($config_imap_provider === 'standard_imap') { echo 'selected'; } ?>>Standard IMAP (Username/Password)</option> <option value="standard_imap" <?php if ($config_imap_provider === 'standard_imap') { echo 'selected'; } ?>>Standard IMAP (Username/Password)</option>
<option value="google_oauth" <?php if ($config_imap_provider === 'google_oauth') { echo 'selected'; } ?>>Google Workspace (OAuth)</option> <option value="google_oauth" <?php if ($config_imap_provider === 'google_oauth') { echo 'selected'; } ?>>Google Workspace (OAuth)</option>
@@ -204,26 +196,23 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
</div> </div>
<div id="imap_conn_fields"> <div id="imap_conn_fields">
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>IMAP Host</label> <label>IMAP Host</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-server"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-server"></i></span></div>
<input type="text" class="form-control" name="config_imap_host" placeholder="imap.yourcompany.com" maxlength="200" value="<?= escapeHtml($config_imap_host) ?>"> <input type="text" class="form-control" name="config_imap_host" placeholder="imap.yourcompany.com" maxlength="200" value="<?= escapeHtml($config_imap_host) ?>">
</div> </div>
</div> </div>
<div class="form-group col-md-3"> <div class="mb-3 col-md-3">
<label>Port</label> <label>Port</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span></div>
<input type="text" class="form-control numeric-only" inputmode="numeric" pattern="[0-9]*" maxlength="5" name="config_imap_port" placeholder="993 / 143" value="<?= !empty($config_imap_port) ? intval($config_imap_port) : '' ?>"> <input type="text" class="form-control numeric-only" inputmode="numeric" pattern="[0-9]*" maxlength="5" name="config_imap_port" placeholder="993 / 143" value="<?= !empty($config_imap_port) ? intval($config_imap_port) : '' ?>">
</div> </div>
</div> </div>
<div class="form-group col-md-3"> <div class="mb-3 col-md-3">
<label>Encryption</label> <label>Encryption</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span></div> <select class="form-select" name="config_imap_encryption">
<select class="form-control" name="config_imap_encryption">
<option value="">None</option> <option value="">None</option>
<option <?php if ($config_imap_encryption == 'tls') { echo "selected"; } ?> value="tls">TLS</option> <option <?php if ($config_imap_encryption == 'tls') { echo "selected"; } ?> value="tls">TLS</option>
<option <?php if ($config_imap_encryption == 'ssl') { echo "selected"; } ?> value="ssl">SSL</option> <option <?php if ($config_imap_encryption == 'ssl') { echo "selected"; } ?> value="ssl">SSL</option>
@@ -233,34 +222,31 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
</div> </div>
</div> </div>
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-6" id="imap_user_group"> <div class="mb-3 col-md-6" id="imap_user_group">
<label id="imap_user_label">IMAP Username</label> <label id="imap_user_label">IMAP Username</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-user"></i></span></div>
<input type="text" class="form-control" name="config_imap_username" placeholder="tickets@yourcompany.com" maxlength="200" value="<?= escapeHtml($config_imap_username) ?>" required> <input type="text" class="form-control" name="config_imap_username" placeholder="tickets@yourcompany.com" maxlength="200" value="<?= escapeHtml($config_imap_username) ?>" required>
</div> </div>
<small class="form-text text-muted" id="imap_user_hint">The mailbox address to monitor for incoming tickets.</small> <small class="form-text text-muted" id="imap_user_hint">The mailbox address to monitor for incoming tickets.</small>
</div> </div>
<div class="form-group col-md-6" id="imap_pass_group"> <div class="mb-3 col-md-6" id="imap_pass_group">
<label>IMAP Password</label> <label>IMAP Password</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-key"></i></span></div> <input type="password" class="form-control" data-toggle="password" name="config_imap_password" placeholder="mailbox or app password" maxlength="200" value="<?= escapeHtml($config_imap_password) ?>" autocomplete="new-password"><span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
<input type="password" class="form-control" data-toggle="password" name="config_imap_password" placeholder="mailbox or app password" maxlength="200" value="<?= escapeHtml($config_imap_password) ?>" autocomplete="new-password">
<div class="input-group-append"><span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span></div>
</div> </div>
</div> </div>
</div> </div>
<div class="alert alert-info" id="imap_oauth_pointer" style="display:none;"> <div class="alert alert-info" id="imap_oauth_pointer" style="display:none;">
<div class="d-flex align-items-center justify-content-between"> <div class="d-flex align-items-center justify-content-between">
<span><i class="fas fa-fw fa-info-circle mr-2"></i>This provider uses OAuth — the password is ignored. Enter app credentials in the OAuth tab.</span> <span><i class="fas fa-fw fa-info-circle me-2"></i>This provider uses OAuth — the password is ignored. Enter app credentials in the OAuth tab.</span>
<button type="button" class="btn btn-sm btn-outline-primary goto-oauth ml-3 text-nowrap"><i class="fas fa-fw fa-key mr-1"></i>Open OAuth</button> <button type="button" class="btn btn-sm btn-outline-primary goto-oauth ms-3 text-nowrap"><i class="fas fa-fw fa-key me-1"></i>Open OAuth</button>
</div> </div>
</div> </div>
<hr> <hr>
<button type="submit" name="edit_mail_imap_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save Receiving Settings</button> <button type="submit" name="edit_mail_imap_settings" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save Receiving Settings</button>
</form> </form>
</div> </div>
@@ -271,63 +257,56 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
<input type="hidden" name="tab" value="oauth"> <input type="hidden" name="tab" value="oauth">
<div class="alert alert-secondary" id="oauth_hint"> <div class="alert alert-secondary" id="oauth_hint">
<i class="fas fa-fw fa-info-circle mr-2"></i>These credentials are shared by any Sending or Receiving provider set to Google / Microsoft OAuth. <i class="fas fa-fw fa-info-circle me-2"></i>These credentials are shared by any Sending or Receiving provider set to Google / Microsoft OAuth.
</div> </div>
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>OAuth Client ID</label> <label>OAuth Client ID</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-id-badge"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-id-badge"></i></span></div>
<input type="text" class="form-control" name="config_mail_oauth_client_id" id="config_mail_oauth_client_id" placeholder="Application (client) ID" maxlength="255" value="<?= escapeHtml($config_mail_oauth_client_id ?? '') ?>"> <input type="text" class="form-control" name="config_mail_oauth_client_id" id="config_mail_oauth_client_id" placeholder="Application (client) ID" maxlength="255" value="<?= escapeHtml($config_mail_oauth_client_id ?? '') ?>">
</div> </div>
</div> </div>
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>OAuth Client Secret</label> <label>OAuth Client Secret</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-key"></i></span></div> <input type="password" class="form-control" data-toggle="password" name="config_mail_oauth_client_secret" id="config_mail_oauth_client_secret" placeholder="Client secret value" maxlength="255" value="<?= escapeHtml($config_mail_oauth_client_secret ?? '') ?>" autocomplete="new-password"><span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
<input type="password" class="form-control" data-toggle="password" name="config_mail_oauth_client_secret" id="config_mail_oauth_client_secret" placeholder="Client secret value" maxlength="255" value="<?= escapeHtml($config_mail_oauth_client_secret ?? '') ?>" autocomplete="new-password">
<div class="input-group-append"><span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span></div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group" id="tenant_row" style="display:none;"> <div class="mb-3" id="tenant_row" style="display:none;">
<label>Tenant ID <small class="text-muted">— Microsoft 365 only</small></label> <label>Tenant ID <small class="text-muted">— Microsoft 365 only</small></label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-building"></i></span></div>
<input type="text" class="form-control" name="config_mail_oauth_tenant_id" placeholder="Directory (tenant) ID, e.g. 00000000-0000-0000-0000-000000000000" maxlength="255" value="<?= escapeHtml($config_mail_oauth_tenant_id ?? '') ?>"> <input type="text" class="form-control" name="config_mail_oauth_tenant_id" placeholder="Directory (tenant) ID, e.g. 00000000-0000-0000-0000-000000000000" maxlength="255" value="<?= escapeHtml($config_mail_oauth_tenant_id ?? '') ?>">
</div> </div>
</div> </div>
<div class="form-row"> <div class="row g-2">
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>Refresh Token</label> <label>Refresh Token</label>
<textarea class="form-control" name="config_mail_oauth_refresh_token" rows="2" placeholder="Paste a refresh token, or use the Connect button below to fetch one"><?= escapeHtml($config_mail_oauth_refresh_token ?? '') ?></textarea> <textarea class="form-control" name="config_mail_oauth_refresh_token" rows="2" placeholder="Paste a refresh token, or use the Connect button below to fetch one"><?= escapeHtml($config_mail_oauth_refresh_token ?? '') ?></textarea>
</div> </div>
<div class="form-group col-md-6"> <div class="mb-3 col-md-6">
<label>Access Token <small class="text-muted">— optional</small></label> <label>Access Token <small class="text-muted">— optional</small></label>
<textarea class="form-control" name="config_mail_oauth_access_token" rows="2" placeholder="Leave blank — auto-refreshed from the refresh token"><?= escapeHtml($config_mail_oauth_access_token ?? '') ?></textarea> <textarea class="form-control" name="config_mail_oauth_access_token" rows="2" placeholder="Leave blank — auto-refreshed from the refresh token"><?= escapeHtml($config_mail_oauth_access_token ?? '') ?></textarea>
<small class="form-text text-muted">Expires at: <?= !empty($config_mail_oauth_access_token_expires_at) ? htmlspecialchars($config_mail_oauth_access_token_expires_at) : 'n/a' ?></small> <small class="form-text text-muted">Expires at: <?= !empty($config_mail_oauth_access_token_expires_at) ? htmlspecialchars($config_mail_oauth_access_token_expires_at) : 'n/a' ?></small>
</div> </div>
</div> </div>
<div class="form-group" id="ms_connect_group" style="display:none;"> <div class="mb-3" id="ms_connect_group" style="display:none;">
<label>Microsoft OAuth Connect (Web)</label> <label>Microsoft OAuth Connect (Web)</label>
<div class="input-group"> <div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-link"></i></span>
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-link"></i></span></div>
<input type="text" class="form-control" readonly value="<?= htmlspecialchars($mail_oauth_callback_uri) ?>"> <input type="text" class="form-control" readonly value="<?= htmlspecialchars($mail_oauth_callback_uri) ?>">
<div class="input-group-append">
<button type="submit" name="oauth_connect_microsoft_mail" class="btn btn-outline-primary"> <button type="submit" name="oauth_connect_microsoft_mail" class="btn btn-outline-primary">
<i class="fab fa-fw fa-microsoft mr-2"></i>Connect Microsoft 365 <i class="fab fa-fw fa-microsoft me-2"></i>Connect Microsoft 365
</button> </button>
</div> </div>
</div>
<small class="form-text text-muted">Add this callback URI in your Entra App Registration, save credentials, then click Connect to store the refresh token automatically.</small> <small class="form-text text-muted">Add this callback URI in your Entra App Registration, save credentials, then click Connect to store the refresh token automatically.</small>
</div> </div>
<hr> <hr>
<button type="submit" name="edit_mail_oauth_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save OAuth Credentials</button> <button type="submit" name="edit_mail_oauth_settings" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save OAuth Credentials</button>
</form> </form>
</div> </div>
@@ -371,7 +350,7 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
</tbody> </tbody>
</table> </table>
<button type="submit" name="edit_mail_from_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save From Addresses</button> <button type="submit" name="edit_mail_from_settings" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save From Addresses</button>
</form> </form>
</div> </div>
@@ -380,18 +359,18 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
<?php if (!$send_ready && !$imap_ready && !$oauth_has_required_fields) { ?> <?php if (!$send_ready && !$imap_ready && !$oauth_has_required_fields) { ?>
<div class="alert alert-secondary mb-0"> <div class="alert alert-secondary mb-0">
<i class="fas fa-fw fa-info-circle mr-2"></i>Finish configuring Sending, Receiving, or OAuth (plus at least one From address) to unlock the tests. <i class="fas fa-fw fa-info-circle me-2"></i>Finish configuring Sending, Receiving, or OAuth (plus at least one From address) to unlock the tests.
</div> </div>
<?php } ?> <?php } ?>
<?php if ($send_ready) { ?> <?php if ($send_ready) { ?>
<div class="mb-4"> <div class="mb-4">
<h6 class="text-bold"><i class="fas fa-fw fa-paper-plane mr-2"></i>Send a Test Email</h6> <h6 class="text-bold"><i class="fas fa-fw fa-paper-plane me-2"></i>Send a Test Email</h6>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="tab" value="tests"> <input type="hidden" name="tab" value="tests">
<div class="input-group"> <div class="input-group">
<select class="form-control select2" name="test_email" required> <select class="form-select select2" name="test_email" required>
<option value="">- Select a From address -</option> <option value="">- Select a From address -</option>
<?php if ($config_mail_from_email) { ?><option value="1"><?= escapeHtml($config_mail_from_name) ?> (<?= escapeHtml($config_mail_from_email) ?>)</option><?php } ?> <?php if ($config_mail_from_email) { ?><option value="1"><?= escapeHtml($config_mail_from_name) ?> (<?= escapeHtml($config_mail_from_email) ?>)</option><?php } ?>
<?php if ($config_invoice_from_email) { ?><option value="2"><?= escapeHtml($config_invoice_from_name) ?> (<?= escapeHtml($config_invoice_from_email) ?>)</option><?php } ?> <?php if ($config_invoice_from_email) { ?><option value="2"><?= escapeHtml($config_invoice_from_name) ?> (<?= escapeHtml($config_invoice_from_email) ?>)</option><?php } ?>
@@ -399,9 +378,7 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
<?php if ($config_ticket_from_email) { ?><option value="4"><?= escapeHtml($config_ticket_from_name) ?> (<?= escapeHtml($config_ticket_from_email) ?>)</option><?php } ?> <?php if ($config_ticket_from_email) { ?><option value="4"><?= escapeHtml($config_ticket_from_name) ?> (<?= escapeHtml($config_ticket_from_email) ?>)</option><?php } ?>
</select> </select>
<input type="email" class="form-control" name="email_to" placeholder="recipient@example.com"> <input type="email" class="form-control" name="email_to" placeholder="recipient@example.com">
<div class="input-group-append"> <button type="submit" name="test_email_smtp" class="btn btn-success"><i class="fas fa-fw fa-paper-plane me-2"></i>Send</button>
<button type="submit" name="test_email_smtp" class="btn btn-success"><i class="fas fa-fw fa-paper-plane mr-2"></i>Send</button>
</div>
</div> </div>
</form> </form>
</div> </div>
@@ -409,24 +386,24 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
<?php if ($imap_ready) { ?> <?php if ($imap_ready) { ?>
<div class="mb-4"> <div class="mb-4">
<h6 class="text-bold"><i class="fas fa-fw fa-plug mr-2"></i>Test IMAP Connection</h6> <h6 class="text-bold"><i class="fas fa-fw fa-plug me-2"></i>Test IMAP Connection</h6>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="tab" value="tests"> <input type="hidden" name="tab" value="tests">
<button type="submit" name="test_email_imap" class="btn btn-success"><i class="fas fa-fw fa-inbox mr-2"></i>Test IMAP</button> <button type="submit" name="test_email_imap" class="btn btn-success"><i class="fas fa-fw fa-inbox me-2"></i>Test IMAP</button>
</form> </form>
</div> </div>
<?php } ?> <?php } ?>
<?php if ($oauth_has_required_fields) { ?> <?php if ($oauth_has_required_fields) { ?>
<div> <div>
<h6 class="text-bold"><i class="fas fa-fw fa-sync-alt mr-2"></i>Test OAuth Token Refresh</h6> <h6 class="text-bold"><i class="fas fa-fw fa-sync-alt me-2"></i>Test OAuth Token Refresh</h6>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="tab" value="tests"> <input type="hidden" name="tab" value="tests">
<input type="hidden" name="oauth_provider" value="<?= htmlspecialchars($oauth_provider_for_test) ?>"> <input type="hidden" name="oauth_provider" value="<?= htmlspecialchars($oauth_provider_for_test) ?>">
<p class="text-muted mb-2">Validates the refresh token and stores a new access token for <?= $oauth_provider_for_test === 'microsoft_oauth' ? 'Microsoft 365' : 'Google Workspace' ?>.</p> <p class="text-muted mb-2">Validates the refresh token and stores a new access token for <?= $oauth_provider_for_test === 'microsoft_oauth' ? 'Microsoft 365' : 'Google Workspace' ?>.</p>
<button type="submit" name="test_oauth_token_refresh" class="btn btn-success"><i class="fas fa-fw fa-sync-alt mr-2"></i>Test OAuth Token Refresh</button> <button type="submit" name="test_oauth_token_refresh" class="btn btn-success"><i class="fas fa-fw fa-sync-alt me-2"></i>Test OAuth Token Refresh</button>
</form> </form>
</div> </div>
<?php } ?> <?php } ?>
@@ -455,29 +432,36 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
// Set when the page was opened directly on the OAuth tab - stops the provider pass hiding it // Set when the page was opened directly on the OAuth tab - stops the provider pass hiding it
const forcedOauthTab = <?= $active_tab === 'oauth' ? 'true' : 'false' ?>; const forcedOauthTab = <?= $active_tab === 'oauth' ? 'true' : 'false' ?>;
const navLinks = Array.from(document.querySelectorAll('#mailTabs .nav-link')); const navLinks = Array.from(document.querySelectorAll('#mailTabs .nav-link'));
const panes = ['tab-smtp', 'tab-imap', 'tab-oauth', 'tab-from', 'tab-tests'] const panes = ['tab-sending', 'tab-receiving', 'tab-oauth', 'tab-from', 'tab-tests']
.map(id => document.getElementById(id)).filter(Boolean); .map(id => document.getElementById(id)).filter(Boolean);
// Server rendered the initial tab; keep the URL honest as the user clicks around // Server rendered the initial tab; keep the URL honest as the user clicks around
function syncTabUrl(target) { function syncTabUrl(target, push) {
const tab = target.replace('#tab-', ''); const tab = target.replace('#tab-', '');
const url = new URL(window.location.href); const url = new URL(window.location.href);
url.searchParams.set('tab', tab); url.searchParams.set('tab', tab);
history.replaceState(null, '', url); // pushState, not replaceState, so back/forward step through the tabs
// instead of jumping straight off the settings page
history[push ? 'pushState' : 'replaceState']({ tab: tab }, '', url);
} }
function activateTab(target) { function activateTab(target, push) {
syncTabUrl(target); syncTabUrl(target, push !== false);
navLinks.forEach(l => l.classList.toggle('active', l.getAttribute('data-target') === target)); navLinks.forEach(l => l.classList.toggle('active', l.getAttribute('data-bs-target') === target));
panes.forEach(p => { panes.forEach(p => {
const on = ('#' + p.id) === target; const on = ('#' + p.id) === target;
p.classList.toggle('active', on); p.classList.toggle('active', on);
p.classList.toggle('show', on); p.classList.toggle('show', on);
}); });
} }
window.addEventListener('popstate', function () {
const tab = new URL(window.location.href).searchParams.get('tab') || 'sending';
activateTab('#tab-' + tab, false);
});
navLinks.forEach(l => l.addEventListener('click', function (e) { navLinks.forEach(l => l.addEventListener('click', function (e) {
e.preventDefault(); e.preventDefault();
activateTab(l.getAttribute('data-target')); activateTab(l.getAttribute('data-bs-target'), true);
})); }));
// ---- Provider-driven field visibility ---- // ---- Provider-driven field visibility ----
@@ -545,13 +529,13 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
: 'xxxxxxxxxxxx.apps.googleusercontent.com'; : 'xxxxxxxxxxxx.apps.googleusercontent.com';
if (oauthClientSecret) oauthClientSecret.placeholder = anyMs ? 'Entra client secret value' : 'Google client secret'; if (oauthClientSecret) oauthClientSecret.placeholder = anyMs ? 'Entra client secret value' : 'Google client secret';
if (oauthHint) oauthHint.innerHTML = anyMs if (oauthHint) oauthHint.innerHTML = anyMs
? '<i class="fas fa-fw fa-info-circle mr-2"></i>Microsoft 365: Client ID / Secret / Tenant from Entra ID; refresh token via the Connect button below.' ? '<i class="fas fa-fw fa-info-circle me-2"></i>Microsoft 365: Client ID / Secret / Tenant from Entra ID; refresh token via the Connect button below.'
: anyOauth ? '<i class="fas fa-fw fa-info-circle mr-2"></i>Google Workspace: Client ID / Secret from Google Cloud; refresh token obtained via the consent flow.' : anyOauth ? '<i class="fas fa-fw fa-info-circle me-2"></i>Google Workspace: Client ID / Secret from Google Cloud; refresh token obtained via the consent flow.'
: '<i class="fas fa-fw fa-info-circle mr-2"></i>These credentials are shared by any Sending or Receiving provider set to Google / Microsoft OAuth.'; : '<i class="fas fa-fw fa-info-circle me-2"></i>These credentials are shared by any Sending or Receiving provider set to Google / Microsoft OAuth.';
if (!anyOauth && !forcedOauthTab) { if (!anyOauth && !forcedOauthTab) {
const oauthLink = document.querySelector('#mailTabs .nav-link[data-target="#tab-oauth"]'); const oauthLink = document.querySelector('#mailTabs .nav-link[data-bs-target="#tab-oauth"]');
if (oauthLink && oauthLink.classList.contains('active')) activateTab('#tab-smtp'); if (oauthLink && oauthLink.classList.contains('active')) activateTab('#tab-sending');
} }
} }

View File

@@ -4,50 +4,50 @@ require_once "includes/inc_all_admin.php";
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-cube mr-2"></i>Modules</h3> <h3 class="card-title"><i class="fas fa-fw fa-cube me-2"></i>Modules</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_module_enable_itdoc" <?php if ($config_module_enable_itdoc == 1) { echo "checked"; } ?> value="1" id="customSwitch1"> <input type="checkbox" class="form-check-input" name="config_module_enable_itdoc" <?php if ($config_module_enable_itdoc == 1) { echo "checked"; } ?> value="1" id="customSwitch1">
<label class="custom-control-label" for="customSwitch1">Show IT Documentation</label> <label class="form-check-label" for="customSwitch1">Show IT Documentation</label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_module_enable_ticketing" <?php if ($config_module_enable_ticketing == 1) { echo "checked"; } ?> value="1" id="customSwitch2"> <input type="checkbox" class="form-check-input" name="config_module_enable_ticketing" <?php if ($config_module_enable_ticketing == 1) { echo "checked"; } ?> value="1" id="customSwitch2">
<label class="custom-control-label" for="customSwitch2">Show Ticketing</label> <label class="form-check-label" for="customSwitch2">Show Ticketing</label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_module_enable_accounting" <?php if ($config_module_enable_accounting == 1) { echo "checked"; } ?> value="1" id="customSwitch3"> <input type="checkbox" class="form-check-input" name="config_module_enable_accounting" <?php if ($config_module_enable_accounting == 1) { echo "checked"; } ?> value="1" id="customSwitch3">
<label class="custom-control-label" for="customSwitch3">Show Invoicing / Accounting</label> <label class="form-check-label" for="customSwitch3">Show Invoicing / Accounting</label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_client_portal_enable" <?php if ($config_client_portal_enable == 1) { echo "checked"; } ?> value="1" id="customSwitch4"> <input type="checkbox" class="form-check-input" name="config_client_portal_enable" <?php if ($config_client_portal_enable == 1) { echo "checked"; } ?> value="1" id="customSwitch4">
<label class="custom-control-label" for="customSwitch4">Enable Client Portal</label> <label class="form-check-label" for="customSwitch4">Enable Client Portal</label>
</div> </div>
</div> </div>
<hr> <hr>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" disabled class="custom-control-input" name="config_whitelabel_enabled" <?php if ($config_whitelabel_enabled == 1) { echo "checked"; } ?> value="1" id="customSwitch5"> <input type="checkbox" disabled class="form-check-input" name="config_whitelabel_enabled" <?php if ($config_whitelabel_enabled == 1) { echo "checked"; } ?> value="1" id="customSwitch5">
<label class="custom-control-label" for="customSwitch5">White-label <small class="text-secondary">(Hides 'Powered by ITFlow' banner)</small></label> <label class="form-check-label" for="customSwitch5">White-label <small class="text-secondary">(Hides 'Powered by ITFlow' banner)</small></label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>White-label key</label> <label>White-label key</label>
<textarea class="form-control" name="config_whitelabel_key" rows="2" placeholder="Enter a key to enable white-labelling the client portal"><?= escapeHtml($config_whitelabel_key) ?></textarea> <textarea class="form-control" name="config_whitelabel_key" rows="2" placeholder="Enter a key to enable white-labelling the client portal"><?= escapeHtml($config_whitelabel_key) ?></textarea>
</div> </div>
@@ -58,7 +58,7 @@ require_once "includes/inc_all_admin.php";
$key_org = $key_info["organisation"]; $key_org = $key_info["organisation"];
$key_expires = $key_info["expires"]; $key_expires = $key_info["expires"];
?> ?>
<div class="form-group"> <div class="mb-3">
<p>White-labelling is active - thank you for your support! :)</p> <p>White-labelling is active - thank you for your support! :)</p>
<ul> <ul>
<li>Key: <?= $key_desc ?></li> <li>Key: <?= $key_desc ?></li>
@@ -71,7 +71,7 @@ require_once "includes/inc_all_admin.php";
<hr> <hr>
<button type="submit" name="edit_module_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_module_settings" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
</form> </form>
</div> </div>

View File

@@ -6,7 +6,7 @@ require_once "includes/inc_all_admin.php";
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-bell mr-2"></i>Notifications</h3> <h3 class="card-title"><i class="fas fa-fw fa-bell me-2"></i>Notifications</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
@@ -14,7 +14,7 @@ require_once "includes/inc_all_admin.php";
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-bordered"> <table class="table table-bordered">
<thead class="thead-dark"> <thead class="table-dark">
<tr> <tr>
<th>Notification</th> <th>Notification</th>
<th>App Notify</th> <th>App Notify</th>
@@ -29,15 +29,15 @@ require_once "includes/inc_all_admin.php";
</tr> </tr>
<tr> <tr>
<th> <th>
<div><i class="fas fa-fw fa-globe mr-2"></i>Domain Expiration Notice</div> <div><i class="fas fa-fw fa-globe me-2"></i>Domain Expiration Notice</div>
<small class="text-muted"> <small class="text-muted">
(This setting triggers a notification when a domain is approaching its expiration date, specifically at 1, 7 and 45 days prior to expiry.) (This setting triggers a notification when a domain is approaching its expiration date, specifically at 1, 7 and 45 days prior to expiry.)
</small> </small>
</th> </th>
<td> <td>
<div class="custom-control custom-checkbox text-center"> <div class="form-check text-center">
<input type="checkbox" class="custom-control-input" name="config_enable_alert_domain_expire" id="customCheck1" <?php if ($config_enable_alert_domain_expire == 1) { echo "checked"; } ?> value="1"> <input type="checkbox" class="form-check-input" name="config_enable_alert_domain_expire" id="customCheck1" <?php if ($config_enable_alert_domain_expire == 1) { echo "checked"; } ?> value="1">
<label class="custom-control-label" for="customCheck1"></label> <label class="form-check-label" for="customCheck1"></label>
</div> </div>
</td> </td>
<td></td> <td></td>
@@ -49,7 +49,7 @@ require_once "includes/inc_all_admin.php";
</tr> </tr>
<tr> <tr>
<th> <th>
<div><i class="fas fa-fw fa-file-invoice mr-2"></i>Invoice Reminders</div> <div><i class="fas fa-fw fa-file-invoice me-2"></i>Invoice Reminders</div>
<small class="text-muted"> <small class="text-muted">
(This will automatically dispatch a reminder email for the invoice to the primary contact's email every 30 days following the invoice's due date.) (This will automatically dispatch a reminder email for the invoice to the primary contact's email every 30 days following the invoice's due date.)
</small> </small>
@@ -59,16 +59,16 @@ require_once "includes/inc_all_admin.php";
</td> </td>
<td></td> <td></td>
<td> <td>
<div class="custom-control custom-checkbox text-center"> <div class="form-check text-center">
<input type="checkbox" class="custom-control-input" name="config_send_invoice_reminders" <?php if ($config_send_invoice_reminders == 1) { echo "checked"; } ?> value="1" id="sendInvoiceRemindersSwitch"> <input type="checkbox" class="form-check-input" name="config_send_invoice_reminders" <?php if ($config_send_invoice_reminders == 1) { echo "checked"; } ?> value="1" id="sendInvoiceRemindersSwitch">
<label class="custom-control-label" for="sendInvoiceRemindersSwitch"></label> <label class="form-check-label" for="sendInvoiceRemindersSwitch"></label>
</div> </div>
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<th> <th>
<div><i class="fas fa-fw fa-redo-alt mr-2"></i>Send Recurring Invoice</div> <div><i class="fas fa-fw fa-redo-alt me-2"></i>Send Recurring Invoice</div>
<small class="text-muted"> <small class="text-muted">
(This will notify all primary and billing contacts of a client that a new invoice was generated from recurring invoices) (This will notify all primary and billing contacts of a client that a new invoice was generated from recurring invoices)
</small> </small>
@@ -78,9 +78,9 @@ require_once "includes/inc_all_admin.php";
</td> </td>
<td></td> <td></td>
<td> <td>
<div class="custom-control custom-checkbox text-center"> <div class="form-check text-center">
<input type="checkbox" class="custom-control-input" name="config_recurring_auto_send_invoice" <?php if ($config_recurring_auto_send_invoice == 1) { echo "checked"; } ?> value="1" id="sendRecurringSwitch"> <input type="checkbox" class="form-check-input" name="config_recurring_auto_send_invoice" <?php if ($config_recurring_auto_send_invoice == 1) { echo "checked"; } ?> value="1" id="sendRecurringSwitch">
<label class="custom-control-label" for="sendRecurringSwitch"></label> <label class="form-check-label" for="sendRecurringSwitch"></label>
</div> </div>
</td> </td>
<td></td> <td></td>
@@ -90,15 +90,15 @@ require_once "includes/inc_all_admin.php";
</tr> </tr>
<tr> <tr>
<th> <th>
<div><i class="fas fa-fw fa-bell mr-2"></i>Send clients general notification emails</div> <div><i class="fas fa-fw fa-bell me-2"></i>Send clients general notification emails</div>
<small class="text-secondary">(Should clients receive automatic emails when tickets are raised/closed?)</small> <small class="text-secondary">(Should clients receive automatic emails when tickets are raised/closed?)</small>
</th> </th>
<td></td> <td></td>
<td></td> <td></td>
<td> <td>
<div class="custom-control custom-checkbox text-center"> <div class="form-check text-center">
<input type="checkbox" class="custom-control-input" name="config_ticket_client_general_notifications" <?php if($config_ticket_client_general_notifications == 1){ echo "checked"; } ?> value="1" id="ticketNotificationSwitch"> <input type="checkbox" class="form-check-input" name="config_ticket_client_general_notifications" <?php if($config_ticket_client_general_notifications == 1){ echo "checked"; } ?> value="1" id="ticketNotificationSwitch">
<label class="custom-control-label" for="ticketNotificationSwitch"></label> <label class="form-check-label" for="ticketNotificationSwitch"></label>
</div> </div>
</td> </td>
<td></td> <td></td>
@@ -109,7 +109,7 @@ require_once "includes/inc_all_admin.php";
<hr> <hr>
<button type="submit" name="edit_notification_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_notification_settings" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
</form> </form>
</div> </div>

View File

@@ -4,7 +4,7 @@ require_once "includes/inc_all_admin.php";
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-project-diagram mr-2"></i>Project Settings</h3> <h3 class="card-title"><i class="fas fa-fw fa-project-diagram me-2"></i>Project Settings</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
@@ -12,29 +12,25 @@ require_once "includes/inc_all_admin.php";
<h4>Project</h4> <h4>Project</h4>
<div class="form-group"> <div class="mb-3">
<label>Project Prefix</label> <label>Project Prefix</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div>
<input type="text" class="form-control" name="config_project_prefix" placeholder="Project Prefix" maxlength="200" value="<?= escapeHtml($config_project_prefix) ?>" required> <input type="text" class="form-control" name="config_project_prefix" placeholder="Project Prefix" maxlength="200" value="<?= escapeHtml($config_project_prefix) ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Next Number</label> <label>Next Number</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div>
<input type="number" min="0" class="form-control" name="config_project_next_number" placeholder="Next Project Number" value="<?= intval($config_project_next_number) ?>" required> <input type="number" min="0" class="form-control" name="config_project_next_number" placeholder="Next Project Number" value="<?= intval($config_project_next_number) ?>" required>
</div> </div>
</div> </div>
<hr> <hr>
<button type="submit" name="edit_project_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_project_settings" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
</form> </form>
</div> </div>

View File

@@ -4,50 +4,44 @@ require_once "includes/inc_all_admin.php";
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-comment-dollar mr-2"></i>Quote Settings</h3> <h3 class="card-title"><i class="fas fa-fw fa-comment-dollar me-2"></i>Quote Settings</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="form-group"> <div class="mb-3">
<label>Quote Prefix</label> <label>Quote Prefix</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div>
<input type="text" class="form-control" name="config_quote_prefix" placeholder="Quote Prefix" maxlength="200" value="<?= escapeHtml($config_quote_prefix) ?>" required> <input type="text" class="form-control" name="config_quote_prefix" placeholder="Quote Prefix" maxlength="200" value="<?= escapeHtml($config_quote_prefix) ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Next Number</label> <label>Next Number</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div>
<input type="number" min="0" class="form-control" name="config_quote_next_number" placeholder="Next Quote Number" value="<?= intval($config_quote_next_number) ?>" required> <input type="number" min="0" class="form-control" name="config_quote_next_number" placeholder="Next Quote Number" value="<?= intval($config_quote_next_number) ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Quote Footer</label> <label>Quote Footer</label>
<textarea class="form-control" rows="4" name="config_quote_footer"><?= escapeHtml($config_quote_footer) ?></textarea> <textarea class="form-control" rows="4" name="config_quote_footer"><?= escapeHtml($config_quote_footer) ?></textarea>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Email address to notify when quotes are accepted/declined <small class="text-secondary">(Ideally a distribution list/shared mailbox)</small></label> <label>Email address to notify when quotes are accepted/declined <small class="text-secondary">(Ideally a distribution list/shared mailbox)</small></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-bell"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-bell"></i></span>
</div>
<input type="email" class="form-control" name="config_quote_notification_email" placeholder="Address to notify for quote accept/declines, leave blank for none" maxlength="200" value="<?= escapeHtml($config_quote_notification_email) ?>"> <input type="email" class="form-control" name="config_quote_notification_email" placeholder="Address to notify for quote accept/declines, leave blank for none" maxlength="200" value="<?= escapeHtml($config_quote_notification_email) ?>">
</div> </div>
</div> </div>
<hr> <hr>
<button type="submit" name="edit_quote_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_quote_settings" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Save</button>
</form> </form>
</div> </div>

View File

@@ -5,57 +5,51 @@ require_once "includes/inc_all_admin.php";
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-shield-alt mr-2"></i>Security</h3> <h3 class="card-title"><i class="fas fa-fw fa-shield-alt me-2"></i>Security</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="form-group"> <div class="mb-3">
<label>Login Message</label> <label>Login Message</label>
<textarea class="form-control" name="config_login_message" rows="5" placeholder="Enter a message to be displayed on the login screen"><?= escapeHtml($config_login_message) ?></textarea> <textarea class="form-control" name="config_login_message" rows="5" placeholder="Enter a message to be displayed on the login screen"><?= escapeHtml($config_login_message) ?></textarea>
</div> </div>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_login_key_required" <?php if ($config_login_key_required == 1) { echo "checked"; } ?> value="1" id="customSwitch1"> <input type="checkbox" class="form-check-input" name="config_login_key_required" <?php if ($config_login_key_required == 1) { echo "checked"; } ?> value="1" id="customSwitch1">
<label class="custom-control-label" for="customSwitch1">Require a login key to access the technician login page?</label> <label class="form-check-label" for="customSwitch1">Require a login key to access the technician login page?</label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Login key secret value <small class="text-secondary">(This must be provided in the URL as /login.php?key=<?= escapeHtml($config_login_key_secret) ?>)</small></label> <label>Login key secret value <small class="text-secondary">(This must be provided in the URL as /login.php?key=<?= escapeHtml($config_login_key_secret) ?>)</small></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div>
<input type="text" class="form-control" name="config_login_key_secret" pattern="\w{3,99}" placeholder="Something really easy for techs to remember: e.g. MYSECRET" maxlength="99" value="<?= escapeHtml($config_login_key_secret) ?>"> <input type="text" class="form-control" name="config_login_key_secret" pattern="\w{3,99}" placeholder="Something really easy for techs to remember: e.g. MYSECRET" maxlength="99" value="<?= escapeHtml($config_login_key_secret) ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>2FA Remember Me Expire <small class="text-secondary">(The amount of days before a device 2FA remember me token will expire)</small></label> <label>2FA Remember Me Expire <small class="text-secondary">(The amount of days before a device 2FA remember me token will expire)</small></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div>
<input type="number" class="form-control" name="config_login_remember_me_expire" placeholder="Enter Days to Expire" value="<?= intval($config_login_remember_me_expire) ?>"> <input type="number" class="form-control" name="config_login_remember_me_expire" placeholder="Enter Days to Expire" value="<?= intval($config_login_remember_me_expire) ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Log retention <small class="text-secondary">(The amount of days before app/audit/auth logs are deleted during nightly cron)</small></label> <label>Log retention <small class="text-secondary">(The amount of days before app/audit/auth logs are deleted during nightly cron)</small></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div>
<input type="number" class="form-control" name="config_log_retention" placeholder="Enter days to retain" value="<?= intval($config_log_retention) ?>"> <input type="number" class="form-control" name="config_log_retention" placeholder="Enter days to retain" value="<?= intval($config_log_retention) ?>">
</div> </div>
</div> </div>
<hr> <hr>
<button type="submit" name="edit_security_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_security_settings" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
</form> </form>
</div> </div>

View File

@@ -4,7 +4,7 @@ require_once "includes/inc_all_admin.php";
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-satellite-dish mr-2"></i>Telemetry</h3> <h3 class="card-title"><i class="fas fa-fw fa-satellite-dish me-2"></i>Telemetry</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
@@ -13,14 +13,12 @@ require_once "includes/inc_all_admin.php";
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="form-group"> <div class="mb-3">
<label>Telemetry</label> <label>Telemetry</label>
<p><i>If you can't measure it, you can't improve it. Please consider turning on telemetry data to provide valuable insights on how you're using ITFlow - so we can improve it for everyone. </i></p> <p><i>If you can't measure it, you can't improve it. Please consider turning on telemetry data to provide valuable insights on how you're using ITFlow - so we can improve it for everyone. </i></p>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-broadcast-tower"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-broadcast-tower"></i></span>
</div> <select class="form-select" name="config_telemetry">
<select class="form-control" name="config_telemetry">
<option <?php if ($config_telemetry == "0") { echo "selected"; } ?> value = "0">Disabled</option> <option <?php if ($config_telemetry == "0") { echo "selected"; } ?> value = "0">Disabled</option>
<option <?php if ($config_telemetry == "1") { echo "selected"; } ?> value = "1">Basic</option> <option <?php if ($config_telemetry == "1") { echo "selected"; } ?> value = "1">Basic</option>
<option <?php if ($config_telemetry == "2") { echo "selected"; } ?> value = "2">Detailed</option> <option <?php if ($config_telemetry == "2") { echo "selected"; } ?> value = "2">Detailed</option>
@@ -31,7 +29,7 @@ require_once "includes/inc_all_admin.php";
<hr> <hr>
<button type="submit" name="edit_telemetry_settings" class="btn btn-primary text-bold float-right"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_telemetry_settings" class="btn btn-primary text-bold float-end"><i class="fas fa-check me-2"></i>Save</button>
</form> </form>
</div> </div>

View File

@@ -1,39 +1,41 @@
<?php <?php
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
// Keep in step with the .theme-<name> blocks in css/itflow_custom.css - a name
// listed here with no matching block renders as an uncoloured, dead choice.
$theme_colors_array = array( $theme_colors_array = array(
'lightblue', 'lightblue',
'blue', 'blue',
'cyan', 'navy',
'green',
'olive',
'teal',
'red',
'maroon',
'pink',
'purple',
'indigo', 'indigo',
'purple',
'fuchsia', 'fuchsia',
'yellow', 'pink',
'maroon',
'red',
'orange', 'orange',
'yellow', 'yellow',
'black', 'olive',
'navy', 'green',
'gray' 'teal',
'cyan',
'gray',
'black'
); );
?> ?>
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-paint-brush mr-2"></i>Theme</h3> <h3 class="card-title"><i class="fas fa-fw fa-paint-brush me-2"></i>Theme</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<label>Select a Theme</label> <p class="text-muted">Sets the colour of the top bar, links, buttons and highlights.</p>
<div class="form-row">
<div class="row row-cols-3 row-cols-sm-4 row-cols-lg-6 g-3">
<?php <?php
@@ -41,18 +43,21 @@ $theme_colors_array = array (
?> ?>
<div class="col-4 text-center mb-3"> <div class="col">
<div class="form-group"> <input type="radio" class="btn-check" onchange="this.form.submit()"
<div class="custom-control custom-radio"> id="theme-<?= $theme_color ?>" name="edit_theme_settings"
<input class="custom-control-input" type="radio" onchange="this.form.submit()" id="customRadio<?= $theme_color ?>" name="edit_theme_settings" value="<?= $theme_color ?>" <?php if ($config_theme == $theme_color) { echo "checked"; } ?>> value="<?= $theme_color ?>"
<label for="customRadio<?= $theme_color ?>" class="custom-control-label"> <?php if ($config_theme == $theme_color) { echo "checked"; } ?>>
<i class="fa fa-fw fa-6x fa-circle text-<?= $theme_color ?>"></i> <label class="itflow-theme-swatch" for="theme-<?= $theme_color ?>">
<br> <?php /* the circle paints itself from --itflow-accent, so it can
<?= $theme_color ?> never drift out of step with the stylesheet */ ?>
<span class="itflow-theme-circle theme-<?= $theme_color ?>">
<i class="fas fa-circle"></i>
<i class="fas fa-check itflow-theme-tick"></i>
</span>
<span class="itflow-theme-name"><?= escapeHtml($theme_color) ?></span>
</label> </label>
</div> </div>
</div>
</div>
<?php } ?> <?php } ?>
@@ -64,7 +69,7 @@ $theme_colors_array = array (
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-image mr-2"></i>Favicon</h3> <h3 class="card-title"><i class="fas fa-fw fa-image me-2"></i>Favicon</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> <form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
@@ -72,15 +77,15 @@ $theme_colors_array = array (
<img class="mb-3" src="<?php if(file_exists("../uploads/favicon.ico")) { echo "../uploads/favicon.ico"; } else { echo "../favicon.ico"; } ?>"> <img class="mb-3" src="<?php if(file_exists("../uploads/favicon.ico")) { echo "../uploads/favicon.ico"; } else { echo "../favicon.ico"; } ?>">
<div class="form-group"> <div class="mb-3">
<input type="file" class="form-control-file" name="file" accept=".ico"> <input type="file" class="form-control" name="file" accept=".ico">
</div> </div>
<hr> <hr>
<button type="submit" name="edit_favicon_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Upload Icon</button> <button type="submit" name="edit_favicon_settings" class="btn btn-primary text-bold"><i class="fa fa-check me-2"></i>Upload Icon</button>
<?php if(file_exists("../uploads/favicon.ico")) { ?> <?php if(file_exists("../uploads/favicon.ico")) { ?>
<a href="post.php?reset_favicon&csrf_token=<?= $_SESSION['csrf_token'] ?>" class="btn btn-outline-danger"><i class="fas fa-redo-alt mr-2"></i>Reset Favicon</a> <a href="post.php?reset_favicon&csrf_token=<?= $_SESSION['csrf_token'] ?>" class="btn btn-outline-danger"><i class="fas fa-redo-alt me-2"></i>Reset Favicon</a>
<?php } ?> <?php } ?>
</form> </form>
</div> </div>

View File

@@ -4,110 +4,100 @@ require_once "includes/inc_all_admin.php";
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-life-ring mr-2"></i>Ticket Settings</h3> <h3 class="card-title"><i class="fas fa-fw fa-life-ring me-2"></i>Ticket Settings</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="form-group"> <div class="mb-3">
<label>Ticket Prefix</label> <label>Ticket Prefix</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-life-ring"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-life-ring"></i></span>
</div>
<input type="text" class="form-control" name="config_ticket_prefix" placeholder="Ticket Prefix" maxlength="200" value="<?= escapeHtml($config_ticket_prefix) ?>" pattern="^[A-Za-z-]+$" title="Only letters and hyphens are allowed" required> <input type="text" class="form-control" name="config_ticket_prefix" placeholder="Ticket Prefix" maxlength="200" value="<?= escapeHtml($config_ticket_prefix) ?>" pattern="^[A-Za-z-]+$" title="Only letters and hyphens are allowed" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Next Number</label> <label>Next Number</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div>
<input type="number" min="<?= intval($config_ticket_next_number) ?>" class="form-control" name="config_ticket_next_number" placeholder="Next Ticket Number" value="<?= intval($config_ticket_next_number) ?>" required> <input type="number" min="<?= intval($config_ticket_next_number) ?>" class="form-control" name="config_ticket_next_number" placeholder="Next Ticket Number" value="<?= intval($config_ticket_next_number) ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_ticket_email_parse" <?php if($config_ticket_email_parse == 1){ echo "checked"; } ?> value="1" id="emailToTicketParseSwitch"> <input type="checkbox" class="form-check-input" name="config_ticket_email_parse" <?php if($config_ticket_email_parse == 1){ echo "checked"; } ?> value="1" id="emailToTicketParseSwitch">
<label class="custom-control-label" for="emailToTicketParseSwitch">Email-to-ticket parsing <small class="text-secondary">(the Ticket Email Parser cron job must also be enabled - see <a href="cron.php">Maintenance &gt; Cron</a>)</small></label> <label class="form-check-label" for="emailToTicketParseSwitch">Email-to-ticket parsing <small class="text-secondary">(the Ticket Email Parser cron job must also be enabled - see <a href="cron.php">Maintenance &gt; Cron</a>)</small></label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_ticket_email_parse_unknown_senders" <?php if($config_ticket_email_parse_unknown_senders == 1){ echo "checked"; } ?> value="1" id="emailToTicketAnonParseSwitch" <?php if($config_ticket_email_parse == 0){ echo "disabled"; } ?>> <input type="checkbox" class="form-check-input" name="config_ticket_email_parse_unknown_senders" <?php if($config_ticket_email_parse_unknown_senders == 1){ echo "checked"; } ?> value="1" id="emailToTicketAnonParseSwitch" <?php if($config_ticket_email_parse == 0){ echo "disabled"; } ?>>
<label class="custom-control-label" for="emailToTicketAnonParseSwitch">Create tickets for emails from unknown senders/domains <small class="text-secondary">(Enable to ensure all emails automatically create tickets)</small></label> <label class="form-check-label" for="emailToTicketAnonParseSwitch">Create tickets for emails from unknown senders/domains <small class="text-secondary">(Enable to ensure all emails automatically create tickets)</small></label>
</div> </div>
</div> </div>
<?php if ($config_module_enable_accounting) { ?> <?php if ($config_module_enable_accounting) { ?>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_ticket_default_billable" <?php if ($config_ticket_default_billable == 1) { echo "checked"; } ?> value="1" id="ticketBillableSwitch"> <input type="checkbox" class="form-check-input" name="config_ticket_default_billable" <?php if ($config_ticket_default_billable == 1) { echo "checked"; } ?> value="1" id="ticketBillableSwitch">
<label class="custom-control-label" for="ticketBillableSwitch">Default to Billable <small class="text-secondary">(This will check the billable box on all new tickets)</small></label> <label class="form-check-label" for="ticketBillableSwitch">Default to Billable <small class="text-secondary">(This will check the billable box on all new tickets)</small></label>
</div> </div>
</div> </div>
<?php } ?> <?php } ?>
<div class="form-group"> <div class="mb-3">
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_ticket_timer_autostart" <?php if ($config_ticket_timer_autostart == 1) { echo "checked"; } ?> value="1" id="ticketTimerSwitch"> <input type="checkbox" class="form-check-input" name="config_ticket_timer_autostart" <?php if ($config_ticket_timer_autostart == 1) { echo "checked"; } ?> value="1" id="ticketTimerSwitch">
<label class="custom-control-label" for="ticketTimerSwitch">Autostart Ticket Timer <small class="text-secondary">(This option will control if the timer starts automatically or manually)</small></label> <label class="form-check-label" for="ticketTimerSwitch">Autostart Ticket Timer <small class="text-secondary">(This option will control if the timer starts automatically or manually)</small></label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Number of hours to auto close resolved tickets</label> <label>Number of hours to auto close resolved tickets</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div>
<input type="number" min="24" class="form-control" name="config_ticket_autoclose_hours" placeholder="Delay in hours before a resolved ticket is fully closed" value="<?= intval($config_ticket_autoclose_hours) ?>"> <input type="number" min="24" class="form-control" name="config_ticket_autoclose_hours" placeholder="Delay in hours before a resolved ticket is fully closed" value="<?= intval($config_ticket_autoclose_hours) ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Email address to notify when new tickets are raised <small class="text-secondary">(Ideally a distribution list/shared mailbox)</small></label> <label>Email address to notify when new tickets are raised <small class="text-secondary">(Ideally a distribution list/shared mailbox)</small></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-bell"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-bell"></i></span>
</div>
<input type="email" class="form-control" name="config_ticket_new_ticket_notification_email" placeholder="Address to notify for new tickets, leave blank for none" maxlength="200" value="<?= escapeHtml($config_ticket_new_ticket_notification_email) ?>"> <input type="email" class="form-control" name="config_ticket_new_ticket_notification_email" placeholder="Address to notify for new tickets, leave blank for none" maxlength="200" value="<?= escapeHtml($config_ticket_new_ticket_notification_email) ?>">
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Tickets Default View</label> <label>Tickets Default View</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
</div> <select class="form-select" name="config_ticket_default_view">
<select class="form-control" name="config_ticket_default_view">
<option value=0 <?php if ($config_ticket_default_view == 0) { echo "selected"; } ?>>List</option> <option value=0 <?php if ($config_ticket_default_view == 0) { echo "selected"; } ?>>List</option>
<option value=1 <?php if ($config_ticket_default_view == 1) { echo "selected"; } ?>>Compact</option> <option value=1 <?php if ($config_ticket_default_view == 1) { echo "selected"; } ?>>Compact</option>
<option value=2 <?php if ($config_ticket_default_view == 2) { echo "selected"; } ?>>Kanban</option> <option value=2 <?php if ($config_ticket_default_view == 2) { echo "selected"; } ?>>Kanban</option>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group"> <div class="mb-3">
<label>Kanban Settings</label> <label>Kanban Settings</label>
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_ticket_ordering" <?php if ($config_ticket_ordering == 1) { echo "checked"; } ?> value="1" id="ticketOrderingSwitch"> <input type="checkbox" class="form-check-input" name="config_ticket_ordering" <?php if ($config_ticket_ordering == 1) { echo "checked"; } ?> value="1" id="ticketOrderingSwitch">
<label class="custom-control-label" for="ticketOrderingSwitch">Allow ticket ordering within its column<small class="text-secondary"> (unchecked = order by priority and id)</small></label> <label class="form-check-label" for="ticketOrderingSwitch">Allow ticket ordering within its column<small class="text-secondary"> (unchecked = order by priority and id)</small></label>
</div> </div>
<div class="custom-control custom-switch"> <div class="form-check form-switch">
<input type="checkbox" class="custom-control-input" name="config_ticket_moving_columns" <?php if ($config_ticket_moving_columns == 1) { echo "checked"; } ?> value="1" id="ticketMovingColumnsSwitch"> <input type="checkbox" class="form-check-input" name="config_ticket_moving_columns" <?php if ($config_ticket_moving_columns == 1) { echo "checked"; } ?> value="1" id="ticketMovingColumnsSwitch">
<label class="custom-control-label" for="ticketMovingColumnsSwitch">Allow moving columns</label> <label class="form-check-label" for="ticketMovingColumnsSwitch">Allow moving columns</label>
</div> </div>
</div> </div>
<hr> <hr>
<button type="submit" name="edit_ticket_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_ticket_settings" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
</form> </form>
</div> </div>

Some files were not shown because too many files have changed in this diff Show More