Compare commits
3 Commits
form-row-c
...
more-fixes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8b60b1d17 | ||
|
|
7dbd8e99ba | ||
|
|
b5a8b29af5 |
@@ -336,6 +336,11 @@ class UsersController extends Controller
|
||||
]
|
||||
)->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'))
|
||||
|
||||
@@ -47,62 +47,6 @@ class ViewAssetsController extends Controller
|
||||
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.
|
||||
@@ -110,18 +54,29 @@ class ViewAssetsController extends Controller
|
||||
*/
|
||||
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();
|
||||
|
||||
// Process manager view if enabled
|
||||
if ($settings->manager_view_enabled) {
|
||||
$subordinates = $this->getViewableUsers($authUser);
|
||||
$selectedUserId = $this->getSelectedUserId($request, $subordinates, $authUser->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)) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 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',
|
||||
@@ -129,23 +84,21 @@ class ViewAssetsController extends Controller
|
||||
'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
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -971,10 +971,6 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
->orWhere('users.employee_num', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('users.username', 'LIKE', '%' . $search . '%')
|
||||
->orwhereRaw('CONCAT(users.first_name," ",users.last_name) LIKE \''.$search.'%\'');
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1022,6 +1018,22 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
},
|
||||
|
||||
3
public/js/dist/all.js
vendored
3
public/js/dist/all.js
vendored
@@ -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;
|
||||
},
|
||||
|
||||
@@ -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",
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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">
|
||||
@@ -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">
|
||||
<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 ((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
|
||||
|
||||
@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>
|
||||
@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
|
||||
|
||||
@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->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">
|
||||
@@ -187,8 +183,8 @@
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<br><br>
|
||||
</div>
|
||||
|
||||
<!-- End button column -->
|
||||
|
||||
Reference in New Issue
Block a user