mirror of
https://github.com/grokability/snipe-it.git
synced 2026-03-12 17:52:00 +08:00
Compare commits
44 Commits
fix-oauth-
...
47d25da371
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47d25da371 | ||
|
|
2cc6109959 | ||
|
|
a186f54478 | ||
|
|
17bbe7736a | ||
|
|
7beabb3a9c | ||
|
|
aac3b7b372 | ||
|
|
fea4a3d53e | ||
|
|
0c3f551dde | ||
|
|
64780e338b | ||
|
|
2dc2e6328f | ||
|
|
5851e2cd68 | ||
|
|
b90f2d719c | ||
|
|
d7fdb71554 | ||
|
|
646de9a074 | ||
|
|
34acd827be | ||
|
|
fbce94f591 | ||
|
|
0b30f9eae6 | ||
|
|
8f6782bdfa | ||
|
|
bbe7393a61 | ||
|
|
d0dbd1e561 | ||
|
|
e7eb4f0e80 | ||
|
|
676a995889 | ||
|
|
a44fe14de1 | ||
|
|
0015dbcd1d | ||
|
|
fc5e7cccbc | ||
|
|
8987f3f951 | ||
|
|
ba671a8f1f | ||
|
|
fbe871f8d1 | ||
|
|
116b2d1229 | ||
|
|
20fd870b59 | ||
|
|
5c46990195 | ||
|
|
fab57020f2 | ||
|
|
b37074f473 | ||
|
|
24e2e81a28 | ||
|
|
ccabc1fbcc | ||
|
|
f847f83cb8 | ||
|
|
e0771827aa | ||
|
|
fa6adaa155 | ||
|
|
e3fb6fabf8 | ||
|
|
6f89af790e | ||
|
|
28f493d84d | ||
|
|
a87e862148 | ||
|
|
6e264bfee0 | ||
|
|
1ecf862f2d |
8
.github/workflows/docker-alpine.yml
vendored
8
.github/workflows/docker-alpine.yml
vendored
@@ -46,13 +46,13 @@ jobs:
|
||||
|
||||
# https://github.com/docker/setup-buildx-action
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
# https://github.com/docker/login-action
|
||||
- name: Login to DockerHub
|
||||
# Only login if not a PR, as PRs only trigger a Docker build and not a push
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
# Get Metadata for docker_build step below
|
||||
- name: Sync metadata (tags, labels) from GitHub to Docker for 'snipe-it' image
|
||||
id: meta_build
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: snipe/snipe-it
|
||||
tags: ${{ env.IMAGE_TAGS }}
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push 'snipe-it' image
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile.alpine
|
||||
|
||||
8
.github/workflows/docker-ubuntu.yml
vendored
8
.github/workflows/docker-ubuntu.yml
vendored
@@ -46,13 +46,13 @@ jobs:
|
||||
|
||||
# https://github.com/docker/setup-buildx-action
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
# https://github.com/docker/login-action
|
||||
- name: Login to DockerHub
|
||||
# Only login if not a PR, as PRs only trigger a Docker build and not a push
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
# Get Metadata for docker_build step below
|
||||
- name: Sync metadata (tags, labels) from GitHub to Docker for 'snipe-it' image
|
||||
id: meta_build
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: snipe/snipe-it
|
||||
tags: ${{ env.IMAGE_TAGS }}
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push 'snipe-it' image
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
|
||||
@@ -1149,7 +1149,7 @@ class AssetsController extends Controller
|
||||
'id' => $asset->id,
|
||||
'asset_tag' => $asset->asset_tag,
|
||||
'note' => e($request->input('note')),
|
||||
'status_label' => e($asset->assetstatus->display_name),
|
||||
'status_label' => e($asset->assetstatus?->display_name),
|
||||
'status_type' => $asset->assetstatus->getStatuslabelType(),
|
||||
'next_audit_date' => Helper::getFormattedDateObject($asset->next_audit_date),
|
||||
];
|
||||
|
||||
@@ -93,7 +93,7 @@ class UploadedFilesController extends Controller
|
||||
|
||||
// Check the permissions to make sure the user can view the object
|
||||
$object = self::$map_object_type[$object_type]::withTrashed()->find($id);
|
||||
$this->authorize('view', $object);
|
||||
$this->authorize('update', $object);
|
||||
|
||||
if (!$object) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.file_upload_status.invalid_object')));
|
||||
|
||||
@@ -109,7 +109,6 @@ class UsersController extends Controller
|
||||
'last_name',
|
||||
'first_name',
|
||||
'display_name',
|
||||
'email',
|
||||
'jobtitle',
|
||||
'username',
|
||||
'employee_num',
|
||||
@@ -126,13 +125,6 @@ class UsersController extends Controller
|
||||
'accessories_count',
|
||||
'manages_users_count',
|
||||
'manages_locations_count',
|
||||
'phone',
|
||||
'mobile',
|
||||
'address',
|
||||
'city',
|
||||
'state',
|
||||
'country',
|
||||
'zip',
|
||||
'id',
|
||||
'ldap_import',
|
||||
'two_factor_optin',
|
||||
@@ -142,7 +134,6 @@ class UsersController extends Controller
|
||||
'start_date',
|
||||
'end_date',
|
||||
'autoassign_licenses',
|
||||
'website',
|
||||
'locale',
|
||||
'notes',
|
||||
'employee_num',
|
||||
@@ -159,6 +150,21 @@ class UsersController extends Controller
|
||||
|
||||
];
|
||||
|
||||
// Do not even request these fields if the requesting user cannot manage user contact info
|
||||
if (auth()->user()->can('manageContactInfo')) {
|
||||
array_push($allowed_columns,
|
||||
'address',
|
||||
'city',
|
||||
'country',
|
||||
'email',
|
||||
'mobile',
|
||||
'phone',
|
||||
'state',
|
||||
'website',
|
||||
'zip',
|
||||
);
|
||||
}
|
||||
|
||||
$filter = [];
|
||||
|
||||
if ($request->filled('filter')) {
|
||||
@@ -196,13 +202,39 @@ class UsersController extends Controller
|
||||
$users = $users->where('users.company_id', '=', $request->input('company_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('phone')) {
|
||||
$users = $users->where('users.phone', '=', $request->input('phone'));
|
||||
|
||||
// Check that the user can view contact info
|
||||
if (auth()->user()->can('manageContactInfo')) {
|
||||
|
||||
if ($request->filled('phone')) {
|
||||
$users = $users->where('users.phone', '=', $request->input('phone'));
|
||||
}
|
||||
|
||||
if ($request->filled('mobile')) {
|
||||
$users = $users->where('users.mobile', '=', $request->input('mobile'));
|
||||
}
|
||||
|
||||
if ($request->filled('email')) {
|
||||
$users = $users->where('users.email', '=', $request->input('email'));
|
||||
}
|
||||
|
||||
if ($request->filled('state')) {
|
||||
$users = $users->where('users.state', '=', $request->input('state'));
|
||||
}
|
||||
|
||||
if ($request->filled('country')) {
|
||||
$users = $users->where('users.country', '=', $request->input('country'));
|
||||
}
|
||||
|
||||
if ($request->filled('website')) {
|
||||
$users = $users->where('users.website', '=', $request->input('website'));
|
||||
}
|
||||
|
||||
if ($request->filled('zip')) {
|
||||
$users = $users->where('users.zip', '=', $request->input('zip'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('mobile')) {
|
||||
$users = $users->where('users.mobile', '=', $request->input('mobile'));
|
||||
}
|
||||
|
||||
if ($request->filled('location_id')) {
|
||||
$users = $users->where('users.location_id', '=', $request->input('location_id'));
|
||||
@@ -212,10 +244,6 @@ class UsersController extends Controller
|
||||
$users = $users->where('users.created_by', '=', $request->input('created_by'));
|
||||
}
|
||||
|
||||
if ($request->filled('email')) {
|
||||
$users = $users->where('users.email', '=', $request->input('email'));
|
||||
}
|
||||
|
||||
if ($request->filled('username')) {
|
||||
$users = $users->where('users.username', '=', $request->input('username'));
|
||||
}
|
||||
@@ -236,21 +264,6 @@ class UsersController extends Controller
|
||||
$users = $users->where('users.employee_num', '=', $request->input('employee_num'));
|
||||
}
|
||||
|
||||
if ($request->filled('state')) {
|
||||
$users = $users->where('users.state', '=', $request->input('state'));
|
||||
}
|
||||
|
||||
if ($request->filled('country')) {
|
||||
$users = $users->where('users.country', '=', $request->input('country'));
|
||||
}
|
||||
|
||||
if ($request->filled('website')) {
|
||||
$users = $users->where('users.website', '=', $request->input('website'));
|
||||
}
|
||||
|
||||
if ($request->filled('zip')) {
|
||||
$users = $users->where('users.zip', '=', $request->input('zip'));
|
||||
}
|
||||
|
||||
if ($request->filled('group_id')) {
|
||||
$users = $users->ByGroup($request->input('group_id'));
|
||||
@@ -384,27 +397,34 @@ class UsersController extends Controller
|
||||
*/
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
$users = User::select(
|
||||
[
|
||||
'users.id',
|
||||
'users.username',
|
||||
'users.employee_num',
|
||||
'users.first_name',
|
||||
'users.last_name',
|
||||
'users.display_name',
|
||||
'users.gravatar',
|
||||
'users.avatar',
|
||||
'users.email',
|
||||
]
|
||||
)->where('show_in_list', '=', '1');
|
||||
|
||||
$select_array = [
|
||||
'users.id',
|
||||
'users.username',
|
||||
'users.employee_num',
|
||||
'users.first_name',
|
||||
'users.last_name',
|
||||
'users.display_name',
|
||||
'users.gravatar',
|
||||
'users.avatar',
|
||||
];
|
||||
|
||||
if (auth()->user()->can('manageContactInfo')) {
|
||||
array_push($select_array, 'users.email');
|
||||
}
|
||||
|
||||
$users = User::select($select_array)->where('show_in_list', '=', '1');
|
||||
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$users = $users->where(function ($query) use ($request) {
|
||||
$query->SimpleNameSearch($request->input('search'))
|
||||
->orWhere('username', 'LIKE', '%'.$request->input('search').'%')
|
||||
->orWhere('display_name', 'LIKE', '%'.$request->input('search').'%')
|
||||
->orWhere('email', 'LIKE', '%'.$request->input('search').'%')
|
||||
->orWhere('employee_num', 'LIKE', '%'.$request->input('search').'%');
|
||||
$query->SimpleNameSearch($request->input('search'));
|
||||
|
||||
// Check that the requesting user can search against the email field
|
||||
if (auth()->user()->can('manageContactInfo')) {
|
||||
$query->orWhere('users.email', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -555,6 +575,7 @@ class UsersController extends Controller
|
||||
$user->fill($request->except(['password', 'username', 'email', 'activated', 'permissions', 'activation_code', 'remember_token', 'two_factor_secret', 'two_factor_enrolled', 'two_factor_optin']));
|
||||
|
||||
|
||||
|
||||
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||
|
||||
if ($request->filled('password')) {
|
||||
@@ -611,6 +632,18 @@ class UsersController extends Controller
|
||||
}
|
||||
|
||||
|
||||
if (auth()->user()->cannot('manageContactInfo')) {
|
||||
$request->request->remove('phone');
|
||||
$request->request->remove('mobile');
|
||||
$request->request->remove('address');
|
||||
$request->request->remove('city');
|
||||
$request->request->remove('state');
|
||||
$request->request->remove('country');
|
||||
$request->request->remove('zip');
|
||||
$request->request->remove('website');
|
||||
}
|
||||
|
||||
|
||||
if ($request->filled('display_name')) {
|
||||
$user->display_name = $request->input('display_name');
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ class BulkUsersController extends Controller
|
||||
{
|
||||
$this->authorize('update', User::class);
|
||||
|
||||
if ((! $request->filled('ids')) || $request->input('ids') <= 0) {
|
||||
if ((!$request->filled('ids')) || $request->input('ids') <= 0) {
|
||||
return redirect()->back()->with('error', trans('general.no_users_selected'));
|
||||
}
|
||||
$user_raw_array = $request->input('ids');
|
||||
@@ -172,9 +172,16 @@ class BulkUsersController extends Controller
|
||||
->conditionallyAddItem('display_name')
|
||||
->conditionallyAddItem('start_date')
|
||||
->conditionallyAddItem('end_date')
|
||||
->conditionallyAddItem('city')
|
||||
->conditionallyAddItem('autoassign_licenses');
|
||||
|
||||
// Check that the user can manage contact info for users
|
||||
if (auth()->user()->can('manageContactInfo')) {
|
||||
$this->conditionallyAddItem('city')
|
||||
->conditionallyAddItem('state')
|
||||
->conditionallyAddItem('country')
|
||||
->conditionallyAddItem('zip');
|
||||
}
|
||||
|
||||
|
||||
// If the manager_id is one of the users being updated, generate a warning.
|
||||
if (array_search($request->input('manager_id'), $user_raw_array)) {
|
||||
|
||||
@@ -14,6 +14,7 @@ use App\Models\Group;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use App\Notifications\WelcomeNotification;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
@@ -88,7 +89,19 @@ class UsersController extends Controller
|
||||
$this->authorize('create', User::class);
|
||||
$user = new User;
|
||||
//Username, email, and password need to be handled specially because the need to respect config values on an edit.
|
||||
$user->email = trim($request->input('email'));
|
||||
|
||||
if (auth()->user()->can('manageContactInfo')) {
|
||||
$user->email = trim($request->input('email'));
|
||||
$user->phone = $request->input('phone');
|
||||
$user->mobile = $request->input('mobile');
|
||||
$user->address = $request->input('address', null);
|
||||
$user->city = $request->input('city', null);
|
||||
$user->state = $request->input('state', null);
|
||||
$user->country = $request->input('country', null);
|
||||
$user->zip = $request->input('zip', null);
|
||||
$user->website = $request->input('website', null);
|
||||
}
|
||||
|
||||
$user->username = trim($request->input('username'));
|
||||
$user->display_name = $request->input('display_name');
|
||||
if ($request->filled('password')) {
|
||||
@@ -100,20 +113,15 @@ class UsersController extends Controller
|
||||
$user->employee_num = $request->input('employee_num');
|
||||
$user->activated = $request->input('activated', 0);
|
||||
$user->jobtitle = $request->input('jobtitle');
|
||||
$user->phone = $request->input('phone');
|
||||
$user->mobile = $request->input('mobile');
|
||||
|
||||
$user->location_id = $request->input('location_id', null);
|
||||
$user->department_id = $request->input('department_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->address = $request->input('address', null);
|
||||
$user->city = $request->input('city', null);
|
||||
$user->state = $request->input('state', null);
|
||||
$user->country = $request->input('country', null);
|
||||
$user->zip = $request->input('zip', null);
|
||||
|
||||
$user->remote = $request->input('remote', 0);
|
||||
$user->website = $request->input('website', null);
|
||||
|
||||
$user->created_by = auth()->id();
|
||||
$user->start_date = $request->input('start_date', null);
|
||||
$user->end_date = $request->input('end_date', null);
|
||||
@@ -268,6 +276,19 @@ class UsersController extends Controller
|
||||
|
||||
// Update the user fields
|
||||
|
||||
if (auth()->user()->can('manageContactInfo')) {
|
||||
$user->email = trim($request->input('email'));
|
||||
$user->phone = $request->input('phone');
|
||||
$user->mobile = $request->input('mobile');
|
||||
$user->address = $request->input('address', null);
|
||||
$user->city = $request->input('city', null);
|
||||
$user->state = $request->input('state', null);
|
||||
$user->country = $request->input('country', null);
|
||||
$user->zip = $request->input('zip', null);
|
||||
$user->website = $request->input('website', null);
|
||||
}
|
||||
|
||||
|
||||
$user->first_name = $request->input('first_name');
|
||||
$user->last_name = $request->input('last_name');
|
||||
$user->display_name = $request->input('display_name');
|
||||
@@ -275,21 +296,13 @@ class UsersController extends Controller
|
||||
$user->locale = $request->input('locale');
|
||||
$user->employee_num = $request->input('employee_num');
|
||||
$user->jobtitle = $request->input('jobtitle', null);
|
||||
$user->phone = $request->input('phone');
|
||||
$user->mobile = $request->input('mobile');
|
||||
$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);
|
||||
$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);
|
||||
@@ -486,11 +499,15 @@ class UsersController extends Controller
|
||||
// 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;
|
||||
$user->username = null;
|
||||
$user->avatar = null;
|
||||
|
||||
if (auth()->user()->can('manageContactInfo')) {
|
||||
$user->email = substr($user->email, ($pos = strpos($user->email, '@')) !== false ? $pos : 0);
|
||||
}
|
||||
|
||||
// Get this user's groups
|
||||
$userGroups = $user_to_clone->groups()->pluck('name', 'id');
|
||||
|
||||
@@ -530,6 +547,65 @@ class UsersController extends Controller
|
||||
// Open output stream
|
||||
$handle = fopen('php://output', 'w');
|
||||
|
||||
$headers = [
|
||||
// strtolower to prevent Excel from trying to open it as a SYLK file
|
||||
strtolower(trans('general.id')),
|
||||
trans('admin/companies/table.title'),
|
||||
trans('admin/users/table.title'),
|
||||
trans('general.employee_number'),
|
||||
trans('admin/users/table.first_name'),
|
||||
trans('admin/users/table.last_name'),
|
||||
trans('admin/users/table.name'),
|
||||
trans('admin/users/table.username'),
|
||||
trans('admin/users/table.display_name'),
|
||||
];
|
||||
|
||||
if (auth()->user()->can('manageContactInfo')) {
|
||||
array_push($headers,
|
||||
trans('admin/users/table.email'),
|
||||
trans('admin/users/table.phone'),
|
||||
trans('admin/users/table.mobile'),
|
||||
trans('general.address'),
|
||||
trans('general.city'),
|
||||
trans('general.state'),
|
||||
trans('general.country'),
|
||||
trans('general.zip'),
|
||||
trans('general.website'));
|
||||
|
||||
}
|
||||
|
||||
array_push($headers,
|
||||
trans('admin/users/table.manager'),
|
||||
trans('admin/users/table.location'),
|
||||
trans('general.department'),
|
||||
trans('admin/users/general.department_manager'),
|
||||
trans('general.assets'),
|
||||
trans('general.licenses'),
|
||||
trans('general.accessories'),
|
||||
trans('general.consumables'),
|
||||
trans('admin/users/table.managed_users'),
|
||||
trans('admin/users/table.managed_locations'),
|
||||
trans('general.groups'),
|
||||
trans('general.permissions'),
|
||||
trans('general.notes'),
|
||||
trans('admin/users/table.activated'),
|
||||
trans('admin/settings/general.ldap_enabled'),
|
||||
trans('admin/users/general.two_factor_enrolled'),
|
||||
trans('admin/users/general.two_factor_active'),
|
||||
trans('general.autoassign_licenses'),
|
||||
trans('admin/users/general.remote'),
|
||||
trans('admin/users/general.vip_label'),
|
||||
trans('general.language'),
|
||||
trans('general.start_date'),
|
||||
trans('general.end_date'),
|
||||
trans('general.last_login'),
|
||||
trans('general.updated_at'),
|
||||
trans('general.created_at'),
|
||||
trans('general.created_by'),
|
||||
);
|
||||
|
||||
|
||||
|
||||
$users = User::with(
|
||||
'assets',
|
||||
'accessories',
|
||||
@@ -540,32 +616,18 @@ class UsersController extends Controller
|
||||
'groups',
|
||||
'userloc',
|
||||
'company'
|
||||
)->orderBy('created_at', 'DESC')
|
||||
->chunk(500, function ($users) use ($handle) {
|
||||
$headers = [
|
||||
// strtolower to prevent Excel from trying to open it as a SYLK file
|
||||
strtolower(trans('general.id')),
|
||||
trans('admin/companies/table.title'),
|
||||
trans('admin/users/table.title'),
|
||||
trans('general.employee_number'),
|
||||
trans('admin/users/table.first_name'),
|
||||
trans('admin/users/table.last_name'),
|
||||
trans('admin/users/table.name'),
|
||||
trans('admin/users/table.username'),
|
||||
trans('admin/users/table.email'),
|
||||
trans('admin/users/table.manager'),
|
||||
trans('admin/users/table.location'),
|
||||
trans('general.department'),
|
||||
trans('general.assets'),
|
||||
trans('general.licenses'),
|
||||
trans('general.accessories'),
|
||||
trans('general.consumables'),
|
||||
trans('general.groups'),
|
||||
trans('general.permissions'),
|
||||
trans('general.notes'),
|
||||
trans('admin/users/table.activated'),
|
||||
trans('general.created_at'),
|
||||
];
|
||||
) ->withCount([
|
||||
'assets as assets_count' => function(Builder $query) {
|
||||
$query->withoutTrashed();
|
||||
},
|
||||
'licenses as licenses_count',
|
||||
'accessories as accessories_count',
|
||||
'consumables as consumables_count',
|
||||
'managesUsers as manages_users_count',
|
||||
'managedLocations as manages_locations_count'
|
||||
])->orderBy('created_at', 'DESC')
|
||||
->chunk(500, function ($users) use ($handle, $headers) {
|
||||
|
||||
|
||||
fputcsv($handle, $headers);
|
||||
|
||||
@@ -599,20 +661,53 @@ class UsersController extends Controller
|
||||
$user->last_name,
|
||||
$user->display_name,
|
||||
$user->username,
|
||||
$user->email,
|
||||
$user->getRawOriginal('display_name'),
|
||||
];
|
||||
|
||||
if (auth()->user()->can('manageContactInfo')) {
|
||||
|
||||
array_push($values,
|
||||
$user->email,
|
||||
$user->phone,
|
||||
$user->mobile,
|
||||
$user->address,
|
||||
$user->city,
|
||||
$user->state,
|
||||
$user->country,
|
||||
$user->zip,
|
||||
$user->website,
|
||||
);
|
||||
}
|
||||
|
||||
array_push($values,
|
||||
($user->manager) ? $user->manager->display_name : '',
|
||||
($user->userloc) ? $user->userloc->name : '',
|
||||
($user->department) ? $user->department->name : '',
|
||||
$user->assets->count(),
|
||||
$user->licenses->count(),
|
||||
$user->accessories->count(),
|
||||
$user->consumables->count(),
|
||||
(($user->department) && ($user->department->manager)) ? $user->department->manager->display_name : '',
|
||||
$user->assets_count,
|
||||
$user->licenses_count,
|
||||
$user->accessories_count,
|
||||
$user->consumables_count,
|
||||
$user->manages_users_count,
|
||||
$user->manages_locations_count,
|
||||
$user_groups,
|
||||
$permissionstring,
|
||||
$user->notes,
|
||||
($user->activated == '1') ? trans('general.yes') : trans('general.no'),
|
||||
($user->ldap_import == '1') ? trans('general.yes') : trans('general.no'),
|
||||
($user->two_factor_active_and_enrolled()) ? trans('general.yes') : trans('general.no'),
|
||||
($user->two_factor_active()) ? trans('general.yes') : trans('general.no'),
|
||||
($user->autoassign_licenses == '1') ? trans('general.yes') : trans('general.no'),
|
||||
($user->remote == '1') ? trans('general.yes') : trans('general.no'),
|
||||
($user->vip == '1') ? trans('general.yes') : trans('general.no'),
|
||||
$user->locale,
|
||||
$user->start_date,
|
||||
$user->end_date,
|
||||
$user->last_login,
|
||||
$user->updated_at,
|
||||
$user->created_at,
|
||||
];
|
||||
$user->createdBy?->display_name,
|
||||
);
|
||||
|
||||
fputcsv($handle, $values);
|
||||
}
|
||||
|
||||
@@ -111,11 +111,11 @@ class AssetModelsTransformer
|
||||
$array = [
|
||||
'id' => (int) $file->id,
|
||||
'filename' => e($file->filename),
|
||||
'note' => $file->note,
|
||||
'note' => $file->note ? e($file->note) : null,
|
||||
'url' => route('show/modelfile', [$assetmodel->id, $file->id]),
|
||||
'created_by' => ($file->adminuser) ? [
|
||||
'id' => (int) $file->adminuser->id,
|
||||
'name'=> e($file->adminuser->present()->fullName),
|
||||
'name'=> e($file->adminuser->display_name),
|
||||
] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($file->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($file->updated_at, 'datetime'),
|
||||
|
||||
@@ -322,14 +322,14 @@ class AssetsTransformer
|
||||
'id' => $accessory_checkout->id,
|
||||
'accessory' => [
|
||||
'id' => $accessory_checkout->accessory->id,
|
||||
'name' => $accessory_checkout->accessory->name,
|
||||
'name' => e($accessory_checkout->accessory->display_name),
|
||||
],
|
||||
'assigned_to' => $accessory_checkout->assigned_to,
|
||||
'image' => ($accessory_checkout->accessory->image) ? Storage::disk('public')->url('accessories/' . e($accessory_checkout->accessory->image)) : null,
|
||||
'note' => $accessory_checkout->note ? e($accessory_checkout->note) : null,
|
||||
'created_by' => $accessory_checkout->adminuser ? [
|
||||
'id' => (int)$accessory_checkout->adminuser->id,
|
||||
'name' => e($accessory_checkout->adminuser->present()->fullName),
|
||||
'name' => e($accessory_checkout->display_name),
|
||||
] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($accessory_checkout->created_at, 'datetime'),
|
||||
'deleted_at' => Helper::getFormattedDateObject($accessory_checkout->deleted_at, 'datetime'),
|
||||
|
||||
@@ -91,7 +91,7 @@ class ComponentsTransformer
|
||||
'id' => (int) $asset->id,
|
||||
'name' => e($asset->model->display_name).' '.e($asset->display_name),
|
||||
'qty' => $asset->pivot->assigned_qty,
|
||||
'note' => $asset->pivot->note,
|
||||
'note' => e($asset->pivot->note),
|
||||
'type' => 'asset',
|
||||
'created_at' => Helper::getFormattedDateObject($asset->pivot->created_at, 'datetime'),
|
||||
'available_actions' => ['checkin' => true],
|
||||
|
||||
@@ -30,7 +30,7 @@ class LocationsTransformer
|
||||
foreach ($location->children as $child) {
|
||||
$children_arr[] = [
|
||||
'id' => (int) $child->id,
|
||||
'name' => $child->name,
|
||||
'name' => e($child->display_name),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -157,7 +157,7 @@ class LocationsTransformer
|
||||
'name' => e($location->name),
|
||||
'created_by' => $location->adminuser ? [
|
||||
'id' => (int) $location->adminuser->id,
|
||||
'name'=> e($location->adminuser->present()->fullName),
|
||||
'name'=> e($location->adminuser->display_name),
|
||||
]: null,
|
||||
'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'),
|
||||
];
|
||||
@@ -171,7 +171,7 @@ class LocationsTransformer
|
||||
if ($accessory) {
|
||||
return [
|
||||
'id' => $accessory->id,
|
||||
'name' => $accessory->name,
|
||||
'name' => e($accessory->display_name),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class UploadedFilesTransformer
|
||||
'note' => ($file->note) ? e($file->note) : null,
|
||||
'created_by' => ($file->adminuser) ? [
|
||||
'id' => (int) $file->adminuser->id,
|
||||
'name'=> e($file->adminuser->present()->fullName),
|
||||
'name'=> e($file->adminuser->display_name),
|
||||
] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($file->created_at, 'datetime'),
|
||||
'deleted_at' => Helper::getFormattedDateObject($file->deleted_at, 'datetime'),
|
||||
|
||||
@@ -28,6 +28,19 @@ class UsersTransformer
|
||||
} elseif ($user->isAdmin()) {
|
||||
$role = 'admin';
|
||||
}
|
||||
|
||||
$sensitive_fields = [
|
||||
'email' => ($user->email) ? e($user->email) : null,
|
||||
'phone' => ($user->phone) ? e($user->phone) : null,
|
||||
'mobile' => ($user->mobile) ? e($user->mobile) : null,
|
||||
'website' => ($user->website) ? e($user->website) : null,
|
||||
'address' => ($user->address) ? e($user->address) : null,
|
||||
'city' => ($user->city) ? e($user->city) : null,
|
||||
'state' => ($user->state) ? e($user->state) : null,
|
||||
'country' => ($user->country) ? e($user->country) : null,
|
||||
'zip' => ($user->zip) ? e($user->zip) : null,
|
||||
];
|
||||
|
||||
$array = [
|
||||
'id' => (int) $user->id,
|
||||
'avatar' => e($user->present()->gravatar) ?? null,
|
||||
@@ -45,15 +58,15 @@ class UsersTransformer
|
||||
] : null,
|
||||
'jobtitle' => ($user->jobtitle) ? e($user->jobtitle) : null,
|
||||
'vip' => ($user->vip == '1') ? true : false,
|
||||
'phone' => ($user->phone) ? e($user->phone) : null,
|
||||
'mobile' => ($user->mobile) ? e($user->mobile) : null,
|
||||
'website' => ($user->website) ? e($user->website) : null,
|
||||
'address' => ($user->address) ? e($user->address) : null,
|
||||
'city' => ($user->city) ? e($user->city) : null,
|
||||
'state' => ($user->state) ? e($user->state) : null,
|
||||
'country' => ($user->country) ? e($user->country) : null,
|
||||
'zip' => ($user->zip) ? e($user->zip) : null,
|
||||
'email' => ($user->email) ? e($user->email) : null,
|
||||
];
|
||||
|
||||
if (auth()->user()->can('manageContactInfo')) {
|
||||
$array += $sensitive_fields;
|
||||
}
|
||||
|
||||
|
||||
$array += [
|
||||
|
||||
'department' => ($user->department) ? [
|
||||
'id' => (int) $user->department->id,
|
||||
'name'=> e($user->department->name),
|
||||
|
||||
@@ -208,6 +208,68 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
* @return Attribute
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* These fields should be hidden if the requesting user cannot view contact info
|
||||
* @return Attribute
|
||||
*/
|
||||
protected function address(): Attribute
|
||||
{
|
||||
return Attribute:: make(
|
||||
get: fn(mixed $value) => (auth()->user() && auth()->user()->can('manageContactInfo')) ? $value : null,
|
||||
);
|
||||
}
|
||||
|
||||
protected function city(): Attribute
|
||||
{
|
||||
return Attribute:: make(
|
||||
get: fn(mixed $value) => (auth()->user() && auth()->user()->can('manageContactInfo')) ? $value : null,
|
||||
);
|
||||
}
|
||||
|
||||
protected function state(): Attribute
|
||||
{
|
||||
return Attribute:: make(
|
||||
get: fn(mixed $value) => (auth()->user() && auth()->user()->can('manageContactInfo')) ? $value : null,
|
||||
);
|
||||
}
|
||||
|
||||
protected function country(): Attribute
|
||||
{
|
||||
return Attribute:: make(
|
||||
get: fn(mixed $value) => (auth()->user() && auth()->user()->can('manageContactInfo')) ? $value : null,
|
||||
);
|
||||
}
|
||||
|
||||
protected function zip(): Attribute
|
||||
{
|
||||
return Attribute:: make(
|
||||
get: fn(mixed $value) => (auth()->user() && auth()->user()->can('manageContactInfo')) ? $value : null,
|
||||
);
|
||||
}
|
||||
|
||||
protected function phone(): Attribute
|
||||
{
|
||||
return Attribute:: make(
|
||||
get: fn(mixed $value) => (auth()->user() && auth()->user()->can('manageContactInfo')) ? $value : null,
|
||||
);
|
||||
}
|
||||
|
||||
protected function mobile(): Attribute
|
||||
{
|
||||
return Attribute:: make(
|
||||
get: fn(mixed $value) => (auth()->user() && auth()->user()->can('manageContactInfo')) ? $value : null,
|
||||
);
|
||||
}
|
||||
|
||||
protected function website(): Attribute
|
||||
{
|
||||
return Attribute:: make(
|
||||
get: fn(mixed $value) => (auth()->user() && auth()->user()->can('manageContactInfo')) ? $value : null,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
protected function displayName(): Attribute
|
||||
{
|
||||
return Attribute:: make(
|
||||
@@ -1033,9 +1095,11 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
*/
|
||||
public function scopeSimpleNameSearch($query, $search)
|
||||
{
|
||||
return $query->where('first_name', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('last_name', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('display_name', 'LIKE', '%' . $search . '%')
|
||||
return $query->where('users.first_name', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('users.last_name', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('users.username', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('users.display_name', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('users.employee_num', 'LIKE', '%' . $search . '%')
|
||||
->orWhereMultipleColumns(
|
||||
[
|
||||
'users.first_name',
|
||||
|
||||
@@ -2,10 +2,17 @@
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UserPolicy extends SnipePermissionsPolicy
|
||||
{
|
||||
protected function columnName()
|
||||
{
|
||||
return 'users';
|
||||
}
|
||||
|
||||
public function manageContactInfo(User $user)
|
||||
{
|
||||
return $user->hasAccess('users.contact');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,11 @@ class UserPresenter extends Presenter
|
||||
'title' => trans('admin/users/general.remote'),
|
||||
'visible' => false,
|
||||
'formatter' => 'trueFalseFormatter',
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
$sensitive_fields = [
|
||||
[
|
||||
'field' => 'email',
|
||||
'searchable' => true,
|
||||
@@ -204,8 +208,17 @@ class UserPresenter extends Presenter
|
||||
'switchable' => true,
|
||||
'title' => trans('general.zip'),
|
||||
'visible' => false,
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
// Add the sensitive fields in if the user can see them
|
||||
if (auth()->user()->can('manageContactInfo')) {
|
||||
foreach ($sensitive_fields as $sensitive_field) {
|
||||
array_push($layout, $sensitive_field);
|
||||
}
|
||||
}
|
||||
|
||||
array_push($layout,
|
||||
[
|
||||
'field' => 'locale',
|
||||
'searchable' => true,
|
||||
@@ -434,8 +447,8 @@ class UserPresenter extends Presenter
|
||||
'formatter' => 'usersActionsFormatter',
|
||||
'printIgnore' => true,
|
||||
'class' => 'hidden-print',
|
||||
],
|
||||
];
|
||||
]
|
||||
);
|
||||
|
||||
return json_encode($layout);
|
||||
}
|
||||
@@ -449,31 +462,6 @@ class UserPresenter extends Presenter
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user full name, it simply concatenates
|
||||
* the user first and last name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
// public function fullName()
|
||||
// {
|
||||
// if ($this->display_name) {
|
||||
// return 'kjdfh'.html_entity_decode($this->display_name, ENT_QUOTES | ENT_XML1, 'UTF-8');
|
||||
// }
|
||||
// return 'roieuoe'.html_entity_decode($this->first_name.' '.$this->last_name, ENT_QUOTES | ENT_XML1, 'UTF-8');
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Standard accessor.
|
||||
// * @TODO Remove presenter::fullName() entirely?
|
||||
// * @return string
|
||||
// */
|
||||
// public function name()
|
||||
// {
|
||||
// return $this->fullName();
|
||||
// }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the user Gravatar image url.
|
||||
@@ -558,4 +546,6 @@ class UserPresenter extends Presenter
|
||||
|
||||
return '<span class="'. (($this->deleted_at!='') ? 'deleted' : '').'">'.e($this->display_name).'</span>';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -162,6 +162,12 @@ class AuthServiceProvider extends ServiceProvider
|
||||
return true;
|
||||
});
|
||||
|
||||
Gate::define('manageContactInfo', function ($user) {
|
||||
if ($user->hasAccess('users.contact')) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Gate::define('admin', function ($user) {
|
||||
if ($user->hasAccess('admin')) {
|
||||
return true;
|
||||
|
||||
@@ -607,7 +607,8 @@ class BreadcrumbsServiceProvider extends ServiceProvider
|
||||
|
||||
Breadcrumbs::for('users.edit', fn (Trail $trail, User $user) =>
|
||||
$trail->parent('users.index', route('users.index'))
|
||||
->push(trans('general.breadcrumb_button_actions.edit_item', ['name' => $user->name]), route('users.edit', $user))
|
||||
->push($user->display_name, route('users.show', $user))
|
||||
->push(trans('general.update'), route('users.edit', $user))
|
||||
);
|
||||
|
||||
|
||||
|
||||
@@ -251,6 +251,14 @@ return [
|
||||
'permission' => 'users.delete',
|
||||
'display' => true,
|
||||
],
|
||||
[
|
||||
'permission' => 'users.files',
|
||||
'display' => true,
|
||||
],
|
||||
[
|
||||
'permission' => 'users.contact',
|
||||
'display' => true,
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
|
||||
@@ -111,6 +111,11 @@ class UserFactory extends Factory
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
public function manageContactInfo()
|
||||
{
|
||||
return $this->appendPermission(['users.contact' => '1']);
|
||||
}
|
||||
|
||||
public function viewAssets()
|
||||
{
|
||||
|
||||
@@ -226,6 +226,16 @@ return array(
|
||||
'usersdelete' => [
|
||||
'name' => 'Delete Users',
|
||||
],
|
||||
|
||||
'usersfiles' => [
|
||||
'name' => 'Manage User Files',
|
||||
'note' => 'Allows the user to view, upload, download, and delete files associated with users.',
|
||||
],
|
||||
|
||||
'userscontact' => [
|
||||
'name' => 'View/Edit User Contact Info',
|
||||
'note' => 'Allows the user to view and edit personal contact information about the user. This includes: address, city, state/province, country, postal code, phone number, mobile number, email address, and website.',
|
||||
],
|
||||
'models' => [
|
||||
'name' => 'Models',
|
||||
'note' => 'Grants access to the Models section of the application.',
|
||||
|
||||
@@ -3,42 +3,6 @@
|
||||
* Macro helpers
|
||||
*/
|
||||
|
||||
/**
|
||||
* Country macro
|
||||
* Generates the dropdown menu of countries for the profile form
|
||||
*/
|
||||
Form::macro('countries', function ($name = 'country', $selected = null, $class = null, $id = null) {
|
||||
|
||||
$idclause = (!is_null($id)) ? $id : '';
|
||||
|
||||
// Pull the autoglossonym array from the localizations translation file
|
||||
$countries_array = trans('localizations.countries');
|
||||
|
||||
$select = '<select name="'.$name.'" class="'.$class.'" style="width:100%" '.$idclause.' aria-label="'.$name.'" data-placeholder="'.trans('localizations.select_country').'" data-allow-clear="true" data-tags="true">';
|
||||
$select .= '<option value="" role="option">'.trans('localizations.select_country').'</option>';
|
||||
|
||||
foreach ($countries_array as $abbr => $country) {
|
||||
|
||||
// We have to handle it this way to handle deprecation warnings since you can't strtoupper on null
|
||||
if ($abbr!='') {
|
||||
$abbr = strtoupper($abbr);
|
||||
}
|
||||
|
||||
// Loop through the countries configured in the localization file
|
||||
$select .= '<option value="' . $abbr . '" role="option" ' . (($selected == $abbr) ? ' selected="selected" aria-selected="true"' : ' aria-selected="false"') . '>' . $country . '</option> ';
|
||||
|
||||
}
|
||||
|
||||
// If the country value doesn't exist in the array, add it as a new option and select it so we don't drop that data
|
||||
if (!array_key_exists($selected, $countries_array)) {
|
||||
$select .= '<option value="' . e($selected) . '" selected="selected" role="option" aria-selected="true">' . e($selected) .' *</option> ';
|
||||
}
|
||||
|
||||
$select .= '</select>';
|
||||
|
||||
return $select;
|
||||
});
|
||||
|
||||
/**
|
||||
* Barcode macro
|
||||
* Generates the dropdown menu of available 1D barcodes
|
||||
@@ -85,29 +49,3 @@ Form::macro('barcode_types', function ($name = 'barcode_type', $selected = null,
|
||||
|
||||
return $select;
|
||||
});
|
||||
|
||||
Form::macro('username_format', function ($name = 'username_format', $selected = null, $class = null) {
|
||||
$formats = [
|
||||
'firstname.lastname' => trans('admin/settings/general.username_formats.firstname_lastname_format'),
|
||||
'firstname' => trans('admin/settings/general.username_formats.first_name_format'),
|
||||
'lastname' => trans('admin/settings/general.username_formats.last_name_format'),
|
||||
'filastname' => trans('admin/settings/general.username_formats.filastname_format'),
|
||||
'lastnamefirstinitial' => trans('admin/settings/general.username_formats.lastnamefirstinitial_format'),
|
||||
'firstname_lastname' => trans('admin/settings/general.username_formats.firstname_lastname_underscore_format'),
|
||||
'firstinitial.lastname' => trans('admin/settings/general.username_formats.firstinitial_lastname'),
|
||||
'lastname_firstinitial' => trans('admin/settings/general.username_formats.lastname_firstinitial'),
|
||||
'lastname.firstinitial' => trans('admin/settings/general.username_formats.lastname_dot_firstinitial_format'),
|
||||
'firstnamelastname' => trans('admin/settings/general.username_formats.firstnamelastname'),
|
||||
'firstnamelastinitial' => trans('admin/settings/general.username_formats.firstnamelastinitial'),
|
||||
'lastname.firstname' => trans('admin/settings/general.username_formats.lastnamefirstname'),
|
||||
];
|
||||
|
||||
$select = '<select name="'.$name.'" class="'.$class.'" style="width: 100%" aria-label="'.$name.'">';
|
||||
foreach ($formats as $format => $label) {
|
||||
$select .= '<option value="'.$format.'"'.($selected == $format ? ' selected="selected" role="option" aria-selected="true"' : ' aria-selected="false"').'>'.$label.'</option> '."\n";
|
||||
}
|
||||
|
||||
$select .= '</select>';
|
||||
|
||||
return $select;
|
||||
});
|
||||
|
||||
@@ -288,9 +288,9 @@
|
||||
|
||||
|
||||
|
||||
@if ((isset($infoPanelObj->parent)) && $infoPanelObj->parent))
|
||||
@if ((isset($infoPanelObj->parent)) && ($infoPanelObj->parent))
|
||||
<x-info-element icon_type="parent" title="{{ trans('admin/locations/table.parent') }}">
|
||||
{{ $infoPanelObj->parent->display_name }}
|
||||
<a href="{{ route('locations.show', $infoPanelObj->parent->id) }}">{{ $infoPanelObj->parent->display_name }}</a>
|
||||
</x-info-element>
|
||||
@endif
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
])
|
||||
|
||||
@if (!$slot->isEmpty())
|
||||
<li {{ $attributes->merge(['class' => 'list-group-item']) }}>
|
||||
<li {{ $attributes->merge(['class' => 'list-group-item']) }} id="{{ strtolower(str_slug($title)) }}">
|
||||
|
||||
@if ($icon_type)
|
||||
<x-icon type="{{ $icon_type }}" :title="$title" class="fa-fw" style="{{ 'color: '.$icon_color.' !important' ?? '' }}" />
|
||||
|
||||
35
resources/views/blade/input/country-select.blade.php
Normal file
35
resources/views/blade/input/country-select.blade.php
Normal file
@@ -0,0 +1,35 @@
|
||||
@props([
|
||||
'name' => 'country',
|
||||
'selected' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
$countries_array = trans('localizations.countries');
|
||||
@endphp
|
||||
|
||||
<select
|
||||
name="{{ $name }}"
|
||||
{{ $attributes->merge(['class' => 'select2']) }}
|
||||
aria-label="{{ $name }}"
|
||||
data-placeholder="{{ trans('localizations.select_country') }}"
|
||||
data-allow-clear="true"
|
||||
>
|
||||
@foreach($countries_array as $abbreviation => $country)
|
||||
@php
|
||||
// We have to handle it this way to handle deprecation warnings since you can't strtoupper on null
|
||||
if ($abbreviation!='') {
|
||||
$abbreviation = strtoupper($abbreviation);
|
||||
}
|
||||
@endphp
|
||||
|
||||
<option value="{{ $abbreviation }}" {{ $selected === $abbreviation ? 'selected' : '' }}>
|
||||
{{ $country }}
|
||||
</option>
|
||||
@endforeach
|
||||
|
||||
{{-- If the country value doesn't exist in the array, add it as a new option and select it so we don't drop that data --}}
|
||||
@if (!array_key_exists($selected, $countries_array)) {
|
||||
<option value="{{ e($selected) }}" selected="selected" role="option" aria-selected="true"> {{ e($selected) }} *</option> ';
|
||||
@endif
|
||||
|
||||
</select>
|
||||
27
resources/views/blade/input/username-select.blade.php
Normal file
27
resources/views/blade/input/username-select.blade.php
Normal file
@@ -0,0 +1,27 @@
|
||||
@php
|
||||
$formats = [
|
||||
'firstname.lastname' => trans('admin/settings/general.username_formats.firstname_lastname_format'),
|
||||
'firstname' => trans('admin/settings/general.username_formats.first_name_format'),
|
||||
'lastname' => trans('admin/settings/general.username_formats.last_name_format'),
|
||||
'filastname' => trans('admin/settings/general.username_formats.filastname_format'),
|
||||
'lastnamefirstinitial' => trans('admin/settings/general.username_formats.lastnamefirstinitial_format'),
|
||||
'firstname_lastname' => trans('admin/settings/general.username_formats.firstname_lastname_underscore_format'),
|
||||
'firstinitial.lastname' => trans('admin/settings/general.username_formats.firstinitial_lastname'),
|
||||
'lastname_firstinitial' => trans('admin/settings/general.username_formats.lastname_firstinitial'),
|
||||
'lastname.firstinitial' => trans('admin/settings/general.username_formats.lastname_dot_firstinitial_format'),
|
||||
'firstnamelastname' => trans('admin/settings/general.username_formats.firstnamelastname'),
|
||||
'firstnamelastinitial' => trans('admin/settings/general.username_formats.firstnamelastinitial'),
|
||||
'lastname.firstname' => trans('admin/settings/general.username_formats.lastnamefirstname'),
|
||||
];
|
||||
@endphp
|
||||
|
||||
<x-input.select {{ $attributes }}>
|
||||
@foreach($formats as $format => $label)
|
||||
<option
|
||||
value="{{ $format }}"
|
||||
@selected($selected == $format)
|
||||
>
|
||||
{{ $label }}
|
||||
</option>
|
||||
@endforeach
|
||||
</x-input.select>
|
||||
@@ -158,7 +158,7 @@
|
||||
if (data.status == 'success') {
|
||||
$('#audited tbody').prepend("<tr class='success'><td>" + data.payload.asset_tag + "</td><td>" + data.messages + "</td><td>" + data.payload.status_label + " (" + data.payload.status_type + ")</td><td>" + data.payload.note + "</td><td><i class='fas fa-check text-success' style='font-size:18px;'></i></td></tr>");
|
||||
|
||||
@if ($user->enable_sounds)
|
||||
@if ($user?->enable_sounds)
|
||||
var audio = new Audio('{{ config('app.url') }}/sounds/success.mp3');
|
||||
audio.play()
|
||||
@endif
|
||||
@@ -182,7 +182,7 @@
|
||||
});
|
||||
|
||||
function handleAuditFail (data, asset_tag) {
|
||||
@if ($user->enable_sounds)
|
||||
@if ($user?->enable_sounds)
|
||||
var audio = new Audio('{{ config('app.url') }}/sounds/error.mp3');
|
||||
audio.play()
|
||||
@endif
|
||||
|
||||
@@ -32,7 +32,13 @@
|
||||
|
||||
<div class="dynamic-form-row">
|
||||
<div class="col-md-3 col-xs-12 country"><label for="modal-country">{{ trans('general.country') }}:</label></div>
|
||||
<div class="col-md-9 col-xs-12">{!! Form::countries('country', old('country'), 'select2 country',"modal-country") !!}</div>
|
||||
<div class="col-md-9 col-xs-12">
|
||||
<x-input.country-select
|
||||
name="country"
|
||||
:selected="old('country')"
|
||||
id="modal-country"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
</div> <!-- /.modal-body-->
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="pull-left" data-dismiss="modal">{{ trans('button.cancel') }}</a>
|
||||
<button type="submit" class="btn btn-theme">{{ trans('button.upload') }}</button>
|
||||
<button type="button" class="btn btn-theme" formnovalidate>{{ trans('button.upload') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -34,7 +34,10 @@
|
||||
<div class="form-group {{ $errors->has('country') ? ' has-error' : '' }}">
|
||||
<label for="country" class="col-md-3 control-label">{{ trans('general.country') }}</label>
|
||||
<div class="col-md-7">
|
||||
{!! Form::countries('country', old('country', $item->country), 'select2') !!}
|
||||
<x-input.country-select
|
||||
name="country"
|
||||
:selected="old('country', $item->country)"
|
||||
/>
|
||||
<p class="help-block">{{ trans('general.countries_manually_entered_help') }}</p>
|
||||
{!! $errors->first('country', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
|
||||
@@ -102,7 +102,12 @@
|
||||
<label for="username_format" class="col-md-3 control-label">{{ trans('admin/settings/general.username_formats.username_format') }}</label>
|
||||
|
||||
<div class="col-md-8">
|
||||
{!! Form::username_format('username_format', old('username_format', $setting->username_format), 'select2') !!}
|
||||
<x-input.username-select
|
||||
name="username_format"
|
||||
:selected="old('username_format', $setting->username_format)"
|
||||
style="width: 100%"
|
||||
aria-label="username_format"
|
||||
/>
|
||||
{!! $errors->first('username_format', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
|
||||
<p class="help-block">
|
||||
|
||||
@@ -80,19 +80,7 @@
|
||||
<!-- start components tab pane -->
|
||||
@can('view', \App\Models\Component::class)
|
||||
<x-tabs.pane name="components" class="{{ $supplier->components->count() == 0 ? 'hidden-print' : '' }}">
|
||||
<x-slot:header>
|
||||
{{ trans('general.components') }}
|
||||
</x-slot:header>
|
||||
|
||||
|
||||
<x-table
|
||||
show_advanced_search="true"
|
||||
buttons="componentButtons"
|
||||
api_url="{{ route('api.components.index', ['supplier_id' => $supplier->id]) }}"
|
||||
:presenter="\App\Presenters\ComponentPresenter::dataTableLayout()"
|
||||
export_filename="export-{{ str_slug($supplier->name) }}-components-{{ date('Y-m-d') }}"
|
||||
/>
|
||||
|
||||
<x-table.components name="components" :route="route('api.components.index', ['supplier_id' => $supplier->id])" />
|
||||
</x-tabs.pane>
|
||||
@endcan
|
||||
<!-- end components tab pane -->
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
margin-left: -20px;
|
||||
}
|
||||
</style>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<x-container class="col-md-6 col-md-offset-3">
|
||||
|
||||
<p>{{ trans('admin/users/general.bulk_update_help') }}</p>
|
||||
|
||||
@@ -108,6 +107,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@can('manageContactInfo')
|
||||
<!-- City -->
|
||||
<div class="form-group{{ $errors->has('city') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="city">{{ trans('general.city') }}</label>
|
||||
@@ -117,6 +117,37 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group{{ $errors->has('state') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="state">{{ trans('general.state') }}</label>
|
||||
<div class="col-md-4">
|
||||
<input class="form-control" type="text" name="state" id="state" aria-label="state" />
|
||||
{!! $errors->first('state', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Country -->
|
||||
<div class="form-group{{ $errors->has('country') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="country">{{ trans('general.country') }}</label>
|
||||
<div class="col-md-6">
|
||||
<x-input.country-select
|
||||
name="country"
|
||||
class="col-md-12"
|
||||
/>
|
||||
|
||||
<p class="help-block">{{ trans('general.countries_manually_entered_help') }}</p>
|
||||
{!! $errors->first('country', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group{{ $errors->has('zip') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="zip">{{ trans('general.zip') }}</label>
|
||||
<div class="col-md-4">
|
||||
<input class="form-control" type="text" name="zip" id="zip" aria-label="zip" />
|
||||
{!! $errors->first('zip', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
@endcan
|
||||
|
||||
<!-- remote -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-3 control-label">
|
||||
@@ -162,7 +193,7 @@
|
||||
</div>
|
||||
</div> <!--/form-group-->
|
||||
|
||||
<!-- activated -->
|
||||
<!-- autoassign -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-3 control-label">
|
||||
{{ trans('general.autoassign_licenses') }}
|
||||
@@ -303,5 +334,5 @@
|
||||
</div> <!--/.box.box-default-->
|
||||
</form>
|
||||
</div> <!--/.col-md-8-->
|
||||
</div>
|
||||
</x-container>
|
||||
@stop
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
|
||||
</style>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<x-container class="col-md-6 col-md-offset-3">
|
||||
|
||||
<form class="form-horizontal" method="post" autocomplete="off"
|
||||
action="{{ (isset($user->id)) ? route('users.update', ['user' => $user->id]) : route('users.store') }}"
|
||||
enctype="multipart/form-data" id="userForm">
|
||||
@@ -237,57 +237,58 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Email -->
|
||||
<div class="form-group {{ $errors->has('email') ? 'has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="email">{{ trans('admin/users/table.email') }} </label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="email" name="email" id="email" maxlength="191" value="{{ old('email', $user->email) }}" autocomplete="off"
|
||||
readonly onfocus="this.removeAttribute('readonly');" {{ (Helper::checkIfRequired($user, 'email')) ? ' required' : '' }}{!! (!Gate::allows('canEditAuthFields', $user)) || ((!Gate::allows('editableOnDemo')) && ($user->id)) ? ' style="cursor: not-allowed" disabled ' : '' !!}>
|
||||
@can('manageContactInfo')
|
||||
<!-- Email -->
|
||||
<div class="form-group {{ $errors->has('email') ? 'has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="email">{{ trans('admin/users/table.email') }} </label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="email" name="email" id="email" maxlength="191" value="{{ old('email', $user->email) }}" autocomplete="off"
|
||||
readonly onfocus="this.removeAttribute('readonly');" {{ (Helper::checkIfRequired($user, 'email')) ? ' required' : '' }}{!! (!Gate::allows('canEditAuthFields', $user)) || ((!Gate::allows('editableOnDemo')) && ($user->id)) ? ' style="cursor: not-allowed" disabled ' : '' !!}>
|
||||
|
||||
@cannot('canEditAuthFields', $user)
|
||||
<!-- authed user is an admin or regular user and is trying to edit someone higher -->
|
||||
<p class="help-block">
|
||||
<x-icon type="locked" />
|
||||
{{ trans('general.action_permission_generic', ['action' => trans('general.edit'), 'item_type' => trans('general.email')]) }}
|
||||
</p>
|
||||
@endcannot
|
||||
@cannot('canEditAuthFields', $user)
|
||||
<!-- authed user is an admin or regular user and is trying to edit someone higher -->
|
||||
<p class="help-block">
|
||||
<x-icon type="locked" />
|
||||
{{ trans('general.action_permission_generic', ['action' => trans('general.edit'), 'item_type' => trans('general.email')]) }}
|
||||
</p>
|
||||
@endcannot
|
||||
|
||||
|
||||
@if (!Gate::allows('editableOnDemo') && ($user->id))
|
||||
<p class="text-warning">
|
||||
<x-icon type="locked" />
|
||||
{{ trans('admin/users/table.lock_passwords') }}
|
||||
</p>
|
||||
@endif
|
||||
@if (!Gate::allows('editableOnDemo') && ($user->id))
|
||||
<p class="text-warning">
|
||||
<x-icon type="locked" />
|
||||
{{ trans('admin/users/table.lock_passwords') }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
{!! $errors->first('email', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
{!! $errors->first('email', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- Send welcome email to user -->
|
||||
@if (!$user->id)
|
||||
<div class="form-group" id="email_user_row">
|
||||
|
||||
<!-- Send welcome email to user -->
|
||||
@if (!$user->id)
|
||||
<div class="form-group" id="email_user_row">
|
||||
<div class="col-md-8 col-md-offset-3">
|
||||
<label class="form-control form-control--disabled">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="send_welcome"
|
||||
id="email_user_checkbox"
|
||||
value="1"
|
||||
aria-label="send_welcome"
|
||||
@checked(old('send_welcome'))
|
||||
/>
|
||||
{{ trans('general.send_welcome_email_to_users') }}
|
||||
</label>
|
||||
|
||||
<div class="col-md-8 col-md-offset-3">
|
||||
<label class="form-control form-control--disabled">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="send_welcome"
|
||||
id="email_user_checkbox"
|
||||
value="1"
|
||||
aria-label="send_welcome"
|
||||
@checked(old('send_welcome'))
|
||||
/>
|
||||
{{ trans('general.send_welcome_email_to_users') }}
|
||||
</label>
|
||||
<p class="help-block"> {{ trans('general.send_welcome_email_help') }}</p>
|
||||
|
||||
<p class="help-block"> {{ trans('general.send_welcome_email_help') }}</p>
|
||||
|
||||
</div>
|
||||
</div> <!--/form-group-->
|
||||
@endif
|
||||
</div>
|
||||
</div> <!--/form-group-->
|
||||
@endif
|
||||
@endcan
|
||||
|
||||
|
||||
@include ('partials.forms.edit.image-upload', ['fieldname' => 'avatar', 'image_path' => app('users_upload_path')])
|
||||
@@ -444,88 +445,94 @@
|
||||
<!-- Location -->
|
||||
@include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'location_id'])
|
||||
|
||||
<!-- Phone -->
|
||||
<div class="form-group {{ $errors->has('phone') ? 'has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="phone">{{ trans('admin/users/table.phone') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="phone" id="phone" value="{{ old('phone', $user->phone) }}" maxlength="191" />
|
||||
{!! $errors->first('phone', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
@can('manageContactInfo')
|
||||
<!-- Phone -->
|
||||
<div class="form-group {{ $errors->has('phone') ? 'has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="phone">{{ trans('admin/users/table.phone') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="phone" id="phone" value="{{ old('phone', $user->phone) }}" maxlength="191" />
|
||||
{!! $errors->first('phone', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile -->
|
||||
<div class="form-group {{ $errors->has('mobile') ? 'has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="phone">{{ trans('admin/users/table.mobile') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="mobile" id="mobile" value="{{ old('mobile', $user->mobile) }}" maxlength="191" />
|
||||
{!! $errors->first('mobile', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
<!-- Mobile -->
|
||||
<div class="form-group {{ $errors->has('mobile') ? 'has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="phone">{{ trans('admin/users/table.mobile') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="mobile" id="mobile" value="{{ old('mobile', $user->mobile) }}" maxlength="191" />
|
||||
{!! $errors->first('mobile', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Website URL -->
|
||||
<div class="form-group {{ $errors->has('website') ? ' has-error' : '' }}">
|
||||
<label for="website" class="col-md-3 control-label">{{ trans('general.website') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="url" name="website" id="website" value="{{ old('website', $user->website) }}" maxlength="191" />
|
||||
{!! $errors->first('website', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
<!-- Website URL -->
|
||||
<div class="form-group {{ $errors->has('website') ? ' has-error' : '' }}">
|
||||
<label for="website" class="col-md-3 control-label">{{ trans('general.website') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="url" name="website" id="website" value="{{ old('website', $user->website) }}" maxlength="191" />
|
||||
{!! $errors->first('website', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Address -->
|
||||
<div class="form-group{{ $errors->has('address') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="address">{{ trans('general.address') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="address" id="address" value="{{ old('address', $user->address) }}" maxlength="191" />
|
||||
{!! $errors->first('address', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
<!-- Address -->
|
||||
<div class="form-group{{ $errors->has('address') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="address">{{ trans('general.address') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="address" id="address" value="{{ old('address', $user->address) }}" maxlength="191" />
|
||||
{!! $errors->first('address', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- City -->
|
||||
<div class="form-group{{ $errors->has('city') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="city">{{ trans('general.city') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="city" id="city" aria-label="city" value="{{ old('city', $user->city) }}" maxlength="191" />
|
||||
{!! $errors->first('city', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
<!-- City -->
|
||||
<div class="form-group{{ $errors->has('city') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="city">{{ trans('general.city') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="city" id="city" aria-label="city" value="{{ old('city', $user->city) }}" maxlength="191" />
|
||||
{!! $errors->first('city', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- State -->
|
||||
<div class="form-group{{ $errors->has('state') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="state">{{ trans('general.state') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="state" id="state" value="{{ old('state', $user->state) }}" maxlength="191" />
|
||||
{!! $errors->first('state', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
<!-- State -->
|
||||
<div class="form-group{{ $errors->has('state') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="state">{{ trans('general.state') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="state" id="state" value="{{ old('state', $user->state) }}" maxlength="191" />
|
||||
{!! $errors->first('state', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Country -->
|
||||
<div class="form-group{{ $errors->has('country') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="country">{{ trans('general.country') }}</label>
|
||||
<div class="col-md-6">
|
||||
{!! Form::countries('country', old('country', $user->country), 'col-md-12 select2') !!}
|
||||
<!-- Country -->
|
||||
<div class="form-group{{ $errors->has('country') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="country">{{ trans('general.country') }}</label>
|
||||
<div class="col-md-6">
|
||||
<x-input.country-select
|
||||
name="country"
|
||||
:selected="old('country', $user->country)"
|
||||
class="col-md-12"
|
||||
/>
|
||||
|
||||
<p class="help-block">{{ trans('general.countries_manually_entered_help') }}</p>
|
||||
{!! $errors->first('country', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
<p class="help-block">{{ trans('general.countries_manually_entered_help') }}</p>
|
||||
{!! $errors->first('country', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Zip -->
|
||||
<div class="form-group{{ $errors->has('zip') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="zip">{{ trans('general.zip') }}</label>
|
||||
<div class="col-md-3 text-right">
|
||||
<input class="form-control" type="text" name="zip" id="zip" value="{{ old('zip', $user->zip) }}" maxlength="10" />
|
||||
{!! $errors->first('zip', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
<!-- Zip -->
|
||||
<div class="form-group{{ $errors->has('zip') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="zip">{{ trans('general.zip') }}</label>
|
||||
<div class="col-md-3 text-right">
|
||||
<input class="form-control" type="text" name="zip" id="zip" value="{{ old('zip', $user->zip) }}" maxlength="10" />
|
||||
{!! $errors->first('zip', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endcan
|
||||
<!-- Notes -->
|
||||
<div class="form-group{!! $errors->has('notes') ? ' has-error' : '' !!}">
|
||||
<label for="notes" class="col-md-3 control-label">{{ trans('admin/users/table.notes') }}</label>
|
||||
<div class="col-md-6">
|
||||
<textarea class="form-control" rows="5" id="notes" name="notes">{{ old('notes', $user->notes) }}</textarea>
|
||||
{!! $errors->first('notes', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Notes -->
|
||||
<x-form.row
|
||||
:label="trans('general.notes')"
|
||||
:item="$user"
|
||||
name="notes"
|
||||
type="textarea"
|
||||
placeholder="{{ trans('general.placeholders.notes') }}"
|
||||
/>
|
||||
|
||||
@if ($snipeSettings->two_factor_enabled!='')
|
||||
@if ($snipeSettings->two_factor_enabled=='1')
|
||||
@@ -579,7 +586,7 @@
|
||||
<label class="col-md-3 control-label" for="groups[]">
|
||||
{{ trans('general.groups') }}
|
||||
</label>
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-8">
|
||||
|
||||
@if ($groups->count())
|
||||
@if ((!Gate::allows('editableOnDemo') || (!Auth::user()->isSuperUser())))
|
||||
@@ -672,7 +679,7 @@
|
||||
</div><!-- nav-tabs-custom -->
|
||||
</form>
|
||||
</div> <!--/col-md-8-->
|
||||
</div><!--/row-->
|
||||
</x-container>
|
||||
@stop
|
||||
|
||||
@section('moar_scripts')
|
||||
|
||||
@@ -83,16 +83,18 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#files" data-toggle="tab">
|
||||
<span class="hidden-lg hidden-md">
|
||||
<x-icon type="files" class="fa-2x" />
|
||||
</span>
|
||||
<span class="hidden-xs hidden-sm">{{ trans('general.file_uploads') }}
|
||||
{!! ($user->uploads->count() > 0 ) ? '<span class="badge badge-secondary">'.number_format($user->uploads->count()).'</span>' : '' !!}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
@can('update', $user)
|
||||
<li>
|
||||
<a href="#files" data-toggle="tab">
|
||||
<span class="hidden-lg hidden-md">
|
||||
<x-icon type="files" class="fa-2x" />
|
||||
</span>
|
||||
<span class="hidden-xs hidden-sm">{{ trans('general.file_uploads') }}
|
||||
{!! ($user->uploads->count() > 0 ) ? '<span class="badge badge-secondary">'.number_format($user->uploads->count()).'</span>' : '' !!}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
@endcan
|
||||
|
||||
<li>
|
||||
<a href="#eulas" data-toggle="tab">
|
||||
@@ -160,7 +162,7 @@
|
||||
</li>
|
||||
@endcan
|
||||
|
||||
@can('update', \App\Models\User::class)
|
||||
@can('manageFiles', $user)
|
||||
<li class="pull-right">
|
||||
<a href="#" data-toggle="modal" data-target="#uploadFileModal">
|
||||
<span class="hidden-xs"><x-icon type="paperclip" /></span>
|
||||
@@ -375,6 +377,7 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@can('manageContactInfo')
|
||||
<!-- address -->
|
||||
@if (($user->address) || ($user->city) || ($user->state) || ($user->country))
|
||||
<div class="row">
|
||||
@@ -402,6 +405,7 @@
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endcan
|
||||
|
||||
<!-- company -->
|
||||
@if (!is_null($user->company))
|
||||
@@ -512,6 +516,7 @@
|
||||
@endif
|
||||
|
||||
|
||||
@can('manageContactInfo')
|
||||
@if ($user->email)
|
||||
<!-- email -->
|
||||
<div class="row">
|
||||
@@ -526,6 +531,7 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
@if ($user->website)
|
||||
<!-- website -->
|
||||
<div class="row">
|
||||
@@ -565,6 +571,7 @@
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endcan
|
||||
@if ($user->userloc)
|
||||
<!-- location -->
|
||||
<div class="row">
|
||||
@@ -997,6 +1004,7 @@
|
||||
</table>
|
||||
</div><!-- /consumables-tab -->
|
||||
|
||||
@can('manageFiles', $user)
|
||||
<div class="tab-pane" id="files">
|
||||
<div class="row">
|
||||
|
||||
@@ -1005,6 +1013,7 @@
|
||||
</div>
|
||||
</div> <!--/ROW-->
|
||||
</div><!--/FILES-->
|
||||
@endcan
|
||||
|
||||
<div class="tab-pane" id="eulas">
|
||||
<table
|
||||
@@ -1114,7 +1123,7 @@
|
||||
@stop
|
||||
|
||||
@section('moar_scripts')
|
||||
@include ('partials.bootstrap-table', ['simple_view' => true])
|
||||
@include ('partials.bootstrap-table', ['simple_view' => true])
|
||||
<script nonce="{{ csrf_token() }}">
|
||||
$(function () {
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class UsersForSelectListTest extends TestCase
|
||||
{
|
||||
User::factory()->create(['first_name' => 'Luke', 'last_name' => 'Skywalker', 'email' => 'luke@jedis.org']);
|
||||
|
||||
Passport::actingAs(User::factory()->create());
|
||||
Passport::actingAs(User::factory()->manageContactInfo()->create());
|
||||
$response = $this->getJson(route('api.users.selectlist', ['search' => 'luke@jedis']))->assertOk();
|
||||
|
||||
$results = collect($response->json('results'));
|
||||
@@ -53,6 +53,18 @@ class UsersForSelectListTest extends TestCase
|
||||
$this->assertTrue($results->pluck('text')->contains(fn($text) => str_contains($text, 'Luke')));
|
||||
}
|
||||
|
||||
public function testUsersCannotBeSearchedByEmailWithoutPermission()
|
||||
{
|
||||
User::factory()->create(['first_name' => 'Luke', 'last_name' => 'Skywalker', 'email' => 'luke@jedis.org']);
|
||||
|
||||
Passport::actingAs(User::factory()->create());
|
||||
$response = $this->getJson(route('api.users.selectlist', ['search' => 'luke@jedis']))->assertOk();
|
||||
|
||||
$results = collect($response->json('results'));
|
||||
|
||||
$this->assertEquals(0, $results->count());
|
||||
}
|
||||
|
||||
public function testUsersScopedToCompanyWhenMultipleFullCompanySupportEnabled()
|
||||
{
|
||||
$this->settings->enableMultipleFullCompanySupport();
|
||||
|
||||
@@ -29,7 +29,7 @@ class CreateUserTest extends TestCase
|
||||
{
|
||||
Notification::fake();
|
||||
|
||||
$response = $this->actingAs(User::factory()->createUsers()->viewUsers()->create())
|
||||
$response = $this->actingAs(User::factory()->createUsers()->viewUsers()->manageContactInfo()->create())
|
||||
->from(route('users.index'))
|
||||
->post(route('users.store'), [
|
||||
'first_name' => 'Test First Name',
|
||||
@@ -59,12 +59,49 @@ class CreateUserTest extends TestCase
|
||||
|
||||
}
|
||||
|
||||
public function testCannotUpdateContactWithoutPermission()
|
||||
{
|
||||
Notification::fake();
|
||||
|
||||
$response = $this->actingAs(User::factory()->createUsers()->viewUsers()->create())
|
||||
->from(route('users.index'))
|
||||
->post(route('users.store'), [
|
||||
'first_name' => 'Test First Name',
|
||||
'last_name' => 'Test Last Name',
|
||||
'username' => 'testuser',
|
||||
'password' => 'testpassword1235!!',
|
||||
'password_confirmation' => 'testpassword1235!!',
|
||||
'activated' => '1',
|
||||
'email' => 'foo@example.org',
|
||||
'notes' => 'Test Note',
|
||||
])
|
||||
->assertSessionHasNoErrors()
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('users.index'));
|
||||
|
||||
$this->assertDatabaseHas('users', [
|
||||
'first_name' => 'Test First Name',
|
||||
'last_name' => 'Test Last Name',
|
||||
'username' => 'testuser',
|
||||
'activated' => '1',
|
||||
'email' => null,
|
||||
'notes' => 'Test Note',
|
||||
|
||||
]);
|
||||
Notification::assertNothingSent();
|
||||
$this->followRedirects($response)->assertSee('Success');
|
||||
|
||||
}
|
||||
|
||||
public function testCanCreateAndNotifyUser()
|
||||
{
|
||||
|
||||
Notification::fake();
|
||||
$admin = User::factory()->createUsers()->viewUsers()->manageContactInfo()->create();
|
||||
|
||||
$response = $this->actingAs(User::factory()->createUsers()->viewUsers()->create())
|
||||
// dd($admin);
|
||||
|
||||
$response = $this->actingAs($admin)
|
||||
->from(route('users.index'))
|
||||
->post(route('users.store'), [
|
||||
'first_name' => 'Test First Name',
|
||||
|
||||
@@ -38,4 +38,5 @@ class ViewUserTest extends TestCase
|
||||
->get(route('users.show', $user))
|
||||
->assertStatus(302);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user