Skip to content

Commit 46779ca

Browse files
authored
Merge pull request #14697 from snipe/bug/sc-25502/disable_delete_if_not_deletable_user
Fixed UI where delete button was not disabled even if the user couldn't be deleted
2 parents 86661e7 + 8c327e6 commit 46779ca

File tree

12 files changed

+247
-35
lines changed

12 files changed

+247
-35
lines changed

app/Http/Controllers/Api/UsersController.php

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ public function index(Request $request)
7575
'users.autoassign_licenses',
7676
'users.website',
7777

78-
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy',)
79-
->withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count');
78+
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy')
79+
->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');
8080

8181

8282
if ($request->filled('activated')) {
@@ -187,6 +187,14 @@ public function index(Request $request)
187187
$users->has('accessories', '=', $request->input('accessories_count'));
188188
}
189189

190+
if ($request->filled('manages_users_count')) {
191+
$users->has('manages_users_count', '=', $request->input('manages_users_count'));
192+
}
193+
194+
if ($request->filled('manages_locations_count')) {
195+
$users->has('manages_locations_count', '=', $request->input('manages_locations_count'));
196+
}
197+
190198
if ($request->filled('autoassign_licenses')) {
191199
$users->where('autoassign_licenses', '=', $request->input('autoassign_licenses'));
192200
}
@@ -244,6 +252,8 @@ public function index(Request $request)
244252
'licenses_count',
245253
'consumables_count',
246254
'accessories_count',
255+
'manages_user_count',
256+
'manages_locations_count',
247257
'phone',
248258
'address',
249259
'city',
@@ -405,11 +415,15 @@ public function show($id)
405415
{
406416
$this->authorize('view', User::class);
407417

408-
$user = User::withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count')->findOrFail($id);
409-
$user = Company::scopeCompanyables($user)->find($id);
410-
$this->authorize('update', $user);
418+
$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');
419+
420+
if ($user = Company::scopeCompanyables($user)->find($id)) {
421+
$this->authorize('view', $user);
422+
return (new UsersTransformer)->transformUser($user);
423+
}
424+
425+
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.user_not_found', compact('id'))));
411426

412-
return (new UsersTransformer)->transformUser($user);
413427
}
414428

415429

@@ -470,7 +484,6 @@ public function update(SaveUserRequest $request, $id)
470484
}
471485

472486

473-
474487
// Update the location of any assets checked out to this user
475488
Asset::where('assigned_type', User::class)
476489
->where('assigned_to', $user->id)->update(['location_id' => $request->input('location_id', null)]);
@@ -480,12 +493,6 @@ public function update(SaveUserRequest $request, $id)
480493

481494
if ($user->save()) {
482495

483-
// Sync group memberships:
484-
// This was changed in Snipe-IT v4.6.x to 4.7, since we upgraded to Laravel 5.5
485-
// which changes the behavior of has vs filled.
486-
// The $request->has method will now return true even if the input value is an empty string or null.
487-
// A new $request->filled method has was added that provides the previous behavior of the has method.
488-
489496
// Check if the request has groups passed and has a value
490497
if ($request->filled('groups')) {
491498

app/Http/Transformers/UsersTransformer.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public function transformUsers(Collection $users, $total)
2121

2222
public function transformUser(User $user)
2323
{
24+
2425
$array = [
2526
'id' => (int) $user->id,
2627
'avatar' => e($user->present()->gravatar),
@@ -64,6 +65,8 @@ public function transformUser(User $user)
6465
'licenses_count' => (int) $user->licenses_count,
6566
'accessories_count' => (int) $user->accessories_count,
6667
'consumables_count' => (int) $user->consumables_count,
68+
'manages_users_count' => (int) $user->manages_users_count,
69+
'manages_locations_count' => (int) $user->manages_locations_count,
6770
'company' => ($user->company) ? ['id' => (int) $user->company->id, 'name'=> e($user->company->name)] : null,
6871
'created_by' => ($user->createdBy) ? [
6972
'id' => (int) $user->createdBy->id,

app/Models/User.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,12 @@ public function isSuperUser()
214214
public function isDeletable()
215215
{
216216
return Gate::allows('delete', $this)
217-
&& ($this->assets()->count() === 0)
218-
&& ($this->licenses()->count() === 0)
219-
&& ($this->consumables()->count() === 0)
220-
&& ($this->accessories()->count() === 0)
217+
&& ($this->assets->count() === 0)
218+
&& ($this->licenses->count() === 0)
219+
&& ($this->consumables->count() === 0)
220+
&& ($this->accessories->count() === 0)
221+
&& ($this->managedLocations->count() === 0)
222+
&& ($this->managesUsers->count() === 0)
221223
&& ($this->deleted_at == '');
222224
}
223225

@@ -410,6 +412,19 @@ public function manager()
410412
return $this->belongsTo(self::class, 'manager_id')->withTrashed();
411413
}
412414

415+
/**
416+
* Establishes the user -> managed users relationship
417+
*
418+
* @author A. Gianotto <[email protected]>
419+
* @since [v6.4.1]
420+
* @return \Illuminate\Database\Eloquent\Relations\Relation
421+
*/
422+
public function managesUsers()
423+
{
424+
return $this->hasMany(\App\Models\User::class, 'manager_id');
425+
}
426+
427+
413428
/**
414429
* Establishes the user -> managed locations relationship
415430
*

app/Presenters/UserPresenter.php

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ public static function dataTableLayout()
221221
'switchable' => true,
222222
'escape' => true,
223223
'class' => 'css-barcode',
224-
'title' => 'Assets',
224+
'title' => trans('general.assets'),
225225
'visible' => true,
226226
],
227227
[
@@ -230,7 +230,7 @@ public static function dataTableLayout()
230230
'sortable' => true,
231231
'switchable' => true,
232232
'class' => 'css-license',
233-
'title' => 'License',
233+
'title' => trans('general.licenses'),
234234
'visible' => true,
235235
],
236236
[
@@ -239,7 +239,7 @@ public static function dataTableLayout()
239239
'sortable' => true,
240240
'switchable' => true,
241241
'class' => 'css-consumable',
242-
'title' => 'Consumables',
242+
'title' => trans('general.consumables'),
243243
'visible' => true,
244244
],
245245
[
@@ -248,7 +248,25 @@ public static function dataTableLayout()
248248
'sortable' => true,
249249
'switchable' => true,
250250
'class' => 'css-accessory',
251-
'title' => 'Accessories',
251+
'title' => trans('general.accessories'),
252+
'visible' => true,
253+
],
254+
[
255+
'field' => 'manages_users_count',
256+
'searchable' => false,
257+
'sortable' => true,
258+
'switchable' => true,
259+
'class' => 'css-users',
260+
'title' => trans('admin/users/table.managed_users'),
261+
'visible' => true,
262+
],
263+
[
264+
'field' => 'manages_locations_count',
265+
'searchable' => false,
266+
'sortable' => true,
267+
'switchable' => true,
268+
'class' => 'css-location',
269+
'title' => trans('admin/users/table.managed_locations'),
252270
'visible' => true,
253271
],
254272
[

public/css/build/app.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,8 @@ th.css-barcode > .th-inner,
881881
th.css-license > .th-inner,
882882
th.css-consumable > .th-inner,
883883
th.css-envelope > .th-inner,
884+
th.css-users > .th-inner,
885+
th.css-location > .th-inner,
884886
th.css-accessory > .th-inner {
885887
font-size: 0px;
886888
line-height: 0.75 !important;
@@ -894,6 +896,8 @@ th.css-barcode > .th-inner::before,
894896
th.css-license > .th-inner::before,
895897
th.css-consumable > .th-inner::before,
896898
th.css-envelope > .th-inner::before,
899+
th.css-users > .th-inner::before,
900+
th.css-location > .th-inner::before,
897901
th.css-accessory > .th-inner::before {
898902
display: inline-block;
899903
font-size: 20px;
@@ -908,6 +912,7 @@ th.css-padlock > .th-inner::before {
908912
font-size: 12px;
909913
}
910914
/**
915+
BEGIN ICON TABLE HEADERS
911916
Set the font-weight css property as 900 (For Solid), 400 (Regular or Brands), 300 (Light for pro icons).
912917
**/
913918
th.css-barcode > .th-inner::before {
@@ -935,6 +940,17 @@ th.css-accessory > .th-inner::before {
935940
font-family: "Font Awesome 5 Free";
936941
font-weight: 400;
937942
}
943+
th.css-users > .th-inner::before {
944+
content: "\f0c0";
945+
font-family: "Font Awesome 5 Free";
946+
font-size: 15px;
947+
}
948+
th.css-location > .th-inner::before {
949+
content: "\f3c5";
950+
font-family: "Font Awesome 5 Free";
951+
font-size: 19px;
952+
margin-bottom: 0px;
953+
}
938954
.small-box .inner {
939955
padding-left: 15px;
940956
padding-right: 15px;

public/css/build/overrides.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,8 @@ th.css-barcode > .th-inner,
514514
th.css-license > .th-inner,
515515
th.css-consumable > .th-inner,
516516
th.css-envelope > .th-inner,
517+
th.css-users > .th-inner,
518+
th.css-location > .th-inner,
517519
th.css-accessory > .th-inner {
518520
font-size: 0px;
519521
line-height: 0.75 !important;
@@ -527,6 +529,8 @@ th.css-barcode > .th-inner::before,
527529
th.css-license > .th-inner::before,
528530
th.css-consumable > .th-inner::before,
529531
th.css-envelope > .th-inner::before,
532+
th.css-users > .th-inner::before,
533+
th.css-location > .th-inner::before,
530534
th.css-accessory > .th-inner::before {
531535
display: inline-block;
532536
font-size: 20px;
@@ -541,6 +545,7 @@ th.css-padlock > .th-inner::before {
541545
font-size: 12px;
542546
}
543547
/**
548+
BEGIN ICON TABLE HEADERS
544549
Set the font-weight css property as 900 (For Solid), 400 (Regular or Brands), 300 (Light for pro icons).
545550
**/
546551
th.css-barcode > .th-inner::before {
@@ -568,6 +573,17 @@ th.css-accessory > .th-inner::before {
568573
font-family: "Font Awesome 5 Free";
569574
font-weight: 400;
570575
}
576+
th.css-users > .th-inner::before {
577+
content: "\f0c0";
578+
font-family: "Font Awesome 5 Free";
579+
font-size: 15px;
580+
}
581+
th.css-location > .th-inner::before {
582+
content: "\f3c5";
583+
font-family: "Font Awesome 5 Free";
584+
font-size: 19px;
585+
margin-bottom: 0px;
586+
}
571587
.small-box .inner {
572588
padding-left: 15px;
573589
padding-right: 15px;

public/css/dist/all.css

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22408,6 +22408,8 @@ th.css-barcode > .th-inner,
2240822408
th.css-license > .th-inner,
2240922409
th.css-consumable > .th-inner,
2241022410
th.css-envelope > .th-inner,
22411+
th.css-users > .th-inner,
22412+
th.css-location > .th-inner,
2241122413
th.css-accessory > .th-inner {
2241222414
font-size: 0px;
2241322415
line-height: 0.75 !important;
@@ -22421,6 +22423,8 @@ th.css-barcode > .th-inner::before,
2242122423
th.css-license > .th-inner::before,
2242222424
th.css-consumable > .th-inner::before,
2242322425
th.css-envelope > .th-inner::before,
22426+
th.css-users > .th-inner::before,
22427+
th.css-location > .th-inner::before,
2242422428
th.css-accessory > .th-inner::before {
2242522429
display: inline-block;
2242622430
font-size: 20px;
@@ -22435,6 +22439,7 @@ th.css-padlock > .th-inner::before {
2243522439
font-size: 12px;
2243622440
}
2243722441
/**
22442+
BEGIN ICON TABLE HEADERS
2243822443
Set the font-weight css property as 900 (For Solid), 400 (Regular or Brands), 300 (Light for pro icons).
2243922444
**/
2244022445
th.css-barcode > .th-inner::before {
@@ -22462,6 +22467,17 @@ th.css-accessory > .th-inner::before {
2246222467
font-family: "Font Awesome 5 Free";
2246322468
font-weight: 400;
2246422469
}
22470+
th.css-users > .th-inner::before {
22471+
content: "\f0c0";
22472+
font-family: "Font Awesome 5 Free";
22473+
font-size: 15px;
22474+
}
22475+
th.css-location > .th-inner::before {
22476+
content: "\f3c5";
22477+
font-family: "Font Awesome 5 Free";
22478+
font-size: 19px;
22479+
margin-bottom: 0px;
22480+
}
2246522481
.small-box .inner {
2246622482
padding-left: 15px;
2246722483
padding-right: 15px;
@@ -23686,6 +23702,8 @@ th.css-barcode > .th-inner,
2368623702
th.css-license > .th-inner,
2368723703
th.css-consumable > .th-inner,
2368823704
th.css-envelope > .th-inner,
23705+
th.css-users > .th-inner,
23706+
th.css-location > .th-inner,
2368923707
th.css-accessory > .th-inner {
2369023708
font-size: 0px;
2369123709
line-height: 0.75 !important;
@@ -23699,6 +23717,8 @@ th.css-barcode > .th-inner::before,
2369923717
th.css-license > .th-inner::before,
2370023718
th.css-consumable > .th-inner::before,
2370123719
th.css-envelope > .th-inner::before,
23720+
th.css-users > .th-inner::before,
23721+
th.css-location > .th-inner::before,
2370223722
th.css-accessory > .th-inner::before {
2370323723
display: inline-block;
2370423724
font-size: 20px;
@@ -23713,6 +23733,7 @@ th.css-padlock > .th-inner::before {
2371323733
font-size: 12px;
2371423734
}
2371523735
/**
23736+
BEGIN ICON TABLE HEADERS
2371623737
Set the font-weight css property as 900 (For Solid), 400 (Regular or Brands), 300 (Light for pro icons).
2371723738
**/
2371823739
th.css-barcode > .th-inner::before {
@@ -23740,6 +23761,17 @@ th.css-accessory > .th-inner::before {
2374023761
font-family: "Font Awesome 5 Free";
2374123762
font-weight: 400;
2374223763
}
23764+
th.css-users > .th-inner::before {
23765+
content: "\f0c0";
23766+
font-family: "Font Awesome 5 Free";
23767+
font-size: 15px;
23768+
}
23769+
th.css-location > .th-inner::before {
23770+
content: "\f3c5";
23771+
font-family: "Font Awesome 5 Free";
23772+
font-size: 19px;
23773+
margin-bottom: 0px;
23774+
}
2374323775
.small-box .inner {
2374423776
padding-left: 15px;
2374523777
padding-right: 15px;

public/mix-manifest.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"/js/build/app.js": "/js/build/app.js?id=ea5f3edebafdb29b616d23fa89106080",
33
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=f677207c6cf9678eb539abecb408c374",
4-
"/css/build/overrides.css": "/css/build/overrides.css?id=be3c0a217bc6c0e0744f75faed784887",
5-
"/css/build/app.css": "/css/build/app.css?id=a168b0a799aa800ee926bffa1b1a434a",
4+
"/css/build/overrides.css": "/css/build/overrides.css?id=3d1aa807fc9395794b76f4cdab99c984",
5+
"/css/build/app.css": "/css/build/app.css?id=40e80d931c21cde71b27be4c8eaaea62",
66
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=dc383f8560a8d4adb51d44fb4043e03b",
77
"/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=6f0563e726c2fe4fab4026daaa5bfdf2",
88
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=620b684d9dd9d3bb5fdda00a3a2467c3",
@@ -18,7 +18,7 @@
1818
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=0a82a6ae6bb4e58fe62d162c4fb50397",
1919
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=da6c7997d9de2f8329142399f0ce50da",
2020
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=44bf834f2110504a793dadec132a5898",
21-
"/css/dist/all.css": "/css/dist/all.css?id=6e9aa08b535262053b95aee495caa7df",
21+
"/css/dist/all.css": "/css/dist/all.css?id=b51ba67a606c04c8f12fa30adcf33fd0",
2222
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
2323
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
2424
"/css/webfonts/fa-brands-400.ttf": "/css/webfonts/fa-brands-400.ttf?id=0141634c24336be626e05c8b77d1fa27",

0 commit comments

Comments
 (0)