mirror of
https://github.com/itflow-org/itflow
synced 2026-08-17 04:55:13 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccaa45b0ae | ||
|
|
698135d53d | ||
|
|
12e5d13282 | ||
|
|
60563e3392 | ||
|
|
885a002611 | ||
|
|
5c89e50f30 | ||
|
|
c650764eb5 | ||
|
|
20e2f22a27 | ||
|
|
376285ef62 | ||
|
|
163aa3062e | ||
|
|
03570ecd04 | ||
|
|
c7ef3627ce | ||
|
|
d1dcc5fb7e |
46
CHANGELOG.md
46
CHANGELOG.md
@@ -2,52 +2,6 @@
|
|||||||
|
|
||||||
This file documents all notable changes made to ITFlow.
|
This file documents all notable changes made to ITFlow.
|
||||||
|
|
||||||
## [26.08.2] Maint Release
|
|
||||||
|
|
||||||
### Upgrading to 26.08.2
|
|
||||||
|
|
||||||
Update the files from Settings > Update as normal. There is no database change in this release, so nothing else is required.
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
- Calendar: fixed the agent calendar showing no events.
|
|
||||||
- Calendar: shared calendar feeds set to publish busy blocks only were publishing full event titles, locations and descriptions to anyone holding the subscription link.
|
|
||||||
- Cron: fixed Maintenance > Cron failing to load. Scheduled jobs themselves were unaffected and kept running.
|
|
||||||
- Exports: restored the missing columns on the ticket, quote, recurring invoice, software and user exports.
|
|
||||||
- API: restored the full record on the credentials list endpoint.
|
|
||||||
- Mail: switching an existing install from Standard SMTP/IMAP to Microsoft 365 or Google OAuth no longer leaves the old mail server behind, which stopped sending and ticket email fetching from working. The connection settings for OAuth providers are now fixed by the provider and cleared on save.
|
|
||||||
|
|
||||||
|
|
||||||
## [26.08.1] Maint Release
|
|
||||||
|
|
||||||
### Upgrading to 26.08.1
|
|
||||||
|
|
||||||
Update the files from Settings > Update as normal. This release moves the database to 2.6.7 and the web updater completes it for you — the command line step that 26.08 required is not needed again.
|
|
||||||
|
|
||||||
### Breaking Changes and Notes
|
|
||||||
|
|
||||||
- Client access: agents with restricted client access now see records that have no client assigned. Previously this varied by page — unassigned tickets and projects were visible, unassigned expenses and credentials were not. It is now consistent everywhere.
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
- Setup: fixed the wizard closing itself after the first user, which left new 26.08 installs stuck in a redirect loop between `/setup` and `/login.php`.
|
|
||||||
- API: tightened client scoping on the expense read and record update endpoints.
|
|
||||||
- Income: revenue rows now respect restricted client access.
|
|
||||||
- Client PDF Export: fixed the export producing a CSV file, and each section is now gated on the module that owns it.
|
|
||||||
- AI: fixed model creation, per-use-case model selection, configurable temperature, and error reporting.
|
|
||||||
- Ticket: system-generated replies no longer record time worked that was never worked.
|
|
||||||
- Ticket: fixed an error when scheduling a ticket.
|
|
||||||
- Ticket: cancelling a schedule now cancels the calendar event on the recipient's calendar.
|
|
||||||
- Ticket: history no longer records a status change when the status did not change.
|
|
||||||
- Recurring Ticket: bulk priority changes no longer deny access to agents who are not administrators.
|
|
||||||
- Contact: deleting a contact now removes the linked portal user, and anonymizing now redacts the phone number.
|
|
||||||
- Calendar: fixed event deletion.
|
|
||||||
|
|
||||||
### New Features & Updates
|
|
||||||
- Performance: queries now select only the columns they use instead of `SELECT *`, cutting memory use and query time across the app and especially in the crons.
|
|
||||||
- Performance: removed client joins that were only there for scoping — side nav badge counts are significantly faster.
|
|
||||||
- Client scoping: added a `clientScopeSql()` helper so list queries scope on the owning column instead of a joined `clients.client_id`.
|
|
||||||
- Contributing: documented the column-selection and client-scoping conventions.
|
|
||||||
|
|
||||||
|
|
||||||
## [26.08]
|
## [26.08]
|
||||||
|
|
||||||
### Upgrading to 26.08
|
### Upgrading to 26.08
|
||||||
|
|||||||
@@ -74,10 +74,6 @@ if (isset($_POST['edit_ticket_priority'])) {
|
|||||||
### The `_model.php` pattern
|
### The `_model.php` pattern
|
||||||
|
|
||||||
Files named `agent/post/*_model.php` hold shared field collection/sanitization logic used by both the create and edit blocks of a module (e.g. `asset_model.php` is included by both `add_asset` and `edit_asset`). If create and edit share more than a couple of fields, use this pattern rather than duplicating. Model files carry the same `FROM_POST_HANDLER` guard and are excluded from the dispatcher's auto-load.
|
Files named `agent/post/*_model.php` hold shared field collection/sanitization logic used by both the create and edit blocks of a module (e.g. `asset_model.php` is included by both `add_asset` and `edit_asset`). If create and edit share more than a couple of fields, use this pattern rather than duplicating. Model files carry the same `FROM_POST_HANDLER` guard and are excluded from the dispatcher's auto-load.
|
||||||
|
|
||||||
**`_model.php` is a reserved suffix.** The exclusion is a filename match, so a *handler* named `*_model.php` is silently never loaded — its form posts, nothing claims the request, and the user gets a blank page with no error anywhere. This is what happened to `admin/post/ai_model.php`, which is why the AI Models handler is now `admin/post/ai_models.php`. Name entity handlers around the suffix (`ai_models.php`, `users.php`, `api_keys.php`).
|
|
||||||
|
|
||||||
A POST that reaches the end of `admin/post.php` or `agent/post.php` without a handler claiming it is logged to App Logs as a `Request` warning, which is the fastest way to spot this class of mistake.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -175,25 +171,7 @@ Everywhere else — anything under `agent/post/` — the call belongs in the blo
|
|||||||
|
|
||||||
### 4. Client scoping is enforced, not assumed.
|
### 4. Client scoping is enforced, not assumed.
|
||||||
|
|
||||||
A user can be restricted to a subset of clients through `user_client_permissions`. Enforcing that has two halves, and a page usually needs both.
|
After loading a record, call `enforceClientAccess()` (optionally with the record's client ID) so technicians restricted to specific clients cannot touch other clients' data by editing an ID in the URL. Look at how `resolve_ticket` does it — including the "skip if the record has no client" case.
|
||||||
|
|
||||||
**One record — `enforceClientAccess()`.** After loading a record, call it (optionally with the record's client ID) so technicians restricted to specific clients cannot touch other clients' data by editing an ID in the URL. Look at how `resolve_ticket` does it.
|
|
||||||
|
|
||||||
**A list — `clientScopeSql()`.** Any query returning more than one row appends the fragment for that resource's own client column:
|
|
||||||
|
|
||||||
```php
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT expense_id, expense_date, expense_amount, expense_description
|
|
||||||
FROM expenses
|
|
||||||
WHERE expense_archived_at IS NULL
|
|
||||||
" . clientScopeSql('expense_client_id') . "
|
|
||||||
ORDER BY expense_date DESC");
|
|
||||||
```
|
|
||||||
|
|
||||||
It returns `" AND ..."` or `""`, so it needs a `WHERE` to hang off — add `WHERE 1=1` if the query has no other condition. It is column-aware and takes an alias fine (`clientScopeSql('t.ticket_client_id')`). The API calls the same helper through the `apiClientScopeSql()` wrapper.
|
|
||||||
|
|
||||||
Scope on the resource's **own** column, not on a joined `clients.client_id`. Joining `clients` just to scope makes the filter depend on the join: with a `LEFT JOIN`, a row whose client column is `0` produces `NULL`, and `NULL IN (...)` is neither true nor false, so the row silently vanishes. If the query joins `clients` for `client_name`, keep the join for that — but still scope on the owning column.
|
|
||||||
|
|
||||||
**Records with no client (`0`) stay visible to restricted users.** `clientScopeSql()` emits `IN (0,...)` deliberately. Client restrictions partition *client* data, and a record belonging to no client is not any client's data to withhold. Do not hand-roll a variant that drops the `0` — the tree had accumulated several before this helper existed, disagreeing with each other, and reconciling them is what surfaced the inconsistency.
|
|
||||||
|
|
||||||
### 5. Escape on output.
|
### 5. Escape on output.
|
||||||
|
|
||||||
@@ -228,29 +206,8 @@ Per [SECURITY.md](SECURITY.md) — never in a public issue.
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Conventions
|
## Conventions
|
||||||
|
|
||||||
**Only technician-entered time is time worked.** `ticket_replies.ticket_reply_time_worked` is billable labour and feeds ticket totals, the technician and client time reports, project totals, invoicing and the API. A reply the *system* writes — assignment, priority change, merge, close, invoice/quote created, schedule edited, task completed or reopened — is an audit trail, not work, and records `'00:00:00'`. Only a value the technician actually typed goes in that column. Task completion estimates are planning information and stay on the task; they are never converted into time worked. `agent/ticket.php` hides the clock badge on a reply whose time is exactly `00:00:00`, so a zero renders as no time rather than as "0m".
|
**Database naming.** Every column is prefixed with the singular name of the entity it belongs to: `tickets.ticket_id`, `tickets.ticket_subject`, `clients.client_name`. This makes JOIN results unambiguous and is why queries can `SELECT *` across joins safely. New tables must follow it.
|
||||||
|
|
||||||
**Database naming.** Every column is prefixed with the singular name of the entity it belongs to: `tickets.ticket_id`, `tickets.ticket_subject`, `clients.client_name`. This makes JOIN results unambiguous, so a `SELECT *` across joins is never *wrong*. New tables must follow it.
|
|
||||||
|
|
||||||
**Select the columns you use, not `*`.** Unambiguous is not the same as cheap. `SELECT *` across three joined tables fetches every column of all three, including the `*_notes` and `*_details` TEXT columns, and throws away whatever the page never renders. A search result list that shows five fields was pulling sixty. List the columns instead:
|
|
||||||
|
|
||||||
```php
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT ticket_id, ticket_prefix, ticket_number, ticket_subject, client_name
|
|
||||||
FROM tickets
|
|
||||||
LEFT JOIN clients ON ticket_client_id = client_id
|
|
||||||
WHERE ticket_archived_at IS NULL
|
|
||||||
" . clientScopeSql('ticket_client_id') . "");
|
|
||||||
```
|
|
||||||
|
|
||||||
Two things follow from that:
|
|
||||||
|
|
||||||
- A query whose result only feeds `mysqli_num_rows()` needs no columns at all — write `SELECT 1`. Do not select a primary key "just in case": if the query joins two tables that both carry that column name, an unqualified `SELECT ticket_template_id` is an ambiguous-column error.
|
|
||||||
- Keep the join even when no column of the joined table survives into the `SELECT`, if the join is doing work — supplying a `WHERE` term, an `ORDER BY`, or the client column you scope on. Dropping a join is a separate decision from trimming the column list.
|
|
||||||
|
|
||||||
The trade is real and worth stating: `SELECT *` picks up new columns for free, an explicit list does not. Add a column to a table and every query that needs it must be updated by hand, and the failure mode is a blank field or a PHP 8 undefined-key warning rather than an error. That is the price of not fetching data nobody reads, and the project has decided to pay it on anything that loops or touches a TEXT column.
|
|
||||||
|
|
||||||
The exception is `api/v1/*/read.php`. Those endpoints hand the whole row to `read_output.php`, which serialises it straight into the JSON response — there the row *is* the output contract, so `SELECT *` is correct and trimming it would silently drop fields from every consumer.
|
|
||||||
|
|
||||||
The prefix is the entity name, which is usually but not always the singular of the table name. Where a table is named for its container rather than its row, the prefix follows the row: `calendar_events` → `event_*`, `asset_interfaces` → `interface_*`, `invoice_items` / `quote_items` → `item_*`, `rack_units` → `unit_*`, `user_roles` → `role_*`, `product_stock` → `stock_*`. Pick the prefix your columns will read best as and use it for every column in the table.
|
The prefix is the entity name, which is usually but not always the singular of the table name. Where a table is named for its container rather than its row, the prefix follows the row: `calendar_events` → `event_*`, `asset_interfaces` → `interface_*`, `invoice_items` / `quote_items` → `item_*`, `rack_units` → `unit_*`, `user_roles` → `role_*`, `product_stock` → `stock_*`. Pick the prefix your columns will read best as and use it for every column in the table.
|
||||||
|
|
||||||
@@ -267,8 +224,6 @@ A single update run applies every pending migration in order, stopping at the fi
|
|||||||
**After acting, log and notify.** State changes call `logAudit($type, $action, $description, $client_id, $entity_id)` for the audit trail. User-facing events may also call `appNotify()`. Fire `triggerCustomAction()` where a site might reasonably want a hook. Then call `flashAlert($message, $type)` and `redirect()` (defaults to the referer) rather than setting session keys or `header()` manually.
|
**After acting, log and notify.** State changes call `logAudit($type, $action, $description, $client_id, $entity_id)` for the audit trail. User-facing events may also call `appNotify()`. Fire `triggerCustomAction()` where a site might reasonably want a hook. Then call `flashAlert($message, $type)` and `redirect()` (defaults to the referer) rather than setting session keys or `header()` manually.
|
||||||
|
|
||||||
**Function names (post-rename).** Helpers were renamed for clarity in 2026; the old names **no longer exist** — code calling them fatals. If you're rebasing an old PR or following an old tutorial, translate: `sanitizeInput` → `escapeSql`, `nullable_htmlentities` → `escapeHtml`, `logAction` → `logAudit`, `flash_alert` → `flashAlert`, `customAction` → `triggerCustomAction`, `encryptLoginEntry`/`decryptLoginEntry` → `encryptCredentialEntry`/`decryptCredentialEntry`, `strtoAZaz09` → `toAlphanumeric`, `fetchUpdates` → `checkForUpdates`, `sanitize_url` → `escapeUrl`.
|
**Function names (post-rename).** Helpers were renamed for clarity in 2026; the old names **no longer exist** — code calling them fatals. If you're rebasing an old PR or following an old tutorial, translate: `sanitizeInput` → `escapeSql`, `nullable_htmlentities` → `escapeHtml`, `logAction` → `logAudit`, `flash_alert` → `flashAlert`, `customAction` → `triggerCustomAction`, `encryptLoginEntry`/`decryptLoginEntry` → `encryptCredentialEntry`/`decryptCredentialEntry`, `strtoAZaz09` → `toAlphanumeric`, `fetchUpdates` → `checkForUpdates`, `sanitize_url` → `escapeUrl`.
|
||||||
|
|
||||||
One removed **variable** deserves its own warning: the old `$access_permission_query` global is gone, replaced by `clientScopeSql()` (security rule 4). Unlike a removed function, it does not fatal — an undefined variable interpolates as an empty string, so a rebased query keeps running with **no client scoping at all**. Grep for it before rebasing anything that touches a list query.
|
|
||||||
|
|
||||||
**Helpers that fetch data return it raw.** If you add a `getXById()`-style helper, return the column value untouched and let callers escape it (security rule 1). Validating what the helper interpolates into its *own* query — table and column names, the id — is still the helper's job; that is query construction, not output escaping, and the two are not the same thing.
|
**Helpers that fetch data return it raw.** If you add a `getXById()`-style helper, return the column value untouched and let callers escape it (security rule 1). Validating what the helper interpolates into its *own* query — table and column names, the id — is still the helper's job; that is query construction, not output escaping, and the two are not the same thing.
|
||||||
|
|
||||||
|
|||||||
31
README.md
31
README.md
@@ -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">Suggest Feature</a>
|
<a href="https://forum.itflow.org/t/features">Request 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.
|
||||||
- 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.
|
||||||
- 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, free platform that you control.
|
- ITFlow consolidates common MSP needs (documentation, ticketing and billing) into one unified system.
|
||||||
|
|
||||||
|
<!-- 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. See the [video](https://www.youtube.com/watch?v=kKz9NOU_1XE) walk through.
|
- 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).
|
||||||
```
|
```
|
||||||
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) (coming soon).
|
- If you'd prefer, we can [host ITFlow for you](https://services.itflow.org/hosting.php).
|
||||||
|
|
||||||
<!-- FEATURES -->
|
<!-- FEATURES -->
|
||||||
## Key Features
|
## Key Features
|
||||||
* Client documentation - assets, contacts, domains, docs/files, passwords, tickets, and more
|
* Client documentation - assets, contacts, domains, docs, files, passwords, and more
|
||||||
* Billing - quotes, invoices and expenses, with Stripe integration for online payments
|
* Accounting / Billing - finance dashboard, quotes, invoices, accounting, expenses, etc
|
||||||
* Alerting - domain and SSL expiry/renewals
|
* Client Portal - self service quote/invoice/ticket management for clients
|
||||||
* Client Portal - self service quote, invoice, and ticket management for clients
|
* Alerting - account balance, invoices, domain/SSL renewals
|
||||||
|
* 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 suggest new features or report bugs.
|
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.
|
||||||
|
|
||||||
<!-- CONTRIBUTING -->
|
<!-- CONTRIBUTING -->
|
||||||
## Support & Contributions
|
## Support & Contributions
|
||||||
|
|
||||||
### Forum
|
### Forum
|
||||||
For help using ITFlow, bugs, feature suggestions, and other general ideas or discussions, please use the community [forum](https://forum.itflow.org).
|
For help using ITFlow, bugs, feature requests, and general ideas / 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,16 +90,17 @@ We have temporarily paused PRs from the community.
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
### Supporters
|
### Supporters
|
||||||
We’re incredibly grateful to the organizations and individuals who [sponsor](https://services.itflow.org) the project - a big thank you to:
|
We’re incredibly grateful to the organizations and individuals who support 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
|
||||||
* We've had a stable release of the project since Jan 2025.
|
* As of 2025, we now have a stable release of the project.
|
||||||
* 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).
|
||||||
|
|
||||||
|
|||||||
16
SECURITY.md
16
SECURITY.md
@@ -1,12 +1,12 @@
|
|||||||
# Security Policy
|
# Security Policy
|
||||||
|
|
||||||
## **Please do NOT report security concerns/vulnerabilities publicly**
|
## **Please do NOT report security concerns/vulnerabilities publicly (Issues/forum)**
|
||||||
|
|
||||||
**ITFlow stores important information, so we take security seriously**
|
**We take security seriously**
|
||||||
|
|
||||||
- Whilst we are confident in the safety of the code, no system is risk-free. Nearly all software has bugs.
|
- 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.
|
||||||
- Use your best judgement before storing highly confidential information in ITFlow.
|
- 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).
|
||||||
- We attempt to follow security best practices where possible, including automated code scanning.
|
- [](https://sonarcloud.io/summary/new_code?id=itflow-org_itflow)
|
||||||
|
|
||||||
## 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,8 +19,6 @@ 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 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 in as much detail as possible, so we can fix it.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ $order = "ASC";
|
|||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
require_once "includes/inc_all_admin.php";
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT ai_model_id, ai_model_name, ai_model_prompt, ai_model_use_case, ai_provider_id,
|
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id ORDER BY $sort $order");
|
||||||
ai_provider_name FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id ORDER BY $sort $order");
|
|
||||||
|
|
||||||
$num_rows = mysqli_num_rows($sql);
|
$num_rows = mysqli_num_rows($sql);
|
||||||
|
|
||||||
@@ -25,9 +24,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 me-2"></i>AI Models</h3>
|
<h3 class="card-title mt-2"><i class="fas fa-fw fa-robot mr-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 me-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 mr-2"></i>Add Model</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -79,18 +78,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 dropstart text-center">
|
<div class="dropdown dropleft text-center">
|
||||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
|
<button class="btn btn-secondary btn-sm" type="button" data-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 me-2"></i>Edit
|
<i class="fas fa-fw fa-edit mr-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 me-2"></i>Delete
|
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ $order = "ASC";
|
|||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
require_once "includes/inc_all_admin.php";
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT ai_provider_api_key, ai_provider_api_url, ai_provider_id, ai_provider_name FROM ai_providers ORDER BY $sort $order");
|
$sql = mysqli_query($mysqli, "SELECT * FROM ai_providers ORDER BY $sort $order");
|
||||||
|
|
||||||
$num_rows = mysqli_num_rows($sql);
|
$num_rows = mysqli_num_rows($sql);
|
||||||
|
|
||||||
@@ -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 me-2"></i>AI Providers</h3>
|
<h3 class="card-title mt-2"><i class="fas fa-fw fa-robot mr-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 me-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 mr-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 bg-dark rounded-pill p-2" href="ai_models.php"><?= $ai_model_count ?></a>
|
<a class="badge badge-dark badge-pill p-2" href="ai_models.php"><?= $ai_model_count ?></a>
|
||||||
<td>
|
<td>
|
||||||
<div class="dropdown dropstart text-center">
|
<div class="dropdown dropleft text-center">
|
||||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
|
<button class="btn btn-secondary btn-sm" type="button" data-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 me-2"></i>Edit
|
<i class="fas fa-fw fa-edit mr-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 me-2"></i>Delete
|
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
|
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT SQL_CALC_FOUND_ROWS api_key_created_at, api_key_expire, api_key_id, api_key_name, api_key_secret, user_name FROM api_keys
|
"SELECT SQL_CALC_FOUND_ROWS * FROM api_keys
|
||||||
LEFT JOIN users on api_key_user_id = user_id
|
LEFT JOIN users on api_key_user_id = user_id
|
||||||
WHERE (api_key_name LIKE '%$q%')
|
WHERE (api_key_name LIKE '%$q%')
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||||
@@ -18,36 +18,38 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card card-dark">
|
||||||
<div class="card-header bg-dark py-2">
|
<div class="card-header py-2">
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-key me-2"></i>API Keys</h3>
|
<h3 class="card-title mt-2"><i class="fas fa-fw fa-key mr-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 me-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 mr-2"></i>New API Key</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-header py-3">
|
<div class="card-body">
|
||||||
|
|
||||||
<form autocomplete="off">
|
<form autocomplete="off">
|
||||||
<div class="row g-2 align-items-center">
|
<div class="row">
|
||||||
|
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<div class="input-group">
|
<div class="input-group mb-3 mb-md-0">
|
||||||
<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-end">
|
<div class="btn-group float-right">
|
||||||
<div class="dropdown ms-2" id="bulkActionButton" hidden>
|
<div class="dropdown ml-2" id="bulkActionButton" hidden>
|
||||||
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
|
||||||
<i class="fas fa-fw fa-layer-group me-2"></i>Bulk Action (<span id="selectedCount">0</span>)
|
<i class="fas fa-fw fa-layer-group mr-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 me-2"></i>Delete
|
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -57,110 +59,111 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
<hr>
|
||||||
|
|
||||||
<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 mb-0">
|
<table class="table table-striped table-borderless table-hover">
|
||||||
<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>
|
|
||||||
<td class="pe-0">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" onclick="checkAll(this)">
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=api_key_name&order=<?= $disp ?>">
|
|
||||||
Name <?php if ($sort == 'api_key_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=api_key_user_id&order=<?= $disp ?>">
|
|
||||||
User <?php if ($sort == 'api_key_user_id') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=api_key_secret&order=<?= $disp ?>">
|
|
||||||
Secret <?php if ($sort == 'api_key_secret') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=api_key_created_at&order=<?= $disp ?>">
|
|
||||||
Created <?php if ($sort == 'api_key_created_at') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=api_key_expire&order=<?= $disp ?>">
|
|
||||||
Expires <?php if ($sort == 'api_key_expire') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
|
||||||
$api_key_id = intval($row['api_key_id']);
|
|
||||||
$api_key_name = escapeHtml($row['api_key_name']);
|
|
||||||
$api_key_secret = escapeHtml("************" . substr($row['api_key_secret'], -4));
|
|
||||||
$api_key_created_at = escapeHtml($row['api_key_created_at']);
|
|
||||||
$api_key_expire = escapeHtml($row['api_key_expire']);
|
|
||||||
if ($api_key_expire < date("Y-m-d H:i:s")) {
|
|
||||||
$api_key_expire = $api_key_expire . " (Expired)";
|
|
||||||
}
|
|
||||||
|
|
||||||
$api_key_user = !empty($row['user_name']) ? escapeHtml($row['user_name']) : "<i>None</i>";
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="pe-0">
|
<td class="pr-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" type="checkbox" onclick="checkAll(this)">
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="text-bold"><?= $api_key_name ?></td>
|
|
||||||
<td><?= $api_key_user ?></td>
|
|
||||||
<td><?= $api_key_secret ?></td>
|
|
||||||
<td><?= $api_key_created_at ?></td>
|
|
||||||
<td><?= $api_key_expire ?></td>
|
|
||||||
<td>
|
|
||||||
<div class="dropdown dropstart text-center">
|
|
||||||
<button class="btn btn-secondary btn-sm" type="button" 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/api/api_key_edit.php?id=<?= $api_key_id ?>">
|
|
||||||
<i class="fas fa-fw fa-edit me-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
<?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'] ?>">
|
|
||||||
<i class="fas fa-fw fa-times me-2"></i>Revoke
|
|
||||||
</a>
|
|
||||||
<?php } ?>
|
|
||||||
<?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'] ?>">
|
|
||||||
<i class="fas fa-fw fa-times me-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=api_key_name&order=<?= $disp ?>">
|
||||||
|
Name <?php if ($sort == 'api_key_name') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=api_key_user_id&order=<?= $disp ?>">
|
||||||
|
User <?php if ($sort == 'api_key_user_id') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=api_key_secret&order=<?= $disp ?>">
|
||||||
|
Secret <?php if ($sort == 'api_key_secret') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=api_key_created_at&order=<?= $disp ?>">
|
||||||
|
Created <?php if ($sort == 'api_key_created_at') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=api_key_expire&order=<?= $disp ?>">
|
||||||
|
Expires <?php if ($sort == 'api_key_expire') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th class="text-center">Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
|
||||||
<?php } ?>
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
|
$api_key_id = intval($row['api_key_id']);
|
||||||
|
$api_key_name = escapeHtml($row['api_key_name']);
|
||||||
|
$api_key_secret = escapeHtml("************" . substr($row['api_key_secret'], -4));
|
||||||
|
$api_key_created_at = escapeHtml($row['api_key_created_at']);
|
||||||
|
$api_key_expire = escapeHtml($row['api_key_expire']);
|
||||||
|
if ($api_key_expire < date("Y-m-d H:i:s")) {
|
||||||
|
$api_key_expire = $api_key_expire . " (Expired)";
|
||||||
|
}
|
||||||
|
|
||||||
|
$api_key_user = !empty($row['user_name']) ? escapeHtml($row['user_name']) : "<i>None</i>";
|
||||||
|
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td class="pr-0">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input bulk-select" type="checkbox" name="api_key_ids[]" value="<?= $api_key_id ?>">
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="text-bold"><?= $api_key_name ?></td>
|
||||||
|
<td><?= $api_key_user ?></td>
|
||||||
|
<td><?= $api_key_secret ?></td>
|
||||||
|
<td><?= $api_key_created_at ?></td>
|
||||||
|
<td><?= $api_key_expire ?></td>
|
||||||
|
<td>
|
||||||
|
<div class="dropdown dropleft text-center">
|
||||||
|
<button class="btn btn-secondary btn-sm" type="button" data-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/api/api_key_edit.php?id=<?= $api_key_id ?>">
|
||||||
|
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
||||||
|
</a>
|
||||||
|
<?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'] ?>">
|
||||||
|
<i class="fas fa-fw fa-times mr-2"></i>Revoke
|
||||||
|
</a>
|
||||||
|
<?php } ?>
|
||||||
|
<?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'] ?>">
|
||||||
|
<i class="fas fa-fw fa-times mr-2"></i>Delete
|
||||||
|
</a>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<?php require_once "../includes/filter_footer.php"; ?>
|
||||||
</div>
|
</div>
|
||||||
<?php require_once "../includes/filter_footer.php"; ?>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="../js/bulk_actions.js"></script>
|
<script src="../js/bulk_actions.js"></script>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ if (isset($_GET['category']) & !empty($_GET['catergory'])) {
|
|||||||
|
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT SQL_CALC_FOUND_ROWS app_log_category, app_log_created_at, app_log_details, app_log_id, app_log_type FROM app_logs
|
"SELECT SQL_CALC_FOUND_ROWS * FROM app_logs
|
||||||
WHERE (app_log_type LIKE '%$q%' OR app_log_category LIKE '%$q%' OR app_log_details LIKE '%$q%')
|
WHERE (app_log_type LIKE '%$q%' OR app_log_category LIKE '%$q%' OR app_log_details LIKE '%$q%')
|
||||||
AND DATE(app_log_created_at) BETWEEN '$dtf' AND '$dtt'
|
AND DATE(app_log_created_at) BETWEEN '$dtf' AND '$dtt'
|
||||||
$log_type_query
|
$log_type_query
|
||||||
@@ -40,26 +40,28 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card card-dark">
|
||||||
<div class="card-header bg-dark py-2">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-history me-2"></i>App 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>App Logs</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
<form autocomplete="off">
|
<form autocomplete="off">
|
||||||
<div class="row g-2 align-items-end">
|
<div class="row">
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<div>
|
<div class="form-group">
|
||||||
<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">
|
||||||
<button class="btn btn-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#advancedFilter"><i class="fas fa-filter"></i></button>
|
<div class="input-group-append">
|
||||||
|
<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>
|
<div class="form-group">
|
||||||
<select class="form-select select2" name="type" onchange="this.form.submit()">
|
<select class="form-control select2" name="type" onchange="this.form.submit()">
|
||||||
<option value="">- All Types -</option>
|
<option value="">- All Types -</option>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
@@ -77,8 +79,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>
|
<div class="form-group">
|
||||||
<select class="form-select select2" name="category" onchange="this.form.submit()">
|
<select class="form-control select2" name="category" onchange="this.form.submit()">
|
||||||
<option value="">- All Categories -</option>
|
<option value="">- All Categories -</option>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
@@ -96,10 +98,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 g-3">
|
<div class="row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div>
|
<div class="form-group">
|
||||||
<label class="form-label">Date range</label>
|
<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 ?? '') ?>">
|
||||||
@@ -109,61 +111,62 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
<hr>
|
||||||
<div class="table-responsive-sm">
|
<div class="table-responsive-sm">
|
||||||
<table class="table table-sm table-striped table-borderless table-hover mb-0">
|
<table class="table table-sm table-striped table-borderless table-hover">
|
||||||
<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>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=app_log_created_at&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=app_log_created_at&order=<?= $disp ?>">
|
||||||
Timestamp <?php if ($sort == 'app_log_created_at') { echo $order_icon; } ?>
|
Timestamp <?php if ($sort == 'app_log_created_at') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=app_log_type&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=app_log_type&order=<?= $disp ?>">
|
||||||
Type <?php if ($sort == 'app_log_type') { echo $order_icon; } ?>
|
Type <?php if ($sort == 'app_log_type') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=app_log_category&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=app_log_category&order=<?= $disp ?>">
|
||||||
Category <?php if ($sort == 'app_log_category') { echo $order_icon; } ?>
|
Category <?php if ($sort == 'app_log_category') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=app_log_details&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=app_log_details&order=<?= $disp ?>">
|
||||||
Details <?php if ($sort == 'app_log_details') { echo $order_icon; } ?>
|
Details <?php if ($sort == 'app_log_details') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$log_id = intval($row['app_log_id']);
|
$log_id = intval($row['app_log_id']);
|
||||||
$log_type = escapeHtml($row['app_log_type']);
|
$log_type = escapeHtml($row['app_log_type']);
|
||||||
$log_category = escapeHtml($row['app_log_category']);
|
$log_category = escapeHtml($row['app_log_category']);
|
||||||
$log_details = escapeHtml($row['app_log_details']);
|
$log_details = escapeHtml($row['app_log_details']);
|
||||||
$log_created_at = escapeHtml($row['app_log_created_at']);
|
$log_created_at = escapeHtml($row['app_log_created_at']);
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="text-monospace"><?= $log_created_at ?></td>
|
||||||
|
<td><?= $log_type ?></td>
|
||||||
|
<td><?= $log_category ?></td>
|
||||||
|
<td><?= $log_details ?></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<tr>
|
</tbody>
|
||||||
<td class="font-monospace"><?= $log_created_at ?></td>
|
</table>
|
||||||
<td><?= $log_type ?></td>
|
</div>
|
||||||
<td><?= $log_category ?></td>
|
<?php require_once "../includes/filter_footer.php";
|
||||||
<td><?= $log_details ?></td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "../includes/filter_footer.php";
|
|
||||||
?>
|
?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ if (isset($_GET['action']) & !empty($_GET['action'])) {
|
|||||||
|
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT SQL_CALC_FOUND_ROWS client_id, client_name, log_action, log_created_at, log_description, log_entity_id, log_id,
|
"SELECT SQL_CALC_FOUND_ROWS * FROM logs
|
||||||
log_ip, log_type, log_user_agent, user_id, user_name FROM logs
|
|
||||||
LEFT JOIN users ON log_user_id = user_id
|
LEFT JOIN users ON log_user_id = user_id
|
||||||
LEFT JOIN clients ON log_client_id = client_id
|
LEFT JOIN clients ON log_client_id = client_id
|
||||||
WHERE (log_type LIKE '%$q%' OR log_action LIKE '%$q%' OR log_description LIKE '%$q%' OR log_ip LIKE '%$q%' OR log_user_agent LIKE '%$q%' OR user_name LIKE '%$q%' OR client_name LIKE '%$q%')
|
WHERE (log_type LIKE '%$q%' OR log_action LIKE '%$q%' OR log_description LIKE '%$q%' OR log_ip LIKE '%$q%' OR log_user_agent LIKE '%$q%' OR user_name LIKE '%$q%' OR client_name LIKE '%$q%')
|
||||||
@@ -65,28 +64,30 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card card-dark">
|
||||||
<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">
|
||||||
<form autocomplete="off">
|
<h3 class="card-title"><i class="fas fa-fw fa-history mr-2"></i>Audit Logs</h3>
|
||||||
<div class="row g-2 align-items-end">
|
</div>
|
||||||
|
<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">
|
<div class="input-group mb-3 mb-md-0">
|
||||||
<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">
|
||||||
<button class="btn btn-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#advancedFilter"><i class="fas fa-filter"></i></button>
|
<div class="input-group-append">
|
||||||
|
<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">
|
<div class="input-group mb-3 mb-md-0">
|
||||||
<select class="form-select select2" name="client" onchange="this.form.submit()">
|
<select class="form-control select2" name="client" onchange="this.form.submit()">
|
||||||
<option value="">- All Clients -</option>
|
<option value="">- All Clients -</option>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql_clients_filter = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients ORDER BY client_name ASC");
|
$sql_clients_filter = mysqli_query($mysqli, "SELECT * FROM clients ORDER BY client_name ASC");
|
||||||
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
|
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
|
||||||
$client_id = intval($row['client_id']);
|
$client_id = intval($row['client_id']);
|
||||||
$client_name = escapeHtml($row['client_name']);
|
$client_name = escapeHtml($row['client_name']);
|
||||||
@@ -101,12 +102,12 @@ $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">
|
<div class="input-group mb-3 mb-md-0">
|
||||||
<select class="form-select select2" name="user" onchange="this.form.submit()">
|
<select class="form-control select2" name="user" onchange="this.form.submit()">
|
||||||
<option value="">- All Users -</option>
|
<option value="">- All Users -</option>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql_users_filter = mysqli_query($mysqli, "SELECT user_id, user_name FROM users ORDER BY user_name ASC");
|
$sql_users_filter = mysqli_query($mysqli, "SELECT * FROM users ORDER BY user_name ASC");
|
||||||
while ($row = mysqli_fetch_assoc($sql_users_filter)) {
|
while ($row = mysqli_fetch_assoc($sql_users_filter)) {
|
||||||
$user_id = intval($row['user_id']);
|
$user_id = intval($row['user_id']);
|
||||||
$user_name = escapeHtml($row['user_name']);
|
$user_name = escapeHtml($row['user_name']);
|
||||||
@@ -121,8 +122,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">
|
<div class="input-group mb-3 mb-md-0">
|
||||||
<select class="form-select select2" name="type" onchange="this.form.submit()">
|
<select class="form-control select2" name="type" onchange="this.form.submit()">
|
||||||
<option value="">- All Types -</option>
|
<option value="">- All Types -</option>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
@@ -140,8 +141,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">
|
<div class="input-group mb-3 mb-md-0">
|
||||||
<select class="form-select select2" name="action" onchange="this.form.submit()">
|
<select class="form-control select2" name="action" onchange="this.form.submit()">
|
||||||
<option value="">- All Actions -</option>
|
<option value="">- All Actions -</option>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
@@ -158,11 +159,11 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
</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 g-3">
|
<div class="row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div>
|
<div class="form-group">
|
||||||
<label class="form-label">Date range</label>
|
<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 ?? '') ?>">
|
||||||
@@ -172,108 +173,109 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
<hr>
|
||||||
<div class="table-responsive-sm">
|
<div class="table-responsive-sm">
|
||||||
<table class="table table-sm table-striped table-borderless table-hover mb-0">
|
<table class="table table-sm table-striped table-borderless table-hover">
|
||||||
<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>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=log_created_at&order=<?= $disp ?>">
|
|
||||||
Timestamp <?php if ($sort == 'log_created_at') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=user_name&order=<?= $disp ?>">
|
|
||||||
User <?php if ($sort == 'user_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<?php if (empty($client)) { ?>
|
|
||||||
<th>
|
<th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=client_name&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=log_created_at&order=<?= $disp ?>">
|
||||||
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
|
Timestamp <?php if ($sort == 'log_created_at') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<?php } ?>
|
<th>
|
||||||
<th>
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=user_name&order=<?= $disp ?>">
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=log_type&order=<?= $disp ?>">
|
User <?php if ($sort == 'user_name') { echo $order_icon; } ?>
|
||||||
Type <?php if ($sort == 'log_type') { echo $order_icon; } ?>
|
</a>
|
||||||
</a>
|
</th>
|
||||||
</th>
|
<?php if (empty($client)) { ?>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=log_action&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=client_name&order=<?= $disp ?>">
|
||||||
Action <?php if ($sort == 'log_action') { echo $order_icon; } ?>
|
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<?php } ?>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=log_description&order=<?= $disp ?>">
|
<th>
|
||||||
Description <?php if ($sort == 'log_description') { echo $order_icon; } ?>
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=log_type&order=<?= $disp ?>">
|
||||||
</a>
|
Type <?php if ($sort == 'log_type') { echo $order_icon; } ?>
|
||||||
</th>
|
</a>
|
||||||
<th>
|
</th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=log_ip&order=<?= $disp ?>">
|
<th>
|
||||||
IP Address <?php if ($sort == 'log_ip') { echo $order_icon; } ?>
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=log_action&order=<?= $disp ?>">
|
||||||
</a>
|
Action <?php if ($sort == 'log_action') { echo $order_icon; } ?>
|
||||||
</th>
|
</a>
|
||||||
<th>
|
</th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=log_user_agent&order=<?= $disp ?>">
|
<th>
|
||||||
User Agent <?php if ($sort == 'log_user_agent') { echo $order_icon; } ?>
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=log_description&order=<?= $disp ?>">
|
||||||
</a>
|
Description <?php if ($sort == 'log_description') { echo $order_icon; } ?>
|
||||||
</th>
|
</a>
|
||||||
</tr>
|
</th>
|
||||||
</thead>
|
<th>
|
||||||
<tbody>
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=log_ip&order=<?= $disp ?>">
|
||||||
<?php
|
IP Address <?php if ($sort == 'log_ip') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=log_user_agent&order=<?= $disp ?>">
|
||||||
|
User Agent <?php if ($sort == 'log_user_agent') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$log_id = intval($row['log_id']);
|
$log_id = intval($row['log_id']);
|
||||||
$log_type = escapeHtml($row['log_type']);
|
$log_type = escapeHtml($row['log_type']);
|
||||||
$log_action = escapeHtml($row['log_action']);
|
$log_action = escapeHtml($row['log_action']);
|
||||||
$log_description = escapeHtml($row['log_description']);
|
$log_description = escapeHtml($row['log_description']);
|
||||||
$log_ip = escapeHtml($row['log_ip']);
|
$log_ip = escapeHtml($row['log_ip']);
|
||||||
$log_user_agent = escapeHtml($row['log_user_agent']);
|
$log_user_agent = escapeHtml($row['log_user_agent']);
|
||||||
$log_user_os = getOS($log_user_agent);
|
$log_user_os = getOS($log_user_agent);
|
||||||
$log_user_browser = getWebBrowser($log_user_agent);
|
$log_user_browser = getWebBrowser($log_user_agent);
|
||||||
$log_created_at = escapeHtml($row['log_created_at']);
|
$log_created_at = escapeHtml($row['log_created_at']);
|
||||||
$user_id = intval($row['user_id']);
|
$user_id = intval($row['user_id']);
|
||||||
$user_name = escapeHtml($row['user_name']);
|
$user_name = escapeHtml($row['user_name']);
|
||||||
if (empty($user_name)) {
|
if (empty($user_name)) {
|
||||||
$user_name_display = "-";
|
$user_name_display = "-";
|
||||||
} else {
|
} else {
|
||||||
$user_name_display = $user_name;
|
$user_name_display = $user_name;
|
||||||
}
|
}
|
||||||
$client_name = escapeHtml($row['client_name']);
|
$client_name = escapeHtml($row['client_name']);
|
||||||
$client_id = intval($row['client_id']);
|
$client_id = intval($row['client_id']);
|
||||||
if (empty($client_name)) {
|
if (empty($client_name)) {
|
||||||
$client_name_display = "-";
|
$client_name_display = "-";
|
||||||
} else {
|
} else {
|
||||||
$client_name_display = "<a href='../agent/client_overview.php?client_id=$client_id'>$client_name</a>";
|
$client_name_display = "<a href='../agent/client_overview.php?client_id=$client_id'>$client_name</a>";
|
||||||
}
|
}
|
||||||
$log_entity_id = intval($row['log_entity_id']);
|
$log_entity_id = intval($row['log_entity_id']);
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="text-monospace"><?= $log_created_at ?></td>
|
||||||
|
<td><?= $user_name_display ?></td>
|
||||||
|
<?php if(empty($client)) { ?>
|
||||||
|
<td><?= $client_name_display ?></td>
|
||||||
|
<?php } ?>
|
||||||
|
<td><?= $log_type ?></td>
|
||||||
|
<td><?= $log_action ?></td>
|
||||||
|
<td><?= $log_description ?></td>
|
||||||
|
<td class="text-monospace"><?= $log_ip ?></td>
|
||||||
|
<td><?= "$log_user_os<div class='text-secondary'>$log_user_browser</div>" ?></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<tr>
|
</tbody>
|
||||||
<td class="font-monospace"><?= $log_created_at ?></td>
|
</table>
|
||||||
<td><?= $user_name_display ?></td>
|
</div>
|
||||||
<?php if(empty($client)) { ?>
|
<?php require_once "../includes/filter_footer.php";
|
||||||
<td><?= $client_name_display ?></td>
|
|
||||||
<?php } ?>
|
|
||||||
<td><?= $log_type ?></td>
|
|
||||||
<td><?= $log_action ?></td>
|
|
||||||
<td><?= $log_description ?></td>
|
|
||||||
<td class="font-monospace"><?= $log_ip ?></td>
|
|
||||||
<td><?= "$log_user_os<div class='text-secondary'>$log_user_browser</div>" ?></td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "../includes/filter_footer.php";
|
|
||||||
?>
|
?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ $cron_is_running = $cron_last_dispatch_at !== null && (time() - strtotime($cron_
|
|||||||
|
|
||||||
$backup_job = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT cron_job_enabled, cron_job_daily_at FROM cron_jobs WHERE cron_job_name = 'backup'"));
|
$backup_job = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT cron_job_enabled, cron_job_daily_at FROM cron_jobs WHERE cron_job_name = 'backup'"));
|
||||||
|
|
||||||
$backups = mysqli_query($mysqli, "SELECT backup_created_at, backup_error, backup_id, backup_size, backup_source, backup_status,
|
$backups = mysqli_query($mysqli, "SELECT * FROM backups ORDER BY backup_created_at DESC LIMIT 100");
|
||||||
backup_type FROM backups ORDER BY backup_created_at DESC LIMIT 100");
|
|
||||||
|
|
||||||
$pending_count = intval(mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT(*) AS c FROM backups WHERE backup_status IN ('Pending','Running')"))['c']);
|
$pending_count = intval(mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT(*) AS c FROM backups WHERE backup_status IN ('Pending','Running')"))['c']);
|
||||||
|
|
||||||
@@ -33,15 +32,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 me-2"></i>Master encryption key</h5>
|
<h5><i class="fas fa-fw fa-key mr-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 font-monospace" value="<?= escapeHtml($master_key_reveal) ?>" readonly onclick="this.select();">
|
<input type="text" class="form-control text-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 me-2"></i>No backup encryption key</h5>
|
<h5><i class="fas fa-fw fa-exclamation-triangle mr-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 = '<32 random characters>';</code> to it yourself.
|
<code>$config_backup_key = '<32 random characters>';</code> to it yourself.
|
||||||
@@ -50,26 +49,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 me-2"></i>Cron is not running</h5>
|
<h5><i class="fas fa-fw fa-exclamation-triangle mr-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 > Cron</a>.
|
start here will sit in the queue. See <a href="cron.php">Maintenance > 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 me-2"></i>Cron is switched off in
|
<i class="fas fa-fw fa-exclamation-circle mr-2"></i>Cron is switched off in
|
||||||
<a href="cron.php">Maintenance > Cron</a>.
|
<a href="cron.php">Maintenance > 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 me-2"></i>Create a Backup</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-cloud-upload-alt mr-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 me-2"></i><strong><?= $pending_count ?></strong> backup<?= $pending_count == 1 ? ' is' : 's are' ?>
|
<i class="fas fa-fw fa-spinner mr-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 +80,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 me-2"></i>Start
|
<i class="fas fa-fw fa-play mr-2"></i>Start
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,7 +90,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 me-2"></i>Start
|
<i class="fas fa-fw fa-play mr-2"></i>Start
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -100,8 +99,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-bs-toggle="modal" data-bs-target="#masterKeyModal">
|
<button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#masterKeyModal">
|
||||||
<i class="fas fa-fw fa-key me-2"></i>Export
|
<i class="fas fa-fw fa-key mr-2"></i>Export
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -112,7 +111,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 me-2"></i>Backups</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-archive mr-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 +123,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-end">Action</th>
|
<th class="text-right">Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -148,12 +147,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 text-bg-<?= $badge ?>"><?= escapeHtml($status) ?></span>
|
<span class="badge badge-<?= $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-end">
|
<td class="text-right">
|
||||||
<?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 +172,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 me-2"></i>Encryption Key</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-lock mr-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 me-2"></i>
|
<i class="fas fa-fw fa-exclamation-triangle mr-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,10 +185,12 @@ 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 font-monospace" value="<?= escapeHtml($backup_key) ?>" readonly onclick="this.select();">
|
<input type="text" class="form-control text-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 } ?>
|
||||||
|
|
||||||
@@ -202,43 +203,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 me-2"></i>Scheduled Backups & Retention</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-clock mr-2"></i>Scheduled Backups & 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="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-4">
|
<div class="form-group col-md-4">
|
||||||
<label>Scheduled backup type</label>
|
<label>Scheduled backup type</label>
|
||||||
<select class="form-select" name="config_backup_cron_type">
|
<select class="form-control" 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="mb-3 col-md-4">
|
<div class="form-group 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="mb-3 col-md-4">
|
<div class="form-group 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 me-2"></i>Save</button>
|
<button type="submit" name="edit_backup_settings" class="btn btn-primary"><i class="fas fa-fw fa-check mr-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 me-2"></i>Scheduled backups run daily at
|
<i class="fas fa-fw fa-check text-success mr-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 me-2"></i>Scheduled backups are switched off.
|
<i class="fas fa-fw fa-times text-danger mr-2"></i>Scheduled backups are switched off.
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
Turn them on or change the time in <a href="cron.php">Maintenance > Cron</a>.
|
Turn them on or change the time in <a href="cron.php">Maintenance > Cron</a>.
|
||||||
</p>
|
</p>
|
||||||
@@ -251,7 +252,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 me-2"></i>Restoring</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-undo mr-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>
|
||||||
@@ -265,8 +266,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 me-2"></i>Export Master Key</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-key mr-2"></i>Export Master Key</h5>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
<button type="button" class="close" data-dismiss="modal"><span>×</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'] ?>">
|
||||||
@@ -274,13 +275,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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Show Master Key</button>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ if (!isset($_GET['backup_id'])) {
|
|||||||
|
|
||||||
$backup_id = intval($_GET['backup_id']);
|
$backup_id = intval($_GET['backup_id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT backup_file_name FROM backups WHERE backup_id = $backup_id AND backup_status = 'Complete' LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM backups WHERE backup_id = $backup_id AND backup_status = 'Complete' LIMIT 1");
|
||||||
|
|
||||||
if (mysqli_num_rows($sql) !== 1) {
|
if (mysqli_num_rows($sql) !== 1) {
|
||||||
http_response_code(404);
|
http_response_code(404);
|
||||||
|
|||||||
@@ -1,134 +0,0 @@
|
|||||||
<?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";
|
|
||||||
@@ -15,7 +15,7 @@ if (isset($_GET['category'])) {
|
|||||||
|
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT SQL_CALC_FOUND_ROWS category_color, category_description, category_id, category_name FROM categories
|
"SELECT SQL_CALC_FOUND_ROWS * FROM categories
|
||||||
WHERE category_name LIKE '%$q%'
|
WHERE category_name LIKE '%$q%'
|
||||||
AND category_type = '$category'
|
AND category_type = '$category'
|
||||||
AND category_$archive_query
|
AND category_$archive_query
|
||||||
@@ -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 me-2"></i>
|
<h3 class="card-title mt-2"><i class="fa fa-fw fa-list-ul mr-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 me-2"></i>New <?= escapeHtml($category_label) ?> Category</button>
|
class="fas fa-plus mr-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-end mb-3">
|
<div class="col-md-3 border-right 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'] ?> me-2"></i><?= escapeHtml($category_type_details['label']) ?>
|
<i class="fa fa-fw <?= $category_type_details['icon'] ?> mr-2"></i><?= escapeHtml($category_type_details['label']) ?>
|
||||||
<span class="badge rounded-pill bg-dark float-end mt-1"><?= $category_type_counts[$category_type] ?? 0 ?></span>
|
<span class="badge badge-pill badge-dark float-right mt-1"><?= $category_type_counts[$category_type] ?? 0 ?></span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
@@ -115,23 +115,25 @@ $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-end <?php if ($archived) {
|
class="btn float-right <?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 me-2"></i>Archived</a>
|
class="fas fa-fw fa-archive mr-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 mb-0">
|
<table class="table table-striped table-borderless table-hover">
|
||||||
<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>
|
||||||
@@ -163,8 +165,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 dropstart text-center">
|
<div class="dropdown dropleft text-center">
|
||||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
|
<button class="btn btn-secondary btn-sm" type="button" data-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">
|
||||||
@@ -173,22 +175,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 me-2"></i>Restore
|
<i class="fas fa-fw fa-redo mr-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 me-2"></i>Delete
|
<i class="fas fa-fw fa-trash mr-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 me-2"></i>Edit
|
<i class="fas fa-fw fa-edit mr-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 me-2"></i>Archive
|
<i class="fas fa-fw fa-archive mr-2"></i>Archive
|
||||||
</a>
|
</a>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,105 +18,108 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card card-dark">
|
||||||
<div class="card-header bg-dark py-2">
|
<div class="card-header py-2">
|
||||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file-contract me-2"></i>Contract Templates</h3>
|
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file-contract mr-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 me-2"></i>New Template
|
<i class="fas fa-plus mr-2"></i>New Template
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-header py-3">
|
<div class="card-body">
|
||||||
|
|
||||||
<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>
|
||||||
</div>
|
<hr>
|
||||||
|
|
||||||
<div class="table-responsive-sm">
|
<div class="table-responsive-sm">
|
||||||
<table class="table table-striped table-borderless table-hover mb-0">
|
<table class="table table-striped table-borderless table-hover">
|
||||||
<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>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
<th>Update Frequency</th>
|
<th>Update Frequency</th>
|
||||||
<th>SLA (L/M/H Response)</th>
|
<th>SLA (L/M/H Response)</th>
|
||||||
<th>SLA (L/M/H Resolution)</th>
|
<th>SLA (L/M/H Resolution)</th>
|
||||||
<th>Hourly Rate</th>
|
<th>Hourly Rate</th>
|
||||||
<th>After Hours Rate</th>
|
<th>After Hours Rate</th>
|
||||||
<th>Support Hours</th>
|
<th>Support Hours</th>
|
||||||
<th>Net Terms</th>
|
<th>Net Terms</th>
|
||||||
<th>Created</th>
|
<th>Created</th>
|
||||||
<th>Updated</th>
|
<th>Updated</th>
|
||||||
<th class="text-center">Action</th>
|
<th class="text-center">Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$id = intval($row['contract_template_id']);
|
$id = intval($row['contract_template_id']);
|
||||||
$name = escapeHtml($row['contract_template_name']);
|
$name = escapeHtml($row['contract_template_name']);
|
||||||
$type = escapeHtml($row['contract_template_type']);
|
$type = escapeHtml($row['contract_template_type']);
|
||||||
$freq = escapeHtml($row['contract_template_renewal_frequency']);
|
$freq = escapeHtml($row['contract_template_update_frequency']);
|
||||||
$sla_low_resp = escapeHtml($row['contract_template_sla_low_response_time']);
|
$sla_low_resp = escapeHtml($row['sla_low_response_time']);
|
||||||
$sla_med_resp = escapeHtml($row['contract_template_sla_medium_response_time']);
|
$sla_med_resp = escapeHtml($row['sla_medium_response_time']);
|
||||||
$sla_high_resp = escapeHtml($row['contract_template_sla_high_response_time']);
|
$sla_high_resp = escapeHtml($row['sla_high_response_time']);
|
||||||
$sla_low_res = escapeHtml($row['contract_template_sla_low_resolution_time']);
|
$sla_low_res = escapeHtml($row['sla_low_resolution_time']);
|
||||||
$sla_med_res = escapeHtml($row['contract_template_sla_medium_resolution_time']);
|
$sla_med_res = escapeHtml($row['sla_medium_resolution_time']);
|
||||||
$sla_high_res = escapeHtml($row['contract_template_sla_high_resolution_time']);
|
$sla_high_res = escapeHtml($row['sla_high_resolution_time']);
|
||||||
$hourly_rate = escapeHtml($row['contract_template_rate_standard']);
|
$hourly_rate = escapeHtml($row['contract_template_hourly_rate']);
|
||||||
$after_hours = escapeHtml($row['contract_template_rate_after_hours']);
|
$after_hours = escapeHtml($row['contract_template_after_hours_hourly_rate']);
|
||||||
$support_hours = escapeHtml($row['contract_template_support_hours']);
|
$support_hours = escapeHtml($row['contract_template_support_hours']);
|
||||||
$net_terms = escapeHtml($row['contract_template_net_terms']);
|
$net_terms = escapeHtml($row['contract_template_net_terms']);
|
||||||
$created = escapeHtml($row['contract_template_created_at']);
|
$created = escapeHtml($row['contract_template_created_at']);
|
||||||
$updated = escapeHtml($row['contract_template_updated_at']);
|
$updated = escapeHtml($row['contract_template_updated_at']);
|
||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a class="text-bold" href="contract_template_details.php?contract_template_id=<?= $id ?>">
|
<a class="text-bold" href="contract_template_details.php?contract_template_id=<?= $id ?>">
|
||||||
<i class="fas fa-fw fa-file-alt text-dark"></i> <?= $name ?>
|
<i class="fas fa-fw fa-file-alt text-dark"></i> <?= $name ?>
|
||||||
</a>
|
</a>
|
||||||
<div class="mt-1 text-secondary"><?= escapeHtml($row['contract_template_description']) ?></div>
|
<div class="mt-1 text-secondary"><?= escapeHtml($row['contract_template_description']) ?></div>
|
||||||
</td>
|
</td>
|
||||||
<td><?= $type ?></td>
|
<td><?= $type ?></td>
|
||||||
<td><?= $freq ?></td>
|
<td><?= $freq ?></td>
|
||||||
<td><?= "$sla_low_resp / $sla_med_resp / $sla_high_resp" ?></td>
|
<td><?= "$sla_low_resp / $sla_med_resp / $sla_high_resp" ?></td>
|
||||||
<td><?= "$sla_low_res / $sla_med_res / $sla_high_res" ?></td>
|
<td><?= "$sla_low_res / $sla_med_res / $sla_high_res" ?></td>
|
||||||
<td><?= $hourly_rate ?></td>
|
<td><?= $hourly_rate ?></td>
|
||||||
<td><?= $after_hours ?></td>
|
<td><?= $after_hours ?></td>
|
||||||
<td><?= $support_hours ?></td>
|
<td><?= $support_hours ?></td>
|
||||||
<td><?= $net_terms ?></td>
|
<td><?= $net_terms ?></td>
|
||||||
<td><?= $created ?></td>
|
<td><?= $created ?></td>
|
||||||
<td><?= $updated ?></td>
|
<td><?= $updated ?></td>
|
||||||
<td>
|
<td>
|
||||||
<div class="dropdown dropstart text-center">
|
<div class="dropdown dropleft text-center">
|
||||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
|
<button class="btn btn-secondary btn-sm" type="button" data-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 me-2"></i>Edit
|
<i class="fas fa-fw fa-edit mr-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 me-2"></i>Delete
|
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</td>
|
||||||
</td>
|
</tr>
|
||||||
</tr>
|
<?php } ?>
|
||||||
<?php } ?>
|
</tbody>
|
||||||
</tbody>
|
</table>
|
||||||
</table>
|
<br>
|
||||||
<br>
|
</div>
|
||||||
|
<?php require_once "../includes/filter_footer.php"; ?>
|
||||||
</div>
|
</div>
|
||||||
<?php require_once "../includes/filter_footer.php"; ?>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php require_once "../includes/footer.php"; ?>
|
<?php require_once "../includes/footer.php"; ?>
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ foreach (cronJobRegistry() as $job) {
|
|||||||
$cron_jobs[$job['name']]['row'] = null;
|
$cron_jobs[$job['name']]['row'] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT cron_job_daily_at, cron_job_enabled, cron_job_id, cron_job_interval_minutes,
|
$sql = mysqli_query($mysqli, "SELECT * FROM cron_jobs");
|
||||||
cron_job_last_duration, cron_job_last_error, cron_job_last_error_at, cron_job_last_run_at, cron_job_last_status,
|
|
||||||
cron_job_name, cron_job_run_now, cron_job_schedule FROM cron_jobs");
|
|
||||||
while ($job_row = mysqli_fetch_assoc($sql)) {
|
while ($job_row = mysqli_fetch_assoc($sql)) {
|
||||||
if (isset($cron_jobs[$job_row['cron_job_name']])) {
|
if (isset($cron_jobs[$job_row['cron_job_name']])) {
|
||||||
$cron_jobs[$job_row['cron_job_name']]['row'] = $job_row;
|
$cron_jobs[$job_row['cron_job_name']]['row'] = $job_row;
|
||||||
@@ -35,13 +33,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 me-2"></i>Cron</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-clock mr-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 me-2"></i>Cron is not running</h5>
|
<h5><i class="fas fa-fw fa-exclamation-triangle mr-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 +47,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 me-2"></i>Cron last checked in <strong><?= escapeHtml(strtolower(cronJobTimeAgo($cron_last_dispatch_at))) ?></strong>.
|
<i class="fas fa-fw fa-check mr-2"></i>Cron last checked in <strong><?= escapeHtml(strtolower(cronJobTimeAgo($cron_last_dispatch_at))) ?></strong>.
|
||||||
<span class="text-muted ms-2"><?= escapeHtml($cron_command) ?></span>
|
<span class="text-muted ml-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-end">
|
<div class="float-right">
|
||||||
<a class="btn btn-sm btn-warning" href="post.php?enable_cron=1&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
<a class="btn btn-sm btn-warning" href="post.php?enable_cron=1&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<i class="fas fa-fw fa-power-off me-2"></i>Turn cron on
|
<i class="fas fa-fw fa-power-off mr-2"></i>Turn cron on
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<h5><i class="fas fa-fw fa-exclamation-circle me-2"></i>Cron is switched off</h5>
|
<h5><i class="fas fa-fw fa-exclamation-circle mr-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 me-1"></i>The master switch is <strong>on</strong>. Turning it off
|
<i class="fas fa-fw fa-power-off mr-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 +110,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 bg-warning text-dark">Queued</span>';
|
$status_badge = '<span class="badge badge-warning">Queued</span>';
|
||||||
} elseif ($last_status === 'Running') {
|
} elseif ($last_status === 'Running') {
|
||||||
$status_badge = '<span class="badge bg-info text-dark">Running</span>';
|
$status_badge = '<span class="badge badge-info">Running</span>';
|
||||||
} elseif ($last_status === 'Completed') {
|
} elseif ($last_status === 'Completed') {
|
||||||
$status_badge = '<span class="badge bg-success">Completed</span>';
|
$status_badge = '<span class="badge badge-success">Completed</span>';
|
||||||
} elseif ($last_status === 'Failed') {
|
} elseif ($last_status === 'Failed') {
|
||||||
$status_badge = '<span class="badge bg-danger">Failed</span>';
|
$status_badge = '<span class="badge badge-danger">Failed</span>';
|
||||||
} elseif ($last_status !== null) {
|
} elseif ($last_status !== null) {
|
||||||
$status_badge = '<span class="badge bg-secondary">Stopped</span>';
|
$status_badge = '<span class="badge badge-secondary">Stopped</span>';
|
||||||
} else {
|
} else {
|
||||||
$status_badge = '<span class="badge bg-light text-dark">Never run</span>';
|
$status_badge = '<span class="badge badge-light">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 bg-secondary ms-1">Disabled</span><?php } ?>
|
<?php if (!$enabled) { ?><span class="badge badge-secondary ml-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 +145,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 dropstart text-center">
|
<div class="dropdown dropleft text-center">
|
||||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
|
<button class="btn btn-secondary btn-sm" type="button" data-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 me-2"></i>Run Now
|
<i class="fas fa-fw fa-play mr-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 me-2"></i>Edit Schedule
|
<i class="fas fa-fw fa-edit mr-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 me-2"></i>Disable
|
<i class="fas fa-fw fa-pause mr-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 me-2"></i>Enable
|
<i class="fas fa-fw fa-play-circle mr-2"></i>Enable
|
||||||
</a>
|
</a>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</div>
|
</div>
|
||||||
@@ -176,13 +174,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-end">
|
<div class="float-right">
|
||||||
<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 me-2"></i>Last error</strong>
|
<strong><i class="fas fa-fw fa-exclamation-triangle mr-2"></i>Last error</strong>
|
||||||
<small class="text-muted ms-2"><?= escapeHtml(cronJobTimeAgo($last_error_at)) ?></small>
|
<small class="text-muted ml-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 +193,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 me-1"></i>Run Now does not start the job in your browser - it asks the
|
<i class="fas fa-fw fa-info-circle mr-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>.
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
|
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT SQL_CALC_FOUND_ROWS custom_link_icon, custom_link_id, custom_link_location, custom_link_name,
|
"SELECT SQL_CALC_FOUND_ROWS * FROM custom_links
|
||||||
custom_link_new_tab, custom_link_order, custom_link_uri FROM custom_links
|
|
||||||
WHERE custom_link_name LIKE '%$q%'
|
WHERE custom_link_name LIKE '%$q%'
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||||
);
|
);
|
||||||
@@ -20,9 +19,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 me-2"></i>Custom Links</h3>
|
<h3 class="card-title mt-2"><i class="fas fa-fw fa-external-link-alt mr-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 me-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 mr-2"></i>New Link</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -32,7 +31,9 @@ $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>
|
||||||
@@ -42,7 +43,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 mb-0">
|
<table class="table table-striped table-borderless table-hover">
|
||||||
<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>
|
||||||
@@ -106,24 +107,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 ?> me-2"></i><?= $custom_link_name ?>
|
<i class="fa fa-fw fa-<?= $custom_link_icon ?> mr-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 dropstart text-center">
|
<div class="dropdown dropleft text-center">
|
||||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
|
<button class="btn btn-secondary btn-sm" type="button" data-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 me-2"></i>Edit
|
<i class="fas fa-fw fa-edit mr-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 me-2"></i>Delete
|
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
|
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
|
||||||
|
|
||||||
// Migrate Payment Methods from Categories Table to new payment_methods table
|
// Migrate Payment Methods from Categories Table to new payment_methods table
|
||||||
$sql_categories = mysqli_query($mysqli, "SELECT category_name FROM categories WHERE category_type = 'Payment Method' AND category_name != 'Stripe' AND category_archived_at IS NULL");
|
$sql_categories = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' AND category_name != 'Stripe' AND category_archived_at IS NULL");
|
||||||
|
|
||||||
while ($row = mysqli_fetch_assoc($sql_categories)) {
|
while ($row = mysqli_fetch_assoc($sql_categories)) {
|
||||||
$category_name = escapeSql($row['category_name']);
|
$category_name = escapeSql($row['category_name']);
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ITFlow - Database update to version 2.6.7 (from 2.6.6)
|
|
||||||
* Included by admin/database_updates.php - do not access directly
|
|
||||||
*/
|
|
||||||
|
|
||||||
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
|
|
||||||
|
|
||||||
// The AI endpoints used to send a hardcoded temperature (0.5, or 0.3 for ticket
|
|
||||||
// summaries). Newer OpenAI models accept nothing but their own default and reject
|
|
||||||
// the request outright, which surfaced as "Failed to get a response from the AI API".
|
|
||||||
//
|
|
||||||
// Temperature is now per-model and optional: NULL means don't send the parameter
|
|
||||||
// at all, which is the setting that works on every provider. Existing rows get
|
|
||||||
// NULL so they stop sending it.
|
|
||||||
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `ai_models` ADD COLUMN IF NOT EXISTS `ai_model_temperature` decimal(3,2) DEFAULT NULL AFTER `ai_model_use_case`");
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<?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'");
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
<?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");
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
<?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.
|
|
||||||
*/
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<?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");
|
|
||||||
@@ -114,12 +114,12 @@ $phpConfig[] = [
|
|||||||
'value' => $post_max_size,
|
'value' => $post_max_size,
|
||||||
];
|
];
|
||||||
|
|
||||||
// PHP Memory Limit >= 512M
|
// PHP Memory Limit >= 128M
|
||||||
$memoryLimit = ini_get('memory_limit');
|
$memoryLimit = ini_get('memory_limit');
|
||||||
$memoryLimitBytes = toBytes($memoryLimit);
|
$memoryLimitBytes = toBytes($memoryLimit);
|
||||||
$memoryLimitPassed = $memoryLimitBytes >= (512 * 1024 * 1024);
|
$memoryLimitPassed = $memoryLimitBytes >= (128 * 1024 * 1024);
|
||||||
$phpConfig[] = [
|
$phpConfig[] = [
|
||||||
'name' => 'PHP Memory Limit >= 512M',
|
'name' => 'PHP Memory Limit >= 128M',
|
||||||
'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 me-2"></i>Debug</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-bug mr-2"></i>Debug</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ if (isset($_GET['document_template_id'])) {
|
|||||||
$document_template_id = intval($_GET['document_template_id']);
|
$document_template_id = intval($_GET['document_template_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql_document = mysqli_query($mysqli, "SELECT document_template_content, document_template_created_at, document_template_description,
|
$sql_document = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id LIMIT 1");
|
||||||
document_template_name, document_template_updated_at FROM document_templates WHERE document_template_id = $document_template_id LIMIT 1");
|
|
||||||
|
|
||||||
if (mysqli_num_rows($sql_document) == 0) {
|
if (mysqli_num_rows($sql_document) == 0) {
|
||||||
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1><a class='btn btn-lg btn-secondary mt-3' href='javascript:history.back()'><i class='fa fa-fw fa-arrow-left'></i> Go Back</a></center>";
|
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1><a class='btn btn-lg btn-secondary mt-3' href='javascript:history.back()'><i class='fa fa-fw fa-arrow-left'></i> Go Back</a></center>";
|
||||||
@@ -44,19 +43,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 me-2"></i><?= $document_template_name ?></li>
|
<li class="breadcrumb-item active"><i class="fas fa-file-alt mr-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 me-2"></i><?= $document_template_name ?></h3>
|
<h3 class="card-title mt-1"><i class="fa fa-fw fa-file-alt mr-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 me-2"></i>
|
<i class="fas fa-edit mr-2"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT SQL_CALC_FOUND_ROWS document_template_content, document_template_created_at, document_template_description,
|
"SELECT SQL_CALC_FOUND_ROWS * FROM document_templates
|
||||||
document_template_id, document_template_name, document_template_updated_at, user_name FROM document_templates
|
|
||||||
LEFT JOIN users ON document_template_created_by = user_id
|
LEFT JOIN users ON document_template_created_by = user_id
|
||||||
WHERE user_name LIKE '%$q%' OR document_template_name LIKE '%$q%'
|
WHERE user_name LIKE '%$q%' OR document_template_name LIKE '%$q%'
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||||
@@ -19,117 +18,120 @@
|
|||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card card-dark">
|
||||||
<div class="card-header bg-dark py-2">
|
<div class="card-header py-2">
|
||||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file-alt me-2"></i>Document Templates</h3>
|
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file-alt mr-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 me-2"></i>New Template
|
<i class="fas fa-plus mr-2"></i>New Template
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-header py-3">
|
<div class="card-body">
|
||||||
|
|
||||||
<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>
|
||||||
</div>
|
<hr>
|
||||||
|
|
||||||
<div class="table-responsive-sm">
|
<div class="table-responsive-sm">
|
||||||
<table class="table table-striped table-borderless table-hover mb-0">
|
<table class="table table-striped table-borderless table-hover">
|
||||||
<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>
|
||||||
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=document_template_name&order=<?= $disp ?>">
|
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=document_template_name&order=<?= $disp ?>">
|
||||||
Template Name <?php if ($sort == 'document_template_name') { echo $order_icon; } ?>
|
Template Name <?php if ($sort == 'document_template_name') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=document_template_created_at&order=<?= $disp ?>">
|
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=document_template_created_at&order=<?= $disp ?>">
|
||||||
Created <?php if ($sort == 'document_template_created_at') { echo $order_icon; } ?>
|
Created <?php if ($sort == 'document_template_created_at') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=document_template_updated_at&order=<?= $disp ?>">
|
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=document_template_updated_at&order=<?= $disp ?>">
|
||||||
Updated <?php if ($sort == 'document_template_updated_at') { echo $order_icon; } ?>
|
Updated <?php if ($sort == 'document_template_updated_at') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th class="text-center">
|
<th class="text-center">
|
||||||
Action
|
Action
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$document_template_id = intval($row['document_template_id']);
|
$document_template_id = intval($row['document_template_id']);
|
||||||
$document_template_name = escapeHtml($row['document_template_name']);
|
$document_template_name = escapeHtml($row['document_template_name']);
|
||||||
$document_template_description = escapeHtml($row['document_template_description']);
|
$document_template_description = escapeHtml($row['document_template_description']);
|
||||||
$document_template_content = escapeHtml($row['document_template_content']);
|
$document_template_content = escapeHtml($row['document_template_content']);
|
||||||
$document_template_created_by_name = escapeHtml($row['user_name']);
|
$document_template_created_by_name = escapeHtml($row['user_name']);
|
||||||
$document_template_created_at = escapeHtml($row['document_template_created_at']);
|
$document_template_created_at = escapeHtml($row['document_template_created_at']);
|
||||||
$document_template_updated_at = escapeHtml($row['document_template_updated_at']) ?: '-';
|
$document_template_updated_at = escapeHtml($row['document_template_updated_at']) ?: '-';
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<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="d-flex">
|
<div class="media">
|
||||||
<i class="fas fa-fw fa-2x fa-file-alt me-2"></i>
|
<i class="fas fa-fw fa-2x fa-file-alt mr-2"></i>
|
||||||
<div class="flex-grow-1">
|
<div class="media-body">
|
||||||
<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>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<?= $document_template_created_at ?>
|
||||||
|
<div class="text-secondary"><?= $document_template_created_by_name ?></div>
|
||||||
|
</td>
|
||||||
|
<td><?= $document_template_updated_at ?></td>
|
||||||
|
<td>
|
||||||
|
<div class="dropdown dropleft text-center">
|
||||||
|
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
|
||||||
|
<i class="fas fa-ellipsis-h"></i>
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
<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
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item ajax-modal" href="#"
|
||||||
|
data-modal-size="xl"
|
||||||
|
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
|
||||||
|
</a>
|
||||||
|
<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'] ?>">
|
||||||
|
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</td>
|
||||||
</td>
|
</tr>
|
||||||
<td>
|
|
||||||
<?= $document_template_created_at ?>
|
|
||||||
<div class="text-secondary"><?= $document_template_created_by_name ?></div>
|
|
||||||
</td>
|
|
||||||
<td><?= $document_template_updated_at ?></td>
|
|
||||||
<td>
|
|
||||||
<div class="dropdown dropstart text-center">
|
|
||||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
|
|
||||||
<i class="fas fa-ellipsis-h"></i>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<a class="dropdown-item" href="document_template.php?document_template_id=<?= $document_template_id ?>">
|
|
||||||
<i class="fas fa-fw fa-eye me-2"></i>View
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item ajax-modal" href="#"
|
|
||||||
data-modal-size="xl"
|
|
||||||
data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_id ?>">
|
|
||||||
<i class="fas fa-fw fa-edit me-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
<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'] ?>">
|
|
||||||
<i class="fas fa-fw fa-trash me-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<br>
|
<br>
|
||||||
|
</div>
|
||||||
|
<?php require_once "../includes/filter_footer.php"; ?>
|
||||||
</div>
|
</div>
|
||||||
<?php require_once "../includes/filter_footer.php"; ?>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php require_once "../includes/footer.php";
|
<?php require_once "../includes/footer.php";
|
||||||
|
|||||||
@@ -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 me-2"></i>Identity Providers</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-fingerprint mr-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,11 +12,13 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" readonly>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -25,25 +27,29 @@ require_once "includes/inc_all_admin.php";
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Save</button>
|
<button type="submit" name="edit_identity_provider" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
<!-- Main Sidebar Container -->
|
<!-- Main Sidebar Container -->
|
||||||
<aside class="app-sidebar shadow d-print-none" data-bs-theme="dark">
|
<aside class="main-sidebar sidebar-dark-<?= escapeHtml($config_theme) ?> d-print-none">
|
||||||
<div class="sidebar-brand">
|
<a class="brand-link pb-1 mt-1" href="/agent/<?= $config_start_page ?>">
|
||||||
<a class="brand-link" href="/agent/<?= $config_start_page ?>">
|
<p class="h6">
|
||||||
<i class="fas fa-arrow-left me-2"></i>
|
<i class="nav-icon fas fa-arrow-left ml-3 mr-2"></i>
|
||||||
<span class="brand-text h6 mb-0">Back | <strong>Administration</strong></span>
|
<span class="brand-text">
|
||||||
</a>
|
Back | <strong>Administration</strong>
|
||||||
</div>
|
</span>
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
|
||||||
<!-- Sidebar -->
|
<!-- Sidebar -->
|
||||||
<div class="sidebar-wrapper">
|
<div class="sidebar">
|
||||||
<!-- Sidebar Menu -->
|
<!-- Sidebar Menu -->
|
||||||
<nav>
|
<nav>
|
||||||
<ul class="nav nav-pills sidebar-menu flex-column mt-2" data-lte-toggle="treeview" data-accordion="false">
|
<ul class="nav nav-pills nav-sidebar flex-column mt-2" data-widget="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";} ?>">
|
||||||
@@ -124,12 +126,6 @@
|
|||||||
<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
|
||||||
@@ -215,7 +211,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!-- SETTINGS Section -->
|
<!-- SETTINGS Section -->
|
||||||
<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' : '') ?>">
|
<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' : '') ?>">
|
||||||
<a href="#" class="nav-link">
|
<a href="#" class="nav-link">
|
||||||
<p>
|
<p>
|
||||||
SETTINGS
|
SETTINGS
|
||||||
@@ -318,7 +314,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql_custom_links = mysqli_query($mysqli, "SELECT custom_link_icon, custom_link_name, custom_link_new_tab, custom_link_uri FROM custom_links
|
$sql_custom_links = mysqli_query($mysqli, "SELECT * FROM custom_links
|
||||||
WHERE custom_link_location = 4 AND custom_link_archived_at IS NULL
|
WHERE custom_link_location = 4 AND custom_link_archived_at IS NULL
|
||||||
ORDER BY custom_link_order ASC, custom_link_name ASC"
|
ORDER BY custom_link_order ASC, custom_link_name ASC"
|
||||||
);
|
);
|
||||||
@@ -340,7 +336,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-end"></i>
|
<i class="fas fa-angle-right nav-icon float-right"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
|
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT SQL_CALC_FOUND_ROWS email_attempts, email_failed_at, email_from, email_from_name, email_id, email_queued_at,
|
"SELECT SQL_CALC_FOUND_ROWS * FROM email_queue
|
||||||
email_recipient, email_recipient_name, email_sent_at, email_status, email_subject FROM email_queue
|
|
||||||
WHERE (email_id LIKE '%$q%' OR email_from LIKE '%$q%' OR email_from_name LIKE '%$q%' OR email_recipient LIKE '%$q%' OR email_recipient_name LIKE '%$q%' OR email_subject LIKE '%$q%')
|
WHERE (email_id LIKE '%$q%' OR email_from LIKE '%$q%' OR email_from_name LIKE '%$q%' OR email_recipient LIKE '%$q%' OR email_recipient_name LIKE '%$q%' OR email_subject LIKE '%$q%')
|
||||||
AND DATE(email_queued_at) BETWEEN '$dtf' AND '$dtt'
|
AND DATE(email_queued_at) BETWEEN '$dtf' AND '$dtt'
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||||
@@ -19,44 +18,46 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card card-dark">
|
||||||
<div class="card-header bg-dark py-2">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-inbox me-2"></i>Email Queue</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-header py-3">
|
<div class="card-header py-3">
|
||||||
<form autocomplete="off">
|
<h3 class="card-title"><i class="fas fa-fw fa-inbox mr-2"></i>Email Queue</h3>
|
||||||
<div class="row g-2 align-items-end">
|
</div>
|
||||||
|
<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">
|
<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">
|
||||||
<button class="btn btn-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#advancedFilter"><i class="fas fa-filter"></i></button>
|
<div class="input-group-append">
|
||||||
|
<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-end" id="bulkActionButton" hidden>
|
<div class="dropdown float-right" id="bulkActionButton" hidden>
|
||||||
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
|
||||||
<i class="fas fa-fw fa-layer-group me-2"></i>Bulk Action (<span id="selectedCount">0</span>)
|
<i class="fas fa-fw fa-layer-group mr-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 me-2"></i>Cancel
|
<i class="fas fa-fw fa-ban mr-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 me-2"></i>Delete
|
<i class="fas fa-fw fa-trash mr-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 g-3">
|
<div class="row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div>
|
<div class="form-group">
|
||||||
<label class="form-label">Date range</label>
|
<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 ?? '') ?>">
|
||||||
@@ -66,123 +67,124 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
<hr>
|
||||||
<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 mb-0">
|
<table class="table table-sm table-striped table-borderless table-hover">
|
||||||
<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 pe-0">
|
<td class="bg-light pr-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>
|
||||||
</td>
|
</td>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=email_queued_at&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=email_queued_at&order=<?= $disp ?>">
|
||||||
Queued <?php if ($sort == 'email_queued_at') { echo $order_icon; } ?>
|
Queued <?php if ($sort == 'email_queued_at') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=email_from&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=email_from&order=<?= $disp ?>">
|
||||||
From <?php if ($sort == 'email_from') { echo $order_icon; } ?>
|
From <?php if ($sort == 'email_from') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=email_recipient&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=email_recipient&order=<?= $disp ?>">
|
||||||
To <?php if ($sort == 'email_recipient') { echo $order_icon; } ?>
|
To <?php if ($sort == 'email_recipient') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=email_subject&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=email_subject&order=<?= $disp ?>">
|
||||||
Subject <?php if ($sort == 'email_subject') { echo $order_icon; } ?>
|
Subject <?php if ($sort == 'email_subject') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=email_status&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=email_status&order=<?= $disp ?>">
|
||||||
Status <?php if ($sort == 'email_status') { echo $order_icon; } ?>
|
Status <?php if ($sort == 'email_status') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=email_attempts&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=email_attempts&order=<?= $disp ?>">
|
||||||
Attempts <?php if ($sort == 'email_attempts') { echo $order_icon; } ?>
|
Attempts <?php if ($sort == 'email_attempts') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th class="text-center">Action</th>
|
<th class="text-center">Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$email_id = intval($row['email_id']);
|
$email_id = intval($row['email_id']);
|
||||||
$email_from = escapeHtml($row['email_from']);
|
$email_from = escapeHtml($row['email_from']);
|
||||||
$email_from_name = escapeHtml($row['email_from_name']);
|
$email_from_name = escapeHtml($row['email_from_name']);
|
||||||
$email_recipient = escapeHtml($row['email_recipient']);
|
$email_recipient = escapeHtml($row['email_recipient']);
|
||||||
$email_recipient_name = escapeHtml($row['email_recipient_name']);
|
$email_recipient_name = escapeHtml($row['email_recipient_name']);
|
||||||
$email_subject = escapeHtml($row['email_subject']);
|
$email_subject = escapeHtml($row['email_subject']);
|
||||||
$email_attempts = intval($row['email_attempts']);
|
$email_attempts = intval($row['email_attempts']);
|
||||||
$email_queued_at = escapeHtml($row['email_queued_at']);
|
$email_queued_at = escapeHtml($row['email_queued_at']);
|
||||||
$email_failed_at = escapeHtml($row['email_failed_at']);
|
$email_failed_at = escapeHtml($row['email_failed_at']);
|
||||||
$email_sent_at = escapeHtml($row['email_sent_at']);
|
$email_sent_at = escapeHtml($row['email_sent_at']);
|
||||||
$email_status = intval($row['email_status']);
|
$email_status = intval($row['email_status']);
|
||||||
if ($email_status == 0) {
|
if ($email_status == 0) {
|
||||||
$email_status_display = "<div class='text-primary'>Queued</div>";
|
$email_status_display = "<div class='text-primary'>Queued</div>";
|
||||||
} 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 font-monospace'>$email_failed_at</small>";
|
$email_status_display = "<div class='text-danger'>Failed</div><small class='text-secondary text-monospace'>$email_failed_at</small>";
|
||||||
} else {
|
} else {
|
||||||
$email_status_display = "<div class='text-success'>Sent</div><small class='text-secondary font-monospace'>$email_sent_at</small>";
|
$email_status_display = "<div class='text-success'>Sent</div><small class='text-secondary text-monospace'>$email_sent_at</small>";
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="pr-0 bg-light">
|
||||||
|
<?php if ($email_status !== 3) { ?>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input bulk-select" type="checkbox" name="email_ids[]" value="<?= $email_id ?>">
|
||||||
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
</td>
|
||||||
|
<td class="text-monospace"><?= $email_queued_at ?></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_subject ?></td>
|
||||||
|
<td><?= $email_status_display ?></td>
|
||||||
|
<td><?= $email_attempts ?></td>
|
||||||
|
<td class="text-center">
|
||||||
|
<a class="btn btn-sm btn-secondary ajax-modal" href="#"
|
||||||
|
data-modal-size="lg"
|
||||||
|
data-modal-url="modals/mail_queue/mail_queue_message_view.php?id=<?= $email_id ?>">
|
||||||
|
<i class="fas fa-fw fa-eye"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Show force resend if all retries have failed -->
|
||||||
|
<?php if ($email_status == 2 && $email_attempts > 3) { ?>
|
||||||
|
<a class="btn btn-sm btn-success" href="post.php?send_failed_mail=<?= $email_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"><i class="fas fa-fw fa-paper-plane"></i></a>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<!-- Allow cancelling a message if it hasn't yet been picked up (e.g. stuck/bugged) -->
|
||||||
|
<?php if ($email_status !== 3) { ?>
|
||||||
|
<a class="btn btn-sm btn-danger confirm-link" href="post.php?cancel_mail=<?= $email_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"><i class="fas fa-fw fa-trash"></i></a>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<tr>
|
</tbody>
|
||||||
<td class="pe-0 bg-light">
|
</table>
|
||||||
<?php if ($email_status !== 3) { ?>
|
</div>
|
||||||
<div class="form-check">
|
</form>
|
||||||
<input class="form-check-input bulk-select" type="checkbox" name="email_ids[]" value="<?= $email_id ?>">
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
</td>
|
|
||||||
<td class="font-monospace"><?= $email_queued_at ?></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_subject ?></td>
|
|
||||||
<td><?= $email_status_display ?></td>
|
|
||||||
<td><?= $email_attempts ?></td>
|
|
||||||
<td class="text-center">
|
|
||||||
<a class="btn btn-sm btn-secondary ajax-modal" href="#"
|
|
||||||
data-modal-size="lg"
|
|
||||||
data-modal-url="modals/mail_queue/mail_queue_message_view.php?id=<?= $email_id ?>">
|
|
||||||
<i class="fas fa-fw fa-eye"></i>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<!-- Show force resend if all retries have failed -->
|
<?php require_once "../includes/filter_footer.php"; ?>
|
||||||
<?php if ($email_status == 2 && $email_attempts > 3) { ?>
|
</div>
|
||||||
<a class="btn btn-sm btn-success" href="post.php?send_failed_mail=<?= $email_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"><i class="fas fa-fw fa-paper-plane"></i></a>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<!-- Allow cancelling a message if it hasn't yet been picked up (e.g. stuck/bugged) -->
|
|
||||||
<?php if ($email_status !== 3) { ?>
|
|
||||||
<a class="btn btn-sm btn-danger confirm-link" href="post.php?cancel_mail=<?= $email_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"><i class="fas fa-fw fa-trash"></i></a>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<?php require_once "../includes/filter_footer.php"; ?>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="../js/bulk_actions.js"></script>
|
<script src="../js/bulk_actions.js"></script>
|
||||||
|
|||||||
@@ -7,22 +7,26 @@ 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 me-2"></i>Add AI Model</h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-robot mr-2"></i>Add AI Model</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="provider" required>
|
</div>
|
||||||
|
<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 * FROM ai_providers");
|
||||||
while ($row = mysqli_fetch_assoc($sql_ai_providers)) {
|
while ($row = mysqli_fetch_assoc($sql_ai_providers)) {
|
||||||
$ai_provider_id = intval($row['ai_provider_id']);
|
$ai_provider_id = intval($row['ai_provider_id']);
|
||||||
$ai_provider_name = escapeHtml($row['ai_provider_name']);
|
$ai_provider_name = escapeHtml($row['ai_provider_name']);
|
||||||
@@ -34,19 +38,23 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="use_case">
|
</div>
|
||||||
|
<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>
|
||||||
@@ -54,23 +62,14 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<label>Temperature</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
|
|
||||||
<input type="number" class="form-control" name="temperature" step="0.1" min="0" max="2" value="" placeholder="Provider default">
|
|
||||||
</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>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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 me-2"></i>Create</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,14 +4,13 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$model_id = intval($_GET['id']);
|
$model_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT ai_model_ai_provider_id, ai_model_id, ai_model_name, ai_model_prompt, ai_model_use_case, ai_model_temperature FROM ai_models WHERE ai_model_id = $model_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models WHERE ai_model_id = $model_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$ai_model_ai_provider_id = intval($row['ai_model_ai_provider_id']);
|
$ai_model_ai_provider_id = intval($row['ai_model_ai_provider_id']);
|
||||||
$model_id = intval($row['ai_model_id']);
|
$model_id = intval($row['ai_model_id']);
|
||||||
$model_name = escapeHtml($row['ai_model_name']);
|
$model_name = escapeHtml($row['ai_model_name']);
|
||||||
$use_case = escapeHtml($row['ai_model_use_case']);
|
$use_case = escapeHtml($row['ai_model_use_case']);
|
||||||
$temperature = escapeHtml($row['ai_model_temperature']);
|
|
||||||
$prompt = escapeHtml($row['ai_model_prompt']);
|
$prompt = escapeHtml($row['ai_model_prompt']);
|
||||||
|
|
||||||
// Generate the HTML form content using output buffering.
|
// Generate the HTML form content using output buffering.
|
||||||
@@ -19,8 +18,10 @@ 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 me-2"></i>Editing: <strong><?= $model_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-robot mr-2"></i>Editing: <strong><?= $model_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-light" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -28,14 +29,16 @@ ob_start();
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="provider" required>
|
</div>
|
||||||
|
<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 * FROM ai_providers");
|
||||||
while ($row = mysqli_fetch_assoc($sql_ai_providers)) {
|
while ($row = mysqli_fetch_assoc($sql_ai_providers)) {
|
||||||
$ai_provider_id = intval($row['ai_provider_id']);
|
$ai_provider_id = intval($row['ai_provider_id']);
|
||||||
$ai_provider_name = escapeHtml($row['ai_provider_name']);
|
$ai_provider_name = escapeHtml($row['ai_provider_name']);
|
||||||
@@ -47,19 +50,23 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="use_case">
|
</div>
|
||||||
|
<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>
|
||||||
@@ -67,22 +74,14 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<label>Temperature</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
|
|
||||||
<input type="number" class="form-control" name="temperature" step="0.1" min="0" max="2" value="<?= $temperature ?>" placeholder="Provider default">
|
|
||||||
</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>
|
|
||||||
</div>
|
|
||||||
<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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -7,42 +7,50 @@ 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 me-2"></i>New AI Provider</h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-robot mr-2"></i>New AI Provider</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Create</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$provider_id = intval($_GET['id']);
|
$provider_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT ai_provider_api_key, ai_provider_api_url, ai_provider_name FROM ai_providers WHERE ai_provider_id = $provider_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM ai_providers WHERE ai_provider_id = $provider_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$provider_name = escapeHtml($row['ai_provider_name']);
|
$provider_name = escapeHtml($row['ai_provider_name']);
|
||||||
@@ -16,8 +16,10 @@ 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 me-2"></i>Editing: <strong><?= $provider_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-robot mr-2"></i>Editing: <strong><?= $provider_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-light" data-dismiss="modal">
|
||||||
|
<span>×</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,34 +27,40 @@ ob_start();
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -10,18 +10,20 @@ 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 me-2"></i>New Key</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-key mr-2"></i>New Key</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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-bs-toggle="pill" href="#pills-api-details">Details</a>
|
<a class="nav-link active" data-toggle="pill" href="#pills-api-details">Details</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-bs-toggle="pill" href="#pills-api-keys">Keys</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-api-keys">Keys</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<hr>
|
<hr>
|
||||||
@@ -33,27 +35,33 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="run_as_user" required>
|
</div>
|
||||||
|
<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");
|
||||||
@@ -69,28 +77,38 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-pane fade" id="pills-api-keys">
|
<div class="tab-pane fade" id="pills-api-keys">
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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">
|
||||||
<input class="form-check-input" type="checkbox" name="ack" value="1" required>
|
<div class="input-group-prepend">
|
||||||
|
<input type="checkbox" name="ack" value="1" required>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -99,8 +117,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 me-2"></i>Create</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$api_key_id = intval($_GET['id']);
|
$api_key_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT api_key_expire, api_key_name, api_key_user_id FROM api_keys WHERE api_key_id = $api_key_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM api_keys WHERE api_key_id = $api_key_id LIMIT 1");
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$api_key_name = escapeHtml($row['api_key_name']);
|
$api_key_name = escapeHtml($row['api_key_name']);
|
||||||
$api_key_expire = escapeHtml($row['api_key_expire']);
|
$api_key_expire = escapeHtml($row['api_key_expire']);
|
||||||
@@ -14,9 +14,11 @@ 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 me-2"></i>Editing API Key:
|
<h5 class="modal-title"><i class="fas fa-fw fa-key mr-2"></i>Editing API Key:
|
||||||
<strong><?= $api_key_name ?></strong></h5>
|
<strong><?= $api_key_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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">
|
||||||
@@ -24,29 +26,35 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="run_as_user" required>
|
</div>
|
||||||
|
<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");
|
||||||
@@ -62,8 +70,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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
<?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';
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
<?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';
|
|
||||||
@@ -9,8 +9,10 @@ $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 me-2"></i>New <strong><?= escapeHtml(ucwords(str_replace('_', ' ', $category))); ?></strong> Category</h5>
|
<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>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -21,11 +23,13 @@ $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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="type" required>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -36,34 +40,40 @@ $category_types_array = ['Expense', 'Income', 'Referral', 'Ticket'];
|
|||||||
|
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Create Category</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$category_id = intval($_GET['id']);
|
$category_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT category_color, category_description, category_name, category_type FROM categories WHERE category_id = $category_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_id = $category_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$category_name = escapeHtml($row['category_name']);
|
$category_name = escapeHtml($row['category_name']);
|
||||||
@@ -16,8 +16,10 @@ $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 me-2"></i>Editing category: <strong><?= $category_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-list-ul mr-2"></i>Editing category: <strong><?= $category_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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,34 +27,40 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Save</button>
|
<button type="submit" name="edit_category" class="btn btn-primary text-bold"><i class="fa fa-check mr-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>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -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 me-2"></i>New Contract Template</h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-file-contract mr-2"></i>New Contract Template</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal"><span>×</span></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-bs-toggle="tab" href="#general" role="tab">General Info</a>
|
<a class="nav-link active" id="general-tab" data-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-bs-toggle="tab" href="#sla" role="tab">SLA</a>
|
<a class="nav-link" id="sla-tab" data-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-bs-toggle="tab" href="#rates" role="tab">Rates & Support</a>
|
<a class="nav-link" id="rates-tab" data-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-bs-toggle="tab" href="#details" role="tab">Details</a>
|
<a class="nav-link" id="details-tab" data-toggle="tab" href="#details" role="tab">Details</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -37,28 +37,34 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="type" required>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -67,11 +73,13 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="renewal_frequency">
|
</div>
|
||||||
|
<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>
|
||||||
@@ -83,52 +91,64 @@ 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="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="form-group 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="mb-3 col-md-6">
|
<div class="form-group 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="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="form-group 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="mb-3 col-md-6">
|
<div class="form-group 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="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="form-group 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="mb-3 col-md-6">
|
<div class="form-group 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>
|
||||||
@@ -137,34 +157,42 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -172,7 +200,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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -182,10 +210,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 me-2"></i>Create Template
|
<i class="fa fa-check mr-2"></i>Create Template
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal">
|
<button type="button" class="btn btn-light" data-dismiss="modal">
|
||||||
<i class="fa fa-times me-2"></i>Cancel
|
<i class="fa fa-times mr-2"></i>Cancel
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -7,13 +7,7 @@ $contract_types_array = ['Fully Managed', 'Partialy Managed', 'Break/Fix'];
|
|||||||
$update_frequency_array = ['Manual', 'Annually', '2 Year', '3 Year', '5 Year', '7 Year'];
|
$update_frequency_array = ['Manual', 'Annually', '2 Year', '3 Year', '5 Year', '7 Year'];
|
||||||
|
|
||||||
// Fetch existing template
|
// Fetch existing template
|
||||||
$sql = mysqli_query($mysqli, "SELECT contract_template_description, contract_template_details, contract_template_name,
|
$sql = mysqli_query($mysqli, "SELECT * FROM contract_templates WHERE contract_template_id = $contract_template_id LIMIT 1");
|
||||||
contract_template_net_terms, contract_template_rate_after_hours,
|
|
||||||
contract_template_rate_standard, contract_template_renewal_frequency,
|
|
||||||
contract_template_sla_high_resolution_time, contract_template_sla_high_response_time,
|
|
||||||
contract_template_sla_low_resolution_time, contract_template_sla_low_response_time,
|
|
||||||
contract_template_sla_medium_resolution_time, contract_template_sla_medium_response_time,
|
|
||||||
contract_template_support_hours, contract_template_type FROM contract_templates WHERE contract_template_id = $contract_template_id LIMIT 1");
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
|
|
||||||
// Assign locals
|
// Assign locals
|
||||||
@@ -37,23 +31,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 me-2"></i>Edit Contract Template</h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-file-contract mr-2"></i>Edit Contract Template</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal"><span>×</span></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-bs-toggle="tab" href="#general" role="tab">General Info</a>
|
<a class="nav-link active" id="general-tab" data-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-bs-toggle="tab" href="#sla" role="tab">SLA</a>
|
<a class="nav-link" id="sla-tab" data-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-bs-toggle="tab" href="#rates" role="tab">Rates & Support</a>
|
<a class="nav-link" id="rates-tab" data-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-bs-toggle="tab" href="#details" role="tab">Details</a>
|
<a class="nav-link" id="details-tab" data-toggle="tab" href="#details" role="tab">Details</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -66,31 +60,37 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="type" required>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -99,11 +99,13 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="renewal_frequency">
|
</div>
|
||||||
|
<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>
|
||||||
@@ -115,57 +117,69 @@ 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="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="form-group 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="mb-3 col-md-6">
|
<div class="form-group 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="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="form-group 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="mb-3 col-md-6">
|
<div class="form-group 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="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="form-group 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="mb-3 col-md-6">
|
<div class="form-group 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>
|
||||||
@@ -175,37 +189,45 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -214,10 +236,12 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -229,10 +253,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 me-2"></i>Save Changes
|
<i class="fa fa-check mr-2"></i>Save Changes
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal">
|
<button type="button" class="btn btn-light" data-dismiss="modal">
|
||||||
<i class="fa fa-times me-2"></i>Cancel
|
<i class="fa fa-times mr-2"></i>Cancel
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ require_once '../../../includes/cron_jobs.php';
|
|||||||
|
|
||||||
$cron_job_id = intval($_GET['id']);
|
$cron_job_id = intval($_GET['id']);
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT cron_job_daily_at, cron_job_enabled, cron_job_interval_minutes, cron_job_name,
|
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM cron_jobs WHERE cron_job_id = $cron_job_id LIMIT 1"));
|
||||||
cron_job_schedule FROM cron_jobs WHERE cron_job_id = $cron_job_id LIMIT 1"));
|
|
||||||
|
|
||||||
$registry = cronJobRegistryByName();
|
$registry = cronJobRegistryByName();
|
||||||
$job = $registry[$row['cron_job_name']] ?? null;
|
$job = $registry[$row['cron_job_name']] ?? null;
|
||||||
@@ -27,27 +26,31 @@ 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 me-2"></i>Editing: <strong><?= $cron_job_label ?></strong></h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-clock mr-2"></i>Editing: <strong><?= $cron_job_label ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<div class="form-check form-switch">
|
<div class="custom-control custom-switch">
|
||||||
<input type="checkbox" class="form-check-input" name="enabled" value="1" id="cronJobEnabledSwitch" <?= $cron_job_enabled == 1 ? 'checked' : '' ?>>
|
<input type="checkbox" class="custom-control-input" name="enabled" value="1" id="cronJobEnabledSwitch" <?= $cron_job_enabled == 1 ? 'checked' : '' ?>>
|
||||||
<label class="form-check-label" for="cronJobEnabledSwitch">Enabled</label>
|
<label class="custom-control-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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select" name="schedule" id="cronJobSchedule">
|
</div>
|
||||||
|
<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 } ?>
|
||||||
@@ -59,20 +62,26 @@ ob_start();
|
|||||||
<?php } ?>
|
<?php } ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3" id="cronJobIntervalGroup">
|
<div class="form-group" 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="mb-3" id="cronJobDailyGroup">
|
<div class="form-group" 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>
|
||||||
@@ -80,8 +89,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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
<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 me-2"></i>Create <?= escapeHtml($table) ?> field</h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-th-list mr-2"></i>Create <?= escapeHtml($table) ?> field</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -11,16 +13,18 @@
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="type" required>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -29,8 +33,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 me-2"></i>Create</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,24 +2,28 @@
|
|||||||
<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 me-2"></i>Editing custom field: <strong><?= $custom_field_label ?></strong></h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-th-list mr-2"></i>Editing custom field: <strong><?= $custom_field_label ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="type" required>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -28,8 +32,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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,54 +7,68 @@ 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 me-2"></i>New Custom Link</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-external-link-alt mr-2"></i>New Custom Link</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 class="form-check-input" type="checkbox" name="new_tab" value="1">
|
<input type="checkbox" name="new_tab" value="1">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="location" required>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -66,8 +80,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 me-2"></i>Create</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$custom_link_id = intval($_GET['id']);
|
$custom_link_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT custom_link_icon, custom_link_location, custom_link_name, custom_link_new_tab,
|
$sql = mysqli_query($mysqli, "SELECT * FROM custom_links WHERE custom_link_id = $custom_link_id LIMIT 1");
|
||||||
custom_link_order, custom_link_uri FROM custom_links WHERE custom_link_id = $custom_link_id LIMIT 1");
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$custom_link_name = escapeHtml($row['custom_link_name']);
|
$custom_link_name = escapeHtml($row['custom_link_name']);
|
||||||
$custom_link_uri = escapeHtml($row['custom_link_uri']);
|
$custom_link_uri = escapeHtml($row['custom_link_uri']);
|
||||||
@@ -19,8 +18,10 @@ 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 me-2"></i>Editing link: <strong><?= $custom_link_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-external-link-alt mr-2"></i>Editing link: <strong><?= $custom_link_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -28,46 +29,58 @@ ob_start();
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 class="form-check-input" type="checkbox" name="new_tab" value="1" <?php if ($custom_link_new_tab == 1) { echo "checked"; } ?>>
|
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="location" required>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -79,8 +92,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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -7,34 +7,38 @@ 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 me-2"></i>Creating Document Template</h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-file-alt mr-2"></i>Creating Document Template</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-1"></i>Generate with AI
|
<i class="fa fa-fw fa-magic mr-1"></i>Generate with AI
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- TinyMCE Content -->
|
<!-- TinyMCE Content -->
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<textarea class="form-control tinymce" name="content"></textarea>
|
<textarea class="form-control tinymce" name="content"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
|
|
||||||
@@ -42,55 +46,41 @@ 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 me-2"></i>Save template</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
$(document).ready(function(){
|
||||||
|
|
||||||
var button = document.getElementById('generateAIContent');
|
$('#generateAIContent').on('click', function(){
|
||||||
var promptField = document.getElementById('aiPrompt');
|
var prompt = $('#aiPrompt').val().trim();
|
||||||
if (!button || !promptField) {
|
if(prompt === '') {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
button.addEventListener('click', function () {
|
|
||||||
var prompt = promptField.value.trim();
|
|
||||||
if (prompt === '') {
|
|
||||||
alert('Please enter a prompt.');
|
alert('Please enter a prompt.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.disabled = true;
|
$('#generateAIContent').prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> Generating...');
|
||||||
button.innerHTML = '<i class="fa fa-spinner fa-spin"></i> Generating...';
|
|
||||||
|
|
||||||
fetch('/agent/ajax.php?ai_create_document_template', {
|
$.ajax({
|
||||||
|
url: '/agent/ajax.php?ai_create_document_template', // The PHP script that calls the OpenAI API
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
data: { prompt: prompt },
|
||||||
credentials: 'same-origin',
|
dataType: 'html',
|
||||||
body: new URLSearchParams({ prompt: prompt }).toString()
|
success: function(response) {
|
||||||
})
|
|
||||||
.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);
|
||||||
})
|
},
|
||||||
.catch(function () {
|
error: function() {
|
||||||
alert('Error generating content. Please try again.');
|
alert('Error generating content. Please try again.');
|
||||||
})
|
},
|
||||||
.finally(function () {
|
complete: function() {
|
||||||
button.disabled = false;
|
$('#generateAIContent').prop('disabled', false).html('<i class="fa fa-fw fa-magic mr-1"></i>Generate with AI');
|
||||||
button.innerHTML = '<i class="fa fa-fw fa-magic me-1"></i>Generate with AI';
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$document_template_id = intval($_GET['id']);
|
$document_template_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT document_template_content, document_template_description, document_template_name FROM document_templates WHERE document_template_id = $document_template_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id LIMIT 1");
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$document_template_name = escapeHtml($row['document_template_name']);
|
$document_template_name = escapeHtml($row['document_template_name']);
|
||||||
$document_template_description = escapeHtml($row['document_template_description']);
|
$document_template_description = escapeHtml($row['document_template_description']);
|
||||||
@@ -14,8 +14,10 @@ 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 me-2"></i>Editing template: <strong><?= $document_template_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-file-alt mr-2"></i>Editing template: <strong><?= $document_template_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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,22 +25,22 @@ ob_start();
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Save template</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ $purifier_config->set('Cache.DefinitionImpl', null); // Disable cache by setting
|
|||||||
$purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]);
|
$purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]);
|
||||||
$purifier = new HTMLPurifier($purifier_config);
|
$purifier = new HTMLPurifier($purifier_config);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT email_attempts, email_content, email_failed_at, email_from, email_from_name,
|
$sql = mysqli_query($mysqli, "SELECT * FROM email_queue WHERE email_id = $email_id LIMIT 1");
|
||||||
email_queued_at, email_recipient, email_recipient_name, email_sent_at, email_status,
|
|
||||||
email_subject FROM email_queue WHERE email_id = $email_id LIMIT 1");
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
|
|
||||||
$email_from = escapeHtml($row['email_from']);
|
$email_from = escapeHtml($row['email_from']);
|
||||||
@@ -42,8 +40,10 @@ 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 me-2'></i><strong><?= $email_subject ?></strong></h5>
|
<h5 class="modal-title"><i class='fas fa-fw fa-envelope-open mr-2'></i><strong><?= $email_subject ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-light" data-dismiss="modal">
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -7,30 +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-credit-card me-2"></i>Creating: <strong>Payment Method</strong></h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i>Creating: <strong>Payment Method</strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Create</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$payment_method_id = intval($_GET['id']);
|
$payment_method_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT payment_method_description, payment_method_id, payment_method_name FROM payment_methods WHERE payment_method_id = $payment_method_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM payment_methods WHERE payment_method_id = $payment_method_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$payment_method_id = intval($row['payment_method_id']);
|
$payment_method_id = intval($row['payment_method_id']);
|
||||||
@@ -15,30 +15,34 @@ $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 me-2"></i>Editing: <strong><?= $payment_method_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i>Editing: <strong><?= $payment_method_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ 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 me-2"></i>Add Payment Provider</h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i>Add Payment Provider</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -16,10 +18,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-bs-toggle="pill" href="#pills-details">Details</a>
|
<a class="nav-link active" data-toggle="pill" href="#pills-details">Details</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-bs-toggle="pill" href="#pills-expense">Expense</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-expense">Expense</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -29,37 +31,45 @@ ob_start();
|
|||||||
|
|
||||||
<div class="tab-pane fade show active" id="pills-details">
|
<div class="tab-pane fade show active" id="pills-details">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="provider">
|
</div>
|
||||||
|
<select class="form-control select2" name="provider">
|
||||||
<option>Stripe</option>
|
<option>Stripe</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="account" required>
|
</div>
|
||||||
|
<select class="form-control select2" name="account" required>
|
||||||
<option value="">- Select an Account -</option>
|
<option value="">- Select an Account -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@@ -78,10 +88,12 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -95,18 +107,20 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<div class="form-check form-switch">
|
<div class="custom-control custom-switch">
|
||||||
<input type="checkbox" class="form-check-input" name="enable_expense" checked value="1" id="enableExpenseSwitch">
|
<input type="checkbox" class="custom-control-input" name="enable_expense" checked value="1" id="enableExpenseSwitch">
|
||||||
<label class="form-check-label" for="enableExpenseSwitch">Enable Expense</label>
|
<label class="custom-control-label" for="enableExpenseSwitch">Enable Expense</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="expense_vendor" required>
|
</div>
|
||||||
|
<select class="form-control select2" name="expense_vendor" required>
|
||||||
<option value="0">Expense Disabled</option>
|
<option value="0">Expense Disabled</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@@ -125,11 +139,13 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="expense_category" required>
|
</div>
|
||||||
|
<select class="form-control select2" name="expense_category" required>
|
||||||
<option value="">- Select a Category -</option>
|
<option value="">- Select a Category -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@@ -144,10 +160,12 @@ 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>
|
||||||
@@ -156,8 +174,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 me-2"></i>Add</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$provider_id = intval($_GET['id']);
|
$provider_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT payment_provider_account, payment_provider_expense_category,
|
$sql = mysqli_query($mysqli, "SELECT * FROM payment_providers WHERE payment_provider_id = $provider_id LIMIT 1");
|
||||||
payment_provider_expense_vendor, payment_provider_name, payment_provider_private_key,
|
|
||||||
payment_provider_public_key, payment_provider_threshold FROM payment_providers WHERE payment_provider_id = $provider_id LIMIT 1");
|
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$provider_name = escapeHtml($row['payment_provider_name']);
|
$provider_name = escapeHtml($row['payment_provider_name']);
|
||||||
@@ -22,8 +20,10 @@ 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 me-2"></i>Editing: <strong><?= $provider_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i>Editing: <strong><?= $provider_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -33,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-bs-toggle="pill" href="#pills-details">Details</a>
|
<a class="nav-link active" data-toggle="pill" href="#pills-details">Details</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-bs-toggle="pill" href="#pills-expense">Expense</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-expense">Expense</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -46,27 +46,33 @@ ob_start();
|
|||||||
|
|
||||||
<div class="tab-pane fade show active" id="pills-details">
|
<div class="tab-pane fade show active" id="pills-details">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="account" required>
|
</div>
|
||||||
|
<select class="form-control select2" name="account" required>
|
||||||
<option value="">- Select an Account -</option>
|
<option value="">- Select an Account -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@@ -85,10 +91,12 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -102,11 +110,13 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="expense_vendor" required>
|
</div>
|
||||||
|
<select class="form-control select2" name="expense_vendor" required>
|
||||||
<option value="0">Expense Disabled</option>
|
<option value="0">Expense Disabled</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@@ -127,11 +137,13 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="expense_category" required>
|
</div>
|
||||||
|
<select class="form-control select2" name="expense_category" required>
|
||||||
<option value="">- Select a Category -</option>
|
<option value="">- Select a Category -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@@ -146,10 +158,12 @@ 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>
|
||||||
@@ -157,8 +171,8 @@ ob_start();
|
|||||||
</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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -6,33 +6,39 @@ 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 me-2"></i>Creating Project Template</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-project-diagram mr-2"></i>Creating Project Template</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Create</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$project_template_id = intval($_GET['project_template_id']);
|
$project_template_id = intval($_GET['project_template_id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT project_template_description, project_template_name FROM project_templates WHERE project_template_id = $project_template_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_id = $project_template_id LIMIT 1");
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$project_template_name = escapeHtml($row['project_template_name']);
|
$project_template_name = escapeHtml($row['project_template_name']);
|
||||||
$project_template_description = escapeHtml($row['project_template_description']);
|
$project_template_description = escapeHtml($row['project_template_description']);
|
||||||
@@ -14,26 +14,32 @@ 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 me-2"></i>Editing Project Template: <strong><?= $project_template_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-project-diagram mr-2"></i>Editing Project Template: <strong><?= $project_template_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -41,8 +47,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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -9,8 +9,10 @@ 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 me-2"></i>Adding Ticket Template</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-life-ring mr-2"></i>Adding Ticket Template</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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,11 +20,13 @@ ob_start();
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="ticket_template_id" required>
|
</div>
|
||||||
|
<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
|
||||||
|
|
||||||
@@ -47,10 +51,12 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -58,8 +64,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 me-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 mr-2"></i>Add</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ 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 me-2"></i>New Role</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>New Role</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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">
|
||||||
@@ -17,10 +19,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-bs-toggle="pill" href="#pills-role-details">Details</a>
|
<a class="nav-link active" data-toggle="pill" href="#pills-role-details">Details</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-bs-toggle="pill" href="#pills-role-permissions">Permissions</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-role-permissions">Permissions</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -31,35 +33,39 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<label>Admin Access <strong class="text-danger">*</strong></label>
|
<label>Admin Access <strong class="text-danger">*</strong></label>
|
||||||
|
|
||||||
<div class="form-check mb-2">
|
<div class="custom-control custom-radio mb-2">
|
||||||
<input type="radio" class="form-check-input" id="admin_no" name="role_is_admin" value="0" checked required>
|
<input type="radio" class="custom-control-input" id="admin_no" name="role_is_admin" value="0" checked required>
|
||||||
<label class="form-check-label" for="admin_no">
|
<label class="custom-control-label" for="admin_no">
|
||||||
No - use permissions on the next tab
|
No - use permissions on the next tab
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-check">
|
<div class="custom-control custom-radio">
|
||||||
<input type="radio" class="form-check-input" id="admin_yes" name="role_is_admin" value="1" required>
|
<input type="radio" class="custom-control-input" id="admin_yes" name="role_is_admin" value="1" required>
|
||||||
<label class="form-check-label" for="admin_yes">
|
<label class="custom-control-label" for="admin_yes">
|
||||||
Yes - this role should have full admin access
|
Yes - this role should have full admin access
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -73,7 +79,7 @@ ob_start();
|
|||||||
|
|
||||||
<?php
|
<?php
|
||||||
// Enumerate modules
|
// Enumerate modules
|
||||||
$sql_modules = mysqli_query($mysqli, "SELECT module_description, module_id, module_name FROM modules");
|
$sql_modules = mysqli_query($mysqli, "SELECT * FROM modules");
|
||||||
while ($row_modules = mysqli_fetch_assoc($sql_modules)) {
|
while ($row_modules = mysqli_fetch_assoc($sql_modules)) {
|
||||||
|
|
||||||
$module_id = intval($row_modules['module_id']);
|
$module_id = intval($row_modules['module_id']);
|
||||||
@@ -92,13 +98,14 @@ ob_start();
|
|||||||
$group_id = "perm_group_$module_id";
|
$group_id = "perm_group_$module_id";
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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 w-100" role="group"
|
<div class="btn-group btn-group-toggle btn-block" data-toggle="buttons" role="group"
|
||||||
aria-label="Permissions for <?= $module_name_display_safe ?>">
|
aria-label="Permissions for <?= $module_name_display_safe ?>">
|
||||||
|
|
||||||
<input class="btn-check"
|
<label class="btn btn-outline-secondary btn-sm active" title="No Access">
|
||||||
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="<?= $field_name ?>"
|
name="<?= $field_name ?>"
|
||||||
id="<?= $group_id ?>_0"
|
id="<?= $group_id ?>_0"
|
||||||
@@ -107,34 +114,41 @@ ob_start();
|
|||||||
checked
|
checked
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<label class="btn btn-outline-secondary btn-sm" title="No Access" for="<?= $group_id ?>_0">None</label>
|
None
|
||||||
|
</label>
|
||||||
|
|
||||||
<input class="btn-check"
|
<label class="btn btn-outline-primary btn-sm" title="Viewing Only">
|
||||||
|
<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"
|
||||||
>
|
>
|
||||||
<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>
|
<i class="fas fa-fw fa-eye mr-1"></i>Read
|
||||||
|
</label>
|
||||||
|
|
||||||
<input class="btn-check"
|
<label class="btn btn-outline-warning btn-sm" title="Read, Edit, Archive">
|
||||||
|
<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"
|
||||||
>
|
>
|
||||||
<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>
|
<i class="fas fa-fw fa-edit mr-1"></i>Modify
|
||||||
|
</label>
|
||||||
|
|
||||||
<input class="btn-check"
|
<label class="btn btn-outline-danger btn-sm" title="Read, Edit, Archive, Delete">
|
||||||
|
<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"
|
||||||
>
|
>
|
||||||
<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>
|
<i class="fas fa-fw fa-trash mr-1"></i>Full
|
||||||
|
</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -150,10 +164,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 me-2"></i>Create
|
<i class="fas fa-check mr-2"></i>Create
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal">
|
<button type="button" class="btn btn-light" data-dismiss="modal">
|
||||||
<i class="fas fa-times me-2"></i>Cancel
|
<i class="fas fa-times mr-2"></i>Cancel
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ $role_admin = intval($row['role_is_admin']);
|
|||||||
$sql_role_user_count = mysqli_query($mysqli, "SELECT COUNT(user_id) FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
|
$sql_role_user_count = mysqli_query($mysqli, "SELECT COUNT(user_id) FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
|
||||||
$role_user_count = mysqli_fetch_row($sql_role_user_count)[0];
|
$role_user_count = mysqli_fetch_row($sql_role_user_count)[0];
|
||||||
|
|
||||||
$sql_users = mysqli_query($mysqli, "SELECT user_name FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
|
$sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
|
||||||
// Initialize an empty array to hold user names
|
// Initialize an empty array to hold user names
|
||||||
$user_names = [];
|
$user_names = [];
|
||||||
|
|
||||||
@@ -35,9 +35,11 @@ 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 me-2"></i>Editing role:
|
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>Editing role:
|
||||||
<strong><?= $role_name ?></strong></h5>
|
<strong><?= $role_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -45,11 +47,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-bs-toggle="pill" href="#pills-role-details">Details</a>
|
<a class="nav-link active" data-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-bs-toggle="pill" href="#pills-role-permissions">Permissions</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-role-permissions">Permissions</a>
|
||||||
</li>
|
</li>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -60,37 +62,41 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<label>Admin Access <strong class="text-danger">*</strong></label>
|
<label>Admin Access <strong class="text-danger">*</strong></label>
|
||||||
<div class="form-check mb-2">
|
<div class="custom-control custom-radio mb-2">
|
||||||
<input type="radio" class="form-check-input" id="admin_yes" name="role_is_admin" value="1"
|
<input type="radio" class="custom-control-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="form-check-label" for="admin_yes">
|
<label class="custom-control-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="form-check">
|
<div class="custom-control custom-radio">
|
||||||
<input type="radio" class="form-check-input" id="admin_no" name="role_is_admin" value="0"
|
<input type="radio" class="custom-control-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="form-check-label" for="admin_no">
|
<label class="custom-control-label" for="admin_no">
|
||||||
No - use permissions on the next tab
|
No - use permissions on the next tab
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -107,7 +113,7 @@ ob_start();
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Enumerate modules
|
// Enumerate modules
|
||||||
$sql_modules = mysqli_query($mysqli, "SELECT module_description, module_id, module_name FROM modules");
|
$sql_modules = mysqli_query($mysqli, "SELECT * FROM modules");
|
||||||
while ($row_modules = mysqli_fetch_assoc($sql_modules)) {
|
while ($row_modules = mysqli_fetch_assoc($sql_modules)) {
|
||||||
$module_id = intval($row_modules['module_id']);
|
$module_id = intval($row_modules['module_id']);
|
||||||
$module_name = escapeHtml($row_modules['module_name']);
|
$module_name = escapeHtml($row_modules['module_name']);
|
||||||
@@ -122,16 +128,17 @@ ob_start();
|
|||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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 w-100" role="group" aria-label="Permissions for <?= $module_name_display ?>">
|
<div class="btn-group btn-group-toggle btn-block" data-toggle="buttons" role="group" aria-label="Permissions for <?= $module_name_display ?>">
|
||||||
|
|
||||||
<input class="btn-check"
|
<label class="btn btn-outline-secondary btn-sm <?php if ($module_permission == 0) { echo 'active'; } ?>" title="No Access">
|
||||||
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="<?= $field_name ?>"
|
name="<?= $field_name ?>"
|
||||||
id="<?= $group_id ?>_0"
|
id="<?= $group_id ?>_0"
|
||||||
@@ -140,9 +147,11 @@ ob_start();
|
|||||||
<?php if ($module_permission == 0) { echo 'checked'; } ?>
|
<?php if ($module_permission == 0) { echo 'checked'; } ?>
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<label class="btn btn-outline-secondary btn-sm" title="No Access" for="<?= $group_id ?>_0">None</label>
|
None
|
||||||
|
</label>
|
||||||
|
|
||||||
<input class="btn-check"
|
<label class="btn btn-outline-primary btn-sm <?php if ($module_permission == 1) { echo 'active'; } ?>" title="Viewing Only">
|
||||||
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="<?= $field_name ?>"
|
name="<?= $field_name ?>"
|
||||||
id="<?= $group_id ?>_1"
|
id="<?= $group_id ?>_1"
|
||||||
@@ -150,9 +159,11 @@ ob_start();
|
|||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
<?php if ($module_permission == 1) { echo 'checked'; } ?>
|
<?php if ($module_permission == 1) { echo 'checked'; } ?>
|
||||||
>
|
>
|
||||||
<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>
|
<i class="fas fa-fw fa-eye mr-1"></i>Read
|
||||||
|
</label>
|
||||||
|
|
||||||
<input class="btn-check"
|
<label class="btn btn-outline-warning btn-sm <?php if ($module_permission == 2) { echo 'active'; } ?>" title="Read, Edit, Archive">
|
||||||
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="<?= $field_name ?>"
|
name="<?= $field_name ?>"
|
||||||
id="<?= $group_id ?>_2"
|
id="<?= $group_id ?>_2"
|
||||||
@@ -160,9 +171,11 @@ ob_start();
|
|||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
<?php if ($module_permission == 2) { echo 'checked'; } ?>
|
<?php if ($module_permission == 2) { echo 'checked'; } ?>
|
||||||
>
|
>
|
||||||
<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>
|
<i class="fas fa-fw fa-edit mr-1"></i>Modify
|
||||||
|
</label>
|
||||||
|
|
||||||
<input class="btn-check"
|
<label class="btn btn-outline-danger btn-sm <?php if ($module_permission == 3) { echo 'active'; } ?>" title="Read, Edit, Archive, Delete">
|
||||||
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="<?= $field_name ?>"
|
name="<?= $field_name ?>"
|
||||||
id="<?= $group_id ?>_3"
|
id="<?= $group_id ?>_3"
|
||||||
@@ -170,7 +183,8 @@ ob_start();
|
|||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
<?php if ($module_permission == 3) { echo 'checked'; } ?>
|
<?php if ($module_permission == 3) { echo 'checked'; } ?>
|
||||||
>
|
>
|
||||||
<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>
|
<i class="fas fa-fw fa-trash mr-1"></i>Full
|
||||||
|
</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -187,8 +201,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 me-2"></i>Save</button>
|
<button type="submit" name="edit_role" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,49 +4,59 @@ 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 me-2"></i>New SLA</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-stopwatch mr-2"></i>New SLA</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Create</button>
|
<button type="submit" name="add_sla" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$sla_id = intval($_GET['id']);
|
$sla_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT sla_description, sla_name, sla_resolution_minutes, sla_response_minutes FROM slas WHERE sla_id = $sla_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM slas WHERE sla_id = $sla_id LIMIT 1");
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$sla_name = escapeHtml($row['sla_name']);
|
$sla_name = escapeHtml($row['sla_name']);
|
||||||
$sla_description = escapeHtml($row['sla_description']);
|
$sla_description = escapeHtml($row['sla_description']);
|
||||||
@@ -14,42 +14,52 @@ 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 me-2"></i>Editing SLA: <strong><?= $sla_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-stopwatch mr-2"></i>Editing SLA: <strong><?= $sla_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -57,8 +67,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 me-2"></i>Save</button>
|
<button type="submit" name="edit_sla" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -17,43 +17,53 @@ 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 me-2"></i>New License Template</h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-cube mr-2"></i>New License Template</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="type" required>
|
</div>
|
||||||
|
<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, "
|
||||||
@@ -71,11 +81,13 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="license_type">
|
</div>
|
||||||
|
<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>
|
||||||
@@ -88,8 +100,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 me-2"></i>Create</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$software_template_id = intval($_GET['id']);
|
$software_template_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT software_template_description, software_template_license_type, software_template_name,
|
$sql = mysqli_query($mysqli, "SELECT * FROM software_templates WHERE software_template_id = $software_template_id LIMIT 1");
|
||||||
software_template_notes, software_template_type, software_template_version FROM software_templates WHERE software_template_id = $software_template_id LIMIT 1");
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$software_name = escapeHtml($row['software_template_name']);
|
$software_name = escapeHtml($row['software_template_name']);
|
||||||
$software_version = escapeHtml($row['software_template_version']);
|
$software_version = escapeHtml($row['software_template_version']);
|
||||||
@@ -29,8 +28,10 @@ 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 me-2"></i>Editing template: <strong><?= $software_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-cube mr-2"></i>Editing template: <strong><?= $software_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -38,35 +39,43 @@ ob_start();
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="type" required>
|
</div>
|
||||||
|
<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, "
|
||||||
@@ -86,11 +95,13 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="license_type">
|
</div>
|
||||||
|
<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>
|
||||||
@@ -103,8 +114,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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -24,18 +24,22 @@ 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 me-2"></i>New <strong><?= $type_display ?></strong> Tag</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-tag mr-2"></i>New <strong><?= $type_display ?></strong> Tag</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -46,11 +50,13 @@ ob_start();
|
|||||||
|
|
||||||
<?php } else { ?>
|
<?php } else { ?>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="type" required>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -63,26 +69,30 @@ ob_start();
|
|||||||
|
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Create Tag</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$tag_id = intval($_GET['id']);
|
$tag_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT tag_color, tag_icon, tag_name, tag_type FROM tags WHERE tag_id = $tag_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_id = $tag_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$tag_name = escapeHtml($row['tag_name']);
|
$tag_name = escapeHtml($row['tag_name']);
|
||||||
@@ -29,8 +29,10 @@ 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 me-2"></i><?= $tag_type_display ?> Tag: <strong><?= $tag_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-tag mr-2"></i><?= $tag_type_display ?> Tag: <strong><?= $tag_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -38,34 +40,40 @@ ob_start();
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Save changes</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -7,25 +7,27 @@ 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 me-2"></i>New Tax</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-balance-scale mr-2"></i>New Tax</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span aria-hidden="true">×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Create</button>
|
<button type="submit" name="add_tax" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$tax_id = intval($_GET['id']);
|
$tax_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT tax_name, tax_percent FROM taxes WHERE tax_id = $tax_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM taxes WHERE tax_id = $tax_id LIMIT 1");
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$tax_name = escapeHtml($row['tax_name']);
|
$tax_name = escapeHtml($row['tax_name']);
|
||||||
$tax_percent = floatval($row['tax_percent']);
|
$tax_percent = floatval($row['tax_percent']);
|
||||||
@@ -14,8 +14,10 @@ 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 me-2"></i>Editing tax: <strong><?= $tax_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-balance-scale mr-2"></i>Editing tax: <strong><?= $tax_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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,20 +25,20 @@ ob_start();
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Save</button>
|
<button type="submit" name="edit_tax" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,35 +4,43 @@ 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 me-2"></i>New Ticket Status</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-info-circle mr-2"></i>New Ticket Status</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="pauses_sla">
|
</div>
|
||||||
|
<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>
|
||||||
@@ -41,8 +49,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 me-2"></i>Create</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,24 +4,23 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$ticket_status_id = intval($_GET['id']);
|
$ticket_status_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT ticket_status_active, ticket_status_color, ticket_status_name, ticket_status_order,
|
$sql = mysqli_query($mysqli, "SELECT * FROM ticket_statuses WHERE ticket_status_id = $ticket_status_id LIMIT 1");
|
||||||
ticket_status_pauses_sla FROM ticket_statuses WHERE ticket_status_id = $ticket_status_id LIMIT 1");
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$ticket_status_name = escapeHtml($row['ticket_status_name']);
|
$ticket_status_name = escapeHtml($row['ticket_status_name']);
|
||||||
$ticket_status_color = escapeHtml($row['ticket_status_color']);
|
$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 me-2"></i>Editing Ticket Status: <strong><?= $ticket_status_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-info-circle mr-2"></i>Editing Ticket Status: <strong><?= $ticket_status_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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 +28,67 @@ ob_start();
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="status" required>
|
</div>
|
||||||
|
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<?php if (is_null($ticket_status_sla_lock)) { ?>
|
</div>
|
||||||
<select class="form-select select2" name="pauses_sla">
|
<select class="form-control 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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -6,51 +6,61 @@ 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 me-2"></i>New Ticket Template</h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-life-ring mr-2"></i>New Ticket Template</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<textarea class="form-control tinymceTicket" name="details"></textarea>
|
<textarea class="form-control tinymceTicket" name="details"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="project_template">
|
</div>
|
||||||
|
<select class="form-control select2" name="project_template">
|
||||||
<option value="0">- No -</option>
|
<option value="0">- No -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql_project_templates = mysqli_query($mysqli, "SELECT project_template_id, project_template_name FROM project_templates WHERE project_template_archived_at IS NULL ORDER BY project_template_name ASC");
|
$sql_project_templates = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_archived_at IS NULL ORDER BY project_template_name ASC");
|
||||||
while ($row = mysqli_fetch_assoc($sql_project_templates)) {
|
while ($row = mysqli_fetch_assoc($sql_project_templates)) {
|
||||||
$project_template_id_select = intval($row['project_template_id']);
|
$project_template_id_select = intval($row['project_template_id']);
|
||||||
$project_template_name_select = escapeHtml($row['project_template_name']); ?>
|
$project_template_name_select = escapeHtml($row['project_template_name']); ?>
|
||||||
@@ -62,8 +72,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 me-2"></i>Create Template</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
<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 me-2"></i>Editing Ticket Template: <?= $ticket_template_name ?></h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-life-ring mr-2"></i>Editing Ticket Template: <?= $ticket_template_name ?></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -12,38 +14,44 @@
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$task_template_id = intval($_GET['id']);
|
$task_template_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT task_template_completion_estimate, task_template_name, task_template_order FROM task_templates WHERE task_template_id = $task_template_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM task_templates WHERE task_template_id = $task_template_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$task_template_name = escapeHtml($row['task_template_name']);
|
$task_template_name = escapeHtml($row['task_template_name']);
|
||||||
@@ -18,8 +18,10 @@ 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 me-2"></i>Editing task</h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-tasks mr-2"></i>Editing task</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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,18 +29,22 @@ ob_start();
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -46,8 +52,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 me-2"></i>Save</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ 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 me-2"></i>New User</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-user-plus mr-2"></i>New User</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -15,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-bs-toggle="pill" href="#pills-user-details">Details</a>
|
<a class="nav-link active" data-toggle="pill" href="#pills-user-details">Details</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-bs-toggle="pill" href="#pills-user-access">Restrict Access</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-user-access">Restrict Access</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -28,40 +30,52 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="role" required>
|
</div>
|
||||||
|
<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 * 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)) {
|
||||||
$role_id = intval($row['role_id']);
|
$role_id = intval($row['role_id']);
|
||||||
$role_name = escapeHtml($row['role_name']);
|
$role_name = escapeHtml($row['role_name']);
|
||||||
@@ -73,24 +87,24 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<label>Avatar</label>
|
<label>Avatar</label>
|
||||||
<input type="file" class="form-control" accept="image/*" name="file">
|
<input type="file" class="form-control-file" accept="image/*" name="file">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3" <?php if(empty($config_smtp_host)) { echo "hidden"; } ?>>
|
<div class="form-group" <?php if(empty($config_smtp_host)) { echo "hidden"; } ?>>
|
||||||
<div class="form-check">
|
<div class="custom-control custom-checkbox">
|
||||||
<input class="form-check-input" type="checkbox" id="sendEmailCheckBox" name="send_email" value="" checked>
|
<input class="custom-control-input" type="checkbox" id="sendEmailCheckBox" name="send_email" value="" checked>
|
||||||
<label for="sendEmailCheckBox" class="form-check-label">
|
<label for="sendEmailCheckBox" class="custom-control-label">
|
||||||
Send user e-mail with login details?
|
Send user e-mail with login details?
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<div class="form-check">
|
<div class="custom-control custom-checkbox">
|
||||||
<input class="form-check-input" type="checkbox" id="forceMFACheckBox" name="force_mfa" value=1>
|
<input class="custom-control-input" type="checkbox" id="forceMFACheckBox" name="force_mfa" value=1>
|
||||||
<label for="forceMFACheckBox" class="form-check-label">
|
<label for="forceMFACheckBox" class="custom-control-label">
|
||||||
Force MFA
|
Force MFA
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -105,7 +119,7 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<small class="text-muted me-2">Set all:</small>
|
<small class="text-muted mr-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>
|
||||||
@@ -124,7 +138,7 @@ ob_start();
|
|||||||
<tbody>
|
<tbody>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql_client_select = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
$sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||||
while ($row = mysqli_fetch_assoc($sql_client_select)) {
|
while ($row = mysqli_fetch_assoc($sql_client_select)) {
|
||||||
$client_id = intval($row['client_id']);
|
$client_id = intval($row['client_id']);
|
||||||
$client_name = escapeHtml($row['client_name']);
|
$client_name = escapeHtml($row['client_name']);
|
||||||
@@ -133,13 +147,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="form-check-input perm-none" name="client_permission[<?= $client_id ?>]" value="" checked>
|
<input type="radio" class="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="form-check-input perm-allow" name="client_permission[<?= $client_id ?>]" value="allow">
|
<input type="radio" class="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="form-check-input perm-deny" name="client_permission[<?= $client_id ?>]" value="deny">
|
<input type="radio" class="perm-deny" name="client_permission[<?= $client_id ?>]" value="deny">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@@ -155,15 +169,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 me-2"></i>Create</button>
|
<button type="submit" name="add_user" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
function generatePassword() {
|
function generatePassword() {
|
||||||
itflowGet(
|
jQuery.get(
|
||||||
"/agent/ajax.php", {
|
"/agent/ajax.php", {
|
||||||
get_readable_pass: 'true'
|
get_readable_pass: 'true'
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,14 +18,16 @@ 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 me-2"></i>Reset passwords</button>
|
<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>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-outline-secondary btn-lg px-5 me-4" data-bs-dismiss="modal">Cancel</button>
|
<button type="button" class="btn btn-outline-secondary btn-lg px-5 mr-4" data-dismiss="modal">Cancel</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$user_id = intval($_GET['id']);
|
$user_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT user_avatar, user_email, user_name FROM users WHERE users.user_id = $user_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE users.user_id = $user_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$user_name = escapeHtml($row['user_name']);
|
$user_name = escapeHtml($row['user_name']);
|
||||||
@@ -12,13 +12,13 @@ $user_email = escapeHtml($row['user_email']);
|
|||||||
$user_avatar = escapeHtml($row['user_avatar']);
|
$user_avatar = escapeHtml($row['user_avatar']);
|
||||||
$user_initials = escapeHtml(initials($user_name));
|
$user_initials = escapeHtml(initials($user_name));
|
||||||
|
|
||||||
$sql_related_tickets = mysqli_query($mysqli, "SELECT 1 FROM tickets
|
$sql_related_tickets = mysqli_query($mysqli, "SELECT * FROM tickets
|
||||||
WHERE ticket_assigned_to = $user_id AND ticket_resolved_at IS NULL AND ticket_closed_at IS NULL");
|
WHERE ticket_assigned_to = $user_id AND ticket_resolved_at IS NULL AND ticket_closed_at IS NULL");
|
||||||
|
|
||||||
$ticket_count = mysqli_num_rows($sql_related_tickets);
|
$ticket_count = mysqli_num_rows($sql_related_tickets);
|
||||||
|
|
||||||
// Related Recurring Tickets Query
|
// Related Recurring Tickets Query
|
||||||
$sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT 1 FROM recurring_tickets WHERE recurring_ticket_assigned_to = $user_id");
|
$sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM recurring_tickets WHERE recurring_ticket_assigned_to = $user_id");
|
||||||
|
|
||||||
$recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets);
|
$recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets);
|
||||||
|
|
||||||
@@ -26,9 +26,11 @@ $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 me-2"></i>Archiving user:
|
<h5 class="modal-title"><i class="fas fa-fw fa-user-slash mr-2"></i>Archiving user:
|
||||||
<strong><?= $user_name ?></strong></h5>
|
<strong><?= $user_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -48,14 +50,16 @@ ob_start();
|
|||||||
</center>
|
</center>
|
||||||
|
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="ticket_assign" required>
|
</div>
|
||||||
|
<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 * FROM users WHERE user_type = 1 AND user_archived_at IS NULL");
|
||||||
while ($row = mysqli_fetch_assoc($sql_users)) {
|
while ($row = mysqli_fetch_assoc($sql_users)) {
|
||||||
$user_id_select = intval($row['user_id']);
|
$user_id_select = intval($row['user_id']);
|
||||||
$user_name_select = escapeHtml($row['user_name']);
|
$user_name_select = escapeHtml($row['user_name']);
|
||||||
@@ -70,8 +74,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 me-2"></i>Archive</button>
|
<button type="submit" name="archive_user" class="btn btn-danger text-bold"><i class="fas fa-archive mr-2"></i>Archive</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$user_id = intval($_GET['id']);
|
$user_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT user_avatar, user_config_force_mfa, user_email, user_name, user_role_id, user_token FROM users
|
$sql = mysqli_query($mysqli, "SELECT * FROM users
|
||||||
LEFT JOIN user_settings ON users.user_id = user_settings.user_id
|
LEFT JOIN user_settings ON users.user_id = user_settings.user_id
|
||||||
WHERE users.user_id = $user_id LIMIT 1"
|
WHERE users.user_id = $user_id LIMIT 1"
|
||||||
);
|
);
|
||||||
@@ -35,9 +35,11 @@ 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 me-2"></i>Editing user:
|
<h5 class="modal-title"><i class="fas fa-fw fa-user-edit mr-2"></i>Editing user:
|
||||||
<strong><?= $user_name ?></strong></h5>
|
<strong><?= $user_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -46,10 +48,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-bs-toggle="pill" href="#pills-user-details<?= $user_id ?>">Details</a>
|
<a class="nav-link active" data-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-bs-toggle="pill" href="#pills-user-access<?= $user_id ?>">Restrict Access</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-user-access<?= $user_id ?>">Restrict Access</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -70,42 +72,54 @@ ob_start();
|
|||||||
<?php } ?>
|
<?php } ?>
|
||||||
</center>
|
</center>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="role" required>
|
</div>
|
||||||
|
<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 * 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)) {
|
||||||
$role_id = intval($row['role_id']);
|
$role_id = intval($row['role_id']);
|
||||||
$role_name = escapeHtml($row['role_name']);
|
$role_name = escapeHtml($row['role_name']);
|
||||||
@@ -118,15 +132,15 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<label>Avatar</label>
|
<label>Avatar</label>
|
||||||
<input type="file" class="form-control" accept="image/*" name="file">
|
<input type="file" class="form-control-file" accept="image/*" name="file">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<div class="form-check">
|
<div class="custom-control custom-checkbox">
|
||||||
<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"; } ?>>
|
<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"; } ?>>
|
||||||
<label for="forceMFACheckBox<?= $user_id ?>" class="form-check-label">
|
<label for="forceMFACheckBox<?= $user_id ?>" class="custom-control-label">
|
||||||
Force MFA
|
Force MFA
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -134,11 +148,13 @@ ob_start();
|
|||||||
|
|
||||||
<?php if (!empty($user_token)) { ?>
|
<?php if (!empty($user_token)) { ?>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select" name="2fa">
|
</div>
|
||||||
|
<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>
|
||||||
@@ -155,7 +171,7 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<small class="text-muted me-2">Set all:</small>
|
<small class="text-muted mr-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>
|
||||||
@@ -174,7 +190,7 @@ ob_start();
|
|||||||
<tbody>
|
<tbody>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql_client_select = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
$sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||||
while ($row = mysqli_fetch_assoc($sql_client_select)) {
|
while ($row = mysqli_fetch_assoc($sql_client_select)) {
|
||||||
$client_id_select = intval($row['client_id']);
|
$client_id_select = intval($row['client_id']);
|
||||||
$client_name_select = escapeHtml($row['client_name']);
|
$client_name_select = escapeHtml($row['client_name']);
|
||||||
@@ -185,13 +201,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="form-check-input perm-none" name="client_permission[<?= $client_id_select ?>]" value="" <?php if (!$client_is_allow && !$client_is_deny) { echo "checked"; } ?>>
|
<input type="radio" class="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="form-check-input perm-allow" name="client_permission[<?= $client_id_select ?>]" value="allow" <?php if ($client_is_allow) { echo "checked"; } ?>>
|
<input type="radio" class="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="form-check-input perm-deny" name="client_permission[<?= $client_id_select ?>]" value="deny" <?php if ($client_is_deny) { echo "checked"; } ?>>
|
<input type="radio" class="perm-deny" name="client_permission[<?= $client_id_select ?>]" value="deny" <?php if ($client_is_deny) { echo "checked"; } ?>>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@@ -206,8 +222,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 me-2"></i>Save</button>
|
<button type="submit" name="edit_user" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@@ -215,7 +231,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
|
||||||
itflowGet(
|
jQuery.get(
|
||||||
"/agent/ajax.php", {
|
"/agent/ajax.php", {
|
||||||
get_readable_pass: 'true'
|
get_readable_pass: 'true'
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -22,8 +22,10 @@ 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 me-2"></i>Export Users</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Users</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php exportTabsNav(); ?>
|
<?php exportTabsNav(); ?>
|
||||||
@@ -35,19 +37,23 @@ ob_start();
|
|||||||
|
|
||||||
<?php exportTabsFiltersOpen(); ?>
|
<?php exportTabsFiltersOpen(); ?>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="archived">
|
</div>
|
||||||
|
<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>
|
||||||
|
|||||||
@@ -7,25 +7,31 @@ 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="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="role" required>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -34,8 +40,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 me-2"></i>Send Invite</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$user_id = intval($_GET['id']);
|
$user_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT user_avatar, user_email, user_name, user_role_id FROM users WHERE user_id = $user_id AND user_archived_at IS NOT NULL LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $user_id AND user_archived_at IS NOT NULL LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$user_name = str_replace(" (archived)", "", $row['user_name']); //Removed (archived) from user_name
|
$user_name = str_replace(" (archived)", "", $row['user_name']); //Removed (archived) from user_name
|
||||||
@@ -18,9 +18,11 @@ $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 me-2"></i>Restoring user:
|
<h5 class="modal-title"><i class="fas fa-fw fa-redo-alt mr-2"></i>Restoring user:
|
||||||
<strong><?= $user_name ?></strong></h5>
|
<strong><?= $user_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -39,23 +41,29 @@ ob_start();
|
|||||||
<?php } ?>
|
<?php } ?>
|
||||||
</center>
|
</center>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="role" required>
|
</div>
|
||||||
|
<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 * 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)) {
|
||||||
$role_id = intval($row['role_id']);
|
$role_id = intval($row['role_id']);
|
||||||
$role_name = escapeHtml($row['role_name']);
|
$role_name = escapeHtml($row['role_name']);
|
||||||
@@ -70,8 +78,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 me-2"></i>Restore</button>
|
<button type="submit" name="restore_user" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Restore</button>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ 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 me-2"></i>New Vendor Template</h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-building mr-2"></i>New Vendor Template</h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -17,13 +19,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-bs-toggle="pill" href="#pills-details">Details</a>
|
<a class="nav-link active" data-toggle="pill" href="#pills-details">Details</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-bs-toggle="pill" href="#pills-support">Support</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-support">Support</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-bs-toggle="pill" href="#pills-notes">Notes</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-notes">Notes</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -33,34 +35,42 @@ ob_start();
|
|||||||
|
|
||||||
<div class="tab-pane fade show active" id="pills-details">
|
<div class="tab-pane fade show active" id="pills-details">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -70,59 +80,71 @@ 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="row g-2">
|
<div class="form-row">
|
||||||
<div class="col-9">
|
<div class="col-9">
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -131,7 +153,7 @@ ob_start();
|
|||||||
|
|
||||||
<div class="tab-pane fade" id="pills-notes">
|
<div class="tab-pane fade" id="pills-notes">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
|
|
||||||
@@ -141,8 +163,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 me-2"></i>Create Template</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,7 @@ require_once '../../includes/modal_header.php';
|
|||||||
|
|
||||||
$vendor_template_id = intval($_GET['id']);
|
$vendor_template_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT vendor_template_account_number, vendor_template_code, vendor_template_contact_name,
|
$sql = mysqli_query($mysqli, "SELECT * FROM vendor_templates WHERE vendor_template_id = $vendor_template_id LIMIT 1");
|
||||||
vendor_template_description, vendor_template_email, vendor_template_extension,
|
|
||||||
vendor_template_hours, vendor_template_name, vendor_template_notes, vendor_template_phone,
|
|
||||||
vendor_template_phone_country_code, vendor_template_sla, vendor_template_website FROM vendor_templates WHERE vendor_template_id = $vendor_template_id LIMIT 1");
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$vendor_name = escapeHtml($row['vendor_template_name']);
|
$vendor_name = escapeHtml($row['vendor_template_name']);
|
||||||
$vendor_description = escapeHtml($row['vendor_template_description']);
|
$vendor_description = escapeHtml($row['vendor_template_description']);
|
||||||
@@ -28,8 +25,10 @@ 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 me-2"></i>Editing vendor template: <strong><?= $vendor_name ?></strong></h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-building mr-2"></i>Editing vendor template: <strong><?= $vendor_name ?></strong></h5>
|
||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</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'] ?>">
|
||||||
@@ -39,13 +38,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-bs-toggle="pill" href="#pills-details<?= $vendor_template_id ?>">Details</a>
|
<a class="nav-link active" data-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-bs-toggle="pill" href="#pills-support<?= $vendor_template_id ?>">Support</a>
|
<a class="nav-link" data-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-bs-toggle="pill" href="#pills-notes<?= $vendor_template_id ?>">Notes</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-notes<?= $vendor_template_id ?>">Notes</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -58,54 +57,70 @@ 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="mb-3">
|
<div class="form-group">
|
||||||
<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 class="form-check-input" type="checkbox" name="global_update_vendor_name" value="1">
|
<input type="checkbox" name="global_update_vendor_name" value="1">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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 class="form-check-input" type="checkbox" name="global_update_vendor_description" value="1">
|
<input type="checkbox" name="global_update_vendor_description" value="1">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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 class="form-check-input" type="checkbox" name="global_update_vendor_account_number" value="1">
|
<input type="checkbox" name="global_update_vendor_account_number" value="1">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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 class="form-check-input" type="checkbox" name="global_update_vendor_contact_name" value="1">
|
<input type="checkbox" name="global_update_vendor_contact_name" value="1">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<div class="form-check">
|
<div class="custom-control custom-checkbox">
|
||||||
<input type="checkbox" class="form-check-input" id="updateVendorsCheckbox<?= $vendor_template_id ?>" name="update_base_vendors" value="1" >
|
<input type="checkbox" class="custom-control-input" id="updateVendorsCheckbox<?= $vendor_template_id ?>" name="update_base_vendors" value="1" >
|
||||||
<label class="form-check-label" for="updateVendorsCheckbox<?= $vendor_template_id ?>">Update All Base Vendors</label>
|
<label class="custom-control-label" for="updateVendorsCheckbox<?= $vendor_template_id ?>">Update All Base Vendors</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -114,11 +129,13 @@ 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="row g-2">
|
<div class="form-row">
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -127,65 +144,87 @@ 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 class="form-check-input" type="checkbox" name="global_update_vendor_phone" value="1">
|
<input type="checkbox" name="global_update_vendor_phone" value="1">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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 class="form-check-input" type="checkbox" name="global_update_vendor_hours" value="1">
|
<input type="checkbox" name="global_update_vendor_hours" value="1">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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 class="form-check-input" type="checkbox" name="global_update_vendor_email" value="1">
|
<input type="checkbox" name="global_update_vendor_email" value="1">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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 class="form-check-input" type="checkbox" name="global_update_vendor_website" value="1">
|
<input type="checkbox" name="global_update_vendor_website" value="1">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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 class="form-check-input" type="checkbox" name="global_update_vendor_sla" value="1">
|
<input type="checkbox" name="global_update_vendor_sla" value="1">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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 class="form-check-input" type="checkbox" name="global_update_vendor_code" value="1">
|
<input type="checkbox" name="global_update_vendor_code" value="1">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -193,13 +232,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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<label>Update Notes Globally?</label>
|
<label>Update Notes Globally?</label>
|
||||||
<input class="form-check-input" type="checkbox" name="global_update_vendor_notes" value="1">
|
<input type="checkbox" name="global_update_vendor_notes" value="1">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -208,8 +247,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 me-2"></i>Update Template</button>
|
<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="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fa fa-times me-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
|
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT SQL_CALC_FOUND_ROWS module_description, module_id, module_name FROM modules
|
"SELECT SQL_CALC_FOUND_ROWS * FROM modules
|
||||||
WHERE (module_name LIKE '%$q%' OR module_description LIKE '%$q%')
|
WHERE (module_name LIKE '%$q%' OR module_description LIKE '%$q%')
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||||
);
|
);
|
||||||
@@ -17,92 +17,95 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card card-dark">
|
||||||
<div class="card-header bg-dark py-2">
|
<div class="card-header py-2">
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-puzzle-piece me-2"></i>Access Modules</h3>
|
<h3 class="card-title mt-2"><i class="fas fa-fw fa-puzzle-piece mr-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 me-2"></i>New Module
|
<i class="fas fa-fw fa-plus mr-2"></i>New Module
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-header py-3">
|
<div class="card-body">
|
||||||
<form autocomplete="off">
|
<form class="mb-4" autocomplete="off">
|
||||||
<div class="row g-2 align-items-center">
|
<div class="row">
|
||||||
<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>
|
||||||
</div>
|
<hr>
|
||||||
<div class="table-responsive-sm">
|
<div class="table-responsive-sm">
|
||||||
<table class="table table-striped table-borderless table-hover mb-0">
|
<table class="table table-striped table-borderless table-hover">
|
||||||
<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>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=module_name&order=<?= $disp ?>">
|
|
||||||
Module <?php if ($sort == 'module_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
|
||||||
$module_id = intval($row['module_id']);
|
|
||||||
$module_name = escapeHtml($row['module_name']);
|
|
||||||
$module_description = escapeHtml($row['module_description']);
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<th>
|
||||||
<a href="#" <?php if ($module_id > 6) { ?> class="ajax-modal" data-modal-url="modals/modules/module_edit.php?id=<?= $module_id ?>" <?php } ?>>
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=module_name&order=<?= $disp ?>">
|
||||||
<strong class="text-dark"><?= $module_name ?></strong>
|
Module <?php if ($sort == 'module_name') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
<div class="text-secondary"><?= $module_description ?></div>
|
</th>
|
||||||
</td>
|
<th class="text-center">Action</th>
|
||||||
<td>
|
|
||||||
<?php if ($module_id > 6) { ?>
|
|
||||||
<div class="dropdown dropstart text-center">
|
|
||||||
<button class="btn btn-secondary btn-sm" type="button" 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/module/module_edit.php?id=<?= $module_id ?>">
|
|
||||||
<i class="fas fa-fw fa-user-edit me-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<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'] ?>">
|
|
||||||
<i class="fas fa-fw fa-archive me-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } else { echo "<p class='text-center'>N/A Predefined</p>"; } ?>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
}
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
|
$module_id = intval($row['module_id']);
|
||||||
|
$module_name = escapeHtml($row['module_name']);
|
||||||
|
$module_description = escapeHtml($row['module_description']);
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="#" <?php if ($module_id > 6) { ?> class="ajax-modal" data-modal-url="modals/modules/module_edit.php?id=<?= $module_id ?>" <?php } ?>>
|
||||||
|
<strong class="text-dark"><?= $module_name ?></strong>
|
||||||
|
</a>
|
||||||
|
<div class="text-secondary"><?= $module_description ?></div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<?php if ($module_id > 6) { ?>
|
||||||
|
<div class="dropdown dropleft text-center">
|
||||||
|
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
|
||||||
|
<i class="fas fa-ellipsis-h"></i>
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
|
||||||
</tbody>
|
<a class="dropdown-item ajax-modal" href="#"
|
||||||
</table>
|
data-modal-url="modals/module/module_edit.php?id=<?= $module_id ?>">
|
||||||
</div>
|
<i class="fas fa-fw fa-user-edit mr-2"></i>Edit
|
||||||
<?php require_once "../includes/filter_footer.php";
|
</a>
|
||||||
|
|
||||||
|
<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'] ?>">
|
||||||
|
<i class="fas fa-fw fa-archive mr-2"></i>Delete
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php } else { echo "<p class='text-center'>N/A Predefined</p>"; } ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<?php require_once "../includes/filter_footer.php";
|
||||||
?>
|
?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ $order = "ASC";
|
|||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
require_once "includes/inc_all_admin.php";
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT payment_method_created_at, payment_method_description, payment_method_id,
|
$sql = mysqli_query($mysqli, "SELECT * FROM payment_methods ORDER BY $sort $order");
|
||||||
payment_method_name FROM payment_methods ORDER BY $sort $order");
|
|
||||||
|
|
||||||
$num_rows = mysqli_num_rows($sql);
|
$num_rows = mysqli_num_rows($sql);
|
||||||
|
|
||||||
@@ -15,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-credit-card me-2"></i>Payment Methods</h3>
|
<h3 class="card-title mt-2"><i class="fas fa-fw fa-credit-card mr-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 me-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 mr-2"></i>Add Payment Method</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -63,18 +62,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 dropstart text-center">
|
<div class="dropdown dropleft text-center">
|
||||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
|
<button class="btn btn-secondary btn-sm" type="button" data-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 me-2"></i>Edit
|
<i class="fas fa-fw fa-edit mr-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 me-2"></i>Delete
|
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ $order = "ASC";
|
|||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
require_once "includes/inc_all_admin.php";
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT account_name, category_name, payment_provider_description, payment_provider_id,
|
$sql = mysqli_query($mysqli, "SELECT * FROM payment_providers
|
||||||
payment_provider_name, payment_provider_threshold, vendor_name FROM payment_providers
|
|
||||||
LEFT JOIN accounts ON payment_provider_account = account_id
|
LEFT JOIN accounts ON payment_provider_account = account_id
|
||||||
LEFT JOIN vendors ON payment_provider_expense_vendor = vendor_id
|
LEFT JOIN vendors ON payment_provider_expense_vendor = vendor_id
|
||||||
LEFT JOIN categories ON payment_provider_expense_category = category_id
|
LEFT JOIN categories ON payment_provider_expense_category = category_id
|
||||||
@@ -20,9 +19,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 me-2"></i>Payment Providers</h3>
|
<h3 class="card-title mt-2"><i class="fas fa-fw fa-credit-card mr-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 me-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 mr-2"></i>Add Provider</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -95,21 +94,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 bg-dark rounded-pill p-2" href="saved_payment_methods.php"><?= $saved_payment_count ?></a>
|
<a class="badge badge-dark badge-pill p-2" href="saved_payment_methods.php"><?= $saved_payment_count ?></a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="dropdown dropstart text-center">
|
<div class="dropdown dropleft text-center">
|
||||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
|
<button class="btn btn-secondary btn-sm" type="button" data-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 me-2"></i>Edit
|
<i class="fas fa-fw fa-edit mr-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 me-2"></i><strong>Delete Provider and</strong>
|
<i class="fas fa-fw fa-trash mr-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>
|
||||||
|
|||||||
@@ -10,11 +10,7 @@ require_once __DIR__ . "/../includes/check_login.php";
|
|||||||
// Only allow running post files via inclusion (prevents people/bots poking them directly)
|
// Only allow running post files via inclusion (prevents people/bots poking them directly)
|
||||||
define('FROM_POST_HANDLER', true);
|
define('FROM_POST_HANDLER', true);
|
||||||
|
|
||||||
// Load all admin module POST logic.
|
// Load all admin module POST logic
|
||||||
// *_model.php is a RESERVED suffix: those files are not handlers, they are inline
|
|
||||||
// field-parsing fragments that read $_POST at include time, so the glob must not
|
|
||||||
// pull them in. A handler named *_model.php is silently never loaded - name entity
|
|
||||||
// handlers around it (admin/post/ai_models.php, not ai_model.php).
|
|
||||||
if (!empty($session_is_admin)) {
|
if (!empty($session_is_admin)) {
|
||||||
foreach (glob(__DIR__ . "/post/*.php") as $admin_module) {
|
foreach (glob(__DIR__ . "/post/*.php") as $admin_module) {
|
||||||
if (!str_ends_with($admin_module, '_model.php')) {
|
if (!str_ends_with($admin_module, '_model.php')) {
|
||||||
@@ -26,11 +22,3 @@ if (!empty($session_is_admin)) {
|
|||||||
// Logout is shared between portals
|
// Logout is shared between portals
|
||||||
require_once __DIR__ . "/../post/logout.php";
|
require_once __DIR__ . "/../post/logout.php";
|
||||||
require_once __DIR__ . "/../post/misc.php";
|
require_once __DIR__ . "/../post/misc.php";
|
||||||
|
|
||||||
// Every handler above exits or redirects, so getting here means no handler claimed
|
|
||||||
// the request - a blank page and no trace of why. Log it; the usual cause is a
|
|
||||||
// handler file that never loaded.
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
||||||
$unhandled = implode(', ', array_slice(array_keys($_POST), 0, 10));
|
|
||||||
logApp('Request', 'warning', "Unhandled POST to admin/post.php - no handler matched. Fields: $unhandled");
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ITFlow - GET/POST request handler for AI Models ('ai_models')
|
* ITFlow - GET/POST request handler for AI Models ('ai_model')
|
||||||
*/
|
*/
|
||||||
|
|
||||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||||
@@ -15,17 +15,9 @@ if (isset($_POST['add_ai_model'])) {
|
|||||||
$prompt = escapeSql($_POST['prompt']);
|
$prompt = escapeSql($_POST['prompt']);
|
||||||
$use_case = escapeSql($_POST['use_case']);
|
$use_case = escapeSql($_POST['use_case']);
|
||||||
|
|
||||||
// Blank means "send no temperature at all" - the only setting that works on every
|
mysqli_query($mysqli,"INSERT INTO ai_models SET ai_model_name = '$model', ai_model_prompt = '$prompt', ai_model_use_case = '$use_case', ai_model_ai_provider_id = $provider_id");
|
||||||
// provider. Anything else rides as a numeric literal, so no quoting.
|
|
||||||
$temperature = ($_POST['temperature'] ?? '') === '' ? 'NULL' : floatval($_POST['temperature']);
|
|
||||||
|
|
||||||
mysqli_query($mysqli,"INSERT INTO ai_models SET ai_model_name = '$model', ai_model_prompt = '$prompt', ai_model_use_case = '$use_case', ai_model_temperature = $temperature, ai_model_ai_provider_id = $provider_id");
|
$ai_model_id = mysqli_insert_id($mysqli);
|
||||||
|
|
||||||
if (!mysqli_affected_rows($mysqli)) {
|
|
||||||
logApp('AI', 'error', 'Failed to create AI Model ' . $model . ': ' . mysqli_error($mysqli));
|
|
||||||
flashAlert("AI Model <strong>$model</strong> could not be created - see Admin > App Logs", 'error');
|
|
||||||
redirect();
|
|
||||||
}
|
|
||||||
|
|
||||||
logAudit("AI Model", "Create", "$session_name created AI Model $model");
|
logAudit("AI Model", "Create", "$session_name created AI Model $model");
|
||||||
|
|
||||||
@@ -44,11 +36,7 @@ if (isset($_POST['edit_ai_model'])) {
|
|||||||
$prompt = escapeSql($_POST['prompt']);
|
$prompt = escapeSql($_POST['prompt']);
|
||||||
$use_case = escapeSql($_POST['use_case']);
|
$use_case = escapeSql($_POST['use_case']);
|
||||||
|
|
||||||
// Blank means "send no temperature at all" - the only setting that works on every
|
mysqli_query($mysqli,"UPDATE ai_models SET ai_model_name = '$model', ai_model_prompt = '$prompt', ai_model_use_case = '$use_case' WHERE ai_model_id = $model_id");
|
||||||
// provider. Anything else rides as a numeric literal, so no quoting.
|
|
||||||
$temperature = ($_POST['temperature'] ?? '') === '' ? 'NULL' : floatval($_POST['temperature']);
|
|
||||||
|
|
||||||
mysqli_query($mysqli,"UPDATE ai_models SET ai_model_name = '$model', ai_model_prompt = '$prompt', ai_model_use_case = '$use_case', ai_model_temperature = $temperature WHERE ai_model_id = $model_id");
|
|
||||||
|
|
||||||
logAudit("AI Model", "Edit", "$session_name edited AI Model $model");
|
logAudit("AI Model", "Edit", "$session_name edited AI Model $model");
|
||||||
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
<?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();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -42,18 +42,8 @@ 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");
|
||||||
|
|||||||
@@ -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 = ['sending', 'receiving', 'oauth', 'from', 'tests'];
|
$mail_tabs = ['smtp', 'imap', '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'];
|
||||||
@@ -91,18 +91,6 @@ if (isset($_POST['edit_mail_smtp_settings'])) {
|
|||||||
$config_smtp_username = escapeSql($_POST['config_smtp_username'] ?? $config_smtp_username);
|
$config_smtp_username = escapeSql($_POST['config_smtp_username'] ?? $config_smtp_username);
|
||||||
$config_smtp_password = escapeSql($_POST['config_smtp_password'] ?? $config_smtp_password);
|
$config_smtp_password = escapeSql($_POST['config_smtp_password'] ?? $config_smtp_password);
|
||||||
|
|
||||||
// The host/port/encryption/password inputs are hidden and disabled for OAuth
|
|
||||||
// providers, so they never post and the ?? fallbacks above keep whatever the
|
|
||||||
// install used before. Clear them instead: the endpoint is fixed by provider,
|
|
||||||
// and the stored values would otherwise be both wrong and unreachable from
|
|
||||||
// the settings page. The mailbox password is no longer used either.
|
|
||||||
if ($config_smtp_provider === 'google_oauth' || $config_smtp_provider === 'microsoft_oauth') {
|
|
||||||
$config_smtp_host = '';
|
|
||||||
$config_smtp_port = 0;
|
|
||||||
$config_smtp_encryption = '';
|
|
||||||
$config_smtp_password = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
mysqli_query($mysqli, "
|
mysqli_query($mysqli, "
|
||||||
UPDATE settings SET
|
UPDATE settings SET
|
||||||
config_smtp_provider = '$config_smtp_provider',
|
config_smtp_provider = '$config_smtp_provider',
|
||||||
@@ -133,15 +121,6 @@ if (isset($_POST['edit_mail_imap_settings'])) {
|
|||||||
$config_imap_username = escapeSql($_POST['config_imap_username'] ?? $config_imap_username);
|
$config_imap_username = escapeSql($_POST['config_imap_username'] ?? $config_imap_username);
|
||||||
$config_imap_password = escapeSql($_POST['config_imap_password'] ?? $config_imap_password);
|
$config_imap_password = escapeSql($_POST['config_imap_password'] ?? $config_imap_password);
|
||||||
|
|
||||||
// Same as the SMTP handler above - the connection fields are hidden for OAuth
|
|
||||||
// providers and never post, so drop the leftovers rather than carrying them.
|
|
||||||
if ($config_imap_provider === 'google_oauth' || $config_imap_provider === 'microsoft_oauth') {
|
|
||||||
$config_imap_host = '';
|
|
||||||
$config_imap_port = 0;
|
|
||||||
$config_imap_encryption = '';
|
|
||||||
$config_imap_password = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
mysqli_query($mysqli, "
|
mysqli_query($mysqli, "
|
||||||
UPDATE settings SET
|
UPDATE settings SET
|
||||||
config_imap_provider = '$config_imap_provider',
|
config_imap_provider = '$config_imap_provider',
|
||||||
@@ -249,7 +228,7 @@ if (isset($_POST['test_email_smtp'])) {
|
|||||||
$mail = addToMailQueue($data);
|
$mail = addToMailQueue($data);
|
||||||
|
|
||||||
if ($mail === true) {
|
if ($mail === true) {
|
||||||
flashAlert("Test email queued! Check <strong>Admin > Mail queue</strong>");
|
flashAlert("Test email queued! <a class='text-bold text-light' href='mail_queue.php'>Check Admin > Mail queue</a>");
|
||||||
} else {
|
} else {
|
||||||
flashAlert("Failed to add test mail to queue", 'error');
|
flashAlert("Failed to add test mail to queue", 'error');
|
||||||
}
|
}
|
||||||
@@ -280,17 +259,26 @@ if (isset($_POST['test_email_imap'])) {
|
|||||||
|
|
||||||
$is_oauth = ($provider === 'google_oauth' || $provider === 'microsoft_oauth');
|
$is_oauth = ($provider === 'google_oauth' || $provider === 'microsoft_oauth');
|
||||||
|
|
||||||
// Override, don't default - a leftover standard-IMAP host from before the
|
|
||||||
// switch to OAuth would otherwise make this test fail against the old server
|
|
||||||
// while the cron parser (which overrides unconditionally) connects fine.
|
|
||||||
if ($provider === 'google_oauth') {
|
if ($provider === 'google_oauth') {
|
||||||
$host = 'imap.gmail.com';
|
if (empty($host)) {
|
||||||
$port = 993;
|
$host = 'imap.gmail.com';
|
||||||
$encryption = 'ssl';
|
}
|
||||||
|
if (empty($port)) {
|
||||||
|
$port = 993;
|
||||||
|
}
|
||||||
|
if (empty($encryption)) {
|
||||||
|
$encryption = 'ssl';
|
||||||
|
}
|
||||||
} elseif ($provider === 'microsoft_oauth') {
|
} elseif ($provider === 'microsoft_oauth') {
|
||||||
$host = 'outlook.office365.com';
|
if (empty($host)) {
|
||||||
$port = 993;
|
$host = 'outlook.office365.com';
|
||||||
$encryption = 'ssl';
|
}
|
||||||
|
if (empty($port)) {
|
||||||
|
$port = 993;
|
||||||
|
}
|
||||||
|
if (empty($encryption)) {
|
||||||
|
$encryption = 'ssl';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($host) || empty($port) || empty($username)) {
|
if (empty($host) || empty($port) || empty($username)) {
|
||||||
|
|||||||
@@ -33,13 +33,7 @@ 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
|
$pauses_sla = intval($_POST['pauses_sla'] ?? 0);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
||||||
|
|
||||||
|
|||||||
@@ -2,53 +2,12 @@
|
|||||||
|
|
||||||
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.
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ if (isset($_POST['add_user'])) {
|
|||||||
// Create Settings
|
// Create Settings
|
||||||
mysqli_query($mysqli, "INSERT INTO user_settings SET user_id = $user_id, user_config_force_mfa = $force_mfa");
|
mysqli_query($mysqli, "INSERT INTO user_settings SET user_id = $user_id, user_config_force_mfa = $force_mfa");
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT company_name FROM companies WHERE company_id = 1");
|
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$company_name = escapeSql($row['company_name']);
|
$company_name = escapeSql($row['company_name']);
|
||||||
|
|
||||||
@@ -328,7 +328,7 @@ if (isset($_POST['restore_user'])) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isExportRequest('export_users')) {
|
if (isset($_POST['export_users'])) {
|
||||||
|
|
||||||
validateCSRFToken();
|
validateCSRFToken();
|
||||||
|
|
||||||
@@ -355,7 +355,7 @@ if (isExportRequest('export_users')) {
|
|||||||
|
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT role_name, user_created_at, user_email, user_name, user_status FROM users
|
"SELECT * FROM users
|
||||||
LEFT JOIN user_roles ON user_role_id = role_id
|
LEFT JOIN user_roles ON user_role_id = role_id
|
||||||
WHERE (user_name LIKE '%$q%' OR user_email LIKE '%$q%')
|
WHERE (user_name LIKE '%$q%' OR user_email LIKE '%$q%')
|
||||||
AND user_type = 1
|
AND user_type = 1
|
||||||
@@ -402,7 +402,7 @@ if (isset($_POST['ir_reset_user_password'])) {
|
|||||||
|
|
||||||
// Confirm logged-in user password, for security
|
// Confirm logged-in user password, for security
|
||||||
$admin_password = $_POST['admin_password'];
|
$admin_password = $_POST['admin_password'];
|
||||||
$sql = mysqli_query($mysqli, "SELECT user_password FROM users WHERE user_id = $session_user_id");
|
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $session_user_id");
|
||||||
$userRow = mysqli_fetch_assoc($sql);
|
$userRow = mysqli_fetch_assoc($sql);
|
||||||
|
|
||||||
if (!password_verify($admin_password, $userRow['user_password'])) {
|
if (!password_verify($admin_password, $userRow['user_password'])) {
|
||||||
@@ -411,7 +411,7 @@ if (isset($_POST['ir_reset_user_password'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get agents/users, other than the current user
|
// Get agents/users, other than the current user
|
||||||
$sql_users = mysqli_query($mysqli, "SELECT user_email, user_id FROM users WHERE (user_archived_at IS NULL AND user_id != $session_user_id)");
|
$sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE (user_archived_at IS NULL AND user_id != $session_user_id)");
|
||||||
|
|
||||||
// Reset passwords
|
// Reset passwords
|
||||||
while ($row = mysqli_fetch_assoc($sql_users)) {
|
while ($row = mysqli_fetch_assoc($sql_users)) {
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
|
|
||||||
$sql_project_templates = mysqli_query(
|
$sql_project_templates = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT project_template_created_at, project_template_description, project_template_name,
|
"SELECT * FROM project_templates
|
||||||
project_template_updated_at FROM project_templates
|
|
||||||
WHERE project_template_id = $project_template_id LIMIT 1"
|
WHERE project_template_id = $project_template_id LIMIT 1"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -28,9 +27,7 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
$project_template_updated_at = escapeHtml($row['project_template_updated_at']);
|
$project_template_updated_at = escapeHtml($row['project_template_updated_at']);
|
||||||
|
|
||||||
// Get Associated Ticket Templates
|
// Get Associated Ticket Templates
|
||||||
$sql_ticket_templates = mysqli_query($mysqli, "SELECT ticket_template_created_at, ticket_template_description,
|
$sql_ticket_templates = mysqli_query($mysqli, "SELECT * FROM ticket_templates, project_template_ticket_templates
|
||||||
project_template_ticket_templates.ticket_template_id, ticket_template_name,
|
|
||||||
ticket_template_order, ticket_template_subject, ticket_template_updated_at FROM ticket_templates, project_template_ticket_templates
|
|
||||||
WHERE ticket_templates.ticket_template_id = project_template_ticket_templates.ticket_template_id
|
WHERE ticket_templates.ticket_template_id = project_template_ticket_templates.ticket_template_id
|
||||||
AND project_template_ticket_templates.project_template_id = $project_template_id
|
AND project_template_ticket_templates.project_template_id = $project_template_id
|
||||||
ORDER BY ticket_template_order ASC, ticket_template_name ASC");
|
ORDER BY ticket_template_order ASC, ticket_template_name ASC");
|
||||||
@@ -38,7 +35,7 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
|
|
||||||
// Get All Task Templates
|
// Get All Task Templates
|
||||||
$sql_task_templates = mysqli_query($mysqli,
|
$sql_task_templates = mysqli_query($mysqli,
|
||||||
"SELECT task_template_id, task_template_name FROM ticket_templates, task_templates, project_template_ticket_templates
|
"SELECT * FROM ticket_templates, task_templates, project_template_ticket_templates
|
||||||
WHERE ticket_templates.ticket_template_id = project_template_ticket_templates.ticket_template_id
|
WHERE ticket_templates.ticket_template_id = project_template_ticket_templates.ticket_template_id
|
||||||
AND project_template_ticket_templates.project_template_id = $project_template_id
|
AND project_template_ticket_templates.project_template_id = $project_template_id
|
||||||
AND ticket_templates.ticket_template_id = task_template_ticket_template_id
|
AND ticket_templates.ticket_template_id = task_template_ticket_template_id
|
||||||
@@ -60,22 +57,22 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<!-- Project Header -->
|
<!-- Project Header -->
|
||||||
<div class="card card-body mb-3">
|
<div class="card card-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<div class="d-flex">
|
<div class="media">
|
||||||
<i class="fa fa-fw fa-2x fa-project-diagram text-secondary me-3"></i>
|
<i class="fa fa-fw fa-2x fa-project-diagram text-secondary mr-3"></i>
|
||||||
<div class="flex-grow-1">
|
<div class="media-body">
|
||||||
<h3 class="mb-0"><?= $project_template_name ?><span class='badge rounded-pill bg-info ms-2'>Template</span></h3>
|
<h3 class="mb-0"><?= $project_template_name ?><span class='badge badge-pill badge-info ml-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="d-flex">
|
<div class="media">
|
||||||
<i class="fa fa-fw fa-2x fa-life-ring text-secondary me-3"></i>
|
<i class="fa fa-fw fa-2x fa-life-ring text-secondary mr-3"></i>
|
||||||
<div class="flex-grow-1">
|
<div class="media-body">
|
||||||
<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 +80,9 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<div class="d-flex">
|
<div class="media">
|
||||||
<i class="fa fa-fw fa-2x fa-tasks text-secondary me-3"></i>
|
<i class="fa fa-fw fa-2x fa-tasks text-secondary mr-3"></i>
|
||||||
<div class="flex-grow-1">
|
<div class="media-body">
|
||||||
<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 +90,28 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<div class="btn-group float-end">
|
<div class="btn-group float-right">
|
||||||
<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 me-2"></i>Add Ticket Template
|
<i class="fas fa-fw fa-plus mr-2"></i>Add Ticket Template
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown dropstart text-center ms-3">
|
<div class="dropdown dropleft text-center ml-3">
|
||||||
<button class="btn btn-secondary btn-sm" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown">
|
<button class="btn btn-secondary btn-sm" type="button" id="dropdownMenuButton" data-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 me-2"></i>Edit Template
|
<i class="fas fa-fw fa-edit mr-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 me-2"></i>Archive (not yet implemented)
|
<i class="fas fa-fw fa-archive mr-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 me-2"></i>Delete
|
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||||
</a>
|
</a>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</div>
|
</div>
|
||||||
@@ -131,7 +128,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 me-2"></i>Project Ticket Templates</h5>
|
<h5 class="text-secondary"><i class="fa fa-fw fa-life-ring mr-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 +155,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 me-2"></i></a>
|
<a href="#" class="drag-handle"><i class="fas fa-bars text-muted mr-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 +189,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 me-2"></i>Project Task Templates</h5>
|
<h5 class="text-secondary"><i class="fas fa-fw fa-tasks mr-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 +198,7 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<i class="far fa-fw fa-check-square text-primary me-3"></i>
|
<i class="far fa-fw fa-check-square text-primary mr-3"></i>
|
||||||
<?= $task_template_name ?>
|
<?= $task_template_name ?>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -227,7 +224,7 @@ new Sortable(document.querySelector('table#ticket_templates tbody'), {
|
|||||||
order: index
|
order: index
|
||||||
}));
|
}));
|
||||||
|
|
||||||
itflowPostForm('/agent/ajax.php', {
|
$.post('/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 ?>,
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
|
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT SQL_CALC_FOUND_ROWS project_template_created_at, project_template_description, project_template_id,
|
"SELECT SQL_CALC_FOUND_ROWS * FROM project_templates
|
||||||
project_template_name FROM project_templates
|
|
||||||
WHERE (project_template_name LIKE '%$q%' OR project_template_description LIKE '%$q%')
|
WHERE (project_template_name LIKE '%$q%' OR project_template_description LIKE '%$q%')
|
||||||
AND project_template_archived_at IS NULL
|
AND project_template_archived_at IS NULL
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||||
@@ -19,21 +18,23 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card card-dark">
|
||||||
<div class="card-header bg-dark py-2">
|
<div class="card-header py-2">
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-project-diagram me-2"></i>Project Templates</h3>
|
<h3 class="card-title mt-2"><i class="fas fa-fw fa-project-diagram mr-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 me-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 mr-2"></i>New Project Template</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-header py-3">
|
<div class="card-body">
|
||||||
<form autocomplete="off">
|
<form autocomplete="off">
|
||||||
<div class="row g-2 align-items-center">
|
<div class="row">
|
||||||
|
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<div class="input-group">
|
<div class="input-group mb-3 mb-md-0">
|
||||||
<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>
|
||||||
|
|
||||||
@@ -42,96 +43,97 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
<hr>
|
||||||
<div class="table-responsive-sm">
|
<div class="table-responsive-sm">
|
||||||
<table class="table table-striped table-borderless table-hover mb-0">
|
<table class="table table-striped table-borderless table-hover">
|
||||||
<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>
|
|
||||||
<th>
|
|
||||||
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=project_template_name&order=<?= $disp ?>">
|
|
||||||
Template <?php if ($sort == 'project_template_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>Tickets</th>
|
|
||||||
<th>Tasks</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while($row = mysqli_fetch_assoc($sql)){
|
|
||||||
$project_template_id = intval($row['project_template_id']);
|
|
||||||
$project_template_name = escapeHtml($row['project_template_name']);
|
|
||||||
$project_template_description = escapeHtml($row['project_template_description']);
|
|
||||||
$project_template_created_at = escapeHtml($row['project_template_created_at']);
|
|
||||||
|
|
||||||
// Get Ticket Template Count
|
|
||||||
$sql_ticket_templates = mysqli_query($mysqli, "SELECT 1 FROM ticket_templates, project_template_ticket_templates
|
|
||||||
WHERE ticket_templates.ticket_template_id = project_template_ticket_templates.ticket_template_id
|
|
||||||
AND project_template_ticket_templates.project_template_id = $project_template_id
|
|
||||||
ORDER BY ticket_template_order ASC, ticket_template_name ASC");
|
|
||||||
$ticket_template_count = mysqli_num_rows($sql_ticket_templates);
|
|
||||||
|
|
||||||
// Get Tasks Template Count
|
|
||||||
$sql_task_templates = mysqli_query($mysqli,
|
|
||||||
"SELECT 1 FROM ticket_templates, task_templates, project_template_ticket_templates
|
|
||||||
WHERE ticket_templates.ticket_template_id = project_template_ticket_templates.ticket_template_id
|
|
||||||
AND project_template_ticket_templates.project_template_id = $project_template_id
|
|
||||||
AND ticket_templates.ticket_template_id = task_template_ticket_template_id
|
|
||||||
ORDER BY task_template_created_at ASC"
|
|
||||||
);
|
|
||||||
$task_template_count = mysqli_num_rows($sql_task_templates);
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<th>
|
||||||
<a class="text-dark" href="project_template.php?project_template_id=<?= $project_template_id ?>">
|
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=project_template_name&order=<?= $disp ?>">
|
||||||
<div class="d-flex">
|
Template <?php if ($sort == 'project_template_name') { echo $order_icon; } ?>
|
||||||
<i class="fa fa-fw fa-2x fa-project-diagram me-3"></i>
|
</a>
|
||||||
<div class="flex-grow-1">
|
</th>
|
||||||
<div>
|
<th>Tickets</th>
|
||||||
<?= $project_template_name ?>
|
<th>Tasks</th>
|
||||||
</div>
|
<th class="text-center">Action</th>
|
||||||
<div>
|
</tr>
|
||||||
<small class="text-secondary"><?= $project_template_description ?></small>
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
while($row = mysqli_fetch_assoc($sql)){
|
||||||
|
$project_template_id = intval($row['project_template_id']);
|
||||||
|
$project_template_name = escapeHtml($row['project_template_name']);
|
||||||
|
$project_template_description = escapeHtml($row['project_template_description']);
|
||||||
|
$project_template_created_at = escapeHtml($row['project_template_created_at']);
|
||||||
|
|
||||||
|
// Get Ticket Template Count
|
||||||
|
$sql_ticket_templates = mysqli_query($mysqli, "SELECT * FROM ticket_templates, project_template_ticket_templates
|
||||||
|
WHERE ticket_templates.ticket_template_id = project_template_ticket_templates.ticket_template_id
|
||||||
|
AND project_template_ticket_templates.project_template_id = $project_template_id
|
||||||
|
ORDER BY ticket_template_order ASC, ticket_template_name ASC");
|
||||||
|
$ticket_template_count = mysqli_num_rows($sql_ticket_templates);
|
||||||
|
|
||||||
|
// Get Tasks Template Count
|
||||||
|
$sql_task_templates = mysqli_query($mysqli,
|
||||||
|
"SELECT * FROM ticket_templates, task_templates, project_template_ticket_templates
|
||||||
|
WHERE ticket_templates.ticket_template_id = project_template_ticket_templates.ticket_template_id
|
||||||
|
AND project_template_ticket_templates.project_template_id = $project_template_id
|
||||||
|
AND ticket_templates.ticket_template_id = task_template_ticket_template_id
|
||||||
|
ORDER BY task_template_created_at ASC"
|
||||||
|
);
|
||||||
|
$task_template_count = mysqli_num_rows($sql_task_templates);
|
||||||
|
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a class="text-dark" href="project_template.php?project_template_id=<?= $project_template_id ?>">
|
||||||
|
<div class="media">
|
||||||
|
<i class="fa fa-fw fa-2x fa-project-diagram mr-3"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<div>
|
||||||
|
<?= $project_template_name ?>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<small class="text-secondary"><?= $project_template_description ?></small>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</a>
|
</td>
|
||||||
</td>
|
<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>
|
|
||||||
<?php if($session_user_role == 3) { ?>
|
|
||||||
<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'] ?>">
|
|
||||||
<i class="fas fa-fw fa-trash me-2"></i>Delete
|
|
||||||
</a>
|
</a>
|
||||||
<?php } ?>
|
<?php if($session_user_role == 3) { ?>
|
||||||
|
<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'] ?>">
|
||||||
|
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||||
|
</a>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</td>
|
||||||
</td>
|
</tr>
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
<?php require_once "../includes/filter_footer.php"; ?>
|
||||||
</div>
|
</div>
|
||||||
<?php require_once "../includes/filter_footer.php"; ?>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
197
admin/roles.php
197
admin/roles.php
@@ -18,129 +18,132 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card card-dark">
|
||||||
<div class="card-header bg-dark py-2">
|
<div class="card-header py-2">
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-user-shield me-2"></i>Roles</h3>
|
<h3 class="card-title mt-2"><i class="fas fa-fw fa-user-shield mr-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 me-2"></i>New Role
|
<i class="fas fa-fw fa-user-plus mr-2"></i>New Role
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-header py-3">
|
<div class="card-body">
|
||||||
<form autocomplete="off">
|
<form class="mb-4" autocomplete="off">
|
||||||
<div class="row g-2 align-items-center">
|
<div class="row">
|
||||||
<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>
|
||||||
</div>
|
<hr>
|
||||||
<div class="table-responsive-sm">
|
<div class="table-responsive-sm">
|
||||||
<table class="table table-striped table-borderless table-hover mb-0">
|
<table class="table table-striped table-borderless table-hover">
|
||||||
<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>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=role_name&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=role_name&order=<?= $disp ?>">
|
||||||
Role <?php if ($sort == 'role_name') { echo $order_icon; } ?>
|
Role <?php if ($sort == 'role_name') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>Members</th>
|
<th>Members</th>
|
||||||
<th>
|
<th>
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=role_is_admin&order=<?= $disp ?>">
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=role_is_admin&order=<?= $disp ?>">
|
||||||
Admin <?php if ($sort == 'role_is_admin') { echo $order_icon; } ?>
|
Admin <?php if ($sort == 'role_is_admin') { echo $order_icon; } ?>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th class="text-center">Action</th>
|
<th class="text-center">Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$role_id = intval($row['role_id']);
|
$role_id = intval($row['role_id']);
|
||||||
$role_name = escapeHtml($row['role_name']);
|
$role_name = escapeHtml($row['role_name']);
|
||||||
$role_description = escapeHtml($row['role_description']);
|
$role_description = escapeHtml($row['role_description']);
|
||||||
$role_admin = intval($row['role_is_admin']);
|
$role_admin = intval($row['role_is_admin']);
|
||||||
$role_archived_at = escapeHtml($row['role_archived_at']);
|
$role_archived_at = escapeHtml($row['role_archived_at']);
|
||||||
|
|
||||||
// Count number of users that have each role
|
// Count number of users that have each role
|
||||||
$sql_role_user_count = mysqli_query($mysqli, "SELECT COUNT(user_id) FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
|
$sql_role_user_count = mysqli_query($mysqli, "SELECT COUNT(user_id) FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
|
||||||
$role_user_count = mysqli_fetch_row($sql_role_user_count)[0];
|
$role_user_count = mysqli_fetch_row($sql_role_user_count)[0];
|
||||||
|
|
||||||
$sql_users = mysqli_query($mysqli, "SELECT user_name FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
|
$sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
|
||||||
// Initialize an empty array to hold user names
|
// Initialize an empty array to hold user names
|
||||||
$user_names = [];
|
$user_names = [];
|
||||||
|
|
||||||
// Fetch each row and store the user_name in the array
|
// Fetch each row and store the user_name in the array
|
||||||
while($row = mysqli_fetch_assoc($sql_users)) {
|
while($row = mysqli_fetch_assoc($sql_users)) {
|
||||||
$user_names[] = escapeHtml($row['user_name']);
|
$user_names[] = escapeHtml($row['user_name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the array of user names to a comma-separated string
|
// Convert the array of user names to a comma-separated string
|
||||||
$user_names_string = implode(",", $user_names);
|
$user_names_string = implode(",", $user_names);
|
||||||
|
|
||||||
|
if (empty($user_names_string)) {
|
||||||
|
$user_names_string = "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<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">
|
||||||
|
<i class="fas fa-fw fa-2x fa-user-shield text-dark mr-2"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<div><?= $role_name ?></div>
|
||||||
|
<div><small class="text-secondary"><?= $role_description ?></small></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td><?= $user_names_string ?></td>
|
||||||
|
<td><?= $role_admin ? 'Yes' : 'No' ?></td>
|
||||||
|
<td>
|
||||||
|
<?php if ($role_id !== 3) { ?>
|
||||||
|
<div class="dropdown dropleft text-center">
|
||||||
|
<button class="btn btn-secondary btn-sm" type="button" data-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/role/role_edit.php?id=<?= $role_id ?>">
|
||||||
|
<i class="fas fa-fw fa-user-edit mr-2"></i>Edit
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<?php if (empty($role_archived_at) && $role_user_count == 0) { ?>
|
||||||
|
<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'] ?>">
|
||||||
|
<i class="fas fa-fw fa-archive mr-2"></i>Archive
|
||||||
|
</a>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
if (empty($user_names_string)) {
|
|
||||||
$user_names_string = "-";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a class="<?php if ($role_id !== 3) { ?> ajax-modal" data-modal-url="modals/role/role_edit.php?id=<?= $role_id ?>" <?php } ?> href="#">
|
|
||||||
<div class="d-flex">
|
|
||||||
<i class="fas fa-fw fa-2x fa-user-shield text-dark me-2"></i>
|
|
||||||
<div class="flex-grow-1">
|
|
||||||
<div><?= $role_name ?></div>
|
|
||||||
<div><small class="text-secondary"><?= $role_description ?></small></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td><?= $user_names_string ?></td>
|
|
||||||
<td><?= $role_admin ? 'Yes' : 'No' ?></td>
|
|
||||||
<td>
|
|
||||||
<?php if ($role_id !== 3) { ?>
|
|
||||||
<div class="dropdown dropstart text-center">
|
|
||||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
|
|
||||||
<i class="fas fa-ellipsis-h"></i>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
|
|
||||||
<a class="dropdown-item ajax-modal" href="#"
|
</tbody>
|
||||||
data-modal-url="modals/role/role_edit.php?id=<?= $role_id ?>">
|
</table>
|
||||||
<i class="fas fa-fw fa-user-edit me-2"></i>Edit
|
</div>
|
||||||
</a>
|
<?php require_once "../includes/filter_footer.php";
|
||||||
|
|
||||||
<?php if (empty($role_archived_at) && $role_user_count == 0) { ?>
|
|
||||||
<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'] ?>">
|
|
||||||
<i class="fas fa-fw fa-archive me-2"></i>Archive
|
|
||||||
</a>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "../includes/filter_footer.php";
|
|
||||||
?>
|
?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
@@ -43,110 +43,113 @@ $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">
|
<div class="card card-dark">
|
||||||
<div class="card-header bg-dark py-2">
|
<div class="card-header">
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-credit-card me-2"></i>Saved Payment Methods</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-credit-card mr-2"></i>Saved Payment Methods</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-header py-3">
|
<div class="card-body">
|
||||||
<form autocomplete="off">
|
<form class="mb-4" autocomplete="off">
|
||||||
<div class="row g-2 align-items-center">
|
<div class="row">
|
||||||
<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>
|
||||||
</div>
|
<hr>
|
||||||
<div class="table-responsive-sm">
|
<div class="table-responsive-sm">
|
||||||
<table class="table table-striped table-borderless table-hover mb-0">
|
<table class="table table-striped table-borderless table-hover">
|
||||||
<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>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=client_name&order=<?= $disp ?>">
|
|
||||||
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=payment_provider_name&order=<?= $disp ?>">
|
|
||||||
Provider <?php if ($sort == 'payment_provider_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=saved_payment_description&order=<?= $disp ?>">
|
|
||||||
Description <?php if ($sort == 'saved_payment_description') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=payment_provider_client&order=<?= $disp ?>">
|
|
||||||
Provider Client ID <?php if ($sort == 'payment_provider_client') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=saved_payment_provider_method&order=<?= $disp ?>">
|
|
||||||
Provider Payment Method ID <?php if ($sort == 'saved_payment_provider_method') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=saved_payment_created_at&order=<?= $disp ?>">
|
|
||||||
Created <?php if ($sort == 'saved_payment_created_at') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
|
||||||
$saved_payment_id = intval($row['saved_payment_id']);
|
|
||||||
$client_id = intval($row['saved_payment_client_id']);
|
|
||||||
$client_name = escapeHtml($row['client_name']);
|
|
||||||
$provider_id = intval($row['saved_payment_provider_id']);
|
|
||||||
$provider_name = escapeHtml($row['payment_provider_name']);
|
|
||||||
$saved_payment_description = escapeHtml($row['saved_payment_description']);
|
|
||||||
$provider_client = escapeHtml($row['payment_provider_client']);
|
|
||||||
$provider_payment_method = escapeHtml($row['saved_payment_provider_method']);
|
|
||||||
$saved_payment_created_at = escapeHtml($row['saved_payment_created_at']);
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<th>
|
||||||
<?= $client_name ?>
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=client_name&order=<?= $disp ?>">
|
||||||
<br>
|
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
|
||||||
<small class="text-secondary">ID: <?= $client_id ?></small>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<?= $provider_name ?>
|
|
||||||
<br>
|
|
||||||
<small class="text-secondary">ID: <?= $provider_id ?></small>
|
|
||||||
</td>
|
|
||||||
<td><?= $saved_payment_description ?></td>
|
|
||||||
<td><?= $provider_client ?></td>
|
|
||||||
<td><?= $provider_payment_method ?></td>
|
|
||||||
<td><?= $saved_payment_created_at ?></td>
|
|
||||||
<td>
|
|
||||||
<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 me-2"></i>Delete
|
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</th>
|
||||||
</tr>
|
<th>
|
||||||
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=payment_provider_name&order=<?= $disp ?>">
|
||||||
|
Provider <?php if ($sort == 'payment_provider_name') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=saved_payment_description&order=<?= $disp ?>">
|
||||||
|
Description <?php if ($sort == 'saved_payment_description') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=payment_provider_client&order=<?= $disp ?>">
|
||||||
|
Provider Client ID <?php if ($sort == 'payment_provider_client') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=saved_payment_provider_method&order=<?= $disp ?>">
|
||||||
|
Provider Payment Method ID <?php if ($sort == 'saved_payment_provider_method') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=saved_payment_created_at&order=<?= $disp ?>">
|
||||||
|
Created <?php if ($sort == 'saved_payment_created_at') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th class="text-center">Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
}
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
|
$saved_payment_id = intval($row['saved_payment_id']);
|
||||||
|
$client_id = intval($row['saved_payment_client_id']);
|
||||||
|
$client_name = escapeHtml($row['client_name']);
|
||||||
|
$provider_id = intval($row['saved_payment_provider_id']);
|
||||||
|
$provider_name = escapeHtml($row['payment_provider_name']);
|
||||||
|
$saved_payment_description = escapeHtml($row['saved_payment_description']);
|
||||||
|
$provider_client = escapeHtml($row['payment_provider_client']);
|
||||||
|
$provider_payment_method = escapeHtml($row['saved_payment_provider_method']);
|
||||||
|
$saved_payment_created_at = escapeHtml($row['saved_payment_created_at']);
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<?= $client_name ?>
|
||||||
|
<br>
|
||||||
|
<small class="text-secondary">ID: <?= $client_id ?></small>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<?= $provider_name ?>
|
||||||
|
<br>
|
||||||
|
<small class="text-secondary">ID: <?= $provider_id ?></small>
|
||||||
|
</td>
|
||||||
|
<td><?= $saved_payment_description ?></td>
|
||||||
|
<td><?= $provider_client ?></td>
|
||||||
|
<td><?= $provider_payment_method ?></td>
|
||||||
|
<td><?= $saved_payment_created_at ?></td>
|
||||||
|
<td>
|
||||||
|
<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
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
</tbody>
|
<?php
|
||||||
</table>
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<?php require_once "../includes/filter_footer.php"; ?>
|
||||||
</div>
|
</div>
|
||||||
<?php require_once "../includes/filter_footer.php"; ?>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
require_once "includes/inc_all_admin.php";
|
require_once "includes/inc_all_admin.php";
|
||||||
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT company_address, company_city, company_country, company_currency, company_email,
|
$sql = mysqli_query($mysqli,"SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
|
||||||
settings.company_id, company_locale, company_logo, company_name, company_phone,
|
|
||||||
company_phone_country_code, company_state, company_tax_id, company_website, company_zip FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
|
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$company_id = intval($row['company_id']);
|
$company_id = intval($row['company_id']);
|
||||||
@@ -29,7 +27,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 me-2"></i>Company Details</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-briefcase mr-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,61 +37,73 @@ $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 w-100">Remove Logo</a>
|
<a href="post.php?remove_company_logo&csrf_token=<?= $_SESSION['csrf_token'] ?>" class="btn btn-outline-danger btn-block">Remove Logo</a>
|
||||||
<hr>
|
<hr>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<label>Upload company logo</label>
|
<label>Upload company logo</label>
|
||||||
<input type="file" class="form-control" name="file" accept=".jpg, .jpeg, .png">
|
<input type="file" class="form-control-file" name="file" accept=".jpg, .jpeg, .png">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="country">
|
</div>
|
||||||
|
<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>
|
||||||
@@ -103,11 +113,13 @@ $company_initials = escapeHtml(initials($company_name));
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label>Phone</label>
|
<label>Phone</label>
|
||||||
<div class="row g-2">
|
<div class="form-row">
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -115,54 +127,39 @@ $company_initials = escapeHtml(initials($company_name));
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
|
|
||||||
<div class="mb-3">
|
<button type="submit" name="edit_company" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||||
<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>
|
||||||
|
|||||||
@@ -26,89 +26,92 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
?>
|
?>
|
||||||
|
|
||||||
|
|
||||||
<div class="card">
|
<div class="card card-dark">
|
||||||
<div class="card-header bg-dark py-2">
|
<div class="card-header py-2">
|
||||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-th-list me-2"></i><?= escapeHtml($table) ?> Fields</h3>
|
<h3 class="card-title mt-2"><i class="fa fa-fw fa-th-list mr-2"></i><?= escapeHtml($table) ?> Fields</h3>
|
||||||
<div class="card-tools">
|
<div class="card-tools">
|
||||||
<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>
|
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#createCustomFieldModal"><i class="fas fa-plus mr-2"></i>Create</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-header py-3">
|
<div class="card-body">
|
||||||
<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 g-2 align-items-center">
|
<div class="row">
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4 mb-2">
|
||||||
<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-end">
|
<div class="btn-group float-right">
|
||||||
<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>
|
||||||
</div>
|
<hr>
|
||||||
<div class="table-responsive-sm">
|
<div class="table-responsive-sm">
|
||||||
<table class="table table-striped table-borderless table-hover mb-0">
|
<table class="table table-striped table-borderless table-hover">
|
||||||
<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>
|
|
||||||
<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_type&order=<?= $disp ?>">Type</a></th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
|
||||||
$custom_field_id = intval($row['custom_field_id']);
|
|
||||||
$custom_field_label = escapeHtml($row['custom_field_label']);
|
|
||||||
$custom_field_type = escapeHtml($row['custom_field_type']);
|
|
||||||
$custom_field_location = intval($row['custom_field_location']);
|
|
||||||
$custom_field_order = intval($row['custom_field_order']);
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><a class="text-dark" href="#" data-bs-toggle="modal" data-bs-target="#editCustomFieldModal<?= $custom_field_id ?>"><?= $custom_field_label ?></a></td>
|
<th><a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=custom_field_label&order=<?= $disp ?>">Label</a></th>
|
||||||
<td><?= $custom_field_type ?></td>
|
<th><a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=custom_field_type&order=<?= $disp ?>">Type</a></th>
|
||||||
<td>
|
<th class="text-center">Action</th>
|
||||||
<div class="dropdown dropstart text-center">
|
|
||||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">
|
|
||||||
<i class="fas fa-ellipsis-h"></i>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<a class="dropdown-item" href="#" data-bs-toggle="modal" data-bs-target="#editCustomFieldModal<?= $custom_field_id ?>">
|
|
||||||
<i class="fas fa-fw fa-edit me-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
<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'] ?>">
|
|
||||||
<i class="fas fa-fw fa-trash me-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
//$colors_diff = array_diff($colors_array,$colors_used_array);
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
|
$custom_field_id = intval($row['custom_field_id']);
|
||||||
|
$custom_field_label = escapeHtml($row['custom_field_label']);
|
||||||
|
$custom_field_type = escapeHtml($row['custom_field_type']);
|
||||||
|
$custom_field_location = intval($row['custom_field_location']);
|
||||||
|
$custom_field_order = intval($row['custom_field_order']);
|
||||||
|
|
||||||
include "custom_field_edit_modal.php";
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><a class="text-dark" href="#" data-toggle="modal" data-target="#editCustomFieldModal<?= $custom_field_id ?>"><?= $custom_field_label ?></a></td>
|
||||||
|
<td><?= $custom_field_type ?></td>
|
||||||
|
<td>
|
||||||
|
<div class="dropdown dropleft text-center">
|
||||||
|
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
|
||||||
|
<i class="fas fa-ellipsis-h"></i>
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editCustomFieldModal<?= $custom_field_id ?>">
|
||||||
|
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
||||||
|
</a>
|
||||||
|
<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'] ?>">
|
||||||
|
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
//$colors_diff = array_diff($colors_array,$colors_used_array);
|
||||||
|
|
||||||
|
include "custom_field_edit_modal.php";
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<?php require_once "../includes/filter_footer.php";
|
<?php require_once "../includes/filter_footer.php";
|
||||||
?>
|
?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
@@ -23,17 +23,19 @@ $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 me-2"></i>Defaults</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-cogs mr-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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="start_page" data-tags="true" required>
|
</div>
|
||||||
|
<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 } ?>
|
||||||
@@ -47,15 +49,17 @@ $net_terms_array = array (
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="calendar">
|
</div>
|
||||||
|
<select class="form-control select2" name="calendar">
|
||||||
<option value="0">- None -</option>
|
<option value="0">- None -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT calendar_id, calendar_name FROM calendars ORDER BY calendar_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM calendars ORDER BY calendar_name ASC");
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$calendar_id = intval($row['calendar_id']);
|
$calendar_id = intval($row['calendar_id']);
|
||||||
$calendar_name = escapeHtml($row['calendar_name']); ?>
|
$calendar_name = escapeHtml($row['calendar_name']); ?>
|
||||||
@@ -68,15 +72,17 @@ $net_terms_array = array (
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="transfer_from_account">
|
</div>
|
||||||
|
<select class="form-control select2" name="transfer_from_account">
|
||||||
<option value="0">- None -</option>
|
<option value="0">- None -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$account_id = intval($row['account_id']);
|
$account_id = intval($row['account_id']);
|
||||||
$account_name = escapeHtml($row['account_name']); ?>
|
$account_name = escapeHtml($row['account_name']); ?>
|
||||||
@@ -89,15 +95,17 @@ $net_terms_array = array (
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="transfer_to_account">
|
</div>
|
||||||
|
<select class="form-control select2" name="transfer_to_account">
|
||||||
<option value="0">- None -</option>
|
<option value="0">- None -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$account_id = intval($row['account_id']);
|
$account_id = intval($row['account_id']);
|
||||||
$account_name = escapeHtml($row['account_name']); ?>
|
$account_name = escapeHtml($row['account_name']); ?>
|
||||||
@@ -110,15 +118,17 @@ $net_terms_array = array (
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="payment_account">
|
</div>
|
||||||
|
<select class="form-control select2" name="payment_account">
|
||||||
<option value="0">- None -</option>
|
<option value="0">- None -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$account_id = intval($row['account_id']);
|
$account_id = intval($row['account_id']);
|
||||||
$account_name = escapeHtml($row['account_name']); ?>
|
$account_name = escapeHtml($row['account_name']); ?>
|
||||||
@@ -133,15 +143,17 @@ $net_terms_array = array (
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="expense_account">
|
</div>
|
||||||
|
<select class="form-control select2" name="expense_account">
|
||||||
<option value="0">- None -</option>
|
<option value="0">- None -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$account_id = intval($row['account_id']);
|
$account_id = intval($row['account_id']);
|
||||||
$account_name = escapeHtml($row['account_name']); ?>
|
$account_name = escapeHtml($row['account_name']); ?>
|
||||||
@@ -154,15 +166,17 @@ $net_terms_array = array (
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="payment_method">
|
</div>
|
||||||
|
<select class="form-control select2" name="payment_method">
|
||||||
<option value="">- None -</option>
|
<option value="">- None -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT category_name FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC");
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$payment_method = escapeHtml($row['category_name']); ?>
|
$payment_method = escapeHtml($row['category_name']); ?>
|
||||||
<option <?php if ($config_default_payment_method == $payment_method) {
|
<option <?php if ($config_default_payment_method == $payment_method) {
|
||||||
@@ -174,15 +188,17 @@ $net_terms_array = array (
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="expense_payment_method">
|
</div>
|
||||||
|
<select class="form-control select2" name="expense_payment_method">
|
||||||
<option value="">- None -</option>
|
<option value="">- None -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT category_name FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC");
|
||||||
while ($row = mysqli_fetch_assoc($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$payment_method = escapeHtml($row['category_name']); ?>
|
$payment_method = escapeHtml($row['category_name']); ?>
|
||||||
<option <?php if ($config_default_expense_payment_method == $payment_method) {
|
<option <?php if ($config_default_expense_payment_method == $payment_method) {
|
||||||
@@ -194,11 +210,13 @@ $net_terms_array = array (
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="net_terms">
|
</div>
|
||||||
|
<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";
|
||||||
@@ -208,17 +226,19 @@ $net_terms_array = array (
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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 me-2"></i>Save</button>
|
<button type="submit" name="edit_default_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -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 me-2"></i>Invoice Settings</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-file-invoice mr-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,58 +12,66 @@ require_once "includes/inc_all_admin.php";
|
|||||||
|
|
||||||
<h4>Invoice</h4>
|
<h4>Invoice</h4>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<div class="form-check form-switch">
|
<div class="custom-control custom-switch">
|
||||||
<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">
|
<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">
|
||||||
<label class="form-check-label" for="customSwitch1">Show Tax ID</label>
|
<label class="custom-control-label" for="customSwitch1">Show Tax ID</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h5>Invoice Late Fees</h5>
|
<h5>Invoice Late Fees</h5>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<div class="form-check form-switch">
|
<div class="custom-control custom-switch">
|
||||||
<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">
|
<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">
|
||||||
<label class="form-check-label" for="customSwitch2">Enable Late Fee</label>
|
<label class="custom-control-label" for="customSwitch2">Enable Late Fee</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -72,18 +80,22 @@ require_once "includes/inc_all_admin.php";
|
|||||||
|
|
||||||
<h4>Recurring Invoice</h4>
|
<h4>Recurring Invoice</h4>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
@@ -92,7 +104,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 me-2"></i>Save</button>
|
<button type="submit" name="edit_invoice_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
require_once "includes/inc_all_admin.php";
|
require_once "includes/inc_all_admin.php";
|
||||||
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT company_currency, company_locale FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
|
$sql = mysqli_query($mysqli,"SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$company_locale = escapeHtml($row['company_locale']);
|
$company_locale = escapeHtml($row['company_locale']);
|
||||||
@@ -15,17 +15,19 @@ $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 me-2"></i>Localization</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-globe mr-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="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="locale" required>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -34,11 +36,13 @@ $timezones = DateTimeZone::listIdentifiers();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="currency_code" required>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -47,11 +51,13 @@ $timezones = DateTimeZone::listIdentifiers();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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>
|
||||||
<select class="form-select select2" name="timezone" required>
|
</div>
|
||||||
|
<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>
|
||||||
@@ -62,7 +68,7 @@ $timezones = DateTimeZone::listIdentifiers();
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<button type="submit" name="edit_localization" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
|
<button type="submit" name="edit_localization" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -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 ms-2" style="font-size:.5rem;vertical-align:middle;" title="Configured"></i>'
|
? '<i class="fas fa-circle text-success ml-2" style="font-size:.5rem;vertical-align:middle;" title="Configured"></i>'
|
||||||
: '<i class="far fa-circle text-muted ms-2" style="font-size:.5rem;vertical-align:middle;" title="Not configured"></i>';
|
: '<i class="far fa-circle text-muted ml-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=receiving) so it can be linked, bookmarked, survives a
|
// The tab lives in the URL (?tab=imap) 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 = ['sending', 'receiving', 'oauth', 'from', 'tests'];
|
$mail_tabs = ['smtp', 'imap', 'oauth', 'from', 'tests'];
|
||||||
$active_tab = isset($_GET['tab']) && in_array($_GET['tab'], $mail_tabs, true) ? $_GET['tab'] : 'sending';
|
$active_tab = isset($_GET['tab']) && in_array($_GET['tab'], $mail_tabs, true) ? $_GET['tab'] : 'smtp';
|
||||||
|
|
||||||
// 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 me-2"></i>Mail Configuration</h3>
|
<h3 class="card-title"><i class="fas fa-fw fa-envelope mr-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 === 'sending') { echo 'active'; } ?>" href="?tab=sending" data-bs-target="#tab-sending">
|
<a class="nav-link <?php if ($active_tab === 'smtp') { echo 'active'; } ?>" href="?tab=smtp" data-target="#tab-smtp">
|
||||||
<i class="fas fa-fw fa-paper-plane me-1"></i>Sending<?= renderMailStatusDot($smtp_on) ?>
|
<i class="fas fa-fw fa-paper-plane mr-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 === 'receiving') { echo 'active'; } ?>" href="?tab=receiving" data-bs-target="#tab-receiving">
|
<a class="nav-link <?php if ($active_tab === 'imap') { echo 'active'; } ?>" href="?tab=imap" data-target="#tab-imap">
|
||||||
<i class="fas fa-fw fa-inbox me-1"></i>Receiving<?= renderMailStatusDot($imap_on) ?>
|
<i class="fas fa-fw fa-inbox mr-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-bs-target="#tab-oauth">
|
<a class="nav-link <?php if ($active_tab === 'oauth') { echo 'active'; } ?>" href="?tab=oauth" data-target="#tab-oauth">
|
||||||
<i class="fas fa-fw fa-key me-1"></i>OAuth
|
<i class="fas fa-fw fa-key mr-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-bs-target="#tab-from">
|
<a class="nav-link <?php if ($active_tab === 'from') { echo 'active'; } ?>" href="?tab=from" data-target="#tab-from">
|
||||||
<i class="fas fa-fw fa-at me-1"></i>From Addresses
|
<i class="fas fa-fw fa-at mr-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-bs-target="#tab-tests">
|
<a class="nav-link <?php if ($active_tab === 'tests') { echo 'active'; } ?>" href="?tab=tests" data-target="#tab-tests">
|
||||||
<i class="fas fa-fw fa-vial me-1"></i>Tests
|
<i class="fas fa-fw fa-vial mr-1"></i>Tests
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -103,15 +103,16 @@ $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 === 'sending') { echo 'show active'; } ?>" id="tab-sending" role="tabpanel">
|
<div class="tab-pane fade <?php if ($active_tab === 'smtp') { echo 'show active'; } ?>" id="tab-smtp" 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="sending">
|
<input type="hidden" name="tab" value="smtp">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<label>SMTP Provider <small class="text-muted">— outbound</small></label>
|
<label>SMTP Provider <small class="text-muted">— outbound</small></label>
|
||||||
<div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-cloud"></i></span>
|
<div class="input-group">
|
||||||
<select class="form-select" name="config_smtp_provider" id="config_smtp_provider">
|
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-cloud"></i></span></div>
|
||||||
|
<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>
|
||||||
@@ -122,23 +123,26 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="smtp_conn_fields">
|
<div id="smtp_conn_fields">
|
||||||
<div class="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label>SMTP Host</label>
|
<label>SMTP Host</label>
|
||||||
<div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-server"></i></span>
|
<div class="input-group">
|
||||||
|
<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="mb-3 col-md-3">
|
<div class="form-group col-md-3">
|
||||||
<label>Port</label>
|
<label>Port</label>
|
||||||
<div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
|
<div class="input-group">
|
||||||
|
<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="mb-3 col-md-3">
|
<div class="form-group col-md-3">
|
||||||
<label>Encryption</label>
|
<label>Encryption</label>
|
||||||
<div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
|
<div class="input-group">
|
||||||
<select class="form-select" name="config_smtp_encryption">
|
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span></div>
|
||||||
|
<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>
|
||||||
@@ -148,44 +152,48 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-6" id="smtp_user_group">
|
<div class="form-group 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"><span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
<div class="input-group">
|
||||||
|
<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="mb-3 col-md-6" id="smtp_pass_group">
|
<div class="form-group col-md-6" id="smtp_pass_group">
|
||||||
<label>SMTP Password</label>
|
<label>SMTP Password</label>
|
||||||
<div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
<div class="input-group">
|
||||||
<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>
|
<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">
|
||||||
|
<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 me-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 mr-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 ms-3 text-nowrap"><i class="fas fa-fw fa-key me-1"></i>Open OAuth</button>
|
<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>
|
||||||
</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 me-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 mr-2"></i>Save Sending Settings</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ============================ RECEIVING / IMAP ============================ -->
|
<!-- ============================ RECEIVING / IMAP ============================ -->
|
||||||
<div class="tab-pane fade <?php if ($active_tab === 'receiving') { echo 'show active'; } ?>" id="tab-receiving" role="tabpanel">
|
<div class="tab-pane fade <?php if ($active_tab === 'imap') { echo 'show active'; } ?>" id="tab-imap" 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="receiving">
|
<input type="hidden" name="tab" value="imap">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="form-group">
|
||||||
<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"><span class="input-group-text"><i class="fa fa-fw fa-cloud"></i></span>
|
<div class="input-group">
|
||||||
<select class="form-select" name="config_imap_provider" id="config_imap_provider">
|
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-cloud"></i></span></div>
|
||||||
|
<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>
|
||||||
@@ -196,23 +204,26 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="imap_conn_fields">
|
<div id="imap_conn_fields">
|
||||||
<div class="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label>IMAP Host</label>
|
<label>IMAP Host</label>
|
||||||
<div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-server"></i></span>
|
<div class="input-group">
|
||||||
|
<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="mb-3 col-md-3">
|
<div class="form-group col-md-3">
|
||||||
<label>Port</label>
|
<label>Port</label>
|
||||||
<div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
|
<div class="input-group">
|
||||||
|
<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="mb-3 col-md-3">
|
<div class="form-group col-md-3">
|
||||||
<label>Encryption</label>
|
<label>Encryption</label>
|
||||||
<div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
|
<div class="input-group">
|
||||||
<select class="form-select" name="config_imap_encryption">
|
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span></div>
|
||||||
|
<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>
|
||||||
@@ -222,31 +233,34 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-6" id="imap_user_group">
|
<div class="form-group 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"><span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
<div class="input-group">
|
||||||
|
<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="mb-3 col-md-6" id="imap_pass_group">
|
<div class="form-group col-md-6" id="imap_pass_group">
|
||||||
<label>IMAP Password</label>
|
<label>IMAP Password</label>
|
||||||
<div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
<div class="input-group">
|
||||||
<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>
|
<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">
|
||||||
|
<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 me-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 mr-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 ms-3 text-nowrap"><i class="fas fa-fw fa-key me-1"></i>Open OAuth</button>
|
<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>
|
||||||
</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 me-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 mr-2"></i>Save Receiving Settings</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -257,56 +271,63 @@ $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 me-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 mr-2"></i>These credentials are shared by any Sending or Receiving provider set to Google / Microsoft OAuth.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label>OAuth Client ID</label>
|
<label>OAuth Client ID</label>
|
||||||
<div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-id-badge"></i></span>
|
<div class="input-group">
|
||||||
|
<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="mb-3 col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label>OAuth Client Secret</label>
|
<label>OAuth Client Secret</label>
|
||||||
<div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
<div class="input-group">
|
||||||
<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>
|
<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">
|
||||||
|
<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="mb-3" id="tenant_row" style="display:none;">
|
<div class="form-group" 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"><span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
|
<div class="input-group">
|
||||||
|
<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="row g-2">
|
<div class="form-row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="form-group 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="mb-3 col-md-6">
|
<div class="form-group 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="mb-3" id="ms_connect_group" style="display:none;">
|
<div class="form-group" id="ms_connect_group" style="display:none;">
|
||||||
<label>Microsoft OAuth Connect (Web)</label>
|
<label>Microsoft OAuth Connect (Web)</label>
|
||||||
<div class="input-group"><span class="input-group-text"><i class="fa fa-fw fa-link"></i></span>
|
<div class="input-group">
|
||||||
|
<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 me-2"></i>Connect Microsoft 365
|
<i class="fab fa-fw fa-microsoft mr-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 me-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 mr-2"></i>Save OAuth Credentials</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -350,7 +371,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 me-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 mr-2"></i>Save From Addresses</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -359,18 +380,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 me-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 mr-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 me-2"></i>Send a Test Email</h6>
|
<h6 class="text-bold"><i class="fas fa-fw fa-paper-plane mr-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-select select2" name="test_email" required>
|
<select class="form-control 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 } ?>
|
||||||
@@ -378,7 +399,9 @@ $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">
|
||||||
<button type="submit" name="test_email_smtp" class="btn btn-success"><i class="fas fa-fw fa-paper-plane me-2"></i>Send</button>
|
<div class="input-group-append">
|
||||||
|
<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>
|
||||||
@@ -386,24 +409,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 me-2"></i>Test IMAP Connection</h6>
|
<h6 class="text-bold"><i class="fas fa-fw fa-plug mr-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 me-2"></i>Test IMAP</button>
|
<button type="submit" name="test_email_imap" class="btn btn-success"><i class="fas fa-fw fa-inbox mr-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 me-2"></i>Test OAuth Token Refresh</h6>
|
<h6 class="text-bold"><i class="fas fa-fw fa-sync-alt mr-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 me-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 mr-2"></i>Test OAuth Token Refresh</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
@@ -432,36 +455,29 @@ $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-sending', 'tab-receiving', 'tab-oauth', 'tab-from', 'tab-tests']
|
const panes = ['tab-smtp', 'tab-imap', '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, push) {
|
function syncTabUrl(target) {
|
||||||
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);
|
||||||
// pushState, not replaceState, so back/forward step through the tabs
|
history.replaceState(null, '', url);
|
||||||
// instead of jumping straight off the settings page
|
|
||||||
history[push ? 'pushState' : 'replaceState']({ tab: tab }, '', url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function activateTab(target, push) {
|
function activateTab(target) {
|
||||||
syncTabUrl(target, push !== false);
|
syncTabUrl(target);
|
||||||
navLinks.forEach(l => l.classList.toggle('active', l.getAttribute('data-bs-target') === target));
|
navLinks.forEach(l => l.classList.toggle('active', l.getAttribute('data-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-bs-target'), true);
|
activateTab(l.getAttribute('data-target'));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// ---- Provider-driven field visibility ----
|
// ---- Provider-driven field visibility ----
|
||||||
@@ -529,13 +545,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 me-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 mr-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 me-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 mr-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 me-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 mr-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-bs-target="#tab-oauth"]');
|
const oauthLink = document.querySelector('#mailTabs .nav-link[data-target="#tab-oauth"]');
|
||||||
if (oauthLink && oauthLink.classList.contains('active')) activateTab('#tab-sending');
|
if (oauthLink && oauthLink.classList.contains('active')) activateTab('#tab-smtp');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user