Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/Http/Controllers/Api/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,11 @@ public function selectlist(Request $request) : array
]
)->where('show_in_list', '=', '1');

if (($request->filled('subordinates')) && (!auth()->user()->isSuperUser())) {
// Regular manager sees only their subordinates + self
$users = auth()->user()->allSubordinates();
}

if ($request->filled('search')) {
$users = $users->where(function ($query) use ($request) {
$query->SimpleNameSearch($request->get('search'))
Expand Down
95 changes: 24 additions & 71 deletions app/Http/Controllers/ViewAssetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,105 +47,58 @@ private function extractCustomFields(User $user): array
return array_unique($fieldArray);
}

/**
* Get list of users viewable by the current user.
*
* @param User $authUser
* @return \Illuminate\Support\Collection
*/
private function getViewableUsers(User $authUser): \Illuminate\Support\Collection
{
// SuperAdmin sees all users
if ($authUser->isSuperUser()) {
return User::select('id', 'first_name', 'last_name', 'username')
->where('activated', 1)
->orderBy('last_name')
->orderBy('first_name')
->get();
}

// Regular manager sees only their subordinates + self
$managedUsers = $authUser->getAllSubordinates();

// If user has subordinates, show them with self at beginning
if ($managedUsers->count() > 0) {
return collect([$authUser])->merge($managedUsers)
->sortBy('last_name')
->sortBy('first_name');
}

// User has no subordinates, only sees themselves
return collect([$authUser]);
}

/**
* Get the selected user ID from request or default to current user.
*
* @param Request $request
* @param \Illuminate\Support\Collection $subordinates
* @param int $defaultUserId
* @return int
*/
private function getSelectedUserId(Request $request, \Illuminate\Support\Collection $subordinates, int $defaultUserId): int
{
// If no subordinates or no user_id in request, return default
if ($subordinates->count() <= 1 || !$request->filled('user_id')) {
return $defaultUserId;
}

$requestedUserId = (int) $request->input('user_id');

// Validate if the requested user is allowed
if ($subordinates->contains('id', $requestedUserId)) {
return $requestedUserId;
}

// If invalid ID or not authorized, return default
return $defaultUserId;
}

/**
* Show user's assigned assets with optional manager view functionality.
*
*/
public function getIndex(Request $request) : View | RedirectResponse
{
$authUser = auth()->user();
$settings = Setting::getSettings();
$subordinates = collect();
$selectedUserId = $authUser->id;
$subordinate_count = 0;
$viewingUser = auth()->user();
$userToView = auth()->user();
$userToViewId = auth()->id();

// Only do the (heavy) recursive subordinate count if the manager view is enabled AND
// the user is trying to view a different user than themselves.
if (($settings->manager_view_enabled == 1) || (request()->get('user_id') != auth()->id())) {
$subordinate_count = auth()->user()->allSubordinates()->count();
if (auth()->user()->allSubordinates()->find($userToViewId)) {

// Process manager view if enabled
if ($settings->manager_view_enabled) {
$subordinates = $this->getViewableUsers($authUser);
$selectedUserId = $this->getSelectedUserId($request, $subordinates, $authUser->id);
}
}

// Load the data for the user to be viewed (either auth user or selected subordinate)

\Log::error('Sub count: '.$subordinate_count);
\Log::error('$viewingUser '.$viewingUser);
\Log::error('$userToView '.$userToView);
\Log::error('$userToViewId '.$userToViewId);
\Log::error(print_r(auth()->user()->allSubordinates()->get(), true));


$userToView = User::with([
'assets',
'assets.model',
'assets.model.fieldset.fields',
'consumables',
'accessories',
'licenses'
])->find($selectedUserId);
])->find($userToViewId);


// If the user to view couldn't be found (shouldn't happen with proper logic), redirect with error
if (!$userToView) {
return redirect()->route('view-assets')->with('error', trans('admin/users/message.user_not_found'));
}

// Process custom fields for the user being viewed
$fieldArray = $this->extractCustomFields($userToView);


// Pass the necessary data to the view
return view('account/view-assets', [
'user' => $userToView, // Use 'user' for compatibility with the existing view
'field_array' => $fieldArray,
'settings' => $settings,
'subordinates' => $subordinates,
'selectedUserId' => $selectedUserId
'subordinates' => $subordinate_count > 0 ?? false,
'selectedUserId' => $userToViewId
]);
}

Expand Down
20 changes: 16 additions & 4 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -971,10 +971,6 @@ public function scopeUserLocation($query, $location, $search){
->orWhere('users.employee_num', 'LIKE', '%' . $search . '%')
->orWhere('users.username', 'LIKE', '%' . $search . '%')
->orwhereRaw('CONCAT(users.first_name," ",users.last_name) LIKE \''.$search.'%\'');




}

/**
Expand Down Expand Up @@ -1022,6 +1018,22 @@ protected function fetchSubordinatesRecursive(User $manager, \Illuminate\Support
}
}





public function directReports()
{
return $this->hasMany(User::class, 'manager_id');
}

public function allSubordinates()
{
return $this->directReports()->with('allSubordinates');
}



/**
* Check if the current user is a direct or indirect manager of the given user.
*
Expand Down
3 changes: 2 additions & 1 deletion public/js/build/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -32369,7 +32369,8 @@ $(function () {
search: params.term,
page: params.page || 1,
assetStatusType: link.data("asset-status-type"),
companyId: link.data("company-id")
companyId: link.data("company-id"),
subordinates: link.data("subordinates")
};
return data;
},
Expand Down
3 changes: 2 additions & 1 deletion public/js/dist/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -91302,7 +91302,8 @@ $(function () {
search: params.term,
page: params.page || 1,
assetStatusType: link.data("asset-status-type"),
companyId: link.data("company-id")
companyId: link.data("company-id"),
subordinates: link.data("subordinates")
};
return data;
},
Expand Down
4 changes: 2 additions & 2 deletions public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"/js/build/app.js": "/js/build/app.js?id=19253af36b58ed3fb6770c7bb944f079",
"/js/build/app.js": "/js/build/app.js?id=eeff00aa3bf3497d4ba36c3fd7ca0c20",
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=78bfb1c7b5782df4fb0ac7e36f80f847",
"/css/dist/skins/_all-skins.css": "/css/dist/skins/_all-skins.css?id=503d0b09e157a22f555e3670d1ec9bb5",
"/css/build/overrides.css": "/css/build/overrides.css?id=2bfc7b71d951c5ac026dbc034f7373b1",
Expand Down Expand Up @@ -111,5 +111,5 @@
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=54d676a6ea8677dd48f6c4b3041292cf",
"/js/build/vendor.js": "/js/build/vendor.js?id=89dffa552c6e3abe3a2aac6c9c7b466b",
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=60097b6b56d80cbc76257d4ecf6f57b4",
"/js/dist/all.js": "/js/dist/all.js?id=8c6d7286f667eeb62a0a28a09851a6c3"
"/js/dist/all.js": "/js/dist/all.js?id=fe4be0933b6c05df1d795f53da658dc7"
}
3 changes: 3 additions & 0 deletions resources/assets/js/snipeit.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,10 @@ $(function () {
page: params.page || 1,
assetStatusType: link.data("asset-status-type"),
companyId: link.data("company-id"),
subordinates: link.data("subordinates"),
};


return data;
},
/* processResults: function (data, params) {
Expand Down
110 changes: 53 additions & 57 deletions resources/views/account/view-assets.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@
@parent
@stop

@section('header_right')
{{-- Manager View Dropdown --}}
@if (isset($settings) && ($settings->manager_view_enabled==1) && ($subordinates))

<form method="GET" action="{{ route('view-assets') }}" class="pull-right" role="form">
<div class="form-group" style="margin-bottom: 0;">
<label for="user_id" class="control-label" style="margin-right: 10px;">
{{ trans('general.select_user') }}:
</label>

<select class="js-data-ajax form-control select2" data-endpoint="users" data-subordinates="true" data-placeholder="{{ trans('general.select_user') }}" name="user_id" style="width: 450px" id="user_id" aria-label="user_id" onchange="this.form.submit()">
</select>

</div>
</form>

@endif
@stop

{{-- Account page content --}}
@section('content')

Expand All @@ -25,30 +44,7 @@
</div>
@endif

{{-- Manager View Dropdown --}}
@if (isset($settings) && $settings->manager_view_enabled && isset($subordinates) && $subordinates->count() > 1)
<div class="row hidden-print" style="margin-bottom: 15px;">
<div class="col-md-12">
<form method="GET" action="{{ route('view-assets') }}" class="pull-right" role="form">
<div class="form-group" style="margin-bottom: 0;">
<label for="user_id" class="control-label" style="margin-right: 10px;">
{{ trans('general.view_user_assets') }}:
</label>
<select name="user_id" id="user_id" class="form-control select2" onchange="this.form.submit()" style="width: 250px; display: inline-block;">
@foreach ($subordinates as $subordinate)
<option value="{{ $subordinate->id }}" {{ (int)$selectedUserId === (int)$subordinate->id ? ' selected' : '' }}>
{{ $subordinate->present()->fullName() }}
@if ($subordinate->id == auth()->id())
({{ trans('general.me') }})
@endif
</option>
@endforeach
</select>
</div>
</form>
</div>
</div>
@endif


<div class="row">
<div class="col-md-12">
Expand Down Expand Up @@ -133,44 +129,44 @@
<div class="col-md-3 col-xs-12 col-sm-push-9">

<div class="col-md-12 text-center">
<img src="{{ $user->present()->gravatar() }}" class=" img-thumbnail hidden-print" style="margin-bottom: 20px;" alt="{{ $user->present()->fullName() }}" alt="User avatar">
</div>
@can('self.profile')
<div class="col-md-12">
<a href="{{ route('profile') }}" style="width: 100%;" class="btn btn-sm btn-warning btn-social btn-block hidden-print">
<x-icon type="edit" />
{{ trans('general.editprofile') }}
</a>
</div>
@endcan

@if ($user->ldap_import!='1')
<div class="col-md-12" style="padding-top: 5px;">
<a href="{{ route('account.password.index') }}" style="width: 100%;" class="btn btn-sm btn-primary btn-social btn-block hidden-print" target="_blank" rel="noopener">
<x-icon type="password" class="fa-fw" />
{{ trans('general.changepassword') }}
</a>
<img src="{{ $user->present()->gravatar() }}" class="img-thumbnail hidden-print" style="margin-bottom: 20px;" alt="{{ $user->present()->fullName() }}" alt="User avatar">
</div>
@endif
@if ((isset($selectedUserId)) && ($selectedUserId == auth()->id()))
@can('self.profile')
<div class="col-md-12">
<a href="{{ route('profile') }}" style="width: 100%;" class="btn btn-sm btn-warning btn-social btn-block hidden-print">
<x-icon type="edit" />
{{ trans('general.editprofile') }}
</a>
</div>
@endcan

@can('self.api')
<div class="col-md-12" style="padding-top: 5px;">
<a href="{{ route('user.api') }}" style="width: 100%;" class="btn btn-sm btn-primary btn-social btn-block hidden-print" target="_blank" rel="noopener">
<x-icon type="api-key" class="fa-fw" />
{{ trans('general.manage_api_keys') }}
</a>
</div>
@endcan
@if ($user->ldap_import!='1')
<div class="col-md-12" style="padding-top: 5px;">
<a href="{{ route('account.password.index') }}" style="width: 100%;" class="btn btn-sm btn-primary btn-social btn-block hidden-print" target="_blank" rel="noopener">
<x-icon type="password" class="fa-fw" />
{{ trans('general.changepassword') }}
</a>
</div>
@endif

@can('self.api')
<div class="col-md-12" style="padding-top: 5px;">
<a href="{{ route('user.api') }}" style="width: 100%;" class="btn btn-sm btn-primary btn-social btn-block hidden-print" target="_blank" rel="noopener">
<x-icon type="api-key" class="fa-fw" />
{{ trans('general.manage_api_keys') }}
</a>
</div>
@endcan
@endif

@if ($user->allAssignedCount() > 0)
<div class="col-md-12" style="padding-top: 5px;">
<a href="{{ route('profile.print') }}" style="width: 100%;" class="btn btn-sm btn-primary btn-social btn-block hidden-print" target="_blank" rel="noopener">
<x-icon type="print" class="fa-fw" />
{{ trans('admin/users/general.print_assigned') }}
</a>
<a href="{{ route('profile.print') }}" style="width: 100%;" class="btn btn-sm btn-primary btn-social btn-block hidden-print" target="_blank" rel="noopener">
<x-icon type="print" class="fa-fw" />
{{ trans('admin/users/general.print_assigned') }}
</a>
</div>


<div class="col-md-12" style="padding-top: 5px;">
@if (!empty($user->email))
<form action="{{ route('profile.email_assets') }}" method="POST">
Expand All @@ -187,8 +183,8 @@
</button>
@endif
</div>
@endif

<br><br>
</div>

<!-- End button column -->
Expand Down
Loading