From 6d6b47365907f76f1534b5559b005dfbb1b69b4c Mon Sep 17 00:00:00 2001 From: Brian Penner Date: Sat, 3 Jan 2026 17:44:45 -0500 Subject: [PATCH 1/6] activation table tweaks --- .../Admin/AppUserActivationCrudController.php | 87 ++++++++----------- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/CloudVeilManager/app/Http/Controllers/Admin/AppUserActivationCrudController.php b/CloudVeilManager/app/Http/Controllers/Admin/AppUserActivationCrudController.php index 322a941..fb56512 100644 --- a/CloudVeilManager/app/Http/Controllers/Admin/AppUserActivationCrudController.php +++ b/CloudVeilManager/app/Http/Controllers/Admin/AppUserActivationCrudController.php @@ -23,7 +23,7 @@ class AppUserActivationCrudController extends CrudController } - /** + /** * Configure the CrudPanel object. Apply settings to all operations. * * @return void @@ -45,67 +45,56 @@ protected function setupListOperation() { $this->crud->setColumns([ [ - 'label' => 'User', - 'type' => 'select', - 'name' => 'user_id', - 'attribute' => 'name', - 'key' => 'user_name', + 'label' => 'Device', + 'type' => 'custom_html', + 'name' => 'device', + 'value' => function ($entry) { + $friendlyName = $entry->friendly_name ?: '-'; + $deviceId = $entry->device_id ?: '-'; + return '
' . e($friendlyName) . '
' . e($deviceId) . '
'; + }, + 'escaped' => false, 'priority' => 1 ], [ - 'label' => 'E-Mail', - 'type' => 'select', + 'label' => 'User', + 'type' => 'custom_html', 'name' => 'user_id', - 'attribute' => 'email', - 'key' => 'user_email', - 'priority' => 2 - ], - [ - 'label' => 'Device ID', - 'type' => 'text', - 'name' => 'device_id', - 'priority' => 1 - ], - [ - 'label' => 'IP Address', - 'type' => 'text', - 'name' => 'ip_address', + 'value' => function ($entry) { + $user = $entry->user; + if (!$user) { + return '-'; + } + return '
' . e($user->name) . '
' . e($user->email) . '
'; + }, + 'escaped' => false, 'priority' => 1 ], [ - 'label' => 'Bypass', - 'type' => 'text', - 'name' => 'bypass_formatted', + 'label' => 'Group', + 'type' => 'select', + 'name' => 'group_id', + 'attribute' => 'name', + 'entity' => 'group', + 'key' => 'group_name', 'priority' => 1 ], [ 'label' => 'Version', - 'type' => 'text', - 'name' => 'app_version', - 'priority' => 1 - ], - [ - 'label' => 'Updated at', - 'type' => 'datetime', - 'name' => 'updated_at', - 'priority' => 1 - ], - [ - 'label' => 'OS', - 'type' => 'text', - 'name' => 'os_formatted', + 'type' => 'custom_html', + 'name' => 'version', + 'value' => function ($entry) { + $appVersion = $entry->app_version ?: '-'; + $osFormatted = $entry->os_formatted ?: '-'; + return '
' . e($appVersion) . '
' . e($osFormatted) . '
'; + }, + 'escaped' => false, 'priority' => 1, - 'orderable' => true, + 'orderable' => true, 'orderLogic' => function ($query, $column, $columnDirection) { return $query->orderBy('platform_name', $columnDirection); } ], - [ - 'label' => 'Friendly Name', - 'type' => 'text', - 'name' => 'friendly_name', - 'priority' => 2 - ], [ 'label' => 'Identifier', 'type' => 'hidden', @@ -123,10 +112,10 @@ protected function setupListOperation() */ protected function setupCreateOperation() { - CRUD::setValidation([ - ]); + CRUD::setValidation([]); - $this->crud->addFields([ + $this->crud->addFields( + [ [ 'label' => 'User Name', 'type' => 'select', From dce17fa9d5e017bd41c935b5d89b0f169ff8799d Mon Sep 17 00:00:00 2001 From: Brian Penner Date: Sat, 3 Jan 2026 19:10:39 -0500 Subject: [PATCH 2/6] add activation filters --- .../Admin/AppUserActivationCrudController.php | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/CloudVeilManager/app/Http/Controllers/Admin/AppUserActivationCrudController.php b/CloudVeilManager/app/Http/Controllers/Admin/AppUserActivationCrudController.php index fb56512..9a24ffe 100644 --- a/CloudVeilManager/app/Http/Controllers/Admin/AppUserActivationCrudController.php +++ b/CloudVeilManager/app/Http/Controllers/Admin/AppUserActivationCrudController.php @@ -4,6 +4,8 @@ use Backpack\CRUD\app\Http\Controllers\CrudController; use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD; +use App\Models\User; +use App\Models\SystemPlatform; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; @@ -102,6 +104,59 @@ protected function setupListOperation() 'searchLogic' => 'text' ] ]); + + // Platform filter + CRUD::filter('platform_name') + ->type('dropdown') + ->label('Platform') + ->values([ + SystemPlatform::PLATFORM_WIN => 'Windows', + SystemPlatform::PLATFORM_OSX => 'macOS', + ]) + ->whenActive(function ($value) { + CRUD::addClause('where', 'platform_name', $value); + }); + + // App Version filter + CRUD::filter('app_version') + ->type('text') + ->label('App Version') + ->whenActive(function ($value) { + CRUD::addClause('where', 'app_version', 'LIKE', "%{$value}%"); + }); + + // User filter + CRUD::filter('user_id') + ->type('select2') + ->label('User') + ->values(function () { + return User::all()->pluck('name', 'id')->toArray(); + }) + ->whenActive(function ($value) { + CRUD::addClause('where', 'user_id', $value); + }); + + // Last Sync Time filter + CRUD::filter('last_sync_time') + ->type('date_range') + ->label('Last Sync Time') + ->whenActive(function ($value) { + $dates = json_decode($value); + if ($dates->from) { + CRUD::addClause('where', 'last_sync_time', '>=', $dates->from); + } + if ($dates->to) { + CRUD::addClause('where', 'last_sync_time', '<=', $dates->to . ' 23:59:59'); + } + }); + + // OS Version filter + CRUD::filter('os_version') + ->type('text') + ->label('OS Version') + ->whenActive(function ($value) { + CRUD::addClause('where', 'os_version', 'LIKE', "%{$value}%"); + }); } /** From 580d6ac400d496397dad082974d1121c21573f2e Mon Sep 17 00:00:00 2001 From: Brian Penner Date: Mon, 5 Jan 2026 16:19:20 -0500 Subject: [PATCH 3/6] fix bootstrap dropdowns --- CloudVeilManager/config/backpack/ui.php | 2 ++ CloudVeilManager/resources/js/bootstrap.js | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CloudVeilManager/config/backpack/ui.php b/CloudVeilManager/config/backpack/ui.php index ccd73d2..0d35c87 100644 --- a/CloudVeilManager/config/backpack/ui.php +++ b/CloudVeilManager/config/backpack/ui.php @@ -115,6 +115,8 @@ // JS files that are loaded in all pages, using Laravel's asset() helper 'scripts' => [ + // Bootstrap 5 JavaScript - required for dropdowns and collapses + 'https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js', // 'js/example.js', // 'https://cdn.jsdelivr.net/npm/vue@2.4.4/dist/vue.min.js', // 'https://cdn.jsdelivr.net/npm/react@16/umd/react.production.min.js', diff --git a/CloudVeilManager/resources/js/bootstrap.js b/CloudVeilManager/resources/js/bootstrap.js index 4d73ffb..f22804c 100644 --- a/CloudVeilManager/resources/js/bootstrap.js +++ b/CloudVeilManager/resources/js/bootstrap.js @@ -1,4 +1,6 @@ -import 'bootstrap'; +// Bootstrap is loaded via CDN in config/backpack/ui.php +// This ensures window.bootstrap is available globally for Backpack's JavaScript +// import 'bootstrap'; /** * We'll load the axios HTTP library which allows us to easily issue requests From e46dffb29a9a1b3afbf2f8a034249832b5fd4e31 Mon Sep 17 00:00:00 2001 From: Brian Penner Date: Mon, 5 Jan 2026 16:33:02 -0500 Subject: [PATCH 4/6] fix license used column --- .../Controllers/Admin/UserCrudController.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/CloudVeilManager/app/Http/Controllers/Admin/UserCrudController.php b/CloudVeilManager/app/Http/Controllers/Admin/UserCrudController.php index 104c4cd..14d42fb 100644 --- a/CloudVeilManager/app/Http/Controllers/Admin/UserCrudController.php +++ b/CloudVeilManager/app/Http/Controllers/Admin/UserCrudController.php @@ -61,8 +61,13 @@ protected function setupListOperation() ], [ 'label' => 'License Used', - 'type' => 'datetime', - 'name' => 'updated_at' + 'type' => 'text', + 'name' => 'license_used', + 'value' => function ($entry) { + $used = $entry->activations_used ?? 0; + $allowed = $entry->activations_allowed ?? 0; + return $used . ' of ' . $allowed; + } ], [ 'label' => 'Active', @@ -106,12 +111,13 @@ protected function setupFields($fromEdit = true) } CRUD::setValidation($validationRules); - $this->crud->addFields([ + $this->crud->addFields( + [ [ 'type' => 'custom_html', 'name' => 'activations', 'value' => ' - Show Activations + Show Activations ', 'tab' => 'Information', ], @@ -334,7 +340,8 @@ protected function setupUpdateOperation() $this->setupFields(true); } - protected function setupCreateOperation() { + protected function setupCreateOperation() + { $this->setupFields(false); } From 97f01d7bd22fd602aaad5e27343e02347e901a7b Mon Sep 17 00:00:00 2001 From: Brian Penner Date: Mon, 5 Jan 2026 17:19:39 -0500 Subject: [PATCH 5/6] remove password confirmation field and update relaxed policy passcode type to password_revealable --- .../Controllers/Admin/UserCrudController.php | 13 +--- .../crud/fields/password_revealable.blade.php | 73 +++++++++++++++++++ 2 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 CloudVeilManager/resources/views/vendor/backpack/crud/fields/password_revealable.blade.php diff --git a/CloudVeilManager/app/Http/Controllers/Admin/UserCrudController.php b/CloudVeilManager/app/Http/Controllers/Admin/UserCrudController.php index 14d42fb..360f424 100644 --- a/CloudVeilManager/app/Http/Controllers/Admin/UserCrudController.php +++ b/CloudVeilManager/app/Http/Controllers/Admin/UserCrudController.php @@ -152,13 +152,6 @@ protected function setupFields($fromEdit = true) 'tab' => 'Information', 'wrapper' => ['class' => 'form-group col-md-6'], ], - [ - 'label' => 'Password Confirm', - 'type' => 'password', - 'name' => 'password_verify', - 'tab' => 'Information', - 'wrapper' => ['class' => 'form-group col-md-6'], - ], [ 'label' => 'Activations Allowed', 'type' => 'number', @@ -185,17 +178,17 @@ protected function setupFields($fromEdit = true) ], [ 'label' => 'Relaxed Policy Passcode', - 'type' => 'password', + 'type' => 'password_revealable', 'name' => 'relaxed_policy_passcode', 'tab' => 'Information', - 'wrapper' => ['class' => 'form-group col-md-8'], + 'wrapper' => ['class' => 'form-group col-md-6'], ], [ 'label' => 'Enable Relaxed Policy Passcode', 'type' => 'switch', 'name' => 'enable_relaxed_policy_passcode', 'tab' => 'Information', - 'wrapper' => ['class' => 'form-group col-md-2 d-flex pt-3'], + 'wrapper' => ['class' => 'form-group col-md-6 d-flex pt-3'], ], [ 'name' => 'BypassesPermitted', diff --git a/CloudVeilManager/resources/views/vendor/backpack/crud/fields/password_revealable.blade.php b/CloudVeilManager/resources/views/vendor/backpack/crud/fields/password_revealable.blade.php new file mode 100644 index 0000000..444e786 --- /dev/null +++ b/CloudVeilManager/resources/views/vendor/backpack/crud/fields/password_revealable.blade.php @@ -0,0 +1,73 @@ +{{-- password_revealable --}} + +@php + $field['value'] = old_empty_or_null($field['name'], '') ?? ($field['value'] ?? ($field['default'] ?? '')); + // autocomplete off, if not otherwise specified + if (!isset($field['attributes']['autocomplete'])) { + $field['attributes']['autocomplete'] = "off"; + } +@endphp + +@include('crud::fields.inc.wrapper_start') + + @include('crud::fields.inc.translatable_icon') + +
+ + + + + + + + + + +
+ + {{-- HINT --}} + @if (isset($field['hint'])) +

{!! $field['hint'] !!}

+ @endif +@include('crud::fields.inc.wrapper_end') + +{{-- FIELD JS - will be loaded in the after_scripts section --}} +@push('crud_fields_scripts') + +@endpush + From a6b8c2764fd49ef5edc918a422e9d1654b800e20 Mon Sep 17 00:00:00 2001 From: Brian Penner Date: Mon, 5 Jan 2026 17:26:22 -0500 Subject: [PATCH 6/6] refactor user form fields to improve layout and reintroduce password and activations allowed fields --- .../Controllers/Admin/UserCrudController.php | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/CloudVeilManager/app/Http/Controllers/Admin/UserCrudController.php b/CloudVeilManager/app/Http/Controllers/Admin/UserCrudController.php index 360f424..4aaaa47 100644 --- a/CloudVeilManager/app/Http/Controllers/Admin/UserCrudController.php +++ b/CloudVeilManager/app/Http/Controllers/Admin/UserCrudController.php @@ -125,38 +125,22 @@ protected function setupFields($fromEdit = true) 'label' => 'User Full Name', 'type' => 'text', 'name' => 'name', - 'tab' => 'Information' + 'tab' => 'Information', + 'wrapper' => ['class' => 'form-group col-md-5'], ], [ 'label' => 'User E-Mail', 'type' => 'text', 'name' => 'email', - 'tab' => 'Information' + 'tab' => 'Information', + 'wrapper' => ['class' => 'form-group col-md-5'], ], [ 'label' => 'Enabled', 'type' => 'switch', 'name' => 'is_enabled', - 'tab' => 'Information' - ], - [ - 'label' => 'Customer ID', - 'type' => 'number', - 'name' => 'customer_id', - 'tab' => 'Information' - ], - [ - 'label' => 'Password', - 'type' => 'password', - 'name' => 'password', 'tab' => 'Information', - 'wrapper' => ['class' => 'form-group col-md-6'], - ], - [ - 'label' => 'Activations Allowed', - 'type' => 'number', - 'name' => 'activations_allowed', - 'tab' => 'Information' + 'wrapper' => ['class' => 'form-group col-md-2 d-flex pt-3'], ], [ 'label' => 'Group', @@ -165,7 +149,15 @@ protected function setupFields($fromEdit = true) 'model' => 'App\Models\Group', 'name' => 'group', 'attribute' => 'name', - 'tab' => 'Information' + 'tab' => 'Information', + 'wrapper' => ['class' => 'form-group col-md-6'], + ], + [ + 'label' => 'Activations Allowed', + 'type' => 'number', + 'name' => 'activations_allowed', + 'tab' => 'Information', + 'wrapper' => ['class' => 'form-group col-md-6'], ], [ 'label' => 'Roles', @@ -174,7 +166,15 @@ protected function setupFields($fromEdit = true) 'model' => 'App\Models\Role', 'attribute' => 'display_name', 'name' => 'roles', - 'tab' => 'Information' + 'tab' => 'Information', + 'wrapper' => ['class' => 'form-group col-md-6'], + ], + [ + 'label' => 'Password', + 'type' => 'password', + 'name' => 'password', + 'tab' => 'Information', + 'wrapper' => ['class' => 'form-group col-md-6'], ], [ 'label' => 'Relaxed Policy Passcode',