Compare commits
249 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6823aabf92 | |||
| f2dddc1226 | |||
| 957becabb9 | |||
| 7df03722ee | |||
| 4642f50d6b | |||
| 2decc3d6d3 | |||
| 2adc4ffa96 | |||
| c8fbf7640c | |||
| 46779ca865 | |||
| 86661e79d1 | |||
| b2a5d86e30 | |||
| 8c327e6523 | |||
| 386b2839e8 | |||
| 934593e0b6 | |||
| a7aa178f24 | |||
| 69122034e7 | |||
| 1117f4289d | |||
| 97bc4a092f | |||
| d942b8f1fb | |||
| 49dc9767b6 | |||
| 482965197d | |||
| 410b547f3c | |||
| f769e8247f | |||
| 2b4a536f85 | |||
| 92ae069629 | |||
| 6f40b21986 | |||
| 3084521521 | |||
| 4f12c86e74 | |||
| 204de99a64 | |||
| fd929f5dd9 | |||
| 7e9c8ba290 | |||
| 6f639f7bf0 | |||
| 3594ed67d1 | |||
| d36a06d8e1 | |||
| c816b960b5 | |||
| 4913e56086 | |||
| 4d00bb98d1 | |||
| db2baae758 | |||
| fdecdf4b15 | |||
| 5c1d4aff23 | |||
| bf0edcb92e | |||
| 39fa8ef3c0 | |||
| 9e8a369bc8 | |||
| 3f3fe8935f | |||
| 82387630c7 | |||
| 16c5033514 | |||
| 46ffaee1e4 | |||
| d936f92a7d | |||
| b424ddf42d | |||
| b3d5a893fc | |||
| 69ea6eebae | |||
| 0892c34125 | |||
| 52e14d501f | |||
| 4d093160fc | |||
| 0bcca99573 | |||
| 63516c4a4f | |||
| 19fb79ffff | |||
| 02835de13d | |||
| 55b004d53d | |||
| c1b72a8ce6 | |||
| fa0bea87e6 | |||
| d146426dd8 | |||
| 1e1782c232 | |||
| dab5874fd7 | |||
| 4850227c04 | |||
| eb9a654cc3 | |||
| 4224bc0c43 | |||
| f893b23129 | |||
| 8c65880504 | |||
| 53cadf80fa | |||
| 8b3bfc6bc9 | |||
| 19cff25300 | |||
| 848e1fe1f6 | |||
| fe147adec3 | |||
| 103809b65f | |||
| a398496dd4 | |||
| 839db8ef44 | |||
| bfd0530597 | |||
| 494ec5cd9c | |||
| fc61a4b88d | |||
| 50d8b02f8b | |||
| 860764a436 | |||
| 52d6a8990a | |||
| 87de67e4a9 | |||
| 8356b57fb4 | |||
| 3f04afee5c | |||
| 2117f61e8c | |||
| d40604b574 | |||
| 76129e9011 | |||
| 9c8411c7ff | |||
| c661d732b3 | |||
| fbe9daace6 | |||
| 651001bf6e | |||
| 9167f8a3ba | |||
| 6dc9ccffcd | |||
| 4b4e3badb7 | |||
| fe4dd23d39 | |||
| de6d71cc3b | |||
| 9e44052709 | |||
| 2d112f227a | |||
| bd8737d986 | |||
| 4b6d236eb7 | |||
| bf058bd5c6 | |||
| dfaf01e8aa | |||
| 2888dd6fd8 | |||
| 2e92ee8eee | |||
| 14b6a75507 | |||
| 2484a9db2c | |||
| bfc30794c5 | |||
| 27bc7a847b | |||
| 2a71877bec | |||
| 30bd920497 | |||
| 1d5b48b88d | |||
| 4295bad12f | |||
| 3a2eeaea7a | |||
| 12418ae91b | |||
| 783a24eb68 | |||
| 2439758ef3 | |||
| 685f1cbfb8 | |||
| e2d1e6b0c5 | |||
| 56cb9a0f4e | |||
| c8c81a360c | |||
| bdd43b7134 | |||
| c50d5a678a | |||
| 96b3af7cbc | |||
| 9e7bbc968d | |||
| 5fc6771543 | |||
| 155f5f35cd | |||
| 7ad6caf30a | |||
| ac8aab0043 | |||
| 14ddf36d46 | |||
| 25f1167c9d | |||
| 420225c2d5 | |||
| 45f5eaac5b | |||
| 5229dd65ce | |||
| cfe39afc11 | |||
| 2aa3ce15bd | |||
| c9873da732 | |||
| 8dd71f99cc | |||
| ab45975883 | |||
| 7f38ca239e | |||
| c3b982e759 | |||
| e330e80c46 | |||
| f0836d4d3a | |||
| 1289920217 | |||
| a6a58094c9 | |||
| 424cbd3248 | |||
| e59b9627c7 | |||
| f080c0cdcd | |||
| 29bda2ef7d | |||
| 1d64692fd6 | |||
| 6f195cb8ec | |||
| 4c02a63acc | |||
| 0fc9fc7516 | |||
| 4450351b75 | |||
| 9bb15aaf1b | |||
| 65dd729e19 | |||
| c21142605d | |||
| 86e274faa3 | |||
| 5e8c129c7f | |||
| ab3b5ca4ef | |||
| 60a5afd752 | |||
| 9d0ea857fe | |||
| f763aea4fc | |||
| e16c04250e | |||
| ad99aa460b | |||
| e47f64f62d | |||
| c6d9da1571 | |||
| ab561d1ce8 | |||
| f39ba0136c | |||
| df60045bfe | |||
| 5e122f780f | |||
| eefe377159 | |||
| 20920c262d | |||
| 870612be1c | |||
| 266424ff0e | |||
| a8d48b758e | |||
| 67a8e0b5c6 | |||
| 7b7d424962 | |||
| a4e959818a | |||
| c3a71cc182 | |||
| da03cfdbe5 | |||
| 2b137d76fa | |||
| 81b8c111ca | |||
| fce98b9ca4 | |||
| c0dcae16f7 | |||
| c604f08749 | |||
| da21424416 | |||
| b5c83721ad | |||
| 9b21fca1a0 | |||
| af94b07771 | |||
| 0d23d28a65 | |||
| 710370ac24 | |||
| ed0a441e4d | |||
| 24e87cc0bb | |||
| 460693c153 | |||
| f54a94bd4c | |||
| a19b86add0 | |||
| 570944a48b | |||
| 5829b02323 | |||
| a2bca0e358 | |||
| 133fdd7a37 | |||
| 0849262243 | |||
| 17095feb33 | |||
| f42ae46338 | |||
| e2679852ce | |||
| 989dab6259 | |||
| adacdc038d | |||
| f0aefaac42 | |||
| 1aeaa0094a | |||
| 6d3fa12f37 | |||
| 052f1eedd0 | |||
| 858da800be | |||
| 954cac3af7 | |||
| d0f171ebc6 | |||
| 90cf612ac7 | |||
| 802b5863ab | |||
| 4baa949a99 | |||
| 3bed04a6d3 | |||
| d548b800d5 | |||
| f7f199d929 | |||
| 5519fddb78 | |||
| a9ed748fb2 | |||
| dcba2bfd25 | |||
| 72c91ead8b | |||
| 774d0aa90c | |||
| 2eea67ce34 | |||
| db1c44f921 | |||
| e11287ec25 | |||
| 4f10adfb76 | |||
| f22803c59f | |||
| a72d4e5dc1 | |||
| df5cacf8a2 | |||
| bb2c73348d | |||
| 4327653d70 | |||
| 5f7f4c9b91 | |||
| d44202e55b | |||
| df95447ea4 | |||
| 01852c7188 | |||
| 79c5697042 | |||
| 658ba092e2 | |||
| b221d99e7b | |||
| a450530c74 | |||
| 1b8c7ff4ec | |||
| aa8af2220c | |||
| 040f826c52 | |||
| 7939c691f7 | |||
| c9d46856a3 | |||
| 6d65f6646f |
@@ -3018,6 +3018,87 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "koiakoia",
|
||||
"name": "koiakoia",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/60405354?v=4",
|
||||
"profile": "https://github.com/koiakoia",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "mustafa-online",
|
||||
"name": "Mustafa Online",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/5323832?v=4",
|
||||
"profile": "https://github.com/mustafa-online",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "franceslui",
|
||||
"name": "franceslui",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/104601439?v=4",
|
||||
"profile": "https://github.com/franceslui",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Q4kK",
|
||||
"name": "Q4kK",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/125313163?v=4",
|
||||
"profile": "https://github.com/Q4kK",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "squintfox",
|
||||
"name": "squintfox",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/55590532?v=4",
|
||||
"profile": "https://github.com/squintfox",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "jeffclay",
|
||||
"name": "Jeff Clay",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1380084?v=4",
|
||||
"profile": "https://github.com/jeffclay",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "PP-JN-RL",
|
||||
"name": "Phil J R",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/52716446?v=4",
|
||||
"profile": "https://github.com/PP-JN-RL",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "chandanchowdhury",
|
||||
"name": "i_virus",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1496725?v=4",
|
||||
"profile": "https://www.corelight.com/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "gitgrimbo",
|
||||
"name": "Paul Grime",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1020541?v=4",
|
||||
"profile": "https://github.com/gitgrimbo",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ DB_SSL_KEY_PATH=null
|
||||
DB_SSL_CERT_PATH=null
|
||||
DB_SSL_CA_PATH=null
|
||||
DB_SSL_CIPHER=null
|
||||
DB_SSL_VERIFY_SERVER=null
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
|
||||
|
||||
@@ -36,6 +36,7 @@ DB_SSL_KEY_PATH=null
|
||||
DB_SSL_CERT_PATH=null
|
||||
DB_SSL_CA_PATH=null
|
||||
DB_SSL_CIPHER=null
|
||||
DB_SSL_VERIFY_SERVER=null
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
|
||||
|
||||
@@ -42,6 +42,7 @@ DB_SSL_KEY_PATH=null
|
||||
DB_SSL_CERT_PATH=null
|
||||
DB_SSL_CA_PATH=null
|
||||
DB_SSL_CIPHER=null
|
||||
DB_SSL_VERIFY_SERVER=null
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
|
||||
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
|
||||
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
|
||||
- name: Run Codacy Analysis CLI
|
||||
uses: codacy/codacy-analysis-cli-action@v4.4.0
|
||||
uses: codacy/codacy-analysis-cli-action@v4.4.1
|
||||
with:
|
||||
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
|
||||
# You can also omit the token and run the tools that support default configurations
|
||||
|
||||
@@ -432,6 +432,17 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bilias"><img src="https://avatars.githubusercontent.com/u/47315739?v=4?s=110" width="110px;" alt="bilias"/><br /><sub><b>bilias</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=bilias" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/coach1988"><img src="https://avatars.githubusercontent.com/u/2565989?v=4?s=110" width="110px;" alt="coach1988"/><br /><sub><b>coach1988</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=coach1988" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mauro-miatello"><img src="https://avatars.githubusercontent.com/u/11910225?v=4?s=110" width="110px;" alt="MrM"/><br /><sub><b>MrM</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=mauro-miatello" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/koiakoia"><img src="https://avatars.githubusercontent.com/u/60405354?v=4?s=110" width="110px;" alt="koiakoia"/><br /><sub><b>koiakoia</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=koiakoia" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mustafa-online"><img src="https://avatars.githubusercontent.com/u/5323832?v=4?s=110" width="110px;" alt="Mustafa Online"/><br /><sub><b>Mustafa Online</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=mustafa-online" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/franceslui"><img src="https://avatars.githubusercontent.com/u/104601439?v=4?s=110" width="110px;" alt="franceslui"/><br /><sub><b>franceslui</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=franceslui" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Q4kK"><img src="https://avatars.githubusercontent.com/u/125313163?v=4?s=110" width="110px;" alt="Q4kK"/><br /><sub><b>Q4kK</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=Q4kK" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/squintfox"><img src="https://avatars.githubusercontent.com/u/55590532?v=4?s=110" width="110px;" alt="squintfox"/><br /><sub><b>squintfox</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=squintfox" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jeffclay"><img src="https://avatars.githubusercontent.com/u/1380084?v=4?s=110" width="110px;" alt="Jeff Clay"/><br /><sub><b>Jeff Clay</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=jeffclay" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PP-JN-RL"><img src="https://avatars.githubusercontent.com/u/52716446?v=4?s=110" width="110px;" alt="Phil J R"/><br /><sub><b>Phil J R</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=PP-JN-RL" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.corelight.com/"><img src="https://avatars.githubusercontent.com/u/1496725?v=4?s=110" width="110px;" alt="i_virus"/><br /><sub><b>i_virus</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=chandanchowdhury" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gitgrimbo"><img src="https://avatars.githubusercontent.com/u/1020541?v=4?s=110" width="110px;" alt="Paul Grime"/><br /><sub><b>Paul Grime</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=gitgrimbo" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -12,7 +12,7 @@ It is built on [Laravel 8](http://laravel.com).
|
||||
Snipe-IT is actively developed and we [release quite frequently](https://github.com/snipe/snipe-it/releases). ([Check out the live demo here](https://snipeitapp.com/demo/).)
|
||||
|
||||
> [!TIP]
|
||||
> __This is web-based software__. This means there is no executable file (aka no .exe files), and it must be run on a web server and accessed through a web browser. It runs on any Mac OSX, flavor of Linux, as well as Windows, and we have a [Docker image](https://snipe-it.readme.io/docs/docker) available if that's what you're into.
|
||||
> __This is web-based software__. This means there is no executable file (aka no .exe files), and it must be run on a web server and accessed through a web browser. It runs on any Mac OSX, any flavor of Linux, as well as Windows, and we have a [Docker image](https://snipe-it.readme.io/docs/docker) available if that's what you're into.
|
||||
|
||||
-----
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ class LdapSync extends Command
|
||||
$user->location_id = $location->id;
|
||||
}
|
||||
}
|
||||
|
||||
$location = null;
|
||||
$user->ldap_import = 1;
|
||||
|
||||
$errors = '';
|
||||
|
||||
@@ -9,7 +9,6 @@ use App\Notifications\ExpectedCheckinAdminNotification;
|
||||
use App\Notifications\ExpectedCheckinNotification;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class SendExpectedCheckinAlerts extends Command
|
||||
{
|
||||
@@ -43,25 +42,31 @@ class SendExpectedCheckinAlerts extends Command
|
||||
public function handle()
|
||||
{
|
||||
$settings = Setting::getSettings();
|
||||
$whenNotify = Carbon::now();
|
||||
$assets = Asset::with('assignedTo')->whereNotNull('assigned_to')->whereNotNull('expected_checkin')->where('expected_checkin', '<=', $whenNotify)->get();
|
||||
$interval = $settings->audit_warning_days ?? 0;
|
||||
$today = Carbon::now();
|
||||
$interval_date = $today->copy()->addDays($interval);
|
||||
|
||||
$assets = Asset::whereNull('deleted_at')->DueOrOverdueForCheckin($settings)->orderBy('assets.expected_checkin', 'desc')->get();
|
||||
|
||||
$this->info($assets->count().' assets must be checked in on or before '.$interval_date.' is deadline');
|
||||
|
||||
$this->info($whenNotify.' is deadline');
|
||||
$this->info($assets->count().' assets');
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
if ($asset->assigned && $asset->checkedOutToUser()) {
|
||||
Log::info('Sending ExpectedCheckinNotification to ' . $asset->assigned->email);
|
||||
$asset->assigned->notify((new ExpectedCheckinNotification($asset)));
|
||||
if ($asset->assignedTo && (isset($asset->assignedTo->email)) && ($asset->assignedTo->email!='') && $asset->checkedOutToUser()) {
|
||||
$this->info('Sending User ExpectedCheckinNotification to: '.$asset->assignedTo->email);
|
||||
$asset->assignedTo->notify((new ExpectedCheckinNotification($asset)));
|
||||
}
|
||||
}
|
||||
|
||||
if (($assets) && ($assets->count() > 0) && ($settings->alert_email != '')) {
|
||||
// Send a rollup to the admin, if settings dictate
|
||||
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item, $key) {
|
||||
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item) {
|
||||
return new AlertRecipient($item);
|
||||
});
|
||||
|
||||
$this->info('Sending Admin ExpectedCheckinNotification to: '.$settings->alert_email);
|
||||
\Notification::send($recipients, new ExpectedCheckinAdminNotification($assets));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\License;
|
||||
use App\Models\Recipients;
|
||||
use App\Models\Recipients\AlertRecipient;
|
||||
use App\Models\Setting;
|
||||
use App\Notifications\ExpiringAssetsNotification;
|
||||
use App\Notifications\SendUpcomingAuditNotification;
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
@@ -46,39 +44,24 @@ class SendUpcomingAuditReport extends Command
|
||||
public function handle()
|
||||
{
|
||||
$settings = Setting::getSettings();
|
||||
$interval = $settings->audit_warning_days ?? 0;
|
||||
$today = Carbon::now();
|
||||
$interval_date = $today->copy()->addDays($interval);
|
||||
|
||||
if (($settings->alert_email != '') && ($settings->audit_warning_days) && ($settings->alerts_enabled == 1)) {
|
||||
$assets = Asset::whereNull('deleted_at')->DueOrOverdueForAudit($settings)->orderBy('assets.next_audit_date', 'desc')->get();
|
||||
$this->info($assets->count().' assets must be audited in on or before '.$interval_date.' is deadline');
|
||||
|
||||
|
||||
if (($assets) && ($assets->count() > 0) && ($settings->alert_email != '')) {
|
||||
// Send a rollup to the admin, if settings dictate
|
||||
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item, $key) {
|
||||
return new \App\Models\Recipients\AlertRecipient($item);
|
||||
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item) {
|
||||
return new AlertRecipient($item);
|
||||
});
|
||||
|
||||
// Assets due for auditing
|
||||
$this->info('Sending Admin SendUpcomingAuditNotification to: '.$settings->alert_email);
|
||||
\Notification::send($recipients, new SendUpcomingAuditNotification($assets, $settings->audit_warning_days));
|
||||
|
||||
$assets = Asset::whereNotNull('next_audit_date')
|
||||
->DueOrOverdueForAudit($settings)
|
||||
->orderBy('last_audit_date', 'asc')->get();
|
||||
|
||||
if ($assets->count() > 0) {
|
||||
$this->info(trans_choice('mail.upcoming-audits', $assets->count(),
|
||||
['count' => $assets->count(), 'threshold' => $settings->audit_warning_days]));
|
||||
\Notification::send($recipients, new SendUpcomingAuditNotification($assets, $settings->audit_warning_days));
|
||||
$this->info('Audit report sent to '.$settings->alert_email);
|
||||
} else {
|
||||
$this->info('No assets to be audited. No report sent.');
|
||||
}
|
||||
} elseif ($settings->alert_email == '') {
|
||||
$this->error('Could not send email. No alert email configured in settings');
|
||||
} elseif (! $settings->audit_warning_days) {
|
||||
$this->error('No audit warning days set in Admin Notifications. No mail will be sent.');
|
||||
} elseif ($settings->alerts_enabled != 1) {
|
||||
$this->info('Alerts are disabled in the settings. No mail will be sent');
|
||||
} else {
|
||||
$this->error('Something went wrong. :( ');
|
||||
$this->error('Admin Notifications Email Setting: '.$settings->alert_email);
|
||||
$this->error('Admin Audit Warning Setting: '.$settings->audit_warning_days);
|
||||
$this->error('Admin Alerts Emnabled: '.$settings->alerts_enabled);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ class AssetsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function index(Request $request, $audit = null)
|
||||
public function index(Request $request, $action = null, $upcoming_status = null)
|
||||
{
|
||||
|
||||
$filter_non_deprecable_assets = false;
|
||||
@@ -155,17 +155,44 @@ class AssetsController extends Controller
|
||||
$assets->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
// This is used by the audit reporting routes
|
||||
if (Gate::allows('audit', Asset::class)) {
|
||||
switch ($audit) {
|
||||
case 'due':
|
||||
$assets->DueOrOverdueForAudit($settings);
|
||||
break;
|
||||
case 'overdue':
|
||||
$assets->overdueForAudit($settings);
|
||||
break;
|
||||
|
||||
/**
|
||||
* Handle due and overdue audits and checkin dates
|
||||
*/
|
||||
switch ($action) {
|
||||
case 'audits':
|
||||
|
||||
switch ($upcoming_status) {
|
||||
case 'due':
|
||||
$assets->DueForAudit($settings);
|
||||
break;
|
||||
case 'overdue':
|
||||
$assets->OverdueForAudit();
|
||||
break;
|
||||
case 'due-or-overdue':
|
||||
$assets->DueOrOverdueForAudit($settings);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'checkins':
|
||||
switch ($upcoming_status) {
|
||||
case 'due':
|
||||
$assets->DueForCheckin($settings);
|
||||
break;
|
||||
case 'overdue':
|
||||
$assets->OverdueForCheckin();
|
||||
break;
|
||||
case 'due-or-overdue':
|
||||
$assets->DueOrOverdueForCheckin($settings);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End handling due and overdue audits and checkin dates
|
||||
*/
|
||||
|
||||
|
||||
// This is used by the sidenav, mostly
|
||||
@@ -665,25 +692,26 @@ class AssetsController extends Controller
|
||||
$model = AssetModel::find($asset->model_id);
|
||||
|
||||
// Update custom fields
|
||||
$problems_updating_encrypted_custom_fields = false;
|
||||
if (($model) && (isset($model->fieldset))) {
|
||||
foreach ($model->fieldset->fields as $field) {
|
||||
$field_val = $request->input($field->db_column, null);
|
||||
|
||||
if ($request->has($field->db_column)) {
|
||||
if ($field->field_encrypted == '1') {
|
||||
if (Gate::allows('admin')) {
|
||||
$asset->{$field->db_column} = Crypt::encrypt($field_val);
|
||||
}
|
||||
}
|
||||
if ($field->element == 'checkbox') {
|
||||
if(is_array($field_val)) {
|
||||
$field_val = implode(',', $field_val);
|
||||
$asset->{$field->db_column} = $field_val;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$asset->{$field->db_column} = $field_val;
|
||||
if ($field->field_encrypted == '1') {
|
||||
if (Gate::allows('admin')) {
|
||||
$field_val = Crypt::encrypt($field_val);
|
||||
} else {
|
||||
$problems_updating_encrypted_custom_fields = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$asset->{$field->db_column} = $field_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -709,8 +737,11 @@ class AssetsController extends Controller
|
||||
$asset->image = $asset->getImageUrl();
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new AssetsTransformer)->transformAsset($asset), trans('admin/hardware/message.update.success')));
|
||||
if ($problems_updating_encrypted_custom_fields) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.encrypted_warning')));
|
||||
} else {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success')));
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
|
||||
|
||||
@@ -75,8 +75,8 @@ class UsersController extends Controller
|
||||
'users.autoassign_licenses',
|
||||
'users.website',
|
||||
|
||||
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy',)
|
||||
->withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count');
|
||||
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy')
|
||||
->withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count', 'managesUsers as manages_users_count', 'managedLocations as manages_locations_count');
|
||||
|
||||
|
||||
if ($request->filled('activated')) {
|
||||
@@ -187,6 +187,14 @@ class UsersController extends Controller
|
||||
$users->has('accessories', '=', $request->input('accessories_count'));
|
||||
}
|
||||
|
||||
if ($request->filled('manages_users_count')) {
|
||||
$users->has('manages_users_count', '=', $request->input('manages_users_count'));
|
||||
}
|
||||
|
||||
if ($request->filled('manages_locations_count')) {
|
||||
$users->has('manages_locations_count', '=', $request->input('manages_locations_count'));
|
||||
}
|
||||
|
||||
if ($request->filled('autoassign_licenses')) {
|
||||
$users->where('autoassign_licenses', '=', $request->input('autoassign_licenses'));
|
||||
}
|
||||
@@ -244,6 +252,8 @@ class UsersController extends Controller
|
||||
'licenses_count',
|
||||
'consumables_count',
|
||||
'accessories_count',
|
||||
'manages_user_count',
|
||||
'manages_locations_count',
|
||||
'phone',
|
||||
'address',
|
||||
'city',
|
||||
@@ -273,6 +283,7 @@ class UsersController extends Controller
|
||||
$users = $users->withTrashed();
|
||||
}
|
||||
|
||||
// Apply companyable scope
|
||||
$users = Company::scopeCompanyables($users);
|
||||
|
||||
|
||||
@@ -403,9 +414,16 @@ class UsersController extends Controller
|
||||
public function show($id)
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$user = User::withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count')->findOrFail($id);
|
||||
|
||||
return (new UsersTransformer)->transformUser($user);
|
||||
$user = User::withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count', 'managesUsers as manages_users_count', 'managedLocations as manages_locations_count');
|
||||
|
||||
if ($user = Company::scopeCompanyables($user)->find($id)) {
|
||||
$this->authorize('view', $user);
|
||||
return (new UsersTransformer)->transformUser($user);
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.user_not_found', compact('id'))));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -423,6 +441,8 @@ class UsersController extends Controller
|
||||
$this->authorize('update', User::class);
|
||||
|
||||
$user = User::findOrFail($id);
|
||||
$user = Company::scopeCompanyables($user)->find($id);
|
||||
$this->authorize('update', $user);
|
||||
|
||||
/**
|
||||
* This is a janky hack to prevent people from changing admin demo user data on the public demo.
|
||||
@@ -459,11 +479,11 @@ class UsersController extends Controller
|
||||
if (! Auth::user()->isSuperUser()) {
|
||||
unset($permissions_array['superuser']);
|
||||
}
|
||||
|
||||
$user->permissions = $permissions_array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Update the location of any assets checked out to this user
|
||||
Asset::where('assigned_type', User::class)
|
||||
->where('assigned_to', $user->id)->update(['location_id' => $request->input('location_id', null)]);
|
||||
@@ -473,14 +493,9 @@ class UsersController extends Controller
|
||||
|
||||
if ($user->save()) {
|
||||
|
||||
// Sync group memberships:
|
||||
// This was changed in Snipe-IT v4.6.x to 4.7, since we upgraded to Laravel 5.5
|
||||
// which changes the behavior of has vs filled.
|
||||
// The $request->has method will now return true even if the input value is an empty string or null.
|
||||
// A new $request->filled method has was added that provides the previous behavior of the has method.
|
||||
|
||||
// Check if the request has groups passed and has a value
|
||||
if ($request->filled('groups')) {
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
'groups.*' => 'integer|exists:permission_groups,id',
|
||||
]);
|
||||
@@ -488,10 +503,19 @@ class UsersController extends Controller
|
||||
if ($validator->fails()){
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $user->getErrors()));
|
||||
}
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
|
||||
// Only save groups if the user is a superuser
|
||||
if (Auth::user()->isSuperUser()) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
}
|
||||
|
||||
// The groups field has been passed but it is null, so we should blank it out
|
||||
} elseif ($request->has('groups')) {
|
||||
$user->groups()->sync([]);
|
||||
|
||||
// Only save groups if the user is a superuser
|
||||
if (Auth::user()->isSuperUser()) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -512,37 +536,43 @@ class UsersController extends Controller
|
||||
public function destroy($id)
|
||||
{
|
||||
$this->authorize('delete', User::class);
|
||||
$user = User::findOrFail($id);
|
||||
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
|
||||
$user = Company::scopeCompanyables($user)->find($id);
|
||||
$this->authorize('delete', $user);
|
||||
|
||||
if (($user->assets) && ($user->assets->count() > 0)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete_has_assets')));
|
||||
}
|
||||
if ($user) {
|
||||
|
||||
if (($user->licenses) && ($user->licenses->count() > 0)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has '.$user->licenses->count().' license(s) associated with them and cannot be deleted.'));
|
||||
}
|
||||
|
||||
if (($user->accessories) && ($user->accessories->count() > 0)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has '.$user->accessories->count().' accessories associated with them.'));
|
||||
}
|
||||
|
||||
if (($user->managedLocations()) && ($user->managedLocations()->count() > 0)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has '.$user->managedLocations()->count().' locations that they manage.'));
|
||||
}
|
||||
|
||||
if ($user->delete()) {
|
||||
|
||||
// Remove the user's avatar if they have one
|
||||
if (Storage::disk('public')->exists('avatars/'.$user->avatar)) {
|
||||
try {
|
||||
Storage::disk('public')->delete('avatars/'.$user->avatar);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
$this->authorize('delete', $user);
|
||||
|
||||
if (($user->assets) && ($user->assets->count() > 0)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete_has_assets')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.success.delete')));
|
||||
if (($user->licenses) && ($user->licenses->count() > 0)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->licenses->count() . ' license(s) associated with them and cannot be deleted.'));
|
||||
}
|
||||
|
||||
if (($user->accessories) && ($user->accessories->count() > 0)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->accessories->count() . ' accessories associated with them.'));
|
||||
}
|
||||
|
||||
if (($user->managedLocations()) && ($user->managedLocations()->count() > 0)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->managedLocations()->count() . ' locations that they manage.'));
|
||||
}
|
||||
|
||||
if ($user->delete()) {
|
||||
|
||||
// Remove the user's avatar if they have one
|
||||
if (Storage::disk('public')->exists('avatars/' . $user->avatar)) {
|
||||
try {
|
||||
Storage::disk('public')->delete('avatars/' . $user->avatar);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.success.delete')));
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete')));
|
||||
@@ -560,6 +590,11 @@ class UsersController extends Controller
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
|
||||
$user = Company::scopeCompanyables($user)->find($id);
|
||||
$this->authorize('view', $user);
|
||||
|
||||
$assets = Asset::where('assigned_to', '=', $id)->where('assigned_type', '=', User::class)->with('model');
|
||||
|
||||
|
||||
@@ -595,7 +630,10 @@ class UsersController extends Controller
|
||||
*/
|
||||
public function emailAssetList(Request $request, $id)
|
||||
{
|
||||
$this->authorize('update', User::class);
|
||||
$user = User::findOrFail($id);
|
||||
$user = Company::scopeCompanyables($user)->find($id);
|
||||
$this->authorize('update', $user);
|
||||
|
||||
if (empty($user->email)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.inventorynotification.error')));
|
||||
@@ -619,6 +657,7 @@ class UsersController extends Controller
|
||||
$this->authorize('view', User::class);
|
||||
$this->authorize('view', Consumable::class);
|
||||
$user = User::findOrFail($id);
|
||||
$this->authorize('update', $user);
|
||||
$consumables = $user->consumables;
|
||||
return (new ConsumablesTransformer)->transformConsumables($consumables, $consumables->count(), $request);
|
||||
}
|
||||
@@ -635,6 +674,7 @@ class UsersController extends Controller
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$user = User::findOrFail($id);
|
||||
$this->authorize('view', $user);
|
||||
$this->authorize('view', Accessory::class);
|
||||
$accessories = $user->accessories;
|
||||
|
||||
@@ -655,6 +695,7 @@ class UsersController extends Controller
|
||||
$this->authorize('view', License::class);
|
||||
|
||||
if ($user = User::where('id', $id)->withTrashed()->first()) {
|
||||
$this->authorize('update', $user);
|
||||
$licenses = $user->licenses()->get();
|
||||
return (new LicensesTransformer())->transformLicenses($licenses, $licenses->count());
|
||||
}
|
||||
@@ -678,6 +719,7 @@ class UsersController extends Controller
|
||||
if ($request->filled('id')) {
|
||||
try {
|
||||
$user = User::find($request->get('id'));
|
||||
$this->authorize('update', $user);
|
||||
$user->two_factor_secret = null;
|
||||
$user->two_factor_enrolled = 0;
|
||||
$user->saveQuietly();
|
||||
|
||||
@@ -38,7 +38,7 @@ class AssetModelsFilesController extends Controller
|
||||
|
||||
$file_name = $request->handleFile('private_uploads/assetmodels/','model-'.$model->id,$file);
|
||||
|
||||
$model->logUpload($file_name, e($request->get('notes')));
|
||||
$model->logUpload($file_name, $request->get('notes'));
|
||||
}
|
||||
|
||||
return redirect()->back()->with('success', trans('general.file_upload_success'));
|
||||
|
||||
@@ -39,6 +39,12 @@ class AssetCheckinController extends Controller
|
||||
|
||||
$this->authorize('checkin', $asset);
|
||||
|
||||
// This asset is already checked in, redirect
|
||||
|
||||
if (is_null($asset->assignedTo)) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkin.already_checked_in'));
|
||||
}
|
||||
|
||||
return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class AssetFilesController extends Controller
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile('private_uploads/assets/','hardware-'.$asset->id, $file);
|
||||
|
||||
$asset->logUpload($file_name, e($request->get('notes')));
|
||||
$asset->logUpload($file_name, $request->get('notes'));
|
||||
}
|
||||
|
||||
return redirect()->back()->with('success', trans('admin/hardware/message.upload.success'));
|
||||
|
||||
@@ -854,11 +854,11 @@ class AssetsController extends Controller
|
||||
return view('hardware/audit-due');
|
||||
}
|
||||
|
||||
public function overdueForAudit()
|
||||
public function dueForCheckin()
|
||||
{
|
||||
$this->authorize('audit', Asset::class);
|
||||
$this->authorize('checkin', Asset::class);
|
||||
|
||||
return view('hardware/audit-overdue');
|
||||
return view('hardware/checkin-due');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ use App\Models\Setting;
|
||||
use App\Models\Supplier;
|
||||
use App\Models\User;
|
||||
use App\View\Label as LabelView;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class LabelsController extends Controller
|
||||
@@ -21,9 +22,9 @@ class LabelsController extends Controller
|
||||
/**
|
||||
* Returns the Label view with test data
|
||||
*
|
||||
* @author Grant Le Roux <grant.leroux+snipe-it@gmail.com>
|
||||
* @param string $labelName
|
||||
* @param string $labelName
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @author Grant Le Roux <grant.leroux+snipe-it@gmail.com>
|
||||
*/
|
||||
public function show(string $labelName)
|
||||
{
|
||||
@@ -66,7 +67,7 @@ class LabelsController extends Controller
|
||||
$exampleAsset->model->category->id = 999999;
|
||||
$exampleAsset->model->category->name = trans('admin/labels/table.example_category');
|
||||
|
||||
$customFieldColumns = CustomField::all()->pluck('db_column');
|
||||
$customFieldColumns = CustomField::where('field_encrypted', '=', 0)->pluck('db_column');
|
||||
|
||||
collect(explode(';', Setting::getSettings()->label2_fields))
|
||||
->filter()
|
||||
|
||||
@@ -11,6 +11,7 @@ use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Licenses for
|
||||
@@ -289,4 +290,106 @@ class LicensesController extends Controller
|
||||
->with('item', $license)
|
||||
->with('maintained_list', $maintained_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports Licenses to CSV
|
||||
*
|
||||
* @author [G. Martinez]
|
||||
* @since [v6.3]
|
||||
* @return StreamedResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function getExportLicensesCsv()
|
||||
{
|
||||
$this->authorize('view', License::class);
|
||||
\Debugbar::disable();
|
||||
|
||||
$response = new StreamedResponse(function () {
|
||||
// Open output stream
|
||||
$handle = fopen('php://output', 'w');
|
||||
$licenses= License::with('company',
|
||||
'manufacturer',
|
||||
'category',
|
||||
'supplier',
|
||||
'adminuser',
|
||||
'assignedusers')
|
||||
->orderBy('created_at', 'DESC');
|
||||
Company::scopeCompanyables($licenses)
|
||||
->chunk(500, function ($licenses) use ($handle) {
|
||||
$headers = [
|
||||
// strtolower to prevent Excel from trying to open it as a SYLK file
|
||||
strtolower(trans('general.id')),
|
||||
trans('general.company'),
|
||||
trans('general.name'),
|
||||
trans('general.serial_number'),
|
||||
trans('general.purchase_date'),
|
||||
trans('general.purchase_cost'),
|
||||
trans('general.order_number'),
|
||||
trans('general.licenses_available'),
|
||||
trans('admin/licenses/table.seats'),
|
||||
trans('general.created_by'),
|
||||
trans('general.depreciation'),
|
||||
trans('general.updated_at'),
|
||||
trans('admin/licenses/table.deleted_at'),
|
||||
trans('general.email'),
|
||||
trans('admin/hardware/form.fully_depreciated'),
|
||||
trans('general.supplier'),
|
||||
trans('admin/licenses/form.expiration'),
|
||||
trans('admin/licenses/form.purchase_order'),
|
||||
trans('admin/licenses/form.termination_date'),
|
||||
trans('admin/licenses/form.maintained'),
|
||||
trans('general.manufacturer'),
|
||||
trans('general.category'),
|
||||
trans('general.min_amt'),
|
||||
trans('admin/licenses/form.reassignable'),
|
||||
trans('general.notes'),
|
||||
trans('general.created_at'),
|
||||
];
|
||||
|
||||
fputcsv($handle, $headers);
|
||||
|
||||
foreach ($licenses as $license) {
|
||||
// Add a new row with data
|
||||
$values = [
|
||||
$license->id,
|
||||
$license->company ? $license->company->name: '',
|
||||
$license->name,
|
||||
$license->serial,
|
||||
$license->purchase_date,
|
||||
$license->purchase_cost,
|
||||
$license->order_number,
|
||||
$license->free_seat_count,
|
||||
$license->seats,
|
||||
$license->adminuser->present()->fullName(),
|
||||
$license->depreciation ? $license->depreciation->name: '',
|
||||
$license->updated_at,
|
||||
$license->deleted_at,
|
||||
$license->email,
|
||||
( $license->depreciate == '1') ? trans('general.yes') : trans('general.no'),
|
||||
($license->supplier) ? $license->supplier->name: '',
|
||||
$license->expiration_date,
|
||||
$license->purchase_order,
|
||||
$license->termination_date,
|
||||
( $license->maintained == '1') ? trans('general.yes') : trans('general.no'),
|
||||
$license->manufacturer ? $license->manufacturer->name: '',
|
||||
$license->category ? $license->category->name: '',
|
||||
$license->min_amt,
|
||||
( $license->reassignable == '1') ? trans('general.yes') : trans('general.no'),
|
||||
$license->notes,
|
||||
$license->created_at,
|
||||
];
|
||||
|
||||
fputcsv($handle, $values);
|
||||
}
|
||||
});
|
||||
|
||||
// Close the output stream
|
||||
fclose($handle);
|
||||
}, 200, [
|
||||
'Content-Type' => 'text/csv; charset=UTF-8',
|
||||
'Content-Disposition' => 'attachment; filename="licenses-'.date('Y-m-d-his').'.csv"',
|
||||
]);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,7 +696,7 @@ class ReportsController extends Controller
|
||||
->whereBetween('action_date',[$checkout_start, $checkout_end])
|
||||
->pluck('item_id');
|
||||
|
||||
$assets->whereIn('id',$actionlogassets);
|
||||
$assets->whereIn('assets.id',$actionlogassets);
|
||||
}
|
||||
|
||||
if (($request->filled('checkin_date_start'))) {
|
||||
|
||||
@@ -804,10 +804,9 @@ class SettingsController extends Controller
|
||||
*/
|
||||
public function getLabels()
|
||||
{
|
||||
return view('settings.labels', [
|
||||
'setting' => Setting::getSettings(),
|
||||
'customFields' => CustomField::all(),
|
||||
]);
|
||||
return view('settings.labels')
|
||||
->with('setting', Setting::getSettings())
|
||||
->with('customFields', CustomField::where('field_encrypted', '=', 0)->get());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -182,8 +182,13 @@ class UsersController extends Controller
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
if ($user = User::find($id)) {
|
||||
$this->authorize('update', $user);
|
||||
|
||||
$this->authorize('update', User::class);
|
||||
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
|
||||
$user = Company::scopeCompanyables($user)->find($id);
|
||||
|
||||
if ($user) {
|
||||
|
||||
$permissions = config('permissions');
|
||||
$groups = Group::pluck('name', 'id');
|
||||
|
||||
@@ -210,106 +215,109 @@ class UsersController extends Controller
|
||||
*/
|
||||
public function update(SaveUserRequest $request, $id = null)
|
||||
{
|
||||
// We need to reverse the UI specific logic for our
|
||||
// permissions here before we update the user.
|
||||
$permissions = $request->input('permissions', []);
|
||||
app('request')->request->set('permissions', $permissions);
|
||||
$this->authorize('update', User::class);
|
||||
|
||||
// This is a janky hack to prevent people from changing admin demo user data on the public demo.
|
||||
// The $ids 1 and 2 are special since they are seeded as superadmins in the demo seeder.
|
||||
// Thanks, jerks. You are why we can't have nice things. - snipe
|
||||
|
||||
if ((($id == 1) || ($id == 2)) && (config('app.lock_passwords'))) {
|
||||
return redirect()->route('users.index')->with('error', 'Permission denied. You cannot update user information for superadmins on the demo.');
|
||||
return redirect()->route('users.index')->with('error', trans('general.permission_denied_superuser_demo'));
|
||||
}
|
||||
|
||||
try {
|
||||
$user = User::findOrFail($id);
|
||||
} catch (ModelNotFoundException $e) {
|
||||
return redirect()->route('users.index')
|
||||
->with('error', trans('admin/users/message.user_not_found', compact('id')));
|
||||
}
|
||||
|
||||
$this->authorize('update', $user);
|
||||
// Figure out of this user was an admin before this edit
|
||||
$orig_permissions_array = $user->decodePermissions();
|
||||
$orig_superuser = '0';
|
||||
if (is_array($orig_permissions_array)) {
|
||||
if (array_key_exists('superuser', $orig_permissions_array)) {
|
||||
$orig_superuser = $orig_permissions_array['superuser'];
|
||||
// We need to reverse the UI specific logic for our
|
||||
// permissions here before we update the user.
|
||||
$permissions = $request->input('permissions', []);
|
||||
app('request')->request->set('permissions', $permissions);
|
||||
|
||||
|
||||
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
|
||||
$user = Company::scopeCompanyables($user)->find($id);
|
||||
|
||||
// User is valid - continue...
|
||||
if ($user) {
|
||||
$this->authorize('update', $user);
|
||||
|
||||
// Figure out of this user was an admin before this edit
|
||||
$orig_permissions_array = $user->decodePermissions();
|
||||
$orig_superuser = '0';
|
||||
if (is_array($orig_permissions_array)) {
|
||||
if (array_key_exists('superuser', $orig_permissions_array)) {
|
||||
$orig_superuser = $orig_permissions_array['superuser'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only save groups if the user is a super user
|
||||
if (Auth::user()->isSuperUser()) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
}
|
||||
// Only save groups if the user is a superuser
|
||||
if (Auth::user()->isSuperUser()) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
}
|
||||
|
||||
// Update the user
|
||||
if ($request->filled('username')) {
|
||||
// Update the user fields
|
||||
$user->username = trim($request->input('username'));
|
||||
}
|
||||
$user->email = trim($request->input('email'));
|
||||
$user->first_name = $request->input('first_name');
|
||||
$user->last_name = $request->input('last_name');
|
||||
$user->two_factor_optin = $request->input('two_factor_optin') ?: 0;
|
||||
$user->locale = $request->input('locale');
|
||||
$user->employee_num = $request->input('employee_num');
|
||||
$user->activated = $request->input('activated', 0);
|
||||
$user->jobtitle = $request->input('jobtitle', null);
|
||||
$user->phone = $request->input('phone');
|
||||
$user->location_id = $request->input('location_id', null);
|
||||
$user->company_id = Company::getIdForUser($request->input('company_id', null));
|
||||
$user->manager_id = $request->input('manager_id', null);
|
||||
$user->notes = $request->input('notes');
|
||||
$user->department_id = $request->input('department_id', null);
|
||||
$user->address = $request->input('address', null);
|
||||
$user->city = $request->input('city', null);
|
||||
$user->state = $request->input('state', null);
|
||||
$user->country = $request->input('country', null);
|
||||
// if a user is editing themselves we should always keep activated true
|
||||
$user->activated = $request->input('activated', $request->user()->is($user) ? 1 : 0);
|
||||
$user->zip = $request->input('zip', null);
|
||||
$user->remote = $request->input('remote', 0);
|
||||
$user->vip = $request->input('vip', 0);
|
||||
$user->website = $request->input('website', null);
|
||||
$user->start_date = $request->input('start_date', null);
|
||||
$user->end_date = $request->input('end_date', null);
|
||||
$user->autoassign_licenses = $request->input('autoassign_licenses', 0);
|
||||
$user->email = trim($request->input('email'));
|
||||
$user->first_name = $request->input('first_name');
|
||||
$user->last_name = $request->input('last_name');
|
||||
$user->two_factor_optin = $request->input('two_factor_optin') ?: 0;
|
||||
$user->locale = $request->input('locale');
|
||||
$user->employee_num = $request->input('employee_num');
|
||||
$user->activated = $request->input('activated', 0);
|
||||
$user->jobtitle = $request->input('jobtitle', null);
|
||||
$user->phone = $request->input('phone');
|
||||
$user->location_id = $request->input('location_id', null);
|
||||
$user->company_id = Company::getIdForUser($request->input('company_id', null));
|
||||
$user->manager_id = $request->input('manager_id', null);
|
||||
$user->notes = $request->input('notes');
|
||||
$user->department_id = $request->input('department_id', null);
|
||||
$user->address = $request->input('address', null);
|
||||
$user->city = $request->input('city', null);
|
||||
$user->state = $request->input('state', null);
|
||||
$user->country = $request->input('country', null);
|
||||
// if a user is editing themselves we should always keep activated true
|
||||
$user->activated = $request->input('activated', $request->user()->is($user) ? 1 : 0);
|
||||
$user->zip = $request->input('zip', null);
|
||||
$user->remote = $request->input('remote', 0);
|
||||
$user->vip = $request->input('vip', 0);
|
||||
$user->website = $request->input('website', null);
|
||||
$user->start_date = $request->input('start_date', null);
|
||||
$user->end_date = $request->input('end_date', null);
|
||||
$user->autoassign_licenses = $request->input('autoassign_licenses', 0);
|
||||
|
||||
// Update the location of any assets checked out to this user
|
||||
Asset::where('assigned_type', User::class)
|
||||
->where('assigned_to', $user->id)
|
||||
->update(['location_id' => $request->input('location_id', null)]);
|
||||
|
||||
// Do we want to update the user password?
|
||||
if ($request->filled('password')) {
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
|
||||
$permissions_array = $request->input('permission');
|
||||
|
||||
// Strip out the superuser permission if the user isn't a superadmin
|
||||
if (! Auth::user()->isSuperUser()) {
|
||||
unset($permissions_array['superuser']);
|
||||
$permissions_array['superuser'] = $orig_superuser;
|
||||
}
|
||||
|
||||
$user->permissions = json_encode($permissions_array);
|
||||
|
||||
// Handle uploaded avatar
|
||||
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
||||
|
||||
if ($user->save()) {
|
||||
// Redirect to the user page
|
||||
return redirect()->route('users.index')
|
||||
->with('success', trans('admin/users/message.success.update'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($user->getErrors());
|
||||
|
||||
// Update the location of any assets checked out to this user
|
||||
Asset::where('assigned_type', User::class)
|
||||
->where('assigned_to', $user->id)
|
||||
->update(['location_id' => $request->input('location_id', null)]);
|
||||
|
||||
// Do we want to update the user password?
|
||||
if ($request->filled('password')) {
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
|
||||
$permissions_array = $request->input('permission');
|
||||
|
||||
// Strip out the superuser permission if the user isn't a superadmin
|
||||
if (! Auth::user()->isSuperUser()) {
|
||||
unset($permissions_array['superuser']);
|
||||
$permissions_array['superuser'] = $orig_superuser;
|
||||
}
|
||||
|
||||
$user->permissions = json_encode($permissions_array);
|
||||
|
||||
// Handle uploaded avatar
|
||||
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
||||
|
||||
//\Log::debug(print_r($user, true));
|
||||
|
||||
// Was the user updated?
|
||||
if ($user->save()) {
|
||||
// Redirect to the user page
|
||||
return redirect()->route('users.index')
|
||||
->with('success', trans('admin/users/message.success.update'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($user->getErrors());
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found', compact('id')));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,12 +331,13 @@ class UsersController extends Controller
|
||||
*/
|
||||
public function destroy($id = null)
|
||||
{
|
||||
try {
|
||||
// Get user information
|
||||
$user = User::findOrFail($id);
|
||||
// Authorize takes care of many of our logic checks now.
|
||||
$this->authorize('delete', User::class);
|
||||
|
||||
$this->authorize('delete', User::class);
|
||||
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
|
||||
$user = Company::scopeCompanyables($user)->find($id);
|
||||
|
||||
|
||||
if ($user) {
|
||||
// Check if we are not trying to delete ourselves
|
||||
if ($user->id === Auth::id()) {
|
||||
// Redirect to the user management page
|
||||
@@ -362,16 +371,12 @@ class UsersController extends Controller
|
||||
|
||||
// Delete the user
|
||||
$user->delete();
|
||||
|
||||
// Prepare the success message
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')->with('success', trans('admin/users/message.success.delete'));
|
||||
} catch (ModelNotFoundException $e) {
|
||||
// Prepare the error message
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')
|
||||
->with('error', trans('admin/users/message.user_not_found', compact('id')));
|
||||
}
|
||||
|
||||
return redirect()->route('users.index')
|
||||
->with('error', trans('admin/users/message.user_not_found', compact('id')));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -427,59 +432,25 @@ class UsersController extends Controller
|
||||
*/
|
||||
public function show($userId = null)
|
||||
{
|
||||
if (! $user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed()->find($userId)) {
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')
|
||||
->with('error', trans('admin/users/message.user_not_found', ['id' => $userId]));
|
||||
}
|
||||
// Make sure the user can view users at all
|
||||
$this->authorize('view', User::class);
|
||||
|
||||
$userlog = $user->userlog->load('item');
|
||||
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
|
||||
$user = Company::scopeCompanyables($user)->find($userId);
|
||||
|
||||
// Make sure they can view this particular user
|
||||
$this->authorize('view', $user);
|
||||
|
||||
return view('users/view', compact('user', 'userlog'))
|
||||
->with('settings', Setting::getSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsuspend a user.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $id
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function getUnsuspend($id = null)
|
||||
{
|
||||
try {
|
||||
// Get user information
|
||||
$user = User::findOrFail($id);
|
||||
$this->authorize('update', $user);
|
||||
|
||||
// Check if we are not trying to unsuspend ourselves
|
||||
if ($user->id === Auth::id()) {
|
||||
// Prepare the error message
|
||||
$error = trans('admin/users/message.error.unsuspend');
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')->with('error', $error);
|
||||
}
|
||||
|
||||
// Do we have permission to unsuspend this user?
|
||||
if ($user->isSuperUser() && ! Auth::user()->isSuperUser()) {
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')->with('error', 'Insufficient permissions!');
|
||||
}
|
||||
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')->with('success', trans('admin/users/message.success.unsuspend'));
|
||||
} catch (ModelNotFoundException $e) {
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')
|
||||
->with('error', trans('admin/users/message.user_not_found', compact('id')));
|
||||
if ($user) {
|
||||
$userlog = $user->userlog->load('item');
|
||||
return view('users/view', compact('user', 'userlog'))->with('settings', Setting::getSettings());
|
||||
}
|
||||
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found', ['id' => $userId]));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a view containing a pre-populated new user form,
|
||||
* populated with some fields from an existing user.
|
||||
@@ -493,22 +464,34 @@ class UsersController extends Controller
|
||||
public function getClone(Request $request, $id = null)
|
||||
{
|
||||
$this->authorize('create', User::class);
|
||||
|
||||
// We need to reverse the UI specific logic for our
|
||||
// permissions here before we update the user.
|
||||
$permissions = $request->input('permissions', []);
|
||||
app('request')->request->set('permissions', $permissions);
|
||||
|
||||
try {
|
||||
// Get the user information
|
||||
$user_to_clone = User::withTrashed()->find($id);
|
||||
|
||||
$user_to_clone = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
|
||||
$user_to_clone = Company::scopeCompanyables($user_to_clone)->find($id);
|
||||
|
||||
// Make sure they can view this particular user
|
||||
$this->authorize('view', $user_to_clone);
|
||||
|
||||
|
||||
if ($user_to_clone) {
|
||||
|
||||
|
||||
$user = clone $user_to_clone;
|
||||
|
||||
// Blank out some fields
|
||||
$user->first_name = '';
|
||||
$user->last_name = '';
|
||||
$user->email = substr($user->email, ($pos = strpos($user->email, '@')) !== false ? $pos : 0);
|
||||
$user->id = null;
|
||||
|
||||
// Get this user groups
|
||||
// Get this user's groups
|
||||
$userGroups = $user_to_clone->groups()->pluck('name', 'id');
|
||||
|
||||
// Get all the available permissions
|
||||
$permissions = config('permissions');
|
||||
$clonedPermissions = $user_to_clone->decodePermissions();
|
||||
@@ -517,16 +500,14 @@ class UsersController extends Controller
|
||||
|
||||
// Show the page
|
||||
return view('users/edit', compact('permissions', 'userPermissions'))
|
||||
->with('user', $user)
|
||||
->with('groups', Group::pluck('name', 'id'))
|
||||
->with('userGroups', $userGroups)
|
||||
->with('clone_user', $user_to_clone);
|
||||
} catch (ModelNotFoundException $e) {
|
||||
// Prepare the error message
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')
|
||||
->with('error', trans('admin/users/message.user_not_found', compact('id')));
|
||||
->with('user', $user)
|
||||
->with('groups', Group::pluck('name', 'id'))
|
||||
->with('userGroups', $userGroups)
|
||||
->with('clone_user', $user_to_clone);
|
||||
}
|
||||
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found', compact('id')));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -546,8 +527,20 @@ class UsersController extends Controller
|
||||
// Open output stream
|
||||
$handle = fopen('php://output', 'w');
|
||||
|
||||
User::with('assets', 'accessories', 'consumables', 'department', 'licenses', 'manager', 'groups', 'userloc', 'company')
|
||||
->orderBy('created_at', 'DESC')
|
||||
$users = User::with(
|
||||
'assets',
|
||||
'accessories',
|
||||
'consumables',
|
||||
'department',
|
||||
'licenses',
|
||||
'manager',
|
||||
'groups',
|
||||
'userloc',
|
||||
'company'
|
||||
)->orderBy('created_at', 'DESC');
|
||||
|
||||
// FMCS scoping
|
||||
Company::scopeCompanyables($users)
|
||||
->chunk(500, function ($users) use ($handle) {
|
||||
$headers = [
|
||||
// strtolower to prevent Excel from trying to open it as a SYLK file
|
||||
@@ -565,7 +558,7 @@ class UsersController extends Controller
|
||||
trans('general.licenses'),
|
||||
trans('general.accessories'),
|
||||
trans('general.consumables'),
|
||||
trans('admin/users/table.groups'),
|
||||
trans('general.groups'),
|
||||
trans('general.notes'),
|
||||
trans('admin/users/table.activated'),
|
||||
trans('general.created_at'),
|
||||
@@ -626,7 +619,11 @@ class UsersController extends Controller
|
||||
public function printInventory($id)
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$show_user = User::where('id', $id)->withTrashed()->first();
|
||||
$show_user = Company::scopeCompanyables(User::where('id', $id)->withTrashed()->first());
|
||||
|
||||
// Make sure they can view this particular user
|
||||
$this->authorize('view', $show_user);
|
||||
|
||||
$assets = Asset::where('assigned_to', $id)->where('assigned_type', User::class)->with('model', 'model.category')->get();
|
||||
$accessories = $show_user->accessories()->get();
|
||||
$consumables = $show_user->consumables()->get();
|
||||
@@ -651,16 +648,23 @@ class UsersController extends Controller
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
|
||||
if (!$user = User::find($id)) {
|
||||
return redirect()->back()
|
||||
->with('error', trans('admin/users/message.user_not_found', ['id' => $id]));
|
||||
}
|
||||
if (empty($user->email)) {
|
||||
return redirect()->back()->with('error', trans('admin/users/message.user_has_no_email'));
|
||||
$user = Company::scopeCompanyables(User::find($id));
|
||||
|
||||
// Make sure they can view this particular user
|
||||
$this->authorize('view', $user);
|
||||
|
||||
if ($user) {
|
||||
|
||||
if (empty($user->email)) {
|
||||
return redirect()->back()->with('error', trans('admin/users/message.user_has_no_email'));
|
||||
}
|
||||
|
||||
$user->notify((new CurrentInventory($user)));
|
||||
return redirect()->back()->with('success', trans('admin/users/general.user_notified'));
|
||||
}
|
||||
|
||||
$user->notify((new CurrentInventory($user)));
|
||||
return redirect()->back()->with('success', trans('admin/users/general.user_notified'));
|
||||
return redirect()->back()->with('error', trans('admin/users/message.user_not_found', ['id' => $id]));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -672,19 +676,19 @@ class UsersController extends Controller
|
||||
*/
|
||||
public function sendPasswordReset($id)
|
||||
{
|
||||
if (($user = User::find($id)) && ($user->activated == '1') && ($user->email != '') && ($user->ldap_import == '0')) {
|
||||
if (($user = Company::scopeCompanyables(User::find($id))) && ($user->activated == '1') && ($user->email != '') && ($user->ldap_import == '0')) {
|
||||
$credentials = ['email' => trim($user->email)];
|
||||
|
||||
try {
|
||||
|
||||
Password::sendResetLink($credentials);
|
||||
|
||||
return redirect()->back()->with('success', trans('admin/users/message.password_reset_sent', ['email' => $user->email]));
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->back()->with('error', ' Error sending email. :( ');
|
||||
return redirect()->back()->with('error', trans('general.error_sending_email'));
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', 'User is not activated, is LDAP synced, or does not have an email address ');
|
||||
return redirect()->back()->with('error', trans('general.pwd_reset_not_sent'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Middleware;
|
||||
use App\Models\Asset;
|
||||
use Auth;
|
||||
use Closure;
|
||||
use App\Models\Setting;
|
||||
|
||||
class AssetCountForSidebar
|
||||
{
|
||||
@@ -17,6 +18,32 @@ class AssetCountForSidebar
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
/**
|
||||
* This needs to be set for the /setup process, since the tables might not exist yet
|
||||
*/
|
||||
$total_assets = 0;
|
||||
$total_due_for_checkin = 0;
|
||||
$total_overdue_for_checkin = 0;
|
||||
$total_due_for_audit = 0;
|
||||
$total_overdue_for_audit = 0;
|
||||
|
||||
try {
|
||||
$settings = Setting::getSettings();
|
||||
view()->share('settings', $settings);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
|
||||
try {
|
||||
$total_assets = Asset::count();
|
||||
if ($settings->show_archived_in_list != '1') {
|
||||
$total_assets -= Asset::Archived()->count();
|
||||
}
|
||||
view()->share('total_assets', $total_assets);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
|
||||
try {
|
||||
$total_rtd_sidebar = Asset::RTD()->count();
|
||||
view()->share('total_rtd_sidebar', $total_rtd_sidebar);
|
||||
@@ -59,6 +86,37 @@ class AssetCountForSidebar
|
||||
\Log::debug($e);
|
||||
}
|
||||
|
||||
try {
|
||||
$total_due_for_audit = Asset::DueForAudit($settings)->count();
|
||||
view()->share('total_due_for_audit', $total_due_for_audit);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
|
||||
try {
|
||||
$total_overdue_for_audit = Asset::OverdueForAudit()->count();
|
||||
view()->share('total_overdue_for_audit', $total_overdue_for_audit);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
|
||||
try {
|
||||
$total_due_for_checkin = Asset::DueForCheckin($settings)->count();
|
||||
view()->share('total_due_for_checkin', $total_due_for_checkin);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
|
||||
try {
|
||||
$total_overdue_for_checkin = Asset::OverdueForCheckin()->count();
|
||||
view()->share('total_overdue_for_checkin', $total_overdue_for_checkin);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
|
||||
view()->share('total_due_and_overdue_for_checkin', ($total_due_for_checkin + $total_overdue_for_checkin));
|
||||
view()->share('total_due_and_overdue_for_audit', ($total_due_for_audit + $total_overdue_for_audit));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ class ImageUploadRequest extends Request
|
||||
return [
|
||||
'image' => 'mimes:png,gif,jpg,jpeg,svg,bmp,svg+xml,webp,avif',
|
||||
'avatar' => 'mimes:png,gif,jpg,jpeg,svg,bmp,svg+xml,webp,avif',
|
||||
'favicon' => 'mimes:png,gif,jpg,jpeg,svg,bmp,svg+xml,webp,image/x-icon,image/vnd.microsoft.icon,ico',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -103,9 +104,9 @@ class ImageUploadRequest extends Request
|
||||
\Log::info('File name will be: '.$file_name);
|
||||
\Log::debug('File extension is: '.$ext);
|
||||
|
||||
if (($image->getMimeType() == 'image/avif') || ($image->getMimeType() == 'image/webp')) {
|
||||
// If the file is a webp or avif, we need to just move it since webp support
|
||||
// needs to be compiled into gd for resizing to be available
|
||||
if (($image->getMimeType() == 'image/vnd.microsoft.icon') || ($image->getMimeType() == 'image/x-icon') || ($image->getMimeType() == 'image/avif') || ($image->getMimeType() == 'image/webp')) {
|
||||
// If the file is an icon, webp or avif, we need to just move it since gd doesn't support resizing
|
||||
// icons or avif, and webp support and needs to be compiled into gd for resizing to be available
|
||||
Storage::disk('public')->put($path.'/'.$file_name, file_get_contents($image));
|
||||
|
||||
} elseif($image->getMimeType() == 'image/svg+xml') {
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Requests;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\Company;
|
||||
use App\Models\Setting;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\Exceptions\InvalidFormatException;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
@@ -45,12 +46,21 @@ class StoreAssetRequest extends ImageUploadRequest
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = array_merge(
|
||||
(new Asset)->getRules(),
|
||||
$modelRules = (new Asset)->getRules();
|
||||
|
||||
if (Setting::getSettings()->digit_separator === '1.234,56' && is_string($this->input('purchase_cost'))) {
|
||||
// If purchase_cost was submitted as a string with a comma separator
|
||||
// then we need to ignore the normal numeric rules.
|
||||
// Since the original rules still live on the model they will be run
|
||||
// right before saving (and after purchase_cost has been
|
||||
// converted to a float via setPurchaseCostAttribute).
|
||||
$modelRules = $this->removeNumericRulesFromPurchaseCost($modelRules);
|
||||
}
|
||||
|
||||
return array_merge(
|
||||
$modelRules,
|
||||
parent::rules(),
|
||||
);
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
private function parseLastAuditDate(): void
|
||||
@@ -69,4 +79,20 @@ class StoreAssetRequest extends ImageUploadRequest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function removeNumericRulesFromPurchaseCost(array $rules): array
|
||||
{
|
||||
$purchaseCost = $rules['purchase_cost'];
|
||||
|
||||
// If rule is in "|" format then turn it into an array
|
||||
if (is_string($purchaseCost)) {
|
||||
$purchaseCost = explode('|', $purchaseCost);
|
||||
}
|
||||
|
||||
$rules['purchase_cost'] = array_filter($purchaseCost, function ($rule) {
|
||||
return $rule !== 'numeric' && $rule !== 'gte:0';
|
||||
});
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ class UsersTransformer
|
||||
|
||||
public function transformUser(User $user)
|
||||
{
|
||||
|
||||
$array = [
|
||||
'id' => (int) $user->id,
|
||||
'avatar' => e($user->present()->gravatar),
|
||||
@@ -64,6 +65,8 @@ class UsersTransformer
|
||||
'licenses_count' => (int) $user->licenses_count,
|
||||
'accessories_count' => (int) $user->accessories_count,
|
||||
'consumables_count' => (int) $user->consumables_count,
|
||||
'manages_users_count' => (int) $user->manages_users_count,
|
||||
'manages_locations_count' => (int) $user->manages_locations_count,
|
||||
'company' => ($user->company) ? ['id' => (int) $user->company->id, 'name'=> e($user->company->name)] : null,
|
||||
'created_by' => ($user->createdBy) ? [
|
||||
'id' => (int) $user->createdBy->id,
|
||||
|
||||
+64
-8
@@ -74,9 +74,9 @@ class Asset extends Depreciable
|
||||
'eol_explicit' => 'boolean',
|
||||
'last_checkout' => 'datetime',
|
||||
'last_checkin' => 'datetime',
|
||||
'expected_checkin' => 'date',
|
||||
'expected_checkin' => 'datetime:m-d-Y',
|
||||
'last_audit_date' => 'datetime',
|
||||
'next_audit_date' => 'date',
|
||||
'next_audit_date' => 'datetime:m-d-Y',
|
||||
'model_id' => 'integer',
|
||||
'status_id' => 'integer',
|
||||
'company_id' => 'integer',
|
||||
@@ -1163,10 +1163,11 @@ class Asset extends Depreciable
|
||||
public function scopeDueForAudit($query, $settings)
|
||||
{
|
||||
$interval = $settings->audit_warning_days ?? 0;
|
||||
$today = Carbon::now();
|
||||
$interval_date = $today->copy()->addDays($interval)->format('Y-m-d');
|
||||
|
||||
return $query->whereNotNull('assets.next_audit_date')
|
||||
->where('assets.next_audit_date', '>=', Carbon::now())
|
||||
->whereRaw("DATE_SUB(assets.next_audit_date, INTERVAL $interval DAY) <= '".Carbon::now()."'")
|
||||
->whereBetween('assets.next_audit_date', [$today->format('Y-m-d'), $interval_date])
|
||||
->where('assets.archived', '=', 0)
|
||||
->NotArchived();
|
||||
}
|
||||
@@ -1188,7 +1189,7 @@ class Asset extends Depreciable
|
||||
public function scopeOverdueForAudit($query)
|
||||
{
|
||||
return $query->whereNotNull('assets.next_audit_date')
|
||||
->where('assets.next_audit_date', '<', Carbon::now())
|
||||
->where('assets.next_audit_date', '<', Carbon::now()->format('Y-m-d'))
|
||||
->where('assets.archived', '=', 0)
|
||||
->NotArchived();
|
||||
}
|
||||
@@ -1209,14 +1210,69 @@ class Asset extends Depreciable
|
||||
|
||||
public function scopeDueOrOverdueForAudit($query, $settings)
|
||||
{
|
||||
$interval = $settings->audit_warning_days ?? 0;
|
||||
|
||||
return $query->whereNotNull('assets.next_audit_date')
|
||||
->whereRaw('DATE_SUB('.DB::getTablePrefix()."assets.next_audit_date, INTERVAL $interval DAY) <= '".Carbon::now()."'")
|
||||
return $query->where(function ($query) {
|
||||
$query->OverdueForAudit();
|
||||
})->orWhere(function ($query) use ($settings) {
|
||||
$query->DueForAudit($settings);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Query builder scope for Assets that are DUE for checkin, based on the assets.expected_checkin
|
||||
* and settings.audit_warning_days. It checks to see if assets.expected_checkin is now
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @since v6.4.0
|
||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||
*/
|
||||
|
||||
public function scopeDueForCheckin($query, $settings)
|
||||
{
|
||||
$interval = $settings->audit_warning_days ?? 0;
|
||||
$today = Carbon::now();
|
||||
$interval_date = $today->copy()->addDays($interval)->format('Y-m-d');
|
||||
|
||||
return $query->whereNotNull('assets.expected_checkin')
|
||||
->whereBetween('assets.expected_checkin', [$today->format('Y-m-d'), $interval_date])
|
||||
->where('assets.archived', '=', 0)
|
||||
->whereNotNull('assets.assigned_to')
|
||||
->NotArchived();
|
||||
}
|
||||
|
||||
/**
|
||||
* Query builder scope for Assets that are overdue for checkin OR overdue
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @since v6.4.0
|
||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||
*/
|
||||
public function scopeOverdueForCheckin($query)
|
||||
{
|
||||
return $query->whereNotNull('assets.expected_checkin')
|
||||
->where('assets.expected_checkin', '<', Carbon::now()->format('Y-m-d'))
|
||||
->where('assets.archived', '=', 0)
|
||||
->whereNotNull('assets.assigned_to')
|
||||
->NotArchived();
|
||||
}
|
||||
|
||||
/**
|
||||
* Query builder scope for Assets that are due for checkin OR overdue
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @since v6.4.0
|
||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||
*/
|
||||
public function scopeDueOrOverdueForCheckin($query, $settings)
|
||||
{
|
||||
return $query->where(function ($query) {
|
||||
$query->OverdueForCheckin();
|
||||
})->orWhere(function ($query) use ($settings) {
|
||||
$query->DueForCheckin($settings);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Query builder scope for Archived assets counting
|
||||
|
||||
+134
-64
@@ -81,26 +81,6 @@ final class Company extends SnipeModel
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scoping table queries, determining if a logged in user is part of a company, and only allows
|
||||
* that user to see items associated with that company
|
||||
*/
|
||||
private static function scopeCompanyablesDirectly($query, $column = 'company_id', $table_name = null)
|
||||
{
|
||||
if (Auth::user()) {
|
||||
$company_id = Auth::user()->company_id;
|
||||
} else {
|
||||
$company_id = null;
|
||||
}
|
||||
|
||||
$table = ($table_name) ? $table_name."." : $query->getModel()->getTable().".";
|
||||
|
||||
if (\Schema::hasColumn($query->getModel()->getTable(), $column)) {
|
||||
return $query->where($table.$column, '=', $company_id);
|
||||
} else {
|
||||
return $query->join('users as users_comp', 'users_comp.id', 'user_id')->where('users_comp.company_id', '=', $company_id);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getIdFromInput($unescaped_input)
|
||||
{
|
||||
@@ -141,25 +121,49 @@ final class Company extends SnipeModel
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the current user should have access to the model.
|
||||
* I hate this method and I think it should be refactored.
|
||||
*
|
||||
* @param $companyable
|
||||
* @return bool|void
|
||||
*/
|
||||
public static function isCurrentUserHasAccess($companyable)
|
||||
{
|
||||
// When would this even happen tho??
|
||||
if (is_null($companyable)) {
|
||||
return false;
|
||||
} elseif (! static::isFullMultipleCompanySupportEnabled()) {
|
||||
return true;
|
||||
} elseif (!$companyable instanceof Company && !\Schema::hasColumn($companyable->getModel()->getTable(), 'company_id')) {
|
||||
// This is primary for the gate:allows-check in location->isDeletable()
|
||||
// Locations don't have a company_id so without this it isn't possible to delete locations with FullMultipleCompanySupport enabled
|
||||
// because this function is called by SnipePermissionsPolicy->before()
|
||||
return true;
|
||||
} else {
|
||||
if (Auth::user()) {
|
||||
$current_user_company_id = Auth::user()->company_id;
|
||||
$companyable_company_id = $companyable->company_id;
|
||||
}
|
||||
|
||||
return $current_user_company_id == null || $current_user_company_id == $companyable_company_id || Auth::user()->isSuperUser();
|
||||
// If FMCS is not enabled, everyone has access, return true
|
||||
if (! static::isFullMultipleCompanySupportEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Again, where would this happen? But check that $companyable is not a string
|
||||
if (!is_string($companyable)) {
|
||||
$company_table = $companyable->getModel()->getTable();
|
||||
try {
|
||||
// This is primary for the gate:allows-check in location->isDeletable()
|
||||
// Locations don't have a company_id so without this it isn't possible to delete locations with FullMultipleCompanySupport enabled
|
||||
// because this function is called by SnipePermissionsPolicy->before()
|
||||
if (!$companyable instanceof Company && !\Schema::hasColumn($company_table, 'company_id')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::warning($e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Auth::user()) {
|
||||
\Log::warning('Companyable is '.$companyable);
|
||||
$current_user_company_id = Auth::user()->company_id;
|
||||
$companyable_company_id = $companyable->company_id;
|
||||
return $current_user_company_id == null || $current_user_company_id == $companyable_company_id || Auth::user()->isSuperUser();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function isCurrentUserAuthorized()
|
||||
@@ -190,6 +194,10 @@ final class Company extends SnipeModel
|
||||
&& ($this->users()->count() === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $unescaped_input
|
||||
* @return int|mixed|string|null
|
||||
*/
|
||||
public static function getIdForUser($unescaped_input)
|
||||
{
|
||||
if (! static::isFullMultipleCompanySupportEnabled() || Auth::user()->isSuperUser()) {
|
||||
@@ -199,38 +207,6 @@ final class Company extends SnipeModel
|
||||
}
|
||||
}
|
||||
|
||||
public static function scopeCompanyables($query, $column = 'company_id', $table_name = null)
|
||||
{
|
||||
// If not logged in and hitting this, assume we are on the command line and don't scope?'
|
||||
if (! static::isFullMultipleCompanySupportEnabled() || (Auth::check() && Auth::user()->isSuperUser()) || (! Auth::check())) {
|
||||
return $query;
|
||||
} else {
|
||||
return static::scopeCompanyablesDirectly($query, $column, $table_name);
|
||||
}
|
||||
}
|
||||
|
||||
public static function scopeCompanyableChildren(array $companyable_names, $query)
|
||||
{
|
||||
if (count($companyable_names) == 0) {
|
||||
throw new Exception('No Companyable Children to scope');
|
||||
} elseif (! static::isFullMultipleCompanySupportEnabled() || (Auth::check() && Auth::user()->isSuperUser())) {
|
||||
return $query;
|
||||
} else {
|
||||
$f = function ($q) {
|
||||
static::scopeCompanyablesDirectly($q);
|
||||
};
|
||||
|
||||
$q = $query->where(function ($q) use ($companyable_names, $f) {
|
||||
$q2 = $q->whereHas($companyable_names[0], $f);
|
||||
|
||||
for ($i = 1; $i < count($companyable_names); $i++) {
|
||||
$q2 = $q2->orWhereHas($companyable_names[$i], $f);
|
||||
}
|
||||
});
|
||||
|
||||
return $q;
|
||||
}
|
||||
}
|
||||
|
||||
public function users()
|
||||
{
|
||||
@@ -261,4 +237,98 @@ final class Company extends SnipeModel
|
||||
{
|
||||
return $this->hasMany(Component::class, 'company_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* START COMPANY SCOPING FOR FMCS
|
||||
*/
|
||||
|
||||
/**
|
||||
* Scoping table queries, determining if a logged in user is part of a company, and only allows the user to access items associated with that company if FMCS is enabled.
|
||||
*
|
||||
* This method is the one that the CompanyableTrait uses to contrain queries automatically, however that trait CANNOT be
|
||||
* applied to the user's model, since it causes an infinite loop against the authenticated user.
|
||||
*
|
||||
* @todo - refactor that trait to handle the user's model as well.
|
||||
*
|
||||
* @author [A. Gianotto] <snipe@snipe.net>
|
||||
* @param $query
|
||||
* @param $column
|
||||
* @param $table_name
|
||||
* @return mixed
|
||||
*/
|
||||
public static function scopeCompanyables($query, $column = 'company_id', $table_name = null)
|
||||
{
|
||||
// If not logged in and hitting this, assume we are on the command line and don't scope?'
|
||||
if (! static::isFullMultipleCompanySupportEnabled() || (Auth::check() && Auth::user()->isSuperUser()) || (! Auth::check())) {
|
||||
return $query;
|
||||
} else {
|
||||
\Log::debug('Fire scopeCompanyablesDirectly.');
|
||||
return static::scopeCompanyablesDirectly($query, $column, $table_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scoping table queries, determining if a logged in user is part of a company, and only allows
|
||||
* that user to see items associated with that company
|
||||
*/
|
||||
private static function scopeCompanyablesDirectly($query, $column = 'company_id', $table_name = null)
|
||||
{
|
||||
// Get the company ID of the logged in user, or set it to null if there is no company assicoated with the user
|
||||
if (Auth::user()) {
|
||||
\Log::debug('Admin company is: '.Auth::user()->company_id);
|
||||
$company_id = Auth::user()->company_id;
|
||||
} else {
|
||||
$company_id = null;
|
||||
}
|
||||
|
||||
// Dynamically get the table name if it's not passed in, based on the model we're querying against
|
||||
$table = ($table_name) ? $table_name."." : $query->getModel()->getTable().".";
|
||||
\Log::debug('Model is: '.$query->getModel());
|
||||
|
||||
\Log::debug('Table is: '.$table);
|
||||
|
||||
// If the column exists in the table, use it to scope the query
|
||||
if (\Schema::hasColumn($query->getModel()->getTable(), $column)) {
|
||||
return $query->where($table.$column, '=', $company_id);
|
||||
} else {
|
||||
return $query->join('users as users_comp', 'users_comp.id', 'user_id')->where('users_comp.company_id', '=', $company_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* I legit do not know what this method does, but we can't remove it (yet).
|
||||
*
|
||||
* This gets invoked by CompanyableChildScope, but I'm not sure what it does.
|
||||
*
|
||||
* @author [A. Gianotto] <snipe@snipe.net>
|
||||
* @param array $companyable_names
|
||||
* @param $query
|
||||
* @return mixed
|
||||
*/
|
||||
public static function scopeCompanyableChildren(array $companyable_names, $query)
|
||||
{
|
||||
\Log::debug('Company Names in scopeCompanyableChildren: '.print_r($companyable_names, true));
|
||||
|
||||
if (count($companyable_names) == 0) {
|
||||
throw new Exception('No Companyable Children to scope');
|
||||
} elseif (! static::isFullMultipleCompanySupportEnabled() || (Auth::check() && Auth::user()->isSuperUser())) {
|
||||
return $query;
|
||||
} else {
|
||||
$f = function ($q) {
|
||||
\Log::debug('scopeCompanyablesDirectly firing ');
|
||||
static::scopeCompanyablesDirectly($q);
|
||||
};
|
||||
|
||||
$q = $query->where(function ($q) use ($companyable_names, $f) {
|
||||
$q2 = $q->whereHas($companyable_names[0], $f);
|
||||
|
||||
for ($i = 1; $i < count($companyable_names); $i++) {
|
||||
$q2 = $q2->orWhereHas($companyable_names[$i], $f);
|
||||
}
|
||||
});
|
||||
|
||||
return $q;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,13 @@ namespace App\Models;
|
||||
trait CompanyableTrait
|
||||
{
|
||||
/**
|
||||
* Boot the companyable trait for a model.
|
||||
* This trait is used to scope models to the current company. To use this scope on companyable models,
|
||||
* we use the "use Companyable;" statement at the top of the mode.
|
||||
*
|
||||
* We CANNOT USE THIS ON USERS, as it causes an infinite loop and prevents users from logging in, since this scope will be
|
||||
* applied to the currently logged in (or logging in) user in addition to the user model for viewing lists of users.
|
||||
*
|
||||
* @see \App\Models\Company\Company::scopeCompanyables()
|
||||
* @return void
|
||||
*/
|
||||
public static function bootCompanyableTrait()
|
||||
|
||||
@@ -18,8 +18,14 @@ class FieldOption {
|
||||
// assignedTo directly on the asset is a special case where
|
||||
// we want to avoid returning the property directly
|
||||
// and instead return the entity's presented name.
|
||||
if ($dataPath[0] === 'assignedTo'){
|
||||
return $asset->assignedTo ? $asset->assignedTo->present()->fullName() : null;
|
||||
if ($dataPath[0] === 'assignedTo') {
|
||||
if ($asset->relationLoaded('assignedTo')) {
|
||||
// If the "assignedTo" relationship was eager loaded then the way to get the
|
||||
// relationship changes from $asset->assignedTo to $asset->assigned.
|
||||
return $asset->assigned ? $asset->assigned->present()->fullName() : null;
|
||||
}
|
||||
|
||||
return $asset->assignedTo ? $asset->assignedTo->present()->fullName() : null;
|
||||
}
|
||||
|
||||
return $dataPath->reduce(function ($myValue, $path) {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Labels\Tapes\Brother;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Labels\Label;
|
||||
|
||||
abstract class TZe_18mm extends Label
|
||||
{
|
||||
private const HEIGHT = 18.00;
|
||||
private const MARGIN_SIDES = 3.20;
|
||||
private const MARGIN_ENDS = 3.20;
|
||||
|
||||
public function getHeight() { return Helper::convertUnit(self::HEIGHT, 'mm', $this->getUnit()); }
|
||||
public function getMarginTop() { return Helper::convertUnit(self::MARGIN_SIDES, 'mm', $this->getUnit()); }
|
||||
public function getMarginBottom() { return Helper::convertUnit(self::MARGIN_SIDES, 'mm', $this->getUnit());}
|
||||
public function getMarginLeft() { return Helper::convertUnit(self::MARGIN_ENDS, 'mm', $this->getUnit()); }
|
||||
public function getMarginRight() { return Helper::convertUnit(self::MARGIN_ENDS, 'mm', $this->getUnit()); }
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Labels\Tapes\Brother;
|
||||
|
||||
class TZe_18mm_A extends TZe_18mm
|
||||
{
|
||||
private const BARCODE_SIZE = 3.20;
|
||||
private const BARCODE_MARGIN = 0.30;
|
||||
private const TEXT_SIZE_MOD = 1.00;
|
||||
|
||||
public function getUnit() { return 'mm'; }
|
||||
public function getWidth() { return 50.0; }
|
||||
public function getSupportAssetTag() { return true; }
|
||||
public function getSupport1DBarcode() { return true; }
|
||||
public function getSupport2DBarcode() { return false; }
|
||||
public function getSupportFields() { return 1; }
|
||||
public function getSupportLogo() { return false; }
|
||||
public function getSupportTitle() { return false; }
|
||||
|
||||
public function preparePDF($pdf) {}
|
||||
|
||||
public function write($pdf, $record) {
|
||||
$pa = $this->getPrintableArea();
|
||||
|
||||
if ($record->has('barcode1d')) {
|
||||
static::write1DBarcode(
|
||||
$pdf, $record->get('barcode1d')->content, $record->get('barcode1d')->type,
|
||||
$pa->x1, $pa->y1, $pa->w, self::BARCODE_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
$currentY = $pa->y1 + self::BARCODE_SIZE + self::BARCODE_MARGIN;
|
||||
$usableHeight = $pa->h - self::BARCODE_SIZE - self::BARCODE_MARGIN;
|
||||
$fontSize = $usableHeight + self::TEXT_SIZE_MOD;
|
||||
|
||||
$tagWidth = $pa->w / 3;
|
||||
$fieldWidth = $pa->w / 3 * 2;
|
||||
|
||||
static::writeText(
|
||||
$pdf, $record->get('tag'),
|
||||
$pa->x1, $currentY,
|
||||
'freemono', 'b', $fontSize, 'L',
|
||||
$tagWidth, $usableHeight, true, 0, 0
|
||||
);
|
||||
|
||||
if ($record->get('fields')->count() >= 1) {
|
||||
static::writeText(
|
||||
$pdf, $record->get('fields')->values()->get(0)['value'],
|
||||
$pa->x1 + ($tagWidth), $currentY,
|
||||
'freemono', 'b', $fontSize, 'R',
|
||||
$fieldWidth, $usableHeight, true, 0, 0
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+20
-2
@@ -81,6 +81,7 @@ class License extends Depreciable
|
||||
'serial',
|
||||
'supplier_id',
|
||||
'termination_date',
|
||||
'free_seat_count',
|
||||
'user_id',
|
||||
'min_amt',
|
||||
];
|
||||
@@ -114,6 +115,7 @@ class License extends Depreciable
|
||||
'category' => ['name'],
|
||||
'depreciation' => ['name'],
|
||||
];
|
||||
protected $appends = ['free_seat_count'];
|
||||
|
||||
/**
|
||||
* Update seat counts when the license is updated
|
||||
@@ -280,6 +282,16 @@ class License extends Depreciable
|
||||
}
|
||||
$this->attributes['termination_date'] = $value;
|
||||
}
|
||||
/**
|
||||
* Sets free_seat_count attribute
|
||||
*
|
||||
* @author G. Martinez
|
||||
* @since [v6.3]
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFreeSeatCountAttribute(){
|
||||
return $this->attributes['free_seat_count'] = $this->remaincount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the license -> company relationship
|
||||
@@ -502,7 +514,13 @@ class License extends Depreciable
|
||||
->whereNull('deleted_at')
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the available seats remaining
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @since [v2.0]
|
||||
* @return int
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the number of total available seats for this license
|
||||
@@ -579,7 +597,7 @@ class License extends Depreciable
|
||||
$taken = $this->assigned_seats_count;
|
||||
$diff = ($total - $taken);
|
||||
|
||||
return $diff;
|
||||
return (int) $diff;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+19
-4
@@ -214,10 +214,12 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
public function isDeletable()
|
||||
{
|
||||
return Gate::allows('delete', $this)
|
||||
&& ($this->assets()->count() === 0)
|
||||
&& ($this->licenses()->count() === 0)
|
||||
&& ($this->consumables()->count() === 0)
|
||||
&& ($this->accessories()->count() === 0)
|
||||
&& ($this->assets->count() === 0)
|
||||
&& ($this->licenses->count() === 0)
|
||||
&& ($this->consumables->count() === 0)
|
||||
&& ($this->accessories->count() === 0)
|
||||
&& ($this->managedLocations->count() === 0)
|
||||
&& ($this->managesUsers->count() === 0)
|
||||
&& ($this->deleted_at == '');
|
||||
}
|
||||
|
||||
@@ -410,6 +412,19 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
return $this->belongsTo(self::class, 'manager_id')->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the user -> managed users relationship
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @since [v6.4.1]
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function managesUsers()
|
||||
{
|
||||
return $this->hasMany(\App\Models\User::class, 'manager_id');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Establishes the user -> managed locations relationship
|
||||
*
|
||||
|
||||
@@ -35,16 +35,50 @@ abstract class SnipePermissionsPolicy
|
||||
|
||||
public function before(User $user, $ability, $item)
|
||||
{
|
||||
// Lets move all company related checks here.
|
||||
if ($item instanceof \App\Models\SnipeModel && ! Company::isCurrentUserHasAccess($item)) {
|
||||
return false;
|
||||
}
|
||||
// If an admin, they can do all asset related tasks.
|
||||
/**
|
||||
* If an admin, they can do all item related tasks, but ARE constrained by FMCSA company access.
|
||||
* That scoping happens on the model level (except for the Users model) via the Companyable trait.
|
||||
*
|
||||
* This does lead to some inconsistencies in the responses, since attempting to edit assets,
|
||||
* accessories, etc (anything other than users) will result in a Forbidden error, whereas the users
|
||||
* area will redirect with "That user doesn't exist" since the scoping is handled directly on those queries.
|
||||
*
|
||||
* The *superuser* global permission gets handled in the AuthServiceProvider before() method.
|
||||
*
|
||||
* @see https://snipe-it.readme.io/docs/permissions
|
||||
*/
|
||||
|
||||
if ($user->hasAccess('admin')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we got here by $this→authorize('something', $actualModel) then we can continue on Il but if we got here
|
||||
* via $this→authorize('something', Model::class) then calling Company:: isCurrentUserHasAccess($item) gets weird.
|
||||
* Bail out here by returning "nothing" and allow the relevant method lower in this class to be called and handle authorization.
|
||||
*/
|
||||
if (!$item instanceof Model){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The Company::isCurrentUserHasAccess() method from the company model handles the check for FMCS already so we
|
||||
* don't have to do that here.
|
||||
*/
|
||||
if (!Company::isCurrentUserHasAccess($item)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* These methods handle the generic view/create/edit/delete permissions for the model.
|
||||
*
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
public function index(User $user)
|
||||
{
|
||||
return $user->hasAccess($this->columnName().'.view');
|
||||
|
||||
@@ -221,7 +221,7 @@ class UserPresenter extends Presenter
|
||||
'switchable' => true,
|
||||
'escape' => true,
|
||||
'class' => 'css-barcode',
|
||||
'title' => 'Assets',
|
||||
'title' => trans('general.assets'),
|
||||
'visible' => true,
|
||||
],
|
||||
[
|
||||
@@ -230,7 +230,7 @@ class UserPresenter extends Presenter
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'class' => 'css-license',
|
||||
'title' => 'License',
|
||||
'title' => trans('general.licenses'),
|
||||
'visible' => true,
|
||||
],
|
||||
[
|
||||
@@ -239,7 +239,7 @@ class UserPresenter extends Presenter
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'class' => 'css-consumable',
|
||||
'title' => 'Consumables',
|
||||
'title' => trans('general.consumables'),
|
||||
'visible' => true,
|
||||
],
|
||||
[
|
||||
@@ -248,7 +248,25 @@ class UserPresenter extends Presenter
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'class' => 'css-accessory',
|
||||
'title' => 'Accessories',
|
||||
'title' => trans('general.accessories'),
|
||||
'visible' => true,
|
||||
],
|
||||
[
|
||||
'field' => 'manages_users_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'class' => 'css-users',
|
||||
'title' => trans('admin/users/table.managed_users'),
|
||||
'visible' => true,
|
||||
],
|
||||
[
|
||||
'field' => 'manages_locations_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'class' => 'css-location',
|
||||
'title' => trans('admin/users/table.managed_locations'),
|
||||
'visible' => true,
|
||||
],
|
||||
[
|
||||
|
||||
@@ -93,21 +93,28 @@ class AuthServiceProvider extends ServiceProvider
|
||||
Passport::personalAccessTokensExpireIn(Carbon::now()->addYears(config('passport.expiration_years')));
|
||||
Passport::withCookieSerialization();
|
||||
|
||||
// --------------------------------
|
||||
// BEFORE ANYTHING ELSE
|
||||
// --------------------------------
|
||||
// If this condition is true, ANYTHING else below will be assumed
|
||||
// to be true. This can cause weird blade behavior.
|
||||
|
||||
/**
|
||||
* BEFORE ANYTHING ELSE
|
||||
*
|
||||
* If this condition is true, ANYTHING else below will be assumed to be true.
|
||||
* This is where we set the superadmin permission to allow superadmins to be able to do everything within the system.
|
||||
*
|
||||
*/
|
||||
Gate::before(function ($user) {
|
||||
if ($user->isSuperUser()) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// --------------------------------
|
||||
// GENERAL GATES
|
||||
// These control general sections of the admin
|
||||
// --------------------------------
|
||||
|
||||
/**
|
||||
* GENERAL GATES
|
||||
*
|
||||
* These control general sections of the admin. These definitions are used in our blades via @can('blah) and also
|
||||
* use in our controllers to determine if a user has access to a certain area.
|
||||
*/
|
||||
|
||||
Gate::define('admin', function ($user) {
|
||||
if ($user->hasAccess('admin')) {
|
||||
return true;
|
||||
|
||||
@@ -279,7 +279,24 @@ class ValidationServiceProvider extends ServiceProvider
|
||||
|
||||
Validator::extend('is_unique_department', function ($attribute, $value, $parameters, $validator) {
|
||||
$data = $validator->getData();
|
||||
if ((array_key_exists('location_id', $data) && $data['location_id'] != null) && (array_key_exists('company_id', $data) && $data['company_id'] != null)) {
|
||||
|
||||
if (
|
||||
array_key_exists('location_id', $data) && $data['location_id'] !== null &&
|
||||
array_key_exists('company_id', $data) && $data['company_id'] !== null
|
||||
) {
|
||||
//for updating existing departments
|
||||
if(array_key_exists('id', $data) && $data['id'] !== null){
|
||||
$count = Department::where('name', $data['name'])
|
||||
->where('location_id', $data['location_id'])
|
||||
->where('company_id', $data['company_id'])
|
||||
->whereNotNull('company_id')
|
||||
->whereNotNull('location_id')
|
||||
->where('id', '!=', $data['id'])
|
||||
->count('name');
|
||||
|
||||
return $count < 1;
|
||||
}else // for entering in new departments
|
||||
{
|
||||
$count = Department::where('name', $data['name'])
|
||||
->where('location_id', $data['location_id'])
|
||||
->where('company_id', $data['company_id'])
|
||||
@@ -289,9 +306,10 @@ class ValidationServiceProvider extends ServiceProvider
|
||||
|
||||
return $count < 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Validator::extend('not_array', function ($attribute, $value, $parameters, $validator) {
|
||||
|
||||
+26
-1
@@ -142,7 +142,32 @@ class Label implements View
|
||||
// Remove Duplicates
|
||||
$toAdd = $field
|
||||
->filter(fn($o) => !$myFields->contains('dataSource', $o['dataSource']))
|
||||
->first();
|
||||
// For fields that have multiple options, we need to combine them
|
||||
// into a single field so all values are displayed.
|
||||
->reduce(function ($previous, $current) {
|
||||
// On the first iteration we simply return the item.
|
||||
// If there is only one item to be processed for the row
|
||||
// then this effectively skips everything below this if block.
|
||||
if (is_null($previous)) {
|
||||
return $current;
|
||||
}
|
||||
|
||||
// At this point we are dealing with a row with multiple items being displayed.
|
||||
// We need to combine the label and value of the current item with the previous item.
|
||||
|
||||
// The end result of this will be in this format:
|
||||
// {labelOne} {valueOne} | {labelTwo} {valueTwo} | {labelThree} {valueThree}
|
||||
$previous['value'] = trim(implode(' | ', [
|
||||
implode(' ', [$previous['label'], $previous['value']]),
|
||||
implode(' ', [$current['label'], $current['value']]),
|
||||
]));
|
||||
|
||||
// We'll set the label to an empty string since we
|
||||
// injected the label into the value field above.
|
||||
$previous['label'] = '';
|
||||
|
||||
return $previous;
|
||||
});
|
||||
|
||||
return $toAdd ? $myFields->push($toAdd) : $myFields;
|
||||
}, new Collection());
|
||||
|
||||
Generated
+8
-8
@@ -10983,20 +10983,20 @@
|
||||
},
|
||||
{
|
||||
"name": "tecnickcom/tcpdf",
|
||||
"version": "6.6.2",
|
||||
"version": "6.7.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tecnickcom/TCPDF.git",
|
||||
"reference": "e3cffc9bcbc76e89e167e9eb0bbda0cab7518459"
|
||||
"reference": "951eabf0338ec2522bd0d5d9c79b08a3a3d36b36"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/e3cffc9bcbc76e89e167e9eb0bbda0cab7518459",
|
||||
"reference": "e3cffc9bcbc76e89e167e9eb0bbda0cab7518459",
|
||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/951eabf0338ec2522bd0d5d9c79b08a3a3d36b36",
|
||||
"reference": "951eabf0338ec2522bd0d5d9c79b08a3a3d36b36",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -11021,7 +11021,7 @@
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-3.0-only"
|
||||
"LGPL-3.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
@@ -11043,7 +11043,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/tecnickcom/TCPDF/issues",
|
||||
"source": "https://github.com/tecnickcom/TCPDF/tree/6.6.2"
|
||||
"source": "https://github.com/tecnickcom/TCPDF/tree/6.7.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -11051,7 +11051,7 @@
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-17T10:28:59+00:00"
|
||||
"time": "2024-04-20T17:25:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "tijsverkoyen/css-to-inline-styles",
|
||||
|
||||
@@ -96,6 +96,7 @@ return [
|
||||
PDO::MYSQL_ATTR_SSL_CERT => env('DB_SSL_CERT_PATH'), // /path/to/cert.pem
|
||||
PDO::MYSQL_ATTR_SSL_CA => env('DB_SSL_CA_PATH'), // /path/to/ca.pem
|
||||
PDO::MYSQL_ATTR_SSL_CIPHER => env('DB_SSL_CIPHER'),
|
||||
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => env('DB_SSL_VERIFY_SERVER'), //true/false
|
||||
]) : [],
|
||||
],
|
||||
|
||||
|
||||
+5
-5
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
return array (
|
||||
'app_version' => 'v6.3.4',
|
||||
'full_app_version' => 'v6.3.4 - build 13139-g6f9ba6ede',
|
||||
'build_version' => '13139',
|
||||
'app_version' => 'v6.4.1',
|
||||
'full_app_version' => 'v6.4.1 - build 13386-g4642f50d6b',
|
||||
'build_version' => '13386',
|
||||
'prerelease_version' => '',
|
||||
'hash_version' => 'g6f9ba6ede',
|
||||
'full_hash' => 'v6.3.4-234-g6f9ba6ede',
|
||||
'hash_version' => 'g4642f50d6b',
|
||||
'full_hash' => 'v6.4.1-31-g4642f50d6b',
|
||||
'branch' => 'master',
|
||||
);
|
||||
@@ -4,6 +4,7 @@ namespace Database\Factories;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Location;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\Supplier;
|
||||
@@ -353,6 +354,16 @@ class AssetFactory extends Factory
|
||||
return $this->state(['requestable' => false]);
|
||||
}
|
||||
|
||||
public function hasEncryptedCustomField(CustomField $field = null)
|
||||
{
|
||||
return $this->state(function () use ($field) {
|
||||
return [
|
||||
'model_id' => AssetModel::factory()->hasEncryptedCustomField($field),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This allows bypassing model level validation if you want to purposefully
|
||||
* create an asset in an invalid state. Validation is turned back on
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\CustomFieldset;
|
||||
use App\Models\Depreciation;
|
||||
use App\Models\Manufacturer;
|
||||
@@ -429,4 +430,13 @@ class AssetModelFactory extends Factory
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
public function hasEncryptedCustomField(CustomField $field = null)
|
||||
{
|
||||
return $this->state(function () use ($field) {
|
||||
return [
|
||||
'fieldset_id' => CustomFieldset::factory()->hasEncryptedCustomField($field),
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\CustomFieldset;
|
||||
use App\Models\CustomField;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class CustomFieldsetFactory extends Factory
|
||||
@@ -43,4 +44,13 @@ class CustomFieldsetFactory extends Factory
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
public function hasEncryptedCustomField(CustomField $field = null)
|
||||
{
|
||||
return $this->afterCreating(function (CustomFieldset $fieldset) use ($field) {
|
||||
$field = $field ?? CustomField::factory()->testEncrypted()->create();
|
||||
|
||||
$fieldset->fields()->attach($field, ['order' => '1', 'required' => false]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+489
-183
@@ -1329,9 +1329,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@fortawesome/fontawesome-free": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.1.tgz",
|
||||
"integrity": "sha512-CNy5vSwN3fsUStPRLX7fUYojyuzoEMSXPl7zSLJ8TgtRfjv24LOnOWKT2zYwaHZCJGkdyRnTmstR0P+Ah503Gw=="
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.2.tgz",
|
||||
"integrity": "sha512-hRILoInAx8GNT5IMkrtIt9blOdrqHOnPBH+k70aWUAqPZPgopb9G5EQJFpaBx/S8zp2fC+mPW349Bziuk1o28Q=="
|
||||
},
|
||||
"@jridgewell/gen-mapping": {
|
||||
"version": "0.1.1",
|
||||
@@ -1460,9 +1460,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz",
|
||||
"integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig=="
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1752,9 +1752,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/raf": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.0.tgz",
|
||||
"integrity": "sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==",
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.3.tgz",
|
||||
"integrity": "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==",
|
||||
"optional": true
|
||||
},
|
||||
"@types/range-parser": {
|
||||
@@ -2424,12 +2424,48 @@
|
||||
}
|
||||
},
|
||||
"array-buffer-byte-length": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
|
||||
"integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
|
||||
"integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"is-array-buffer": "^3.0.1"
|
||||
"call-bind": "^1.0.5",
|
||||
"is-array-buffer": "^3.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"call-bind": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"set-function-length": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"array-filter": {
|
||||
@@ -3781,9 +3817,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "3.32.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.0.tgz",
|
||||
"integrity": "sha512-rd4rYZNlF3WuoYuRIDEmbR/ga9CeuWX9U05umAvgrrZoHY4Z++cp/xwPQMvUpBB4Ag6J8KfD80G0zwCyaSxDww==",
|
||||
"version": "3.37.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.0.tgz",
|
||||
"integrity": "sha512-fu5vHevQ8ZG4og+LXug8ulUtVxjOcEYvifJr7L5Bfq9GOztVqsKd9/59hUk2ZSbCrS3BqUr3EpaYGIYzq7g3Ug==",
|
||||
"optional": true
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
@@ -4373,9 +4409,9 @@
|
||||
}
|
||||
},
|
||||
"crypto-js": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
|
||||
"integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
|
||||
},
|
||||
"css-declaration-sorter": {
|
||||
"version": "6.3.0",
|
||||
@@ -4607,14 +4643,14 @@
|
||||
}
|
||||
},
|
||||
"deep-equal": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz",
|
||||
"integrity": "sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz",
|
||||
"integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==",
|
||||
"requires": {
|
||||
"array-buffer-byte-length": "^1.0.0",
|
||||
"call-bind": "^1.0.2",
|
||||
"call-bind": "^1.0.5",
|
||||
"es-get-iterator": "^1.1.3",
|
||||
"get-intrinsic": "^1.2.1",
|
||||
"get-intrinsic": "^1.2.2",
|
||||
"is-arguments": "^1.1.1",
|
||||
"is-array-buffer": "^3.0.2",
|
||||
"is-date-object": "^1.0.5",
|
||||
@@ -4624,36 +4660,58 @@
|
||||
"object-is": "^1.1.5",
|
||||
"object-keys": "^1.1.1",
|
||||
"object.assign": "^4.1.4",
|
||||
"regexp.prototype.flags": "^1.5.0",
|
||||
"regexp.prototype.flags": "^1.5.1",
|
||||
"side-channel": "^1.0.4",
|
||||
"which-boxed-primitive": "^1.0.2",
|
||||
"which-collection": "^1.0.1",
|
||||
"which-typed-array": "^1.1.9"
|
||||
"which-typed-array": "^1.1.13"
|
||||
},
|
||||
"dependencies": {
|
||||
"available-typed-arrays": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
|
||||
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
|
||||
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
|
||||
"requires": {
|
||||
"possible-typed-array-names": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"call-bind": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"set-function-length": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
|
||||
"integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
|
||||
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
|
||||
"requires": {
|
||||
"define-data-property": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.0",
|
||||
"object-keys": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
|
||||
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3"
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
@@ -4693,26 +4751,26 @@
|
||||
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
|
||||
},
|
||||
"object.assign": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
|
||||
"integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
|
||||
"integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.4",
|
||||
"call-bind": "^1.0.5",
|
||||
"define-properties": "^1.2.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"object-keys": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"which-typed-array": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
|
||||
"integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
|
||||
"version": "1.1.15",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
|
||||
"integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
|
||||
"requires": {
|
||||
"available-typed-arrays": "^1.0.5",
|
||||
"call-bind": "^1.0.2",
|
||||
"available-typed-arrays": "^1.0.7",
|
||||
"call-bind": "^1.0.7",
|
||||
"for-each": "^0.3.3",
|
||||
"gopd": "^1.0.1",
|
||||
"has-tostringtag": "^1.0.0"
|
||||
"has-tostringtag": "^1.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4731,6 +4789,16 @@
|
||||
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
|
||||
"integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="
|
||||
},
|
||||
"define-data-property": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"define-lazy-prop": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
|
||||
@@ -4902,9 +4970,9 @@
|
||||
}
|
||||
},
|
||||
"dompurify": {
|
||||
"version": "2.4.7",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.7.tgz",
|
||||
"integrity": "sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ==",
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.2.tgz",
|
||||
"integrity": "sha512-5vSyvxRAb45EoWwAktUT3AYqAwXK4FL7si22Cgj46U6ICsj/YJczCN+Bk7WNABIQmpWRymGfslMhrRUZkQNnqA==",
|
||||
"optional": true
|
||||
},
|
||||
"domutils": {
|
||||
@@ -5071,6 +5139,43 @@
|
||||
"string.prototype.trimstart": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"es-define-property": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
|
||||
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
|
||||
"requires": {
|
||||
"get-intrinsic": "^1.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
|
||||
},
|
||||
"es-get-iterator": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
|
||||
@@ -5087,15 +5192,21 @@
|
||||
"stop-iteration-iterator": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
|
||||
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3"
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
@@ -15154,15 +15265,21 @@
|
||||
"get-intrinsic": "^1.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
|
||||
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3"
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
@@ -15236,17 +15353,17 @@
|
||||
"dev": true
|
||||
},
|
||||
"has-property-descriptors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
|
||||
"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||
"requires": {
|
||||
"get-intrinsic": "^1.1.1"
|
||||
"es-define-property": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
|
||||
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q=="
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.1",
|
||||
@@ -15254,11 +15371,11 @@
|
||||
"integrity": "sha1-n1IUdYpEGWxAbZvXbOv4HsLdMeg="
|
||||
},
|
||||
"has-tostringtag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
|
||||
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"requires": {
|
||||
"has-symbols": "^1.0.2"
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"has-symbols": {
|
||||
@@ -15318,6 +15435,21 @@
|
||||
"minimalistic-assert": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"he": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||
@@ -15813,31 +15945,13 @@
|
||||
}
|
||||
},
|
||||
"internal-slot": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
|
||||
"integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==",
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
|
||||
"integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
|
||||
"requires": {
|
||||
"get-intrinsic": "^1.2.0",
|
||||
"has": "^1.0.3",
|
||||
"es-errors": "^1.3.0",
|
||||
"hasown": "^2.0.0",
|
||||
"side-channel": "^1.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
|
||||
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"interpret": {
|
||||
@@ -15880,55 +15994,35 @@
|
||||
}
|
||||
},
|
||||
"is-array-buffer": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
|
||||
"integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
|
||||
"integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"get-intrinsic": "^1.2.0",
|
||||
"is-typed-array": "^1.1.10"
|
||||
"get-intrinsic": "^1.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"available-typed-arrays": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
|
||||
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
|
||||
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3"
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
},
|
||||
"is-typed-array": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
|
||||
"integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
|
||||
"requires": {
|
||||
"which-typed-array": "^1.1.11"
|
||||
}
|
||||
},
|
||||
"which-typed-array": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
|
||||
"integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
|
||||
"requires": {
|
||||
"available-typed-arrays": "^1.0.5",
|
||||
"call-bind": "^1.0.2",
|
||||
"for-each": "^0.3.3",
|
||||
"gopd": "^1.0.1",
|
||||
"has-tostringtag": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -16018,9 +16112,9 @@
|
||||
}
|
||||
},
|
||||
"is-map": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
|
||||
"integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg=="
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
|
||||
"integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="
|
||||
},
|
||||
"is-negative-zero": {
|
||||
"version": "2.0.1",
|
||||
@@ -16065,16 +16159,52 @@
|
||||
}
|
||||
},
|
||||
"is-set": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
|
||||
"integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g=="
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
|
||||
"integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="
|
||||
},
|
||||
"is-shared-array-buffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
|
||||
"integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
|
||||
"integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2"
|
||||
"call-bind": "^1.0.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"call-bind": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"set-function-length": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"is-stream": {
|
||||
@@ -16112,17 +16242,53 @@
|
||||
}
|
||||
},
|
||||
"is-weakmap": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
|
||||
"integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA=="
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
|
||||
"integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w=="
|
||||
},
|
||||
"is-weakset": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
|
||||
"integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz",
|
||||
"integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"get-intrinsic": "^1.1.1"
|
||||
"call-bind": "^1.0.7",
|
||||
"get-intrinsic": "^1.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"call-bind": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"set-function-length": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"is-what": {
|
||||
@@ -16366,9 +16532,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "3.32.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.0.tgz",
|
||||
"integrity": "sha512-rd4rYZNlF3WuoYuRIDEmbR/ga9CeuWX9U05umAvgrrZoHY4Z++cp/xwPQMvUpBB4Ag6J8KfD80G0zwCyaSxDww==",
|
||||
"version": "3.37.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.0.tgz",
|
||||
"integrity": "sha512-fu5vHevQ8ZG4og+LXug8ulUtVxjOcEYvifJr7L5Bfq9GOztVqsKd9/59hUk2ZSbCrS3BqUr3EpaYGIYzq7g3Ug==",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
@@ -17500,12 +17666,58 @@
|
||||
"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw=="
|
||||
},
|
||||
"object-is": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
|
||||
"integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
|
||||
"integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.3"
|
||||
"call-bind": "^1.0.7",
|
||||
"define-properties": "^1.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"call-bind": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"set-function-length": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
|
||||
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
|
||||
"requires": {
|
||||
"define-data-property": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.0",
|
||||
"object-keys": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"object-keys": {
|
||||
@@ -17853,6 +18065,11 @@
|
||||
"resolved": "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz",
|
||||
"integrity": "sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g=="
|
||||
},
|
||||
"possible-typed-array-names": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
|
||||
"integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q=="
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.4.5",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz",
|
||||
@@ -18695,23 +18912,59 @@
|
||||
}
|
||||
},
|
||||
"regexp.prototype.flags": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz",
|
||||
"integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==",
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
|
||||
"integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.2.0",
|
||||
"functions-have-names": "^1.2.3"
|
||||
"call-bind": "^1.0.6",
|
||||
"define-properties": "^1.2.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"set-function-name": "^2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"define-properties": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
|
||||
"integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
|
||||
"call-bind": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"set-function-length": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
|
||||
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
|
||||
"requires": {
|
||||
"define-data-property": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.0",
|
||||
"object-keys": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -19077,6 +19330,54 @@
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
|
||||
"dev": true
|
||||
},
|
||||
"set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||
"requires": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"gopd": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"set-function-name": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
|
||||
"integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
|
||||
"requires": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
"functions-have-names": "^1.2.3",
|
||||
"has-property-descriptors": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"setimmediate": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||
@@ -19162,6 +19463,11 @@
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"signature_pad": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/signature_pad/-/signature_pad-4.2.0.tgz",
|
||||
"integrity": "sha512-YLWysmaUBaC5wosAKkgbX7XI+LBv2w5L0QUcI6Jc4moHYzv9BUBJtAyNLpWzHjtjKTeWOH6bfP4a4pzf0UinfQ=="
|
||||
},
|
||||
"simple-concat": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
|
||||
@@ -19328,9 +19634,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"stackblur-canvas": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.6.0.tgz",
|
||||
"integrity": "sha512-8S1aIA+UoF6erJYnglGPug6MaHYGo1Ot7h5fuXx4fUPvcvQfcdw2o/ppCse63+eZf8PPidSu4v1JnmEVtEDnpg==",
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz",
|
||||
"integrity": "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==",
|
||||
"optional": true
|
||||
},
|
||||
"statuses": {
|
||||
@@ -19623,9 +19929,9 @@
|
||||
}
|
||||
},
|
||||
"tableexport.jquery.plugin": {
|
||||
"version": "1.28.0",
|
||||
"resolved": "https://registry.npmjs.org/tableexport.jquery.plugin/-/tableexport.jquery.plugin-1.28.0.tgz",
|
||||
"integrity": "sha512-ydDjOhw8A+LOu+801zPXDeMF8MoU1q2HtS2msphCuny0tdXgbXG9GJfA4ll1hBs0ABiAnOaVVZaRuxBmW/qHtw==",
|
||||
"version": "1.30.0",
|
||||
"resolved": "https://registry.npmjs.org/tableexport.jquery.plugin/-/tableexport.jquery.plugin-1.30.0.tgz",
|
||||
"integrity": "sha512-kMztiFUsGbxsknFVCDph+5j4e9xmqBBV6Na7T9vRYCUGDxtlndrdxMs9qLJDSOXjlgkIqCUv+S/e5iTUNAFF/g==",
|
||||
"requires": {
|
||||
"file-saver": ">=2.0.4",
|
||||
"html2canvas": ">=1.0.0",
|
||||
@@ -20602,14 +20908,14 @@
|
||||
}
|
||||
},
|
||||
"which-collection": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
|
||||
"integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
|
||||
"integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
|
||||
"requires": {
|
||||
"is-map": "^2.0.1",
|
||||
"is-set": "^2.0.1",
|
||||
"is-weakmap": "^2.0.1",
|
||||
"is-weakset": "^2.0.1"
|
||||
"is-map": "^2.0.3",
|
||||
"is-set": "^2.0.3",
|
||||
"is-weakmap": "^2.0.2",
|
||||
"is-weakset": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"which-module": {
|
||||
|
||||
+3
-2
@@ -28,7 +28,7 @@
|
||||
"vue-template-compiler": "2.4.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.5.0",
|
||||
"@fortawesome/fontawesome-free": "^6.5.2",
|
||||
"acorn": "^8.11.2",
|
||||
"acorn-import-assertions": "^1.9.0",
|
||||
"admin-lte": "^2.4.18",
|
||||
@@ -56,7 +56,8 @@
|
||||
"papaparse": "^4.3.3",
|
||||
"select2": "4.0.13",
|
||||
"sheetjs": "^2.0.0",
|
||||
"tableexport.jquery.plugin": "1.28.0",
|
||||
"signature_pad": "^4.2.0",
|
||||
"tableexport.jquery.plugin": "1.30.0",
|
||||
"tether": "^1.4.0",
|
||||
"vue-resource": "^1.5.2",
|
||||
"webpack": "^5.90.2"
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+26
-26
@@ -1,52 +1,52 @@
|
||||
{
|
||||
"/js/build/app.js": "/js/build/app.js?id=6bbc4dd6b643fefe492261fdfe6fae5a",
|
||||
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=392cc93cfc0be0349bab9697669dd091",
|
||||
"/css/build/overrides.css": "/css/build/overrides.css?id=87c4587df4ab5c64e0e3ee920310ba2a",
|
||||
"/css/build/app.css": "/css/build/app.css?id=28a7726dc9fa61365d36ed7067461490",
|
||||
"/css/build/overrides.css": "/css/build/overrides.css?id=c071d0741611371e84c380de2fb13b46",
|
||||
"/css/build/app.css": "/css/build/app.css?id=cd07d2f45297c702527a330dce45dd46",
|
||||
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=f25c77ed07053646a42e9c19923d24fa",
|
||||
"/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=268041e902b019730c23ee3875838005",
|
||||
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=d409d9b1a3b69247df8b98941ba06e33",
|
||||
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=4a9e8c5e7b09506fa3e3a3f42849e07f",
|
||||
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=21fef066e0bb1b02fd83fcb6694fad5f",
|
||||
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=03075904b967308132b810bc0205ab1c",
|
||||
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=47ab28abd019c2b1f9aae60a3d44824a",
|
||||
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=af8c7daf7e9a2c784eafb76f65c418f7",
|
||||
"/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=fc7adb943668ac69fe4b646625a7571f",
|
||||
"/css/dist/skins/skin-purple-dark.css": "/css/dist/skins/skin-purple-dark.css?id=9f944e8021781af1ce45d27765d1c0c2",
|
||||
"/css/dist/skins/skin-purple-dark.css": "/css/dist/skins/skin-purple-dark.css?id=7fb8cf2421ad272b41393fdf5844559f",
|
||||
"/css/dist/skins/skin-purple.css": "/css/dist/skins/skin-purple.css?id=cf6c8c340420724b02d6e787ef9bded5",
|
||||
"/css/dist/skins/skin-red-dark.css": "/css/dist/skins/skin-red-dark.css?id=7f0eb9e355b36b41c61c3af3b4d41143",
|
||||
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=6cf460bed48ab738041f60231a3f005a",
|
||||
"/css/dist/skins/skin-red-dark.css": "/css/dist/skins/skin-red-dark.css?id=122d3df19d2c0552d7ef388e69f7d71f",
|
||||
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=5414c37b1403f41e051ad7b3aac112b4",
|
||||
"/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=1f33ca3d860461c1127ec465ab3ebb6b",
|
||||
"/css/dist/skins/skin-green-dark.css": "/css/dist/skins/skin-green-dark.css?id=0ed42b67f9b02a74815e885bfd9e3f66",
|
||||
"/css/dist/skins/skin-green-dark.css": "/css/dist/skins/skin-green-dark.css?id=bd61fefb56b30ed6d8c946f02bc956fb",
|
||||
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=b48f4d8af0e1ca5621c161e93951109f",
|
||||
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=f0fbbb0ac729ea092578fb05ca615460",
|
||||
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=b9a74ec0cd68f83e7480d5ae39919beb",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=3a58b0695460d60eaed66bc3b7f4e796",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=3785387b68b5d74dccd037fe5340e038",
|
||||
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||
"/css/webfonts/fa-brands-400.ttf": "/css/webfonts/fa-brands-400.ttf?id=69e5d8e4e818f05fd882cceb758d1eba",
|
||||
"/css/webfonts/fa-brands-400.woff2": "/css/webfonts/fa-brands-400.woff2?id=189b85e9c72c6f75e464c3f58a6707cf",
|
||||
"/css/webfonts/fa-regular-400.ttf": "/css/webfonts/fa-regular-400.ttf?id=ed4c23399d1013809882e90bfe396d1b",
|
||||
"/css/webfonts/fa-regular-400.woff2": "/css/webfonts/fa-regular-400.woff2?id=be75b1958ae0da55e1eed562d9b7713d",
|
||||
"/css/webfonts/fa-solid-900.ttf": "/css/webfonts/fa-solid-900.ttf?id=dfdc7801582dd0d20ea75faa3b96c296",
|
||||
"/css/webfonts/fa-solid-900.woff2": "/css/webfonts/fa-solid-900.woff2?id=a0feb384c3c6071947a49708f2b0bc85",
|
||||
"/css/webfonts/fa-v4compatibility.ttf": "/css/webfonts/fa-v4compatibility.ttf?id=e24ec0b8661f7fa333b29444df39e399",
|
||||
"/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=e11465c0eff0549edd4e8ea6bbcf242f",
|
||||
"/css/webfonts/fa-brands-400.ttf": "/css/webfonts/fa-brands-400.ttf?id=0141634c24336be626e05c8b77d1fa27",
|
||||
"/css/webfonts/fa-brands-400.woff2": "/css/webfonts/fa-brands-400.woff2?id=b3cf7a6dd618bd392f3ddcc61343a463",
|
||||
"/css/webfonts/fa-regular-400.ttf": "/css/webfonts/fa-regular-400.ttf?id=9cf69d99de9d83f82466a647f5cb1f94",
|
||||
"/css/webfonts/fa-regular-400.woff2": "/css/webfonts/fa-regular-400.woff2?id=f0549181a126fe40849a53792bb0e077",
|
||||
"/css/webfonts/fa-solid-900.ttf": "/css/webfonts/fa-solid-900.ttf?id=509c0e46de844df754d10179cf03c953",
|
||||
"/css/webfonts/fa-solid-900.woff2": "/css/webfonts/fa-solid-900.woff2?id=96d16b1bdb177fd796c810b9e706c780",
|
||||
"/css/webfonts/fa-v4compatibility.ttf": "/css/webfonts/fa-v4compatibility.ttf?id=8994b282f9f3b7a00380bb1e2731a4bf",
|
||||
"/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=111e341dba724e1df946e8d1f406a7bd",
|
||||
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=99c395f0bab5966f32f63f4e55899e64",
|
||||
"/js/build/vendor.js": "/js/build/vendor.js?id=a2b971da417306a63385c8098acfe4af",
|
||||
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=857da5daffd13e0553510e5ccd410c79",
|
||||
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=e3bde6c62806c5ae510c964de17cd610",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=fca6ea9956fd827d9790c08e0e982b22",
|
||||
"/js/dist/all-defer.js": "/js/dist/all-defer.js?id=19ccc62a8f1ea103dede4808837384d4",
|
||||
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=b48f4d8af0e1ca5621c161e93951109f",
|
||||
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=0ed42b67f9b02a74815e885bfd9e3f66",
|
||||
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=bd61fefb56b30ed6d8c946f02bc956fb",
|
||||
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=1f33ca3d860461c1127ec465ab3ebb6b",
|
||||
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=6cf460bed48ab738041f60231a3f005a",
|
||||
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=5414c37b1403f41e051ad7b3aac112b4",
|
||||
"/css/dist/skins/skin-blue.min.css": "/css/dist/skins/skin-blue.min.css?id=392cc93cfc0be0349bab9697669dd091",
|
||||
"/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=4a9e8c5e7b09506fa3e3a3f42849e07f",
|
||||
"/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=47ab28abd019c2b1f9aae60a3d44824a",
|
||||
"/css/dist/skins/skin-yellow.min.css": "/css/dist/skins/skin-yellow.min.css?id=fc7adb943668ac69fe4b646625a7571f",
|
||||
"/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=21fef066e0bb1b02fd83fcb6694fad5f",
|
||||
"/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=af8c7daf7e9a2c784eafb76f65c418f7",
|
||||
"/css/dist/skins/skin-red.min.css": "/css/dist/skins/skin-red.min.css?id=b9a74ec0cd68f83e7480d5ae39919beb",
|
||||
"/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=7f0eb9e355b36b41c61c3af3b4d41143",
|
||||
"/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=122d3df19d2c0552d7ef388e69f7d71f",
|
||||
"/css/dist/skins/skin-purple.min.css": "/css/dist/skins/skin-purple.min.css?id=cf6c8c340420724b02d6e787ef9bded5",
|
||||
"/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=9f944e8021781af1ce45d27765d1c0c2",
|
||||
"/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=7fb8cf2421ad272b41393fdf5844559f",
|
||||
"/css/dist/skins/skin-orange.min.css": "/css/dist/skins/skin-orange.min.css?id=268041e902b019730c23ee3875838005",
|
||||
"/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=d409d9b1a3b69247df8b98941ba06e33",
|
||||
"/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=03075904b967308132b810bc0205ab1c",
|
||||
"/css/dist/skins/skin-contrast.min.css": "/css/dist/skins/skin-contrast.min.css?id=f0fbbb0ac729ea092578fb05ca615460"
|
||||
}
|
||||
|
||||
@@ -358,6 +358,10 @@ body {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading {
|
||||
z-index: 0 !important;
|
||||
}
|
||||
|
||||
@media print {
|
||||
a[href]:after {
|
||||
content: none;
|
||||
@@ -582,6 +586,8 @@ th.css-barcode > .th-inner,
|
||||
th.css-license > .th-inner,
|
||||
th.css-consumable > .th-inner,
|
||||
th.css-envelope > .th-inner,
|
||||
th.css-users > .th-inner,
|
||||
th.css-location > .th-inner,
|
||||
th.css-accessory > .th-inner
|
||||
{
|
||||
font-size: 0px;
|
||||
@@ -598,6 +604,8 @@ th.css-barcode > .th-inner::before,
|
||||
th.css-license > .th-inner::before,
|
||||
th.css-consumable > .th-inner::before,
|
||||
th.css-envelope > .th-inner::before,
|
||||
th.css-users > .th-inner::before,
|
||||
th.css-location > .th-inner::before,
|
||||
th.css-accessory > .th-inner::before
|
||||
|
||||
{
|
||||
@@ -617,6 +625,7 @@ th.css-padlock > .th-inner::before
|
||||
}
|
||||
|
||||
/**
|
||||
BEGIN ICON TABLE HEADERS
|
||||
Set the font-weight css property as 900 (For Solid), 400 (Regular or Brands), 300 (Light for pro icons).
|
||||
**/
|
||||
th.css-barcode > .th-inner::before
|
||||
@@ -639,12 +648,20 @@ th.css-envelope > .th-inner::before
|
||||
content: "\f0e0"; font-family: "Font Awesome 5 Free"; font-weight: 400;
|
||||
}
|
||||
|
||||
|
||||
th.css-accessory > .th-inner::before
|
||||
{
|
||||
content: "\f11c"; font-family: "Font Awesome 5 Free"; font-weight: 400;
|
||||
}
|
||||
|
||||
th.css-users > .th-inner::before {
|
||||
content: "\f0c0"; font-family: "Font Awesome 5 Free"; font-size: 15px;
|
||||
}
|
||||
|
||||
th.css-location > .th-inner::before {
|
||||
content: "\f3c5"; font-family: "Font Awesome 5 Free"; font-size: 19px; margin-bottom: 0px;
|
||||
}
|
||||
|
||||
|
||||
.small-box .inner {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
@@ -684,6 +701,12 @@ th.css-accessory > .th-inner::before
|
||||
.sidebar-menu {
|
||||
margin-top:100px
|
||||
}
|
||||
.navbar-custom-menu > .navbar-nav > li.dropdown.user.user-menu {
|
||||
float:right;
|
||||
}
|
||||
.navbar-custom-menu > .navbar-nav > li > .dropdown-menu {
|
||||
margin-right:-39px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1268px) and (min-width: 912px){
|
||||
@@ -890,4 +913,10 @@ input[type="radio"]:checked::before {
|
||||
}
|
||||
.datepicker.dropdown-menu {
|
||||
z-index: 1030 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-menu > li .badge {
|
||||
margin-top: 0px;
|
||||
filter: brightness(70%);
|
||||
font-size: 70%;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
&.btn-primary, .btn-primary:link {
|
||||
background-color: darken(@black, 10%);
|
||||
border-color: darken(@black, 20%);
|
||||
border-color: #FFF;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@@ -375,7 +375,10 @@ input[type=text], input[type=search] {
|
||||
color: var(--text-main);
|
||||
}
|
||||
.skin-black-dark .main-header .navbar .dropdown-menu li a {
|
||||
color: var(--header);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.skin-black-dark .main-header .navbar .dropdown-menu li a:hover {
|
||||
background-color: #000000;
|
||||
}
|
||||
.fixed-table-body thead th .th-inner, .skin-black-dark .sidebar-menu>li.active>a, .skin-black .sidebar-menu>li:hover>a, .sidebar-toggle:hover {
|
||||
background-color: var(--header)!important;
|
||||
|
||||
@@ -245,7 +245,6 @@ body {
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: var(--button-primary);
|
||||
color: var(--link)!important;
|
||||
}
|
||||
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
||||
color: var(--text-main);
|
||||
@@ -361,7 +360,10 @@ input[type=text], input[type=search] {
|
||||
color: var(--text-main);
|
||||
}
|
||||
.skin-blue-dark .main-header .navbar .dropdown-menu li a {
|
||||
color: var(--header);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.skin-blue-dark .main-header .navbar .dropdown-menu li a:hover {
|
||||
background-color: #3c8dbc;
|
||||
}
|
||||
.fixed-table-body thead th .th-inner, .skin-blue-dark .sidebar-menu>li.active>a, .skin-blue .sidebar-menu>li:hover>a, .sidebar-toggle:hover {
|
||||
background-color: var(--header)!important;
|
||||
|
||||
@@ -236,7 +236,6 @@ body {
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: var(--button-primary);
|
||||
color: var(--link)!important;
|
||||
}
|
||||
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
||||
color: var(--text-main);
|
||||
@@ -348,7 +347,10 @@ input[type=text], input[type=search] {
|
||||
color: var(--text-main);
|
||||
}
|
||||
.skin-green-dark .main-header .navbar .dropdown-menu li a {
|
||||
color: var(--link);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.skin-green-dark .main-header .navbar .dropdown-menu li a:hover {
|
||||
background-color: #006300;
|
||||
}
|
||||
.fixed-table-body thead th .th-inner, .skin-green-dark .sidebar-menu>li.active>a, .skin-green .sidebar-menu>li:hover>a, .sidebar-toggle:hover {
|
||||
background-color: var(--header)!important;
|
||||
|
||||
@@ -243,7 +243,6 @@ a:link.btn-default{
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: var(--button-primary);
|
||||
color: var(--link)!important;
|
||||
}
|
||||
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
||||
color: var(--text-main);
|
||||
@@ -359,7 +358,10 @@ input[type=text], input[type=search] {
|
||||
color: var(--text-main);
|
||||
}
|
||||
.skin-orange-dark .main-header .navbar .dropdown-menu li a {
|
||||
color: var(--header);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.skin-orange-dark .main-header .navbar .dropdown-menu li a:hover {
|
||||
background-color: #ff8c00;
|
||||
}
|
||||
.fixed-table-body thead th .th-inner, .skin-orange-dark .sidebar-menu>li.active>a, .skin-orange .sidebar-menu>li:hover>a, .sidebar-toggle:hover {
|
||||
background-color: var(--header)!important;
|
||||
|
||||
@@ -246,7 +246,6 @@ body {
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: var(--button-primary);
|
||||
color: var(--link)!important;
|
||||
}
|
||||
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
||||
color: var(--text-main);
|
||||
@@ -362,7 +361,10 @@ input[type=text], input[type=search] {
|
||||
color: var(--text-main);
|
||||
}
|
||||
.skin-purple-dark .main-header .navbar .dropdown-menu li a {
|
||||
color: var(--header);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.skin-purple-dark .main-header .navbar .dropdown-menu li a:hover {
|
||||
background-color: #5f5ca8;
|
||||
}
|
||||
.fixed-table-body thead th .th-inner, .skin-purple-dark .sidebar-menu>li.active>a, .skin-purple .sidebar-menu>li:hover>a, .sidebar-toggle:hover {
|
||||
background-color: var(--header)!important;
|
||||
|
||||
@@ -247,7 +247,6 @@ body {
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: var(--button-primary);
|
||||
color: var(--link)!important;
|
||||
}
|
||||
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
||||
color: var(--text-main);
|
||||
@@ -363,7 +362,10 @@ input[type=text], input[type=search] {
|
||||
color: var(--text-main);
|
||||
}
|
||||
.skin-red-dark .main-header .navbar .dropdown-menu li a {
|
||||
color: var(--header);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.skin-red-dark .main-header .navbar .dropdown-menu li a:hover {
|
||||
background-color: #c23320;
|
||||
}
|
||||
.fixed-table-body thead th .th-inner, .skin-red-dark .sidebar-menu>li.active>a, .skin-red .sidebar-menu>li:hover>a, .sidebar-toggle:hover {
|
||||
background-color: var(--header)!important;
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
&.btn-primary, .btn-primary:link {
|
||||
background-color: var(--button-default);
|
||||
border-color: var(--button-default);
|
||||
border-color: #000000;
|
||||
color: #545454;
|
||||
}
|
||||
|
||||
@@ -355,8 +355,11 @@ input[type=text], input[type=search] {
|
||||
.skin-yellow-dark .main-header .navbar .dropdown-menu li a {
|
||||
color: var(--header);
|
||||
}
|
||||
.skin-yellow-dark .main-header .navbar .dropdown-menu li a:hover {
|
||||
background-color: #000000;
|
||||
}
|
||||
tr th div.th-inner {
|
||||
color:var(--text-main);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.tab-content, .tab-pane {
|
||||
background-color: var(--back-main);
|
||||
|
||||
@@ -17,6 +17,7 @@ return [
|
||||
'update' => [
|
||||
'error' => 'Asset was not updated, please try again',
|
||||
'success' => 'Asset updated successfully.',
|
||||
'encrypted_warning' => 'Asset updated successfully, but encrypted custom fields were not due to permissions',
|
||||
'nothing_updated' => 'No fields were selected, so nothing was updated.',
|
||||
'no_assets_selected' => 'No assets were selected, so nothing was updated.',
|
||||
'assets_do_not_exist_or_are_invalid' => 'Selected assets cannot be updated.',
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
return array(
|
||||
|
||||
'does_not_exist' => 'License does not exist or you do not have permission to view it.',
|
||||
'user_does_not_exist' => 'User does not exist.',
|
||||
'user_does_not_exist' => 'User does not exist or you do not have permission to view them.',
|
||||
'asset_does_not_exist' => 'The asset you are trying to associate with this license does not exist.',
|
||||
'owner_doesnt_match_asset' => 'The asset you are trying to associate with this license is owned by somene other than the person selected in the assigned to dropdown.',
|
||||
'assoc_users' => 'This license is currently checked out to a user and cannot be deleted. Please check the license in first, and then try deleting again. ',
|
||||
|
||||
@@ -4,6 +4,7 @@ return array(
|
||||
|
||||
'assigned_to' => 'Assigned To',
|
||||
'checkout' => 'In/Out',
|
||||
'deleted_at' => 'Deleted at',
|
||||
'id' => 'ID',
|
||||
'license_email' => 'License Email',
|
||||
'license_name' => 'Licensed To',
|
||||
|
||||
@@ -20,6 +20,7 @@ return array(
|
||||
'lock_passwords' => 'Login details cannot be changed on this installation.',
|
||||
'manager' => 'Manager',
|
||||
'managed_locations' => 'Managed Locations',
|
||||
'managed_users' => 'Managed Users',
|
||||
'name' => 'Name',
|
||||
'nogroup' => 'No groups have been created yet. To add one, visit: ',
|
||||
'notes' => 'Notes',
|
||||
|
||||
@@ -176,7 +176,7 @@ return [
|
||||
'last_name' => 'Last Name',
|
||||
'license' => 'License',
|
||||
'license_report' => 'License Report',
|
||||
'licenses_available' => 'licenses available',
|
||||
'licenses_available' => 'Licenses available',
|
||||
'licenses' => 'Licenses',
|
||||
'list_all' => 'List All',
|
||||
'loading' => 'Loading... please wait....',
|
||||
@@ -245,6 +245,7 @@ return [
|
||||
'select_all' => 'Select All',
|
||||
'search' => 'Search',
|
||||
'select_category' => 'Select a Category',
|
||||
'select_datasource' => 'Select a Datasource',
|
||||
'select_department' => 'Select a Department',
|
||||
'select_depreciation' => 'Select a Depreciation Type',
|
||||
'select_location' => 'Select a Location',
|
||||
@@ -312,6 +313,10 @@ return [
|
||||
'token_expired' => 'Your form session has expired. Please try again.',
|
||||
'login_enabled' => 'Login Enabled',
|
||||
'audit_due' => 'Due for Audit',
|
||||
'audit_due_days' => 'Assets Due for Audit Within :days Day|Assets Due for Audit Within :days Days',
|
||||
'checkin_due' => 'Due for Checkin',
|
||||
'checkin_overdue' => 'Overdue for Checkin',
|
||||
'checkin_due_days' => 'Assets Due for Checkin Within :days Day|Assets Due for Checkin Within :days Days',
|
||||
'audit_overdue' => 'Overdue for Audit',
|
||||
'accept' => 'Accept :asset',
|
||||
'i_accept' => 'I accept',
|
||||
@@ -507,6 +512,9 @@ return [
|
||||
'or' => 'or',
|
||||
'url' => 'URL',
|
||||
'edit_fieldset' => 'Edit fieldset fields and options',
|
||||
'permission_denied_superuser_demo' => 'Permission denied. You cannot update user information for superadmins on the demo.',
|
||||
'pwd_reset_not_sent' => 'User is not activated, is LDAP synced, or does not have an email address',
|
||||
'error_sending_email' => 'Error sending email',
|
||||
'bulk' => [
|
||||
'delete' =>
|
||||
[
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
<h3 style="padding-top: 20px">{{trans('general.sign_tos')}}</h3>
|
||||
<div id="signature-pad" class="m-signature-pad">
|
||||
<div class="m-signature-pad--body col-md-12 col-sm-12 col-lg-12 col-xs-12">
|
||||
<canvas></canvas>
|
||||
<canvas style="width:100%;"></canvas>
|
||||
<input type="hidden" name="signature_output" id="signature_output">
|
||||
</div>
|
||||
<div class="col-md-12 col-sm-12 col-lg-12 col-xs-12 text-center">
|
||||
@@ -94,6 +94,7 @@
|
||||
@section('moar_scripts')
|
||||
|
||||
<script nonce="{{ csrf_token() }}">
|
||||
|
||||
var wrapper = document.getElementById("signature-pad"),
|
||||
clearButton = wrapper.querySelector("[data-action=clear]"),
|
||||
saveButton = wrapper.querySelector("[data-action=save]"),
|
||||
@@ -103,19 +104,20 @@
|
||||
// Adjust canvas coordinate space taking into account pixel ratio,
|
||||
// to make it look crisp on mobile devices.
|
||||
// This also causes canvas to be cleared.
|
||||
function resizeCanvas() {
|
||||
// When zoomed out to less than 100%, for some very strange reason,
|
||||
// some browsers report devicePixelRatio as less than 1
|
||||
// and only part of the canvas is cleared then.
|
||||
var ratio = Math.max(window.devicePixelRatio || 1, 1);
|
||||
canvas.width = canvas.offsetWidth * ratio;
|
||||
canvas.height = canvas.offsetHeight * ratio;
|
||||
canvas.getContext("2d").scale(ratio, ratio);
|
||||
if (window.matchMedia("(min-width: 768px)").matches) {
|
||||
function resizeCanvas() {
|
||||
// When zoomed out to less than 100%, for some very strange reason,
|
||||
// some browsers report devicePixelRatio as less than 1
|
||||
// and only part of the canvas is cleared then.
|
||||
var ratio = Math.max(window.devicePixelRatio || 1, 1);
|
||||
canvas.width = canvas.offsetWidth * ratio;
|
||||
canvas.height = canvas.offsetHeight * ratio;
|
||||
canvas.getContext("2d").scale(ratio, ratio);
|
||||
}
|
||||
window.onresize = resizeCanvas;
|
||||
resizeCanvas();
|
||||
}
|
||||
|
||||
window.onresize = resizeCanvas;
|
||||
resizeCanvas();
|
||||
|
||||
signaturePad = new SignaturePad(canvas);
|
||||
|
||||
$('#clear_button').on("click", function (event) {
|
||||
|
||||
@@ -1,40 +1,59 @@
|
||||
@extends('layouts/default')
|
||||
|
||||
@section('title0')
|
||||
|
||||
@if ((Request::get('company_id')) && ($company))
|
||||
{{ $company->name }}
|
||||
@endif
|
||||
|
||||
{{ trans('general.audit_due') }}
|
||||
|
||||
@stop
|
||||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
@yield('title0') @parent
|
||||
{{ trans_choice('general.audit_due_days', $settings->audit_warning_days, ['days' => $settings->audit_warning_days]) }}
|
||||
@stop
|
||||
|
||||
|
||||
|
||||
{{-- Page content --}}
|
||||
@section('content')
|
||||
|
||||
{{-- Page content --}}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box">
|
||||
<div class="box-body">
|
||||
|
||||
@include('partials.asset-bulk-actions')
|
||||
<!-- Custom Tabs -->
|
||||
<div class="nav-tabs-custom">
|
||||
<ul class="nav nav-tabs hidden-print">
|
||||
|
||||
<li class="active">
|
||||
<a href="#due" data-toggle="tab">{{ trans('general.audit_due') }}
|
||||
<span class="hidden-lg hidden-md">
|
||||
<i class="far fa-file fa-2x" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="badge">{{ (isset($total_due_for_audit)) ? $total_due_for_audit : '' }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#overdue" data-toggle="tab">{{ trans('general.audit_overdue') }}
|
||||
<span class="hidden-lg hidden-md">
|
||||
<i class="far fa-file fa-2x" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="badge">{{ (isset($total_overdue_for_audit)) ? $total_overdue_for_audit : '' }}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane active" id="due">
|
||||
|
||||
@include('partials.asset-bulk-actions',
|
||||
[
|
||||
'id_divname' => 'dueAssetEditToolbar',
|
||||
'id_formname' => 'dueAssetEditForm',
|
||||
'id_button' => 'dueAssetEditButton'])
|
||||
|
||||
<div class="row">
|
||||
<div class="table table-responsive">
|
||||
<div class="col-md-12">
|
||||
|
||||
<table
|
||||
data-click-to-select="true"
|
||||
data-columns="{{ \App\Presenters\AssetAuditPresenter::dataTableLayout() }}"
|
||||
data-cookie-id-table="assetsAuditListingTable"
|
||||
data-cookie-id-table="dueAssetAuditListing"
|
||||
data-pagination="true"
|
||||
data-id-table="assetsAuditListingTable"
|
||||
data-id-table="dueAssetAuditListing"
|
||||
data-search="true"
|
||||
data-side-pagination="server"
|
||||
data-show-columns="true"
|
||||
@@ -44,28 +63,71 @@
|
||||
data-show-refresh="true"
|
||||
data-sort-order="asc"
|
||||
data-sort-name="name"
|
||||
data-toolbar="#assetsBulkEditToolbar"
|
||||
data-bulk-button-id="#bulkAssetEditButton"
|
||||
data-bulk-form-id="#assetsBulkForm"
|
||||
id="assetsAuditListingTable"
|
||||
data-toolbar="#dueAssetEditToolbar"
|
||||
data-bulk-button-id="#dueAssetEditButton"
|
||||
data-bulk-form-id="#dueAssetEditForm"
|
||||
id="#dueAssetAuditListing"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{ route('api.asset.to-audit', ['audit' => 'due']) }}"
|
||||
data-url="{{ route('api.assets.list-upcoming', ['action' => 'audits', 'upcoming_status' => 'due']) }}"
|
||||
data-export-options='{
|
||||
"fileName": "export-assets-due-audit-{{ date('Y-m-d') }}",
|
||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||
}'>
|
||||
</table>
|
||||
</div> <!-- end col-md-12 -->
|
||||
</div><!-- end table-responsive -->
|
||||
</div><!-- end row -->
|
||||
</div><!-- end tab-pane -->
|
||||
|
||||
<div class="tab-pane" id="overdue">
|
||||
|
||||
@include('partials.asset-bulk-actions',
|
||||
[
|
||||
'id_divname' => 'overdueAssetEditToolbar',
|
||||
'id_formname' => 'overdueAssetEditForm',
|
||||
'id_button' => 'overdueAssetEditButton'])
|
||||
|
||||
<div class="row">
|
||||
<div class="table table-responsive">
|
||||
<div class="col-md-12">
|
||||
<table
|
||||
data-click-to-select="true"
|
||||
data-columns="{{ \App\Presenters\AssetAuditPresenter::dataTableLayout() }}"
|
||||
data-cookie-id-table="overdueAssetAuditListing"
|
||||
data-pagination="true"
|
||||
data-id-table="overdueAssetAuditListing"
|
||||
data-search="true"
|
||||
data-side-pagination="server"
|
||||
data-show-columns="true"
|
||||
data-show-fullscreen="true"
|
||||
data-show-export="true"
|
||||
data-show-footer="true"
|
||||
data-show-refresh="true"
|
||||
data-sort-order="asc"
|
||||
data-sort-name="name"
|
||||
data-toolbar="#overdueAssetEditToolbar"
|
||||
data-bulk-button-id="#overdueAssetEditButton"
|
||||
data-bulk-form-id="#overdueAssetEditForm"
|
||||
id="#overdueAssetAuditListing"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{ route('api.assets.list-upcoming', ['action' => 'audits', 'upcoming_status' => 'overdue']) }}"
|
||||
data-export-options='{
|
||||
"fileName": "export-assets-overdue-audit-{{ date('Y-m-d') }}",
|
||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||
}'>
|
||||
</table>
|
||||
</div> <!-- end col-md-12 -->
|
||||
</div><!-- end table-responsive -->
|
||||
</div><!-- end row -->
|
||||
</div><!-- end tab-pane -->
|
||||
</div><!-- end tab-content -->
|
||||
</div><!-- end nav-tabs-custom -->
|
||||
|
||||
</div><!-- /.col -->
|
||||
</div><!-- /.row -->
|
||||
{{ Form::close() }}
|
||||
</div><!-- ./box-body -->
|
||||
</div><!-- /.box -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
||||
@section('moar_scripts')
|
||||
@include('partials.bootstrap-table')
|
||||
|
||||
@stop
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
@extends('layouts/default')
|
||||
|
||||
@section('title0')
|
||||
|
||||
@if ((Request::get('company_id')) && ($company))
|
||||
{{ $company->name }}
|
||||
@endif
|
||||
|
||||
{{ trans('general.audit_overdue') }}
|
||||
|
||||
@stop
|
||||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
@yield('title0') @parent
|
||||
@stop
|
||||
|
||||
|
||||
{{-- Page content --}}
|
||||
@section('content')
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box">
|
||||
<div class="box-body">
|
||||
@include('partials.asset-bulk-actions')
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
||||
<table
|
||||
data-click-to-select="true"
|
||||
data-columns="{{ \App\Presenters\AssetAuditPresenter::dataTableLayout() }}"
|
||||
data-cookie-id-table="assetsOverdueAuditListingTable"
|
||||
data-pagination="true"
|
||||
data-id-table="assetsOverdueAuditListingTable"
|
||||
data-search="true"
|
||||
data-side-pagination="server"
|
||||
data-show-columns="true"
|
||||
data-show-fullscreen="true"
|
||||
data-show-export="true"
|
||||
data-show-footer="true"
|
||||
data-show-refresh="true"
|
||||
data-sort-order="asc"
|
||||
data-sort-name="name"
|
||||
data-toolbar="#assetsBulkEditToolbar"
|
||||
data-bulk-button-id="#bulkAssetEditButton"
|
||||
data-bulk-form-id="#assetsBulkForm"
|
||||
id="assetsAuditListingTable"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{ route('api.asset.to-audit', ['audit' => 'overdue']) }}"
|
||||
data-export-options='{
|
||||
"fileName": "export-assets-due-audit-{{ date('Y-m-d') }}",
|
||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||
}'>
|
||||
</table>
|
||||
|
||||
</div><!-- /.col -->
|
||||
</div><!-- /.row -->
|
||||
{{ Form::close() }}
|
||||
</div><!-- ./box-body -->
|
||||
</div><!-- /.box -->
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('moar_scripts')
|
||||
@include('partials.bootstrap-table')
|
||||
|
||||
@stop
|
||||
@@ -0,0 +1,131 @@
|
||||
@extends('layouts/default')
|
||||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
{{ trans_choice('general.checkin_due_days', $settings->audit_warning_days, ['days' => $settings->audit_warning_days]) }}
|
||||
@stop
|
||||
|
||||
{{-- Page content --}}
|
||||
@section('content')
|
||||
{{-- Page content --}}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
||||
<!-- Custom Tabs -->
|
||||
<div class="nav-tabs-custom">
|
||||
<ul class="nav nav-tabs hidden-print">
|
||||
|
||||
<li class="active">
|
||||
<a href="#due" data-toggle="tab">{{ trans('general.checkin_due') }}
|
||||
<span class="hidden-lg hidden-md">
|
||||
<i class="far fa-file fa-2x" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="badge">{{ (isset($total_due_for_checkin)) ? $total_due_for_checkin : '' }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#overdue" data-toggle="tab">{{ trans('general.checkin_overdue') }}
|
||||
<span class="hidden-lg hidden-md">
|
||||
<i class="far fa-file fa-2x" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="badge">{{ (isset($total_overdue_for_checkin)) ? $total_overdue_for_checkin : '' }}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane active" id="due">
|
||||
|
||||
@include('partials.asset-bulk-actions',
|
||||
[
|
||||
'id_divname' => 'dueAssetEditToolbar',
|
||||
'id_formname' => 'dueAssetEditForm',
|
||||
'id_button' => 'dueAssetEditButton'])
|
||||
|
||||
<div class="row">
|
||||
<div class="table table-responsive">
|
||||
<div class="col-md-12">
|
||||
<table
|
||||
data-click-to-select="true"
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-cookie-id-table="dueAssetcheckinListing"
|
||||
data-pagination="true"
|
||||
data-id-table="dueAssetcheckinListing"
|
||||
data-search="true"
|
||||
data-side-pagination="server"
|
||||
data-show-columns="true"
|
||||
data-show-fullscreen="true"
|
||||
data-show-export="true"
|
||||
data-show-footer="true"
|
||||
data-show-refresh="true"
|
||||
data-sort-order="asc"
|
||||
data-sort-name="name"
|
||||
data-toolbar="#dueAssetEditToolbar"
|
||||
data-bulk-button-id="#dueAssetEditButton"
|
||||
data-bulk-form-id="#dueAssetEditForm"
|
||||
id="#dueAssetcheckinListing"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{ route('api.assets.list-upcoming', ['action' => 'checkins', 'upcoming_status' => 'due']) }}"
|
||||
data-export-options='{
|
||||
"fileName": "export-assets-due-checkin-{{ date('Y-m-d') }}",
|
||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||
}'>
|
||||
</table>
|
||||
</div> <!-- end col-md-12 -->
|
||||
</div><!-- end table-responsive -->
|
||||
</div><!-- end row -->
|
||||
</div><!-- end tab-pane -->
|
||||
|
||||
<div class="tab-pane" id="overdue">
|
||||
|
||||
@include('partials.asset-bulk-actions',
|
||||
[
|
||||
'id_divname' => 'overdueAssetEditToolbar',
|
||||
'id_formname' => 'overdueAssetEditForm',
|
||||
'id_button' => 'overdueAssetEditButton'])
|
||||
|
||||
<div class="row">
|
||||
<div class="table table-responsive">
|
||||
<div class="col-md-12">
|
||||
<table
|
||||
data-click-to-select="true"
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-cookie-id-table="overdueAssetcheckinListing"
|
||||
data-pagination="true"
|
||||
data-id-table="overdueAssetcheckinListing"
|
||||
data-search="true"
|
||||
data-side-pagination="server"
|
||||
data-show-columns="true"
|
||||
data-show-fullscreen="true"
|
||||
data-show-export="true"
|
||||
data-show-footer="true"
|
||||
data-show-refresh="true"
|
||||
data-sort-order="asc"
|
||||
data-sort-name="name"
|
||||
data-toolbar="#overdueAssetEditToolbar"
|
||||
data-bulk-button-id="#overdueAssetEditButton"
|
||||
data-bulk-form-id="#overdueAssetEditForm"
|
||||
id="#overdueAssetcheckinListing"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{ route('api.assets.list-upcoming', ['action' => 'checkins', 'upcoming_status' => 'overdue']) }}"
|
||||
data-export-options='{
|
||||
"fileName": "export-assets-overdue-checkin-{{ date('Y-m-d') }}",
|
||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||
}'>
|
||||
</table>
|
||||
</div> <!-- end col-md-12 -->
|
||||
</div><!-- end table-responsive -->
|
||||
</div><!-- end row -->
|
||||
</div><!-- end tab-pane -->
|
||||
</div><!-- end tab-content -->
|
||||
</div><!-- end nav-tabs-custom -->
|
||||
|
||||
</div><!-- /.col -->
|
||||
</div><!-- /.row -->
|
||||
|
||||
@stop
|
||||
|
||||
@section('moar_scripts')
|
||||
@include('partials.bootstrap-table')
|
||||
@stop
|
||||
@@ -32,8 +32,6 @@
|
||||
<div class="col-md-12">
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Custom Tabs -->
|
||||
<div class="nav-tabs-custom">
|
||||
<ul class="nav nav-tabs">
|
||||
@@ -53,7 +51,7 @@
|
||||
<i class="far fa-save fa-2x" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="hidden-xs hidden-sm">{{ trans('general.licenses') }}
|
||||
{!! ($asset->licenses->count() > 0 ) ? '<badge class="badge badge-secondary">'.number_format($asset->licenses->count()).'</badge>' : '' !!}
|
||||
{!! ($asset->licenses->count() > 0 ) ? '<span class="badge badge-secondary">'.number_format($asset->licenses->count()).'</span>' : '' !!}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
@@ -64,7 +62,7 @@
|
||||
<i class="far fa-hdd fa-2x" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="hidden-xs hidden-sm">{{ trans('general.components') }}
|
||||
{!! ($asset->components->count() > 0 ) ? '<badge class="badge badge-secondary">'.number_format($asset->components->count()).'</badge>' : '' !!}
|
||||
{!! ($asset->components->count() > 0 ) ? '<span class="badge badge-secondary">'.number_format($asset->components->count()).'</span>' : '' !!}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
@@ -75,7 +73,7 @@
|
||||
<i class="fas fa-barcode fa-2x" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="hidden-xs hidden-sm">{{ trans('general.assets') }}
|
||||
{!! ($asset->assignedAssets()->count() > 0 ) ? '<badge class="badge badge-secondary">'.number_format($asset->assignedAssets()->count()).'</badge>' : '' !!}
|
||||
{!! ($asset->assignedAssets()->count() > 0 ) ? '<span class="badge badge-secondary">'.number_format($asset->assignedAssets()->count()).'</span>' : '' !!}
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -98,7 +96,7 @@
|
||||
<i class="fas fa-wrench fa-2x" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="hidden-xs hidden-sm">{{ trans('general.maintenances') }}
|
||||
{!! ($asset->assetmaintenances()->count() > 0 ) ? '<badge class="badge badge-secondary">'.number_format($asset->assetmaintenances()->count()).'</badge>' : '' !!}
|
||||
{!! ($asset->assetmaintenances()->count() > 0 ) ? '<span class="badge badge-secondary">'.number_format($asset->assetmaintenances()->count()).'</span>' : '' !!}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
@@ -109,7 +107,7 @@
|
||||
<i class="far fa-file fa-2x" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="hidden-xs hidden-sm">{{ trans('general.files') }}
|
||||
{!! ($asset->uploads->count() > 0 ) ? '<badge class="badge badge-secondary">'.number_format($asset->uploads->count()).'</badge>' : '' !!}
|
||||
{!! ($asset->uploads->count() > 0 ) ? '<span class="badge badge-secondary">'.number_format($asset->uploads->count()).'</span>' : '' !!}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
@@ -121,7 +119,7 @@
|
||||
</span>
|
||||
<span class="hidden-xs hidden-sm">
|
||||
{{ trans('general.additional_files') }}
|
||||
{!! ($asset->model) && ($asset->model->uploads->count() > 0 ) ? '<badge class="badge badge-secondary">'.number_format($asset->model->uploads->count()).'</badge>' : '' !!}
|
||||
{!! ($asset->model) && ($asset->model->uploads->count() > 0 ) ? '<span class="badge badge-secondary">'.number_format($asset->model->uploads->count()).'</span>' : '' !!}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
@@ -140,6 +138,7 @@
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade in active" id="details">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
@@ -415,19 +414,24 @@
|
||||
|
||||
@if ($field->isFieldDecryptable($asset->{$field->db_column_name()} ))
|
||||
@can('assets.view.encrypted_custom_fields')
|
||||
<span id="text-{{ $field->id }}-to-hide">********</span>
|
||||
<span class="js-copy-{{ $field->id }}" id="text-{{ $field->id }}-to-show" style="font-size: 0px;">
|
||||
@if (($field->format=='URL') && ($asset->{$field->db_column_name()}!=''))
|
||||
<a href="{{ Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}) }}" target="_new">{{ Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}) }}</a>
|
||||
@elseif (($field->format=='DATE') && ($asset->{$field->db_column_name()}!=''))
|
||||
{{ \App\Helpers\Helper::gracefulDecrypt($field, \App\Helpers\Helper::getFormattedDateObject($asset->{$field->db_column_name()}, 'date', false)) }}
|
||||
@else
|
||||
{{ Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}) }}
|
||||
@endif
|
||||
</span>
|
||||
<i class="fa-regular fa-clipboard js-copy-link" data-clipboard-target=".js-copy-{{ $field->id }}" aria-hidden="true" data-tooltip="true" data-placement="top" title="{{ trans('general.copy_to_clipboard') }}">
|
||||
<span class="sr-only">{{ trans('general.copy_to_clipboard') }}</span>
|
||||
</i>
|
||||
@php
|
||||
$fieldSize=strlen(Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}))
|
||||
@endphp
|
||||
@if ($fieldSize>0)
|
||||
<span id="text-{{ $field->id }}-to-hide">{{ str_repeat('*', $fieldSize) }}</span>
|
||||
<span class="js-copy-{{ $field->id }}" id="text-{{ $field->id }}-to-show" style="font-size: 0px;">
|
||||
@if (($field->format=='URL') && ($asset->{$field->db_column_name()}!=''))
|
||||
<a href="{{ Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}) }}" target="_new">{{ Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}) }}</a>
|
||||
@elseif (($field->format=='DATE') && ($asset->{$field->db_column_name()}!=''))
|
||||
{{ \App\Helpers\Helper::gracefulDecrypt($field, \App\Helpers\Helper::getFormattedDateObject($asset->{$field->db_column_name()}, 'date', false)) }}
|
||||
@else
|
||||
{{ Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}) }}
|
||||
@endif
|
||||
</span>
|
||||
<i class="fa-regular fa-clipboard js-copy-link" data-clipboard-target=".js-copy-{{ $field->id }}" aria-hidden="true" data-tooltip="true" data-placement="top" title="{{ trans('general.copy_to_clipboard') }}">
|
||||
<span class="sr-only">{{ trans('general.copy_to_clipboard') }}</span>
|
||||
</i>
|
||||
@endif
|
||||
@else
|
||||
{{ strtoupper(trans('admin/custom_fields/general.encrypted')) }}
|
||||
@endcan
|
||||
@@ -926,6 +930,7 @@
|
||||
<button class="btn btn-sm btn-warning col-md-12">{{ trans('general.restore') }}</button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
@endcan
|
||||
|
||||
@if (($asset->assignedTo) && ($asset->deleted_at==''))
|
||||
@@ -995,7 +1000,7 @@
|
||||
</div> <!-- div.col-md-4 -->
|
||||
</div><!-- /row -->
|
||||
</div><!-- /.tab-pane asset details -->
|
||||
</div>
|
||||
|
||||
|
||||
<div class="tab-pane fade" id="software">
|
||||
<div class="row">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}"
|
||||
dir="{{ in_array(app()->getLocale(),['ar-SA','fa-IR', 'he-IL']) ? 'rtl' : 'ltr' }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
@@ -374,7 +375,7 @@
|
||||
</a>
|
||||
</li>
|
||||
@endcan
|
||||
<li class="divider"></li>
|
||||
<li class="divider" style="margin-top: -1px; margin-bottom: -1px"></li>
|
||||
<li>
|
||||
|
||||
<a href="{{ route('logout.get') }}"
|
||||
@@ -437,6 +438,9 @@
|
||||
<a href="{{ url('hardware') }}">
|
||||
<i class="far fa-circle text-grey fa-fw" aria-hidden="true"></i>
|
||||
{{ trans('general.list_all') }}
|
||||
<span class="badge">
|
||||
{{ (isset($total_assets)) ? $total_assets : '' }}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -447,7 +451,8 @@
|
||||
<a href="{{ route('statuslabels.show', ['statuslabel' => $status_nav->id]) }}">
|
||||
<i class="fas fa-circle text-grey fa-fw"
|
||||
aria-hidden="true"{!! ($status_nav->color!='' ? ' style="color: '.e($status_nav->color).'"' : '') !!}></i>
|
||||
{{ $status_nav->name }} ({{ $status_nav->asset_count }})</a></li>
|
||||
{{ $status_nav->name }}
|
||||
<span class="badge badge-secondary">{{ $status_nav->asset_count }}</span></a></li>
|
||||
@endforeach
|
||||
@endif
|
||||
|
||||
@@ -455,49 +460,43 @@
|
||||
<li{!! (Request::query('status') == 'Deployed' ? ' class="active"' : '') !!}>
|
||||
<a href="{{ url('hardware?status=Deployed') }}">
|
||||
<i class="far fa-circle text-blue fa-fw"></i>
|
||||
{{ trans('general.all') }}
|
||||
{{ trans('general.deployed') }}
|
||||
({{ (isset($total_deployed_sidebar)) ? $total_deployed_sidebar : '' }})
|
||||
<span class="badge">{{ (isset($total_deployed_sidebar)) ? $total_deployed_sidebar : '' }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li{!! (Request::query('status') == 'RTD' ? ' class="active"' : '') !!}>
|
||||
<a href="{{ url('hardware?status=RTD') }}">
|
||||
<i class="far fa-circle text-green fa-fw"></i>
|
||||
{{ trans('general.all') }}
|
||||
{{ trans('general.ready_to_deploy') }}
|
||||
({{ (isset($total_rtd_sidebar)) ? $total_rtd_sidebar : '' }})
|
||||
<span class="badge">{{ (isset($total_rtd_sidebar)) ? $total_rtd_sidebar : '' }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li{!! (Request::query('status') == 'Pending' ? ' class="active"' : '') !!}><a
|
||||
href="{{ url('hardware?status=Pending') }}"><i
|
||||
class="far fa-circle text-orange fa-fw"></i>
|
||||
{{ trans('general.all') }}
|
||||
{{ trans('general.pending') }}
|
||||
({{ (isset($total_pending_sidebar)) ? $total_pending_sidebar : '' }})
|
||||
<span class="badge">{{ (isset($total_pending_sidebar)) ? $total_pending_sidebar : '' }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li{!! (Request::query('status') == 'Undeployable' ? ' class="active"' : '') !!} ><a
|
||||
href="{{ url('hardware?status=Undeployable') }}"><i
|
||||
class="fas fa-times text-red fa-fw"></i>
|
||||
{{ trans('general.all') }}
|
||||
{{ trans('general.undeployable') }}
|
||||
({{ (isset($total_undeployable_sidebar)) ? $total_undeployable_sidebar : '' }})
|
||||
<span class="badge">{{ (isset($total_undeployable_sidebar)) ? $total_undeployable_sidebar : '' }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li{!! (Request::query('status') == 'byod' ? ' class="active"' : '') !!}><a
|
||||
href="{{ url('hardware?status=byod') }}"><i
|
||||
class="fas fa-times text-red fa-fw"></i>
|
||||
{{ trans('general.all') }}
|
||||
{{ trans('general.byod') }}
|
||||
({{ (isset($total_byod_sidebar)) ? $total_byod_sidebar : '' }})
|
||||
<span class="badge">{{ (isset($total_byod_sidebar)) ? $total_byod_sidebar : '' }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li{!! (Request::query('status') == 'Archived' ? ' class="active"' : '') !!}><a
|
||||
href="{{ url('hardware?status=Archived') }}"><i
|
||||
class="fas fa-times text-red fa-fw"></i>
|
||||
{{ trans('general.all') }}
|
||||
{{ trans('admin/hardware/general.archived') }}
|
||||
({{ (isset($total_archived_sidebar)) ? $total_archived_sidebar : '' }})
|
||||
<span class="badge">{{ (isset($total_archived_sidebar)) ? $total_archived_sidebar : '' }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li{!! (Request::query('status') == 'Requestable' ? ' class="active"' : '') !!}><a
|
||||
@@ -511,13 +510,18 @@
|
||||
<li{!! (Request::is('hardware/audit/due') ? ' class="active"' : '') !!}>
|
||||
<a href="{{ route('assets.audit.due') }}">
|
||||
<i class="fas fa-history text-yellow fa-fw"></i> {{ trans('general.audit_due') }}
|
||||
<span class="badge">{{ (isset($total_due_and_overdue_for_audit)) ? $total_due_and_overdue_for_audit : '' }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li{!! (Request::is('hardware/audit/overdue') ? ' class="active"' : '') !!}>
|
||||
<a href="{{ route('assets.audit.overdue') }}">
|
||||
<i class="fas fa-exclamation-triangle text-red fa-fw"></i> {{ trans('general.audit_overdue') }}
|
||||
</a>
|
||||
</li>
|
||||
@endcan
|
||||
|
||||
@can('checkin', \App\Models\Asset::class)
|
||||
<li{!! (Request::is('hardware/checkins/due') ? ' class="active"' : '') !!}>
|
||||
<a href="{{ route('assets.checkins.due') }}">
|
||||
<i class="fas fa-history text-yellow fa-fw"></i> {{ trans('general.checkin_due') }}
|
||||
<span class="badge">{{ (isset($total_due_and_overdue_for_checkin)) ? $total_due_and_overdue_for_checkin : '' }}</span>
|
||||
</a>
|
||||
</li>
|
||||
@endcan
|
||||
|
||||
<li class="divider"> </li>
|
||||
@@ -1041,6 +1045,64 @@
|
||||
});
|
||||
});
|
||||
|
||||
// Select encrypted custom fields to hide them in the asset list
|
||||
$(document).ready(function() {
|
||||
// Selector for elements with css-padlock class
|
||||
var selector = 'td.css-padlock';
|
||||
|
||||
// Function to add original value to elements
|
||||
function addValue($element) {
|
||||
// Get original value of the element
|
||||
var originalValue = $element.text().trim();
|
||||
|
||||
// Show asterisks only for not empty values
|
||||
if (originalValue !== '') {
|
||||
// This is necessary to avoid loop because value is generated dynamically
|
||||
if (originalValue !== '' && originalValue !== asterisks) $element.attr('value', originalValue);
|
||||
|
||||
// Hide the original value and show asterisks of the same length
|
||||
var asterisks = '*'.repeat(originalValue.length);
|
||||
$element.text(asterisks);
|
||||
|
||||
// Add click event to show original text
|
||||
$element.click(function() {
|
||||
var $this = $(this);
|
||||
if ($this.text().trim() === asterisks) {
|
||||
$this.text($this.attr('value'));
|
||||
} else {
|
||||
$this.text(asterisks);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// Add value to existing elements
|
||||
$(selector).each(function() {
|
||||
addValue($(this));
|
||||
});
|
||||
|
||||
// Function to handle mutations in the DOM because content is generated dynamically
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
// Check if new nodes have been inserted
|
||||
if (mutation.type === 'childList') {
|
||||
mutation.addedNodes.forEach(function(node) {
|
||||
if ($(node).is(selector)) {
|
||||
addValue($(node));
|
||||
} else {
|
||||
$(node).find(selector).each(function() {
|
||||
addValue($(this));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Configure the observer to observe changes in the DOM
|
||||
var config = { childList: true, subtree: true };
|
||||
observer.observe(document.body, config);
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
{{ trans('general.create') }}
|
||||
</a>
|
||||
@endcan
|
||||
@can('view', \App\Models\License::class)
|
||||
<a class="btn btn-default pull-right" href="{{ route('licenses.export') }}" style="margin-right: 5px;">{{ trans('general.export') }}</a>
|
||||
@endcan
|
||||
@stop
|
||||
|
||||
{{-- Page content --}}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<div class="dynamic-form-row">
|
||||
<div class="col-md-4 col-xs-12"><label for="modal-city">{{ trans('general.city') }}:</label></div>
|
||||
<div class="col-md-8 col-xs-12 required"><input type='text' name="city" id='modal-city' class="form-control"></div>
|
||||
<div class="col-md-8 col-xs-12"><input type='text' name="city" id='modal-city' class="form-control"></div>
|
||||
</div>
|
||||
|
||||
<div class="dynamic-form-row">
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
@php
|
||||
$checkin = Helper::getFormattedDateObject($asset->expected_checkin, 'date');
|
||||
@endphp
|
||||
| [{{ $asset->present()->name }}]({{ route('hardware.show', ['hardware' => $asset->id]) }}) | [{{ $asset->assigned->present()->fullName }}]({{ route($asset->targetShowRoute().'.show', [$asset->assigned->id]) }}) | {{ $checkin['formatted'] }}
|
||||
| [{{ $asset->present()->name }}]({{ route('hardware.show', ['hardware' => $asset->id]) }}) | [{{ $asset->assignedTo->present()->fullName }}]({{ route($asset->targetShowRoute().'.show', [$asset->assignedTo->id]) }}) | {{ $checkin['formatted'] }}
|
||||
@endforeach
|
||||
@endcomponent
|
||||
|
||||
|
||||
@@ -306,6 +306,7 @@
|
||||
<label style="grid-area: source-title">DataSource</label>
|
||||
<select style="grid-area: source-field" x-model="option.datasource">
|
||||
<optgroup label="Asset">
|
||||
<option value="" disabled>{{ trans('general.select_datasource') }}</option>
|
||||
<option value="asset_tag">{{trans('admin/hardware/table.asset_tag')}}</option>
|
||||
<option value="name">{{trans('admin/hardware/form.name')}}</option>
|
||||
<option value="serial">{{trans('admin/hardware/table.serial')}}</option>
|
||||
@@ -313,6 +314,8 @@
|
||||
<option value="order_number">{{trans('admin/hardware/form.order')}}</option>
|
||||
<option value="purchase_date">{{trans('admin/hardware/table.purchase_date')}}</option>
|
||||
<option value="assignedTo">{{trans('admin/hardware/table.assigned_to')}}</option>
|
||||
<option value="last_audit_date">{{trans('general.last_audit')}}</option>
|
||||
<option value="next_audit_date">{{trans('general.next_audit_date')}}</option>
|
||||
</optgroup>
|
||||
<optgroup label="Asset Model">
|
||||
<option value="model.name">{{trans('admin/models/table.name')}}</option>
|
||||
@@ -348,6 +351,7 @@
|
||||
</optgroup>
|
||||
<optgroup label="Custom Fields">
|
||||
@foreach($customFields as $customField)
|
||||
|
||||
<option value="{{ $customField->db_column }}">{{ $customField->name }}</option>
|
||||
@endforeach
|
||||
</optgroup>
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
<span id="searchclear" class="fas fa-times" aria-hidden="true"></span>
|
||||
<button type="submit" disabled style="display: none" aria-hidden="true"></button>
|
||||
</div>
|
||||
<a href="{{ route('settings.index') }}" class="btn btn-primary pull-right" style="margin-left: 10px;">{{ trans('general.back') }}</a>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
@@ -89,9 +89,9 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@if ($user->managedLocations()->count() >= 0 )
|
||||
@if ($user->managedLocations->count() >= 0 )
|
||||
<li>
|
||||
<a href="#managed" data-toggle="tab">
|
||||
<a href="#managed-locations" data-toggle="tab">
|
||||
<span class="hidden-lg hidden-md">
|
||||
<i class="fas fa-map-marker-alt fa-2x"></i></span>
|
||||
<span class="hidden-xs hidden-sm">{{ trans('admin/users/table.managed_locations') }}
|
||||
@@ -100,7 +100,19 @@
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@can('update', $user)
|
||||
@if ($user->managesUsers->count() >= 0 )
|
||||
<li>
|
||||
<a href="#managed-users" data-toggle="tab">
|
||||
<span class="hidden-lg hidden-md">
|
||||
<i class="fa-solid fa-users fa-2x"></i></span>
|
||||
<span class="hidden-xs hidden-sm">{{ trans('admin/users/table.managed_users') }}
|
||||
{!! ($user->managesUsers->count() > 0 ) ? '<badge class="badge badge-secondary">'.number_format($user->managesUsers->count()).'</badge>' : '' !!}
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
|
||||
@can('update', $user)
|
||||
<li class="dropdown pull-right">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<span class="hidden-xs"><i class="fas fa-cog" aria-hidden="true"></i></span>
|
||||
@@ -114,7 +126,7 @@
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{ route('users.edit', $user->id) }}">{{ trans('admin/users/general.edit') }}</a></li>
|
||||
<li><a href="{{ route('users.clone.show', $user->id) }}">{{ trans('admin/users/general.clone') }}</a></li>
|
||||
@if ((Auth::user()->id !== $user->id) && (!config('app.lock_passwords')) && ($user->deleted_at==''))
|
||||
@if ((Auth::user()->id !== $user->id) && (!config('app.lock_passwords')) && ($user->deleted_at=='') && ($user->isDeletable()))
|
||||
<li><a href="{{ route('users.destroy', $user->id) }}">{{ trans('button.delete') }}</a></li>
|
||||
@endif
|
||||
</ul>
|
||||
@@ -221,11 +233,15 @@
|
||||
@can('delete', $user)
|
||||
@if ($user->deleted_at=='')
|
||||
<div class="col-md-12" style="padding-top: 30px;">
|
||||
<form action="{{route('users.destroy',$user->id)}}" method="POST">
|
||||
{{csrf_field()}}
|
||||
{{ method_field("DELETE")}}
|
||||
<button style="width: 100%;" class="btn btn-sm btn-warning hidden-print">{{ trans('button.delete')}}</button>
|
||||
</form>
|
||||
@if ($user->isDeletable())
|
||||
<form action="{{route('users.destroy',$user->id)}}" method="POST">
|
||||
{{csrf_field()}}
|
||||
{{ method_field("DELETE")}}
|
||||
<button style="width: 100%;" class="btn btn-sm btn-warning hidden-print">{{ trans('button.delete')}}</button>
|
||||
</form>
|
||||
@else
|
||||
<button style="width: 100%;" class="btn btn-sm btn-warning hidden-print disabled">{{ trans('button.delete')}}</button>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-md-12" style="padding-top: 5px;">
|
||||
<form action="{{ route('users/bulkedit') }}" method="POST">
|
||||
@@ -1014,7 +1030,7 @@
|
||||
</div>
|
||||
</div><!-- /.tab-pane -->
|
||||
|
||||
<div class="tab-pane" id="managed">
|
||||
<div class="tab-pane" id="managed-locations">
|
||||
|
||||
@include('partials.locations-bulk-actions')
|
||||
|
||||
@@ -1046,6 +1062,39 @@
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="managed-users">
|
||||
|
||||
@include('partials.locations-bulk-actions')
|
||||
|
||||
|
||||
<table
|
||||
data-columns="{{ \App\Presenters\UserPresenter::dataTableLayout() }}"
|
||||
data-cookie-id-table="managedUsersTable"
|
||||
data-click-to-select="true"
|
||||
data-pagination="true"
|
||||
data-id-table="managedUsersTable"
|
||||
data-toolbar="#usersBulkEditToolbar"
|
||||
data-bulk-button-id="#bulkUsersEditButton"
|
||||
data-bulk-form-id="#usersBulkForm"
|
||||
data-search="true"
|
||||
data-show-footer="true"
|
||||
data-side-pagination="server"
|
||||
data-show-columns="true"
|
||||
data-show-fullscreen="true"
|
||||
data-show-export="true"
|
||||
data-show-refresh="true"
|
||||
data-sort-order="asc"
|
||||
id="managedUsersTable"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{ route('api.users.index', ['manager_id' => $user->id]) }}"
|
||||
data-export-options='{
|
||||
"fileName": "export-users-{{ date('Y-m-d') }}",
|
||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||
}'>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div><!-- /consumables-tab -->
|
||||
</div><!-- /.tab-content -->
|
||||
</div><!-- nav-tabs-custom -->
|
||||
|
||||
+15
-1
@@ -496,13 +496,27 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi
|
||||
)->name('api.assets.show.byserial')
|
||||
->where('any', '.*');
|
||||
|
||||
Route::get('audit/{audit}',
|
||||
// LEGACY URL - Get assets that are due or overdue for audit
|
||||
Route::get('audit/{status}',
|
||||
[
|
||||
Api\AssetsController::class,
|
||||
'index'
|
||||
]
|
||||
)->name('api.asset.to-audit');
|
||||
|
||||
|
||||
|
||||
// This gets the "due or overdue" API endpoints for audits and checkins
|
||||
Route::get('{action}/{upcoming_status}',
|
||||
[
|
||||
Api\AssetsController::class,
|
||||
'index'
|
||||
]
|
||||
)->name('api.assets.list-upcoming')
|
||||
->where(['action' => 'audits|checkins', 'upcoming_status' => 'due|overdue|due-or-overdue']);
|
||||
|
||||
|
||||
|
||||
Route::post('audit',
|
||||
[
|
||||
Api\AssetsController::class,
|
||||
|
||||
+4
-20
@@ -50,26 +50,10 @@ Route::group(
|
||||
[AssetsController::class, 'dueForAudit']
|
||||
)->name('assets.audit.due');
|
||||
|
||||
Route::get('audit/overdue',
|
||||
[AssetsController::class, 'overdueForAudit']
|
||||
)->name('assets.audit.overdue');
|
||||
|
||||
Route::get('audit/due',
|
||||
[AssetsController::class, 'dueForAudit']
|
||||
)->name('assets.audit.due');
|
||||
|
||||
Route::get('audit/overdue',
|
||||
[AssetsController::class, 'overdueForAudit']
|
||||
)->name('assets.audit.overdue');
|
||||
|
||||
Route::get('audit/due',
|
||||
[AssetsController::class, 'dueForAudit']
|
||||
)->name('assets.audit.due');
|
||||
|
||||
Route::get('audit/overdue',
|
||||
[AssetsController::class, 'overdueForAudit']
|
||||
)->name('assets.audit.overdue');
|
||||
|
||||
Route::get('checkins/due',
|
||||
[AssetsController::class, 'dueForCheckin']
|
||||
)->name('assets.checkins.due');
|
||||
|
||||
Route::get('audit/{id}',
|
||||
[AssetsController::class, 'audit']
|
||||
)->name('asset.audit.create');
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user