mirror of
https://github.com/grocy/grocy.git
synced 2025-08-20 04:12:59 +00:00
[WIP] Implemented basic permissions (#960)
* Add permissions to Database & add "User"-classes * Add UI & API for Permissions, protect "User"-(Api)-Controller with new permissions. * Add some permissions. * Add permission localization * Add error handling. * Error pages: only redirect on 404 * ExceptionController: return JSON-Response on api-routes * Rename PRODUCT_ADD to PRODUCT_PURCHASE * Move translation to new file * Fix checkboxes stay selected on reload. * Remove configurable User-implementation * Remove MASTER_DATA_READ * Disable buttons the user isn't allowed to use. * Add default permissions for new users * When migration to permissions, everyone starts as ADMIN * Permission-Localization: add to transifex & LocalizationService * Review Co-authored-by: Bernd Bestel <bernd@berrnd.de>
This commit is contained in:
committed by
GitHub
parent
f28697e5b4
commit
b7d1b21f1d
@@ -20,7 +20,7 @@
|
||||
<hr>
|
||||
<div class="row mt-3">
|
||||
<div class="col-xs-12 col-md-2 col-xl-1">
|
||||
<a class="btn btn-primary btn-sm responsive-button w-100 mb-3" href="{{ $U('/battery/new') }}">
|
||||
<a class="btn btn-primary btn-sm responsive-button w-100 mb-3 permission-MASTER_DATA_EDIT" href="{{ $U('/battery/new') }}">
|
||||
{{ $__t('Add') }}
|
||||
</a>
|
||||
</div>
|
||||
@@ -57,10 +57,10 @@
|
||||
@foreach($batteries as $battery)
|
||||
<tr>
|
||||
<td class="fit-content border-right">
|
||||
<a class="btn btn-info btn-sm" href="{{ $U('/battery/') }}{{ $battery->id }}">
|
||||
<a class="btn btn-info btn-sm permission-MASTER_DATA_EDIT" href="{{ $U('/battery/') }}{{ $battery->id }}">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<a class="btn btn-danger btn-sm battery-delete-button" href="#" data-battery-id="{{ $battery->id }}" data-battery-name="{{ $battery->name }}">
|
||||
<a class="btn btn-danger btn-sm battery-delete-button permission-MASTER_DATA_EDIT" href="#" data-battery-id="{{ $battery->id }}" data-battery-name="{{ $battery->name }}">
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
</td>
|
||||
|
@@ -50,7 +50,7 @@
|
||||
@foreach($chargeCycles as $chargeCycleEntry)
|
||||
<tr id="charge-cycle-{{ $chargeCycleEntry->id }}-row" class="@if($chargeCycleEntry->undone == 1) text-muted @endif">
|
||||
<td class="fit-content border-right">
|
||||
<a class="btn btn-secondary btn-sm undo-battery-execution-button @if($chargeCycleEntry->undone == 1) disabled @endif" href="#" data-charge-cycle-id="{{ $chargeCycleEntry->id }}" data-toggle="tooltip" data-placement="left" title="{{ $__t('Undo charge cycle') }}">
|
||||
<a class="btn btn-secondary btn-sm undo-battery-execution-button @if($chargeCycleEntry->undone == 1) disabled @endif permission-BATTERY_UNDO_TRACK_CHARGE_CYCLE" href="#" data-charge-cycle-id="{{ $chargeCycleEntry->id }}" data-toggle="tooltip" data-placement="left" title="{{ $__t('Undo charge cycle') }}">
|
||||
<i class="fas fa-undo"></i>
|
||||
</a>
|
||||
</td>
|
||||
|
@@ -69,7 +69,7 @@
|
||||
@foreach($current as $currentBatteryEntry)
|
||||
<tr id="battery-{{ $currentBatteryEntry->battery_id }}-row" class="@if(FindObjectInArrayByPropertyValue($batteries, 'id', $currentBatteryEntry->battery_id)->charge_interval_days > 0 && $currentBatteryEntry->next_estimated_charge_time < date('Y-m-d H:i:s')) table-danger @elseif(FindObjectInArrayByPropertyValue($batteries, 'id', $currentBatteryEntry->battery_id)->charge_interval_days > 0 && $currentBatteryEntry->next_estimated_charge_time < date('Y-m-d H:i:s', strtotime("+$nextXDays days"))) table-warning @endif">
|
||||
<td class="fit-content border-right">
|
||||
<a class="btn btn-success btn-sm track-charge-cycle-button" href="#" data-toggle="tooltip" data-placement="left" title="{{ $__t('Track charge cycle of battery %s', FindObjectInArrayByPropertyValue($batteries, 'id', $currentBatteryEntry->battery_id)->name) }}"
|
||||
<a class="btn btn-success btn-sm track-charge-cycle-button permission-BATTERY_TRACK_CHARGE_CYCLE" href="#" data-toggle="tooltip" data-placement="left" title="{{ $__t('Track charge cycle of battery %s', FindObjectInArrayByPropertyValue($batteries, 'id', $currentBatteryEntry->battery_id)->name) }}"
|
||||
data-battery-id="{{ $currentBatteryEntry->battery_id }}"
|
||||
data-battery-name="{{ FindObjectInArrayByPropertyValue($batteries, 'id', $currentBatteryEntry->battery_id)->name }}">
|
||||
<i class="fas fa-fire"></i>
|
||||
@@ -85,7 +85,7 @@
|
||||
<a class="dropdown-item" type="button" href="{{ $U('/batteriesjournal?battery=') }}{{ $currentBatteryEntry->battery_id }}">
|
||||
<span class="dropdown-item-icon"><i class="fas fa-file-alt"></i></span> <span class="dropdown-item-text">{{ $__t('Journal for this battery') }}</span>
|
||||
</a>
|
||||
<a class="dropdown-item" type="button" href="{{ $U('/battery/') }}{{ $currentBatteryEntry->battery_id }}">
|
||||
<a class="dropdown-item permission-MASTER_DATA_EDIT" type="button" href="{{ $U('/battery/') }}{{ $currentBatteryEntry->battery_id }}">
|
||||
<span class="dropdown-item-icon"><i class="fas fa-edit"></i></span> <span class="dropdown-item-text">{{ $__t('Edit battery') }}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
@@ -53,7 +53,7 @@
|
||||
@foreach($choresLog as $choreLogEntry)
|
||||
<tr id="chore-execution-{{ $choreLogEntry->id }}-row" class="@if($choreLogEntry->undone == 1) text-muted @endif">
|
||||
<td class="fit-content border-right">
|
||||
<a class="btn btn-secondary btn-sm undo-chore-execution-button @if($choreLogEntry->undone == 1) disabled @endif" href="#" data-execution-id="{{ $choreLogEntry->id }}" data-toggle="tooltip" data-placement="left" title="{{ $__t('Undo chore execution') }}">
|
||||
<a class="btn btn-secondary btn-sm undo-chore-execution-button permission-CHORE_UNDO @if($choreLogEntry->undone == 1) disabled @endif" href="#" data-execution-id="{{ $choreLogEntry->id }}" data-toggle="tooltip" data-placement="left" title="{{ $__t('Undo chore execution') }}">
|
||||
<i class="fas fa-undo"></i>
|
||||
</a>
|
||||
</td>
|
||||
|
@@ -95,7 +95,7 @@
|
||||
@foreach($currentChores as $curentChoreEntry)
|
||||
<tr id="chore-{{ $curentChoreEntry->chore_id }}-row" class="@if(FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->period_type !== \Grocy\Services\ChoresService::CHORE_PERIOD_TYPE_MANUALLY && $curentChoreEntry->next_estimated_execution_time < date('Y-m-d H:i:s')) table-danger @elseif(FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->period_type !== \Grocy\Services\ChoresService::CHORE_PERIOD_TYPE_MANUALLY && $curentChoreEntry->next_estimated_execution_time < date('Y-m-d H:i:s', strtotime("+$nextXDays days"))) table-warning @endif">
|
||||
<td class="fit-content border-right">
|
||||
<a class="btn btn-success btn-sm track-chore-button" href="#" data-toggle="tooltip" data-placement="left" title="{{ $__t('Track execution of chore %s', FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->name) }}"
|
||||
<a class="btn btn-success btn-sm track-chore-button permission-CHORE_TRACK" href="#" data-toggle="tooltip" data-placement="left" title="{{ $__t('Track execution of chore %s', FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->name) }}"
|
||||
data-chore-id="{{ $curentChoreEntry->chore_id }}"
|
||||
data-chore-name="{{ FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->name }}">
|
||||
<i class="fas fa-play"></i>
|
||||
@@ -111,7 +111,7 @@
|
||||
<a class="dropdown-item" type="button" href="{{ $U('/choresjournal?chore=') }}{{ $curentChoreEntry->chore_id }}">
|
||||
<span class="dropdown-item-icon"><i class="fas fa-file-alt"></i></span> <span class="dropdown-item-text">{{ $__t('Journal for this chore') }}</span>
|
||||
</a>
|
||||
<a class="dropdown-item" type="button" href="{{ $U('/chore/') }}{{ $curentChoreEntry->chore_id }}">
|
||||
<a class="dropdown-item permission-MASTER_DATA_EDIT" type="button" href="{{ $U('/chore/') }}{{ $curentChoreEntry->chore_id }}">
|
||||
<span class="dropdown-item-icon"><i class="fas fa-edit"></i></span> <span class="dropdown-item-text">{{ $__t('Edit chore') }}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
15
views/components/userpermission_select.blade.php
Normal file
15
views/components/userpermission_select.blade.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<label>
|
||||
<input type="checkbox" name="{{ $perm->permission_name }}" class="permission-cb" data-perm-id="{{ $perm->permission_id }}" @if($perm->has_permission) checked @endif autocomplete="off">
|
||||
{{ $__t($perm->permission_name) }}
|
||||
</label>
|
||||
<div id="permission-sub-{{ $perm->permission_name }}">
|
||||
<ul>
|
||||
@foreach($perm->uihelper_user_permissionsList(array('user_id' => $user->id))->via('parent') as $p)
|
||||
<li>
|
||||
@include('components.userpermission_select', array(
|
||||
'perm' => $p
|
||||
))
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
11
views/errors/403.blade.php
Normal file
11
views/errors/403.blade.php
Normal file
@@ -0,0 +1,11 @@
|
||||
@extends('errors.base')
|
||||
|
||||
@section('title', $__t('Unauthorized'))
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="alert alert-danger">{{ $__t('You are not allowed to view this page') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
13
views/errors/404.blade.php
Normal file
13
views/errors/404.blade.php
Normal file
@@ -0,0 +1,13 @@
|
||||
@extends('errors.base')
|
||||
|
||||
@section('title', $__t('Page not found'))
|
||||
|
||||
@section('content')
|
||||
<meta http-equiv="refresh" content="5;url={{$U('/')}}">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="alert alert-danger">{{ $__t('This page does not exists') }}</div>
|
||||
<div>{{ $__t('You will be redirected to the default page in %s seconds', '5') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
16
views/errors/500.blade.php
Normal file
16
views/errors/500.blade.php
Normal file
@@ -0,0 +1,16 @@
|
||||
@extends('errors.base')
|
||||
|
||||
@section('title', $__t('Server error'))
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="alert alert-danger">{{ $__t('A server error occured while processing your request') }}</div>
|
||||
<div class="alert alert-warning">
|
||||
{{ $__t('If you think this is a bug, please report it') }}<br>
|
||||
→ <a target="_blank" href="https://github.com/grocy/grocy/issues">https://github.com/grocy/grocy/issues</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@parent
|
||||
@stop
|
20
views/errors/base.blade.php
Normal file
20
views/errors/base.blade.php
Normal file
@@ -0,0 +1,20 @@
|
||||
@extends('layout.default')
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div>
|
||||
<h6>{{ $__t('Error source') }}</h6>
|
||||
<pre><code>{!! $exception->getFile() !!}:{!! $exception->getLine() !!}</code></pre>
|
||||
</div>
|
||||
<div>
|
||||
<h6>{{ $__t('Error message') }}</h6>
|
||||
<pre><code>{!! $exception->getMessage() !!}</code></pre>
|
||||
</div>
|
||||
<div>
|
||||
<h6>{{ $__t('Stack trace') }}</h6>
|
||||
<pre><code>{!! $exception->getTraceAsString() !!}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
@@ -62,6 +62,7 @@
|
||||
@if (GROCY_AUTHENTICATED)
|
||||
Grocy.UserSettings = {!! json_encode($userSettings) !!};
|
||||
Grocy.UserId = {{ GROCY_USER_ID }};
|
||||
Grocy.UserPermissions = {!! json_encode($permissions) !!};
|
||||
@else
|
||||
Grocy.UserSettings = { };
|
||||
Grocy.UserId = -1;
|
||||
@@ -163,27 +164,27 @@
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_STOCK)
|
||||
<div class="nav-item-divider"></div>
|
||||
<li class="nav-item nav-item-sidebar" data-toggle="tooltip" data-placement="right" title="{{ $__t('Purchase') }}" data-nav-for-page="purchase">
|
||||
<li class="nav-item nav-item-sidebar permission-PRODUCT_PURCHASE" data-toggle="tooltip" data-placement="right" title="{{ $__t('Purchase') }}" data-nav-for-page="purchase">
|
||||
<a class="nav-link discrete-link" href="{{ $U('/purchase') }}">
|
||||
<i class="fas fa-shopping-cart"></i>
|
||||
<span class="nav-link-text">{{ $__t('Purchase') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item nav-item-sidebar" data-toggle="tooltip" data-placement="right" title="{{ $__t('Consume') }}" data-nav-for-page="consume">
|
||||
<li class="nav-item nav-item-sidebar permission-PRODUCT_CONSUME" data-toggle="tooltip" data-placement="right" title="{{ $__t('Consume') }}" data-nav-for-page="consume">
|
||||
<a class="nav-link discrete-link" href="{{ $U('/consume') }}">
|
||||
<i class="fas fa-utensils"></i>
|
||||
<span class="nav-link-text">{{ $__t('Consume') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING)
|
||||
<li class="nav-item nav-item-sidebar" data-toggle="tooltip" data-placement="right" title="{{ $__t('Transfer') }}" data-nav-for-page="transfer">
|
||||
<li class="nav-item nav-item-sidebar permission-STOCK_TRANSFER" data-toggle="tooltip" data-placement="right" title="{{ $__t('Transfer') }}" data-nav-for-page="transfer">
|
||||
<a class="nav-link discrete-link" href="{{ $U('/transfer') }}">
|
||||
<i class="fas fa-exchange-alt"></i>
|
||||
<span class="nav-link-text">{{ $__t('Transfer') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
<li class="nav-item nav-item-sidebar" data-toggle="tooltip" data-placement="right" title="{{ $__t('Inventory') }}" data-nav-for-page="inventory">
|
||||
<li class="nav-item nav-item-sidebar permission-STOCK_CORRECTION" data-toggle="tooltip" data-placement="right" title="{{ $__t('Inventory') }}" data-nav-for-page="inventory">
|
||||
<a class="nav-link discrete-link" href="{{ $U('/inventory') }}">
|
||||
<i class="fas fa-list"></i>
|
||||
<span class="nav-link-text">{{ $__t('Inventory') }}</span>
|
||||
@@ -191,7 +192,7 @@
|
||||
</li>
|
||||
@endif
|
||||
@if(GROCY_FEATURE_FLAG_CHORES)
|
||||
<li class="nav-item nav-item-sidebar" data-toggle="tooltip" data-placement="right" title="{{ $__t('Chore tracking') }}" data-nav-for-page="choretracking">
|
||||
<li class="nav-item nav-item-sidebar permission-CHORE_TRACK_OTHERS" data-toggle="tooltip" data-placement="right" title="{{ $__t('Chore tracking') }}" data-nav-for-page="choretracking">
|
||||
<a class="nav-link discrete-link" href="{{ $U('/choretracking') }}">
|
||||
<i class="fas fa-play"></i>
|
||||
<span class="nav-link-text">{{ $__t('Chore tracking') }}</span>
|
||||
@@ -199,7 +200,7 @@
|
||||
</li>
|
||||
@endif
|
||||
@if(GROCY_FEATURE_FLAG_BATTERIES)
|
||||
<li class="nav-item nav-item-sidebar" data-toggle="tooltip" data-placement="right" title="{{ $__t('Battery tracking') }}" data-nav-for-page="batterytracking">
|
||||
<li class="nav-item nav-item-sidebar permission-BATTERY_TRACK_CHARGE_CYCLE" data-toggle="tooltip" data-placement="right" title="{{ $__t('Battery tracking') }}" data-nav-for-page="batterytracking">
|
||||
<a class="nav-link discrete-link" href="{{ $U('/batterytracking') }}">
|
||||
<i class="fas fa-fire"></i>
|
||||
<span class="nav-link-text">{{ $__t('Battery tracking') }}</span>
|
||||
@@ -417,7 +418,7 @@
|
||||
@endif
|
||||
<div class="dropdown-divider"></div>
|
||||
@if(GROCY_SHOW_AUTH_VIEWS)
|
||||
<a class="dropdown-item discrete-link" href="{{ $U('/users') }}"><i class="fas fa-users"></i> {{ $__t('Manage users') }}</a>
|
||||
<a class="dropdown-item discrete-link permission-READ_USER" href="{{ $U('/users') }}"><i class="fas fa-users"></i> {{ $__t('Manage users') }}</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item discrete-link" href="{{ $U('/manageapikeys') }}"><i class="fas fa-handshake"></i> {{ $__t('Manage API keys') }}</a>
|
||||
@endif
|
||||
|
@@ -121,14 +121,14 @@
|
||||
@foreach($currentStock as $currentStockEntry)
|
||||
<tr id="product-{{ $currentStockEntry->product_id }}-row" class="@if(GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING && $currentStockEntry->best_before_date < date('Y-m-d 23:59:59', strtotime('-1 days')) && $currentStockEntry->amount > 0) table-danger @elseif(GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING && $currentStockEntry->best_before_date < date('Y-m-d 23:59:59', strtotime("+$nextXDays days")) && $currentStockEntry->amount > 0) table-warning @elseif ($currentStockEntry->product_missing) table-info @endif">
|
||||
<td class="fit-content border-right">
|
||||
<a class="btn btn-success btn-sm product-consume-button @if($currentStockEntry->amount < 1 || $currentStockEntry->enable_tare_weight_handling == 1) disabled @endif" href="#" data-toggle="tooltip" data-placement="left" title="{{ $__t('Consume %1$s of %2$s', '1 ' . $currentStockEntry->qu_unit_name, $currentStockEntry->product_name) }}"
|
||||
<a class="permission-PRODUCT_CONSUME btn btn-success btn-sm product-consume-button @if($currentStockEntry->amount < 1 || $currentStockEntry->enable_tare_weight_handling == 1) disabled @endif" href="#" data-toggle="tooltip" data-placement="left" title="{{ $__t('Consume %1$s of %2$s', '1 ' . $currentStockEntry->qu_unit_name, $currentStockEntry->product_name) }}"
|
||||
data-product-id="{{ $currentStockEntry->product_id }}"
|
||||
data-product-name="{{ $currentStockEntry->product_name }}"
|
||||
data-product-qu-name="{{ $currentStockEntry->qu_unit_name }}"
|
||||
data-consume-amount="1">
|
||||
<i class="fas fa-utensils"></i> 1
|
||||
</a>
|
||||
<a id="product-{{ $currentStockEntry->product_id }}-consume-all-button" class="d-none d-sm-inline-block btn btn-danger btn-sm product-consume-button @if($currentStockEntry->amount == 0) disabled @endif" href="#" data-toggle="tooltip" data-placement="right" title="{{ $__t('Consume all %s which are currently in stock', $currentStockEntry->product_name) }}"
|
||||
<a id="product-{{ $currentStockEntry->product_id }}-consume-all-button" class="permission-PRODUCT_CONSUME d-none d-sm-inline-block btn btn-danger btn-sm product-consume-button @if($currentStockEntry->amount == 0) disabled @endif" href="#" data-toggle="tooltip" data-placement="right" title="{{ $__t('Consume all %s which are currently in stock', $currentStockEntry->product_name) }}"
|
||||
data-product-id="{{ $currentStockEntry->product_id }}"
|
||||
data-product-name="{{ $currentStockEntry->product_name }}"
|
||||
data-product-qu-name="{{ $currentStockEntry->qu_unit_name }}"
|
||||
@@ -156,22 +156,22 @@
|
||||
data-consume-amount="{{ $currentStockEntry->amount }}">
|
||||
<span class="dropdown-item-icon"><i class="fas fa-utensils"></i></span> <span class="dropdown-item-text">{{ $__t('Consume all %s which are currently in stock', $currentStockEntry->product_name) }}</span>
|
||||
</a>
|
||||
<a class="dropdown-item show-as-dialog-link" type="button" href="{{ $U('/shoppinglistitem/new?embedded&updateexistingproduct&product=' . $currentStockEntry->product_id ) }}">
|
||||
<a class="dropdown-item show-as-dialog-link permission-SHOPPINGLIST_ITEMS_ADD" type="button" href="{{ $U('/shoppinglistitem/new?embedded&updateexistingproduct&product=' . $currentStockEntry->product_id ) }}">
|
||||
<span class="dropdown-item-icon"><i class="fas fa-shopping-cart"></i></span> <span class="dropdown-item-text">{{ $__t('Add to shopping list') }}</span>
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item show-as-dialog-link" type="button" href="{{ $U('/purchase?embedded&product=' . $currentStockEntry->product_id ) }}">
|
||||
<a class="dropdown-item show-as-dialog-link permission-PRODUCT_PURCHASE" type="button" href="{{ $U('/purchase?embedded&product=' . $currentStockEntry->product_id ) }}">
|
||||
<span class="dropdown-item-icon"><i class="fas fa-shopping-cart"></i></span> <span class="dropdown-item-text">{{ $__t('Purchase') }}</span>
|
||||
</a>
|
||||
<a class="dropdown-item show-as-dialog-link" type="button" href="{{ $U('/consume?embedded&product=' . $currentStockEntry->product_id ) }}">
|
||||
<a class="dropdown-item show-as-dialog-link permission-PRODUCT_CONSUME" type="button" href="{{ $U('/consume?embedded&product=' . $currentStockEntry->product_id ) }}">
|
||||
<span class="dropdown-item-icon"><i class="fas fa-utensils"></i></span> <span class="dropdown-item-text">{{ $__t('Consume') }}</span>
|
||||
</a>
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING)
|
||||
<a class="dropdown-item show-as-dialog-link @if($currentStockEntry->amount < 1) disabled @endif" type="button" href="{{ $U('/transfer?embedded&product=' . $currentStockEntry->product_id) }}">
|
||||
<a class="dropdown-item show-as-dialog-link permission-STOCK_TRANSFER @if($currentStockEntry->amount < 1) disabled @endif" type="button" href="{{ $U('/transfer?embedded&product=' . $currentStockEntry->product_id) }}">
|
||||
<span class="dropdown-item-icon"><i class="fas fa-exchange-alt"></i></span> <span class="dropdown-item-text">{{ $__t('Transfer') }}</span>
|
||||
</a>
|
||||
@endif
|
||||
<a class="dropdown-item show-as-dialog-link" type="button" href="{{ $U('/inventory?embedded&product=' . $currentStockEntry->product_id ) }}">
|
||||
<a class="dropdown-item show-as-dialog-link permission-STOCK_CORRECTION" type="button" href="{{ $U('/inventory?embedded&product=' . $currentStockEntry->product_id ) }}">
|
||||
<span class="dropdown-item-icon"><i class="fas fa-list"></i></span> <span class="dropdown-item-text">{{ $__t('Inventory') }}</span>
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
@@ -185,11 +185,11 @@
|
||||
<a class="dropdown-item" type="button" href="{{ $U('/stockjournal?product=') }}{{ $currentStockEntry->product_id }}">
|
||||
<span class="dropdown-item-icon"><i class="fas fa-file-alt"></i></span> <span class="dropdown-item-text">{{ $__t('Stock journal for this product') }}</span>
|
||||
</a>
|
||||
<a class="dropdown-item" type="button" href="{{ $U('/product/') }}{{ $currentStockEntry->product_id . '?returnto=%2Fstockoverview' }}">
|
||||
<a class="dropdown-item permission-MASTER_DATA_EDIT" type="button" href="{{ $U('/product/') }}{{ $currentStockEntry->product_id . '?returnto=%2Fstockoverview' }}">
|
||||
<span class="dropdown-item-icon"><i class="fas fa-edit"></i></span> <span class="dropdown-item-text">{{ $__t('Edit product') }}</span>
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item product-consume-button product-consume-button-spoiled @if($currentStockEntry->amount < 1) disabled @endif" type="button" href="#"
|
||||
<a class="dropdown-item product-consume-button product-consume-button-spoiled permission-PRODUCT_CONSUME @if($currentStockEntry->amount < 1) disabled @endif" type="button" href="#"
|
||||
data-product-id="{{ $currentStockEntry->product_id }}"
|
||||
data-product-name="{{ $currentStockEntry->product_name }}"
|
||||
data-product-qu-name="{{ $currentStockEntry->qu_unit_name }}"
|
||||
|
34
views/userpermissions.blade.php
Normal file
34
views/userpermissions.blade.php
Normal file
@@ -0,0 +1,34 @@
|
||||
@extends('layout.default')
|
||||
|
||||
@section('title', $__t('Permissions for user %s', GetUserDisplayName($user)))
|
||||
@section('activeNav', '')
|
||||
@section('viewJsName', 'userpermissions')
|
||||
|
||||
@push('pageScripts')
|
||||
<script>
|
||||
Grocy.EditObjectId = {{ $user->id }};
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2 class="title">@yield('title')</h2>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row mt-3">
|
||||
<div class="col">
|
||||
<ul>
|
||||
@foreach($permissions as $perm)
|
||||
<li>
|
||||
@include('components.userpermission_select', array(
|
||||
'permission' => $perm
|
||||
))
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
<button id="permission-save" class="btn btn-success" type="submit">{{ $__t('Save') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
@@ -47,6 +47,9 @@
|
||||
<a class="btn btn-info btn-sm" href="{{ $U('/user/') }}{{ $user->id }}">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<a class="btn btn-info btn-sm" href="{{ $U('/user/' . $user->id . '/permissions') }}">
|
||||
<i class="fas fa-lock"></i>
|
||||
</a>
|
||||
<a class="btn btn-danger btn-sm user-delete-button @if($user->id == GROCY_USER_ID) disabled @endif" href="#" data-user-id="{{ $user->id }}" data-user-username="{{ $user->username }}">
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
|
Reference in New Issue
Block a user