feat: ✨ clean project (policies, translations, breadcrumbs, dead code etc...)
This commit is contained in:
parent
b5d46f54ee
commit
b13a4ced30
143 changed files with 3774 additions and 2373 deletions
|
|
@ -8,3 +8,6 @@
|
|||
|
||||
- continue migrations :
|
||||
`php artisan migrate`
|
||||
|
||||
TODO:
|
||||
- sur les méthodes GET le token est visible dans les logs server..
|
||||
|
|
|
|||
|
|
@ -28,18 +28,18 @@ class CreateAdmin extends Command
|
|||
protected $description = 'Create a backend admin user';
|
||||
|
||||
/**
|
||||
* The firstname of the new user.
|
||||
* The first name of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $firstname;
|
||||
protected $first_name;
|
||||
|
||||
/**
|
||||
* The lastname of the new user.
|
||||
* The last name of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $lastname;
|
||||
protected $last_name;
|
||||
|
||||
/**
|
||||
* The email of the new user.
|
||||
|
|
@ -48,13 +48,6 @@ class CreateAdmin extends Command
|
|||
*/
|
||||
protected $email;
|
||||
|
||||
/**
|
||||
* The password of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* The role of the new user.
|
||||
*
|
||||
|
|
@ -69,27 +62,23 @@ class CreateAdmin extends Command
|
|||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->firstname = null;
|
||||
$this->first_name = null;
|
||||
$this->addFirstname();
|
||||
|
||||
$this->lastname = null;
|
||||
$this->last_name = null;
|
||||
$this->addLastname();
|
||||
|
||||
$this->email = null;
|
||||
$this->addEmail();
|
||||
|
||||
$this->password = null;
|
||||
$this->addPassword();
|
||||
|
||||
$this->role = null;
|
||||
$this->addRole();
|
||||
|
||||
$user = new User([
|
||||
'firstname' => $this->firstname,
|
||||
'lastname' => $this->lastname,
|
||||
'first_name' => $this->first_name,
|
||||
'last_name' => $this->last_name,
|
||||
'email' => $this->email,
|
||||
'email_verified_at' => now(),
|
||||
'password' => $this->password,
|
||||
'role' => $this->role,
|
||||
]);
|
||||
$user->saveOrFail();
|
||||
|
|
@ -106,14 +95,14 @@ class CreateAdmin extends Command
|
|||
*/
|
||||
private function addFirstname(): void
|
||||
{
|
||||
while (is_null($this->firstname)) {
|
||||
while (is_null($this->first_name)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user firstname', 'Admin');
|
||||
$validator = Validator::make(['firstname' => $tmp], [
|
||||
'firstname' => 'required|min:3|max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->firstname = $tmp;
|
||||
$this->first_name = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid firstname %s',
|
||||
|
|
@ -131,14 +120,14 @@ class CreateAdmin extends Command
|
|||
*/
|
||||
private function addLastname(): void
|
||||
{
|
||||
while (is_null($this->lastname)) {
|
||||
while (is_null($this->last_name)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user lastname', 'Saïtama');
|
||||
$validator = Validator::make(['lastname' => $tmp], [
|
||||
'lastname' => 'required|min:3|max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->lastname = $tmp;
|
||||
$this->last_name = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid lastname %s',
|
||||
|
|
@ -174,22 +163,6 @@ class CreateAdmin extends Command
|
|||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a password to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addPassword(): void
|
||||
{
|
||||
while (
|
||||
($this->password = $this->secret(
|
||||
(!\is_null($this->password) ? 'Failed to confirm, ' : '') . 'Type the wanted user password'
|
||||
)) !== $this->secret('Confirm the password')
|
||||
) {
|
||||
continue;
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a role to the user.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -6,19 +6,26 @@ use App\Http\Controllers\Controller;
|
|||
use App\Http\Requests\Bo\AppUser\StoreAppUserRequest;
|
||||
use App\Http\Requests\Bo\AppUser\UpdateAppUserRequest;
|
||||
use App\Http\Requests\Bo\ImportRequest;
|
||||
use App\Http\Requests\Bo\UpdateChangeOrderRequest;
|
||||
use App\Imports\AppUserImport;
|
||||
use App\Models\AppUser;
|
||||
use App\Models\Directory;
|
||||
use App\Traits\Controllers\ChangesModelOrder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
|
||||
class AppUserController extends Controller
|
||||
{
|
||||
use ChangesModelOrder;
|
||||
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(AppUser::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
|
@ -49,23 +56,27 @@ class AppUserController extends Controller
|
|||
/** Sort columns with a query */
|
||||
$this->sortQuery($query);
|
||||
|
||||
$app_users = $this->paginate($query);
|
||||
$appUserModels = $this->paginate($query);
|
||||
|
||||
return view('bo.pages.app-users.index', compact('app_users', 'searchFields'));
|
||||
return view('bo.pages.app_users.index', compact('appUserModels', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\AppUser $app_user
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create(): \Illuminate\View\View
|
||||
public function create(AppUser $app_user): \Illuminate\View\View
|
||||
{
|
||||
$directories = Directory::renderDirectories(
|
||||
Directory::query()->where('needAuthorization', 1)->orderBy('name', 'ASC')->get()
|
||||
);
|
||||
|
||||
return view('bo.pages.app-users.create', compact('directories'));
|
||||
return view('bo.pages.app_users.create', [
|
||||
'appUserModel' => $app_user,
|
||||
'directories' => $directories
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -83,10 +94,10 @@ class AppUserController extends Controller
|
|||
if ($app_user->saveOrFail()) {
|
||||
$app_user->directories()->sync(collect($request->directories)->pluck('id'));
|
||||
return redirect()
|
||||
->route('bo.app-users.edit', ['tenant' => \tenant(), 'app_user' => $app_user])
|
||||
->route('bo.app_users.edit', ['tenant' => \tenant(), 'app_user' => $app_user])
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular(trans('models.classes.app_users'))]
|
||||
['model' => trans('models.classes.app_user')]
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +105,7 @@ class AppUserController extends Controller
|
|||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été créé',
|
||||
['model' => Str::singular(trans('models.classes.app_users'))]
|
||||
['model' => trans('models.classes.app_user')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -113,9 +124,9 @@ class AppUserController extends Controller
|
|||
// @phpstan-ignore assign.propertyReadOnly
|
||||
$app_user->directories = Directory::renderDirectories($app_user->directories);
|
||||
|
||||
return view('bo.pages.app-users.edit', [
|
||||
'app_userModel' => $app_user,
|
||||
'directories' => $directories
|
||||
return view('bo.pages.app_users.edit', [
|
||||
'appUserModel' => $app_user,
|
||||
'directories' => $directories
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -138,17 +149,17 @@ class AppUserController extends Controller
|
|||
|
||||
if ($app_user->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.app-users.edit', ['tenant' => \tenant(), 'app_user' => $app_user])
|
||||
->route('bo.app_users.edit', ['tenant' => \tenant(), 'app_user' => $app_user])
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.app_users'))]
|
||||
['model' => trans('models.classes.app_user')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.app_users'))]
|
||||
['model' => trans('models.classes.app_user')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -163,10 +174,10 @@ class AppUserController extends Controller
|
|||
{
|
||||
if ($app_user->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.app-users.index', ['tenant' => \tenant()])
|
||||
->route('bo.app_users.index', ['tenant' => \tenant()])
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.app_users'))]
|
||||
['model' => trans('models.classes.app_user')]
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -174,10 +185,21 @@ class AppUserController extends Controller
|
|||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.app_users'))]
|
||||
['model' => trans('models.classes.app_user')]
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\AppUser $app_user
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(AppUser $app_user): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($app_user->replicate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Mass import by CSV.
|
||||
* matricule;lastname;firstname;email
|
||||
|
|
@ -190,68 +212,7 @@ class AppUserController extends Controller
|
|||
{
|
||||
Excel::import(new AppUserImport(), $request->import, null, \Maatwebsite\Excel\Excel::CSV);
|
||||
|
||||
return redirect()->route('bo.app-users.index', ['tenant' => \tenant()])->with('success', 'Import terminé.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Change order.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\UpdateChangeOrderRequest $request
|
||||
* @param mixed ...$params
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \RuntimeException Si le nom du parametre de la route ne correspond pas au params utilisé.
|
||||
*/
|
||||
public function changeOrder(UpdateChangeOrderRequest $request, mixed ...$params): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$paramNames = collect(request()->route()->parameterNames);
|
||||
$className = Str::of($paramNames->get($paramNames->count() - 2))->lower()->studly();
|
||||
$className = "\\App\\Models\\AppUser";
|
||||
$modelId = Arr::get($params, $paramNames->count() - 2);
|
||||
$model = AppUser::find($modelId);
|
||||
|
||||
if (!class_exists($className)) {
|
||||
throw new \RuntimeException("The {$className} class doesn't exist.");
|
||||
}
|
||||
|
||||
if (!\is_object($model)) {
|
||||
throw new \RuntimeException("The second last param isn't an object.");
|
||||
}
|
||||
|
||||
if (get_class($model) !== (string) Str::of($className)->replaceStart('\\', '')) {
|
||||
throw new \RuntimeException("The {$className} doesn't match second last binded param.");
|
||||
}
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Model|null */
|
||||
$model = $className::query()
|
||||
->where('tenant_id', \tenant())
|
||||
->where($model->getRouteKeyName(), $model->getRouteKey())
|
||||
->first();
|
||||
|
||||
if (!$model) {
|
||||
return back()->with('error', trans('crud.messages.order_not_changed'));
|
||||
}
|
||||
|
||||
return DB::transaction(function () use ($request, $className, $model) {
|
||||
/** @var \Illuminate\Database\Eloquent\Model|null */
|
||||
$tmp = $className::query()
|
||||
->where('tenant_id', \tenant())
|
||||
->where('order', $request->direction ? '<' : '>', $model->getOriginal('order'))
|
||||
->orderBy('order', $request->direction ? 'DESC' : 'ASC')->first();
|
||||
|
||||
if (!$tmp) {
|
||||
return back()->with('error', trans('crud.messages.order_not_changed'));
|
||||
}
|
||||
|
||||
$newOrder = $tmp->getOriginal('order');
|
||||
// @phpstan-ignore property.notFound
|
||||
$tmp->order = $model->getOriginal('order');
|
||||
$tmp->saveQuietly();
|
||||
// @phpstan-ignore property.notFound
|
||||
$model->order = $newOrder;
|
||||
$model->saveQuietly();
|
||||
Session::flash('success', trans('crud.messages.order_changed'));
|
||||
|
||||
return back();
|
||||
});
|
||||
return redirect()->route('bo.app_users.index', ['tenant' => \tenant()])
|
||||
->with('success', 'Import terminé.');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,14 @@ use Illuminate\Database\Eloquent\Builder;
|
|||
|
||||
class ContactController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Contact::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
|
@ -49,11 +57,11 @@ class ContactController extends Controller
|
|||
});
|
||||
}
|
||||
|
||||
$contactModelList = $this->paginate($query);
|
||||
$contactModels = $this->paginate($query);
|
||||
|
||||
$appUsers = AppUser::query()->select(['id', 'lastname', 'firstname'])->orderBy('lastname')->get();
|
||||
|
||||
return view('bo.pages.contacts.index', compact('contactModelList', 'searchFields', 'appUsers'));
|
||||
return view('bo.pages.contacts.index', compact('contactModels', 'searchFields', 'appUsers'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -9,10 +9,17 @@ use App\Models\Directory;
|
|||
use App\Models\Setting;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DirectoriesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Directory::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
|
|
@ -20,8 +27,8 @@ class DirectoriesController extends Controller
|
|||
*/
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$directories = $this->getDirectoriesForComponent();
|
||||
return \view('bo.pages.directories.index', \compact('directories'));
|
||||
$directoryModels = $this->getDirectoriesForComponent();
|
||||
return \view('bo.pages.directories.index', \compact('directoryModels'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -40,14 +47,14 @@ class DirectoriesController extends Controller
|
|||
->route('bo.directories.index', ['tenant' => \tenant()])
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular(trans('models.classes.directories'))]
|
||||
['model' => trans('models.classes.directory')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été créé',
|
||||
['model' => Str::singular(trans('models.classes.directories'))]
|
||||
['model' => trans('models.classes.directory')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -60,7 +67,6 @@ class DirectoriesController extends Controller
|
|||
*/
|
||||
public function edit(Directory $directory): \Illuminate\View\View
|
||||
{
|
||||
$this->authorize('edit', $directory);
|
||||
return view('bo.pages.directories.edit', ['directoryModel' => $directory]);
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +79,6 @@ class DirectoriesController extends Controller
|
|||
*/
|
||||
public function update(UpdateDirectoryRequest $request, Directory $directory): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$this->authorize('edit', $directory);
|
||||
return DB::transaction(function () use ($request, $directory) {
|
||||
$directory->fill($request->validated());
|
||||
|
||||
|
|
@ -82,14 +87,14 @@ class DirectoriesController extends Controller
|
|||
->route('bo.directories.edit', ['tenant' => \tenant(), 'directory' => $directory])
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.directories'))]
|
||||
['model' => trans('models.classes.directory')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.directories'))]
|
||||
['model' => trans('models.classes.directory')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -102,7 +107,6 @@ class DirectoriesController extends Controller
|
|||
*/
|
||||
public function destroy(Directory $directory): \Illuminate\Database\Eloquent\Collection
|
||||
{
|
||||
$this->authorize('delete', $directory);
|
||||
return DB::transaction(function () use ($directory) {
|
||||
/** @var \App\Models\Directory $directoryChild */
|
||||
foreach ($directory->children as $directoryChild) {
|
||||
|
|
@ -126,7 +130,7 @@ class DirectoriesController extends Controller
|
|||
':model :name n\'a pas été supprimé,
|
||||
un bouton est encore associé à ce dernier dans les paramètres :',
|
||||
[
|
||||
'model' => Str::singular(trans('models.classes.directories')),
|
||||
'model' => trans('models.classes.directory'),
|
||||
'name' => $directory->name['fr']
|
||||
]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,14 @@ class DocumentController extends Controller
|
|||
{
|
||||
use ChangesModelOrder;
|
||||
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Document::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
|
@ -57,28 +65,34 @@ class DocumentController extends Controller
|
|||
/** Sort columns with a query */
|
||||
$this->sortQuery($query);
|
||||
|
||||
$documents = $this->paginate($query);
|
||||
$documentModels = $this->paginate($query);
|
||||
|
||||
return view('bo.pages.documents.index', [
|
||||
'documents' => $documents,
|
||||
'searchFields' => $searchFields,
|
||||
'searchTag' => $request->tag,
|
||||
'tags' => $tags
|
||||
'documentModels' => $documentModels,
|
||||
'searchFields' => $searchFields,
|
||||
'searchTag' => $request->tag,
|
||||
'tags' => $tags
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Document $document
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create(): \Illuminate\View\View
|
||||
public function create(Document $document): \Illuminate\View\View
|
||||
{
|
||||
$documents = Document::where('lang', LangEnum::fr)->get();
|
||||
$directories = Directory::getChildrenDirectories();
|
||||
$tags = Tag::get();
|
||||
$documentsList = Document::query()->where('lang', LangEnum::fr)->get();
|
||||
$directories = Directory::getChildrenDirectories();
|
||||
$tags = Tag::get();
|
||||
|
||||
return view('bo.pages.documents.create', compact('documents', 'directories', 'tags'));
|
||||
return view('bo.pages.documents.create', [
|
||||
'documentModel' => $document,
|
||||
'documentsList' => $documentsList,
|
||||
'directories' => $directories,
|
||||
'tags' => $tags
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -98,14 +112,14 @@ class DocumentController extends Controller
|
|||
->route('bo.documents.edit', ['tenant' => \tenant(), 'document' => $document])
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular(trans('models.classes.documents'))]
|
||||
['model' => trans('models.classes.document')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été créé',
|
||||
['model' => Str::singular(trans('models.classes.documents'))]
|
||||
['model' => trans('models.classes.document')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -118,13 +132,13 @@ class DocumentController extends Controller
|
|||
*/
|
||||
public function edit(Document $document): \Illuminate\View\View
|
||||
{
|
||||
$documents = Document::where('lang', LangEnum::fr)->get();
|
||||
$directories = Directory::getChildrenDirectories();
|
||||
$tags = Tag::get();
|
||||
$documentsList = Document::query()->where('lang', LangEnum::fr)->get();
|
||||
$directories = Directory::getChildrenDirectories();
|
||||
$tags = Tag::get();
|
||||
|
||||
return view('bo.pages.documents.edit', [
|
||||
'documents' => $documents,
|
||||
'documentModel' => $document,
|
||||
'documentsList' => $documentsList,
|
||||
'directories' => $directories,
|
||||
'tags' => $tags
|
||||
]);
|
||||
|
|
@ -147,14 +161,14 @@ class DocumentController extends Controller
|
|||
->route('bo.documents.edit', ['tenant' => \tenant(), 'document' => $document])
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.documents'))]
|
||||
['model' => trans('models.classes.document')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.documents'))]
|
||||
['model' => trans('models.classes.document')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -181,14 +195,14 @@ class DocumentController extends Controller
|
|||
->route('bo.documents.index', array_merge(['tenant' => \tenant()], $previousQueries))
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.documents'))]
|
||||
['model' => trans('models.classes.document')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.documents'))]
|
||||
['model' => trans('models.classes.document')]
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -201,7 +215,7 @@ class DocumentController extends Controller
|
|||
public function download(string $uuid): \Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||
{
|
||||
$doc = Document::where('uuid', $uuid)->firstOrFail();
|
||||
$pathToFile = public_path() . Storage::url(sprintf("docs/%s.%s", $doc->uuid, $doc->type->name()));
|
||||
$pathToFile = public_path() . Storage::url(sprintf("docs/%s.%s", $doc->uuid, $doc->type));
|
||||
return response()->download($pathToFile, $doc->path);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Enums\Formularies\InputStatusEnum;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Formularies\StoreFormularyRequest;
|
||||
use App\Http\Requests\Bo\Formularies\UpdateFormularyRequest;
|
||||
|
|
@ -11,12 +10,19 @@ use App\Models\Formulary;
|
|||
use App\Traits\Controllers\ChangesModelOrder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class FormularyController extends Controller
|
||||
{
|
||||
use ChangesModelOrder;
|
||||
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Formulary::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
|
@ -41,19 +47,20 @@ class FormularyController extends Controller
|
|||
/** Sort columns with a query */
|
||||
$this->sortQuery($query);
|
||||
|
||||
$formulariesModel = $this->paginate($query);
|
||||
$formularyModels = $this->paginate($query);
|
||||
|
||||
return view('bo.pages.formularies.index', compact('formulariesModel', 'searchFields'));
|
||||
return view('bo.pages.formularies.index', compact('formularyModels', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Formulary $formulary
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create(): \Illuminate\View\View
|
||||
public function create(Formulary $formulary): \Illuminate\View\View
|
||||
{
|
||||
return view('bo.pages.formularies.create');
|
||||
return view('bo.pages.formularies.create', ['formularyModel' => $formulary]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -73,14 +80,14 @@ class FormularyController extends Controller
|
|||
->route('bo.formularies.edit', ['tenant' => \tenant(), 'formulary' => $formulary])
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular(trans('models.classes.formularies'))]
|
||||
['model' => trans('models.classes.formulary')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été créé',
|
||||
['model' => Str::singular(trans('models.classes.formularies'))]
|
||||
['model' => trans('models.classes.formulary')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -93,17 +100,9 @@ class FormularyController extends Controller
|
|||
*/
|
||||
public function edit(Formulary $formulary): \Illuminate\Http\RedirectResponse|\Illuminate\Contracts\View\View
|
||||
{
|
||||
if ($formulary->status->equals(InputStatusEnum::system)) {
|
||||
return redirect()->route('bo.formularies.index')
|
||||
->with('error', trans(
|
||||
'Administration du champs :name impossible car il est vérouillé !',
|
||||
['name' => $formulary->name]
|
||||
));
|
||||
} else {
|
||||
return view('bo.pages.formularies.edit', [
|
||||
'formularyModel' => $formulary
|
||||
]);
|
||||
}
|
||||
return view('bo.pages.formularies.edit', [
|
||||
'formularyModel' => $formulary
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -123,14 +122,14 @@ class FormularyController extends Controller
|
|||
->route('bo.formularies.edit', ['tenant' => \tenant(), 'formulary' => $formulary])
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.formularies'))]
|
||||
['model' => trans('models.classes.formulary')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.formularies'))]
|
||||
['model' => trans('models.classes.formulary')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -154,14 +153,25 @@ class FormularyController extends Controller
|
|||
->route('bo.formularies.index', array_merge(['tenant' => \tenant()], $previousQueries))
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.formularies'))]
|
||||
['model' => trans('models.classes.formulary')]
|
||||
));
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', trans(
|
||||
':model n\'a pas été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.formularies'))]
|
||||
['model' => trans('models.classes.formulary')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\Formulary $formulary
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(Formulary $formulary): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($formulary->replicate());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,27 +6,47 @@ use App\Http\Controllers\Controller;
|
|||
use App\Http\Requests\Bo\Settings\UpdateSettingRequest;
|
||||
use App\Models\Directory;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class SettingController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Setting::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$directories = Directory::renderDirectories(Directory::query()->whereNull('directory_id')->get());
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $settings */
|
||||
$settings = Setting::query();
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||
$query = Setting::query();
|
||||
|
||||
$this->sortQuery($settings);
|
||||
$settings = $settings->get();
|
||||
if ($request->search) {
|
||||
$this->searchQuery(
|
||||
$query,
|
||||
$request->search,
|
||||
null,
|
||||
'key',
|
||||
);
|
||||
}
|
||||
$searchFields = trans('validation.custom.key');
|
||||
|
||||
return view('bo.pages.settings.index', compact('settings', 'directories'));
|
||||
$this->sortQuery($query);
|
||||
|
||||
$settingModels = $query->get();
|
||||
|
||||
return view('bo.pages.settings.index', compact('settingModels', 'searchFields', 'directories'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -58,14 +78,14 @@ class SettingController extends Controller
|
|||
->route('bo.settings.edit', ['tenant' => \tenant(), 'setting' => $setting])
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.settings'))]
|
||||
['model' => trans('models.classes.setting')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.settings'))]
|
||||
['model' => trans('models.classes.setting')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -81,17 +101,17 @@ class SettingController extends Controller
|
|||
return DB::transaction(function () use ($setting) {
|
||||
if ($setting->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.settings.index')
|
||||
->route('bo.settings.index', ['tenant' => \tenant()])
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.settings'))]
|
||||
['model' => trans('models.classes.setting')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.settings'))]
|
||||
['model' => trans('models.classes.setting')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,19 @@ use App\Models\Tag;
|
|||
use App\Traits\Controllers\ChangesModelOrder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class TagController extends Controller
|
||||
{
|
||||
use ChangesModelOrder;
|
||||
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Tag::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
|
@ -39,19 +46,20 @@ class TagController extends Controller
|
|||
/** Sort columns with a query */
|
||||
$this->sortQuery($query);
|
||||
|
||||
$tags = $this->paginate($query);
|
||||
$tagModels = $this->paginate($query);
|
||||
|
||||
return view('bo.pages.tags.index', compact('tags', 'searchFields'));
|
||||
return view('bo.pages.tags.index', compact('tagModels', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Tag $tag
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(): \Illuminate\Contracts\View\View
|
||||
public function create(Tag $tag): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.tags.create');
|
||||
return view('bo.pages.tags.create', ['tagModel' => $tag]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -70,14 +78,14 @@ class TagController extends Controller
|
|||
->route('bo.tags.edit', ['tenant' => \tenant(), 'tag' => $tag])
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular(trans('models.classes.tags'))]
|
||||
['model' => trans('models.classes.tag')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été créé',
|
||||
['model' => Str::singular(trans('models.classes.tags'))]
|
||||
['model' => trans('models.classes.tag')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -110,14 +118,14 @@ class TagController extends Controller
|
|||
->route('bo.tags.edit', ['tenant' => \tenant(), 'tag' => $tag])
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.tags'))]
|
||||
['model' => trans('models.classes.tag')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.tags'))]
|
||||
['model' => trans('models.classes.tag')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -139,15 +147,26 @@ class TagController extends Controller
|
|||
->route('bo.tags.index', array_merge(['tenant' => \tenant()], $previousQueries))
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.tags'))]
|
||||
['model' => trans('models.classes.tag')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.tags'))]
|
||||
['model' => trans('models.classes.tag')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\Tag $tag
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(Tag $tag): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($tag->replicate());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,22 @@
|
|||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Tenants\TenantRequest;
|
||||
use App\Http\Requests\Bo\Tenants\StoreTenantRequest;
|
||||
use App\Http\Requests\Bo\Tenants\UpdateTenantRequest;
|
||||
use App\Models\Tenant;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class TenantController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Tenant::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
|
@ -35,28 +43,29 @@ class TenantController extends Controller
|
|||
/** Sort columns with a query */
|
||||
$this->sortQuery($query);
|
||||
|
||||
$tenants = $this->paginate($query);
|
||||
$tenantModels = $this->paginate($query);
|
||||
|
||||
return view('bo.pages.tenants.index', compact('tenants', 'searchFields'));
|
||||
return view('bo.pages.tenants.index', compact('tenantModels', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Tenant $tenant
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(): \Illuminate\Contracts\View\View
|
||||
public function create(Tenant $tenant): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.tenants.create');
|
||||
return view('bo.pages.tenants.create', ['tenantModel' => $tenant]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Tenants\TenantRequest $request
|
||||
* @param \App\Http\Requests\Bo\Tenants\StoreTenantRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(TenantRequest $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(StoreTenantRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$tenant = new Tenant();
|
||||
|
|
@ -66,14 +75,14 @@ class TenantController extends Controller
|
|||
->route('bo.tenants.edit', ['tenant' => $tenant])
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular(trans('models.classes.tenants'))]
|
||||
['model' => trans('models.classes.tenant')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été créé',
|
||||
['model' => Str::singular(trans('models.classes.tenants'))]
|
||||
['model' => trans('models.classes.tenant')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -92,11 +101,11 @@ class TenantController extends Controller
|
|||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Tenants\TenantRequest $request
|
||||
* @param \App\Models\Tenant $tenant
|
||||
* @param \App\Http\Requests\Bo\Tenants\UpdateTenantRequest $request
|
||||
* @param \App\Models\Tenant $tenant
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(TenantRequest $request, Tenant $tenant): \Illuminate\Http\RedirectResponse
|
||||
public function update(UpdateTenantRequest $request, Tenant $tenant): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $tenant) {
|
||||
$tenant->fill($request->validated());
|
||||
|
|
@ -106,14 +115,14 @@ class TenantController extends Controller
|
|||
->route('bo.tenants.edit', ['tenant' => $tenant])
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.tenants'))]
|
||||
['model' => trans('models.classes.tenant')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.tenants'))]
|
||||
['model' => trans('models.classes.tenant')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -132,18 +141,29 @@ class TenantController extends Controller
|
|||
return DB::transaction(function () use ($tenant, $previousQueries) {
|
||||
if ($tenant->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.tenants.index', array_merge(['tenant' => \tenant()], $previousQueries))
|
||||
->route('bo.tenants.index', $previousQueries)
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.tenants'))]
|
||||
['model' => trans('models.classes.tenant')]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.tenants'))]
|
||||
['model' => trans('models.classes.tenant')]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\Tenant $tenant
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(Tenant $tenant): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($tenant->replicate());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace App\Http\Controllers\Bo;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Users\StoreUserRequest;
|
||||
use App\Http\Requests\Bo\Users\UpdateUserRequest;
|
||||
use App\Models\Tenant;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
|
@ -12,6 +13,14 @@ use Illuminate\Support\Str;
|
|||
|
||||
class UserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
|
@ -20,35 +29,48 @@ class UserController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||
$query = User::query();
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $userModels */
|
||||
$userModels = User::query();
|
||||
|
||||
if ($request->search) {
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$query,
|
||||
$request->search,
|
||||
$userModels,
|
||||
$search,
|
||||
null,
|
||||
'name',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'role',
|
||||
);
|
||||
}
|
||||
$searchFields = trans('validation.attributes.name');
|
||||
$searchFields = \implode(', ', [
|
||||
trans('validation.attributes.first_name'),
|
||||
trans('validation.attributes.last_name'),
|
||||
trans('validation.attributes.email'),
|
||||
trans('validation.attributes.role'),
|
||||
]);
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($query);
|
||||
$this->sortQuery($userModels);
|
||||
|
||||
$users = $this->paginate($query);
|
||||
/** Custom pagination */
|
||||
$userModels = $this->paginate($userModels);
|
||||
|
||||
return view('bo.pages.users.index', compact('users', 'searchFields'));
|
||||
return view('bo.pages.users.index', compact('userModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(): \Illuminate\Contracts\View\View
|
||||
public function create(User $user): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.users.create');
|
||||
$tenants = Tenant::query()->orderBy('name', 'ASC')->get();
|
||||
return view('bo.pages.users.create', ['userModel' => $user, 'tenants' => $tenants]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -62,20 +84,18 @@ class UserController extends Controller
|
|||
return DB::transaction(function () use ($request) {
|
||||
$user = new User();
|
||||
$user->fill($request->validated());
|
||||
|
||||
if ($user->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.users.edit', ['tenant' => \tenant(), 'user' => $user])
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular(trans('models.classes.users'))]
|
||||
));
|
||||
$user->tenants()->sync(array_column($request->validated()['tenants'], 'id'));
|
||||
return redirect()->route('bo.users.edit', ['tenant' => tenant(), 'user' => $user])
|
||||
->with('success', __('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été créé',
|
||||
['model' => Str::singular(trans('models.classes.users'))]
|
||||
));
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_created', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +107,8 @@ class UserController extends Controller
|
|||
*/
|
||||
public function edit(User $user): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.users.edit', ['userModel' => $user]);
|
||||
$tenants = Tenant::query()->orderBy('name', 'ASC')->get();
|
||||
return view('bo.pages.users.edit', ['userModel' => $user, 'tenants' => $tenants]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -103,19 +124,16 @@ class UserController extends Controller
|
|||
$user->fill($request->validated());
|
||||
|
||||
if ($user->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.users.edit', ['tenant' => \tenant(), 'user' => $user])
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.users'))]
|
||||
));
|
||||
$user->tenants()->sync(array_column($request->validated()['tenants'], 'id'));
|
||||
return redirect()->route('bo.users.edit', ['tenant' => tenant(), 'user' => $user])
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.users'))]
|
||||
));
|
||||
return redirect()->route('bo.users.edit', ['tenant' => tenant(), 'user' => $user])
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -127,24 +145,26 @@ class UserController extends Controller
|
|||
*/
|
||||
public function destroy(User $user): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
/** @var array<string,string> */
|
||||
$previousQueries = [];
|
||||
\parse_str(\parse_url(url()->previous(), \PHP_URL_QUERY), $previousQueries);
|
||||
return DB::transaction(function () use ($user, $previousQueries) {
|
||||
if ($user->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.users.index', array_merge(['tenant' => \tenant(), 'user' => $user], $previousQueries))
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.users'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.users'))]
|
||||
));
|
||||
});
|
||||
if ($user->deleteOrFail()) {
|
||||
return redirect()->route('bo.users.index', ['tenant' => tenant()])
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(User $user): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($user->replicate());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use App\Models\Tenant;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
|
|
@ -166,20 +164,4 @@ class Controller extends BaseController
|
|||
$query = $query->paginate($pagination);
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect with default tenant.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function redirectWithDefaultTenant(): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$user = auth('backend')->user();
|
||||
$tenant = UserRolesEnum::admin->equals($user->role) ?
|
||||
Tenant::first()->getKey() :
|
||||
$user->tenants->first()->getKey();
|
||||
return redirect()->route('bo.dashboard', [
|
||||
'tenant' => $tenant
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class RedirectIfAuthenticated
|
|||
case 'frontend':
|
||||
return \redirect()->route('home');
|
||||
case 'backend':
|
||||
return \redirect()->route('bo.dashboard', ['tenant' => tenant()]);
|
||||
return \redirect()->route('bo.dashboard');
|
||||
default:
|
||||
throw new \RuntimeException("Unhandled guard `{$guard}` .");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use App\Models\Tenant;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
|
@ -19,19 +18,36 @@ class RestrictTenantAccess
|
|||
*/
|
||||
public function handle(Request $request, Closure $next): \Symfony\Component\HttpFoundation\Response
|
||||
{
|
||||
/** @var \App\Models\User|null $user */
|
||||
$user = \auth('backend')->user();
|
||||
if ($user) {
|
||||
if ($request->routeIs('bo.tenants.*')) {
|
||||
tenancy()->initialize(Tenant::firstOrFail());
|
||||
if (
|
||||
!$request->routeIs('bo.dashboard') &&
|
||||
!$request->routeIs('bo.users.*') &&
|
||||
!$request->routeIs('bo.tenants.*') &&
|
||||
$request->tenant &&
|
||||
!\in_array($request->tenant, Tenant::get()->pluck('id')->toArray())
|
||||
) {
|
||||
// @phpstan-ignore argument.type
|
||||
abort('404');
|
||||
}
|
||||
if (
|
||||
(Tenant::count() && $request->routeIs('bo.tenants.*') && $user->can('isAdmin')) ||
|
||||
(Tenant::count() && $request->routeIs('bo.users.*') && $user->can('isAdmin'))
|
||||
) {
|
||||
$tenant = Tenant::first()->getKey();
|
||||
tenancy()->initialize($tenant);
|
||||
return $next($request);
|
||||
}
|
||||
if (
|
||||
!\in_array($request->tenant, $user->tenants->pluck('id')->toArray()) &&
|
||||
!(UserRolesEnum::admin->equals($user->role))
|
||||
Tenant::count() && ($request->routeIs('bo.dashboard')
|
||||
|| $request->routeIs('bo.users.edit', $user->getKey()))
|
||||
) {
|
||||
abort(403);
|
||||
$tenant = ($user->tenants->count()) ? $user->tenants->first() : Tenant::first()->getKey();
|
||||
tenancy()->initialize($tenant);
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
} //end if
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class SendFlyerRequest extends FormRequest
|
|||
'email' => trans('validation.attributes.email'),
|
||||
'subject' => trans('validation.attributes.subject'),
|
||||
'message' => trans('validation.attributes.message'),
|
||||
'app_user_id' => trans('models.classes.app_users'),
|
||||
'app_user_id' => trans('models.classes.app_user'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@
|
|||
namespace App\Http\Requests\Bo\AppUser;
|
||||
|
||||
use App\Enums\AppUserRolesEnum;
|
||||
use App\Models\AppUser;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
|
@ -17,7 +20,7 @@ class StoreAppUserRequest extends FormRequest
|
|||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
return Gate::check('create', AppUser::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -76,13 +79,13 @@ class StoreAppUserRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'lastname' => \trans('nom'),
|
||||
'firstname' => \trans('prénom'),
|
||||
'email' => \trans('email'),
|
||||
'password' => \trans('mot de passe'),
|
||||
'authorizedFolders' => \trans('dossiers autorisés'),
|
||||
'role' => \trans('rôle'),
|
||||
'status' => \trans('statut')
|
||||
'lastname' => \trans('validation.attributes.last_name'),
|
||||
'firstname' => \trans('validation.attributes.first_name'),
|
||||
'email' => \trans('validation.attributes.email'),
|
||||
'password' => \trans('validation.attributes.password'),
|
||||
'authorizedFolders' => Str::of(\trans('models.classes.directory'))->plural(),
|
||||
'role' => \trans('validation.custom.role'),
|
||||
'status' => \trans('validation.custom.status')
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,22 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\AppUser;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class UpdateAppUserRequest extends StoreAppUserRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return Gate::check('update', $this->route('app_user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
namespace App\Http\Requests\Bo\Directories;
|
||||
|
||||
use App\Enums\Documents\LangEnum;
|
||||
use App\Models\Directory;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class StoreDirectoryRequest extends FormRequest
|
||||
{
|
||||
|
|
@ -14,7 +16,7 @@ class StoreDirectoryRequest extends FormRequest
|
|||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
return Gate::check('create', Directory::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -51,14 +53,12 @@ class StoreDirectoryRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => \trans('nom du dossier'),
|
||||
'needAuthorization' => \trans('autorisation du dossier')
|
||||
'name' => \trans('validation.attributes.name'),
|
||||
'needAuthorization' => \trans('validation.custom.authorization')
|
||||
];
|
||||
/** @var Object $langEnum */
|
||||
foreach (LangEnum::toArray() as $langEnum) {
|
||||
$rules["name.{$langEnum->name}"] = \trans('nom du dossier :lang', [
|
||||
'lang' => $langEnum->label
|
||||
]);
|
||||
$rules["name.{$langEnum->name}"] = sprintf('%s %s', trans('validation.attributes.name'), $langEnum->label);
|
||||
}
|
||||
return $rules;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,17 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\Directories;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class UpdateDirectoryRequest extends StoreDirectoryRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return Gate::check('update', $this->route('directory'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ use App\Enums\Documents\TypeEnum;
|
|||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Models\Document;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
class StoreDocumentRequest extends FormRequest
|
||||
|
|
@ -19,7 +21,7 @@ class StoreDocumentRequest extends FormRequest
|
|||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
return Gate::check('create', Document::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -30,7 +32,7 @@ class StoreDocumentRequest extends FormRequest
|
|||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'status' => $this->status ? true : false
|
||||
'status' => $this->status ? true : false,
|
||||
]);
|
||||
// * Sanitize Path
|
||||
if (!empty($this->path)) {
|
||||
|
|
@ -66,10 +68,12 @@ class StoreDocumentRequest extends FormRequest
|
|||
'directory_id' => 'required|integer',
|
||||
'document_id' => 'sometimes:directory_id|nullable|integer',
|
||||
'uuid' => [
|
||||
'required',
|
||||
'uuid',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
'required', 'uuid', function ($attribute, $value, $fail) use ($disk) {
|
||||
if ($this->type and \in_array($this->type, TypeEnum::toValues())) {
|
||||
$extension = TypeEnum::make($this->type, 'value')->name();
|
||||
function ($attribute, $value, $fail) use ($disk) {
|
||||
if ($this->type and \array_column(TypeEnum::toArray(), 'name')) {
|
||||
$extension = TypeEnum::make($this->type, 'name')->name();
|
||||
$value = "{$value}.{$extension}";
|
||||
}
|
||||
if (!$disk->has($value)) {
|
||||
|
|
@ -81,15 +85,9 @@ class StoreDocumentRequest extends FormRequest
|
|||
}
|
||||
],
|
||||
'title' => 'required|min:3|max:255',
|
||||
'type' => [
|
||||
'required',
|
||||
new Enum(TypeEnum::class)
|
||||
],
|
||||
'type' => ['required', 'string', Rule::in(array_column(TypeEnum::toArray(), 'name'))],
|
||||
'path' => 'required|min:3|max:255',
|
||||
'lang' => [
|
||||
'required',
|
||||
new Enum(LangEnum::class)
|
||||
],
|
||||
'lang' => ['required', new Enum(LangEnum::class)],
|
||||
'status' => 'required|boolean'
|
||||
];
|
||||
}
|
||||
|
|
@ -102,14 +100,14 @@ class StoreDocumentRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'directory_id' => \trans('dossier à associer'),
|
||||
'document_id' => \trans('document (FR) à associer'),
|
||||
'title' => \trans('titre'),
|
||||
'uuid' => \trans('document'),
|
||||
'type' => \trans('type du document'),
|
||||
'path' => \trans('chemin du document'),
|
||||
'lang' => \trans('langue du document'),
|
||||
'status' => \trans('état de publication du document'),
|
||||
'directory_id' => \trans('models.classes.directory'),
|
||||
'document_id' => \trans('models.classes.document'),
|
||||
'title' => \trans('validation.attributes.title'),
|
||||
'uuid' => \trans('models.classes.document'),
|
||||
'type' => \trans('validation.custom.type'),
|
||||
'path' => \trans('validation.custom.path'),
|
||||
'lang' => \trans('validation.custom.lang'),
|
||||
'status' => \trans('validation.custom.status'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,17 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\Documents;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class UpdateDocumentRequest extends StoreDocumentRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return Gate::check('update', $this->route('document'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class FilterCustomerRequest extends FormRequest
|
|||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ namespace App\Http\Requests\Bo\Formularies;
|
|||
|
||||
use App\Enums\Formularies\InputStatusEnum;
|
||||
use App\Enums\Formularies\InputTypeEnum;
|
||||
use App\Models\Formulary;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
class StoreFormularyRequest extends FormRequest
|
||||
|
|
@ -15,6 +17,7 @@ class StoreFormularyRequest extends FormRequest
|
|||
* @var string[]
|
||||
*/
|
||||
private $mobileAppLocales = ['fr', 'en', 'de', 'nl'];
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
|
|
@ -22,7 +25,7 @@ class StoreFormularyRequest extends FormRequest
|
|||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
return Gate::check('create', Formulary::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -71,14 +74,14 @@ class StoreFormularyRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
$attributes = [
|
||||
'type' => trans('type'),
|
||||
'name' => trans('nom'),
|
||||
'placeholder' => trans('placeholder'),
|
||||
'details' => trans('détail'),
|
||||
'details.*' => trans('détail 2'),
|
||||
'details.*.value' => trans('valeur d\'un élément dans la liste des détails du contenu'),
|
||||
'required' => trans('l\'état d\'obligation'),
|
||||
'is_visible' => trans('l\'état de visibilité'),
|
||||
'type' => trans('validation.custom.type'),
|
||||
'name' => trans('validation.attributes.name'),
|
||||
'placeholder' => trans('validation.custom.placeholder'),
|
||||
'details' => trans('validation.custom.detail'),
|
||||
'details.*' => trans('validation.custom.detail'),
|
||||
'details.*.value' => trans('validation.custom.valeur'),
|
||||
'required' => trans('validation.custom.required'),
|
||||
'is_visible' => trans('validation.custom.visibility'),
|
||||
];
|
||||
foreach ($this->mobileAppLocales as $locale) {
|
||||
$attributes["placeholder.{$locale}"] = trans('placeholder (:lang)', ['lang' => $locale]);
|
||||
|
|
|
|||
|
|
@ -2,8 +2,20 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\Formularies;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class UpdateFormularyRequest extends StoreFormularyRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return Gate::check('update', $this->route('formulary'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\Settings;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use App\Models\Setting;
|
||||
use App\Traits\Requests\HasPicture;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class UpdateSettingRequest extends FormRequest
|
||||
{
|
||||
|
|
@ -25,9 +25,11 @@ class UpdateSettingRequest extends FormRequest
|
|||
$this->key === "Button3" ||
|
||||
$this->key === "ShowIsActive"
|
||||
) {
|
||||
return auth('backend')->check();
|
||||
return Gate::check('update', $this->route('setting'));
|
||||
} else {
|
||||
return (auth('backend')->check() && Auth::user()->role->value() === UserRolesEnum::admin->value());
|
||||
/** @var \App\Models\User $user */
|
||||
$user = Auth::guard('backend')->user();
|
||||
return $user->can('isAdmin');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,9 +72,9 @@ class UpdateSettingRequest extends FormRequest
|
|||
) {
|
||||
$buttonsNullable = 0;
|
||||
$buttons = Setting::where('key', 'Button1')
|
||||
->orWhere('key', 'Button2')
|
||||
->orWhere('key', 'Button3')
|
||||
->get();
|
||||
->orWhere('key', 'Button2')
|
||||
->orWhere('key', 'Button3')
|
||||
->get();
|
||||
foreach ($buttons as $button) {
|
||||
if ($button->value === null) {
|
||||
if ($button->key !== $this->key) {
|
||||
|
|
@ -110,9 +112,9 @@ class UpdateSettingRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'key' => \trans('clé'),
|
||||
'value' => \trans('valeur'),
|
||||
'type' => \trans('type'),
|
||||
'key' => \trans('validation.custom.key'),
|
||||
'value' => \trans('validation.custom.value'),
|
||||
'type' => \trans('validation.custom.type'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\Tags;
|
||||
|
||||
use App\Models\Tag;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StoreTagRequest extends FormRequest
|
||||
{
|
||||
|
|
@ -14,7 +17,7 @@ class StoreTagRequest extends FormRequest
|
|||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
return Gate::check('create', Tag::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -38,6 +41,11 @@ class StoreTagRequest extends FormRequest
|
|||
{
|
||||
return [
|
||||
'name' => 'required|string|min:2|max:25',
|
||||
'slug' => [
|
||||
'required',
|
||||
'string',
|
||||
Rule::unique('tags', 'slug')->where('tenant_id', tenant('id'))
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -49,8 +57,8 @@ class StoreTagRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'name' => trans('name of the tag'),
|
||||
'slug' => trans('slug of the tag'),
|
||||
'name' => trans('models.classes.tag'),
|
||||
'slug' => trans('validation.custom.slug'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,17 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\Tags;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class UpdateTagRequest extends StoreTagRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return Gate::check('update', $this->route('tag'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use Illuminate\Foundation\Http\FormRequest;
|
|||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class TenantRequest extends FormRequest
|
||||
class StoreTenantRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
18
app/Http/Requests/Bo/Tenants/UpdateTenantRequest.php
Normal file
18
app/Http/Requests/Bo/Tenants/UpdateTenantRequest.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Tenants;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class UpdateTenantRequest extends StoreTenantRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return Gate::check('update', $this->route('tenant'));
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ class UploadRequest extends FormRequest
|
|||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return \auth()->check();
|
||||
return \auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
61
app/Http/Requests/Bo/Users/StoreUserRequest.php
Normal file
61
app/Http/Requests/Bo/Users/StoreUserRequest.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Users;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
class StoreUserRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return Gate::check('create', User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'first_name' => 'required|string|min:3|max:255',
|
||||
'last_name' => 'required|string|min:3|max:255',
|
||||
'email' => [
|
||||
'required',
|
||||
'email:rfc,strict,dns,spoof,filter',
|
||||
Rule::unique('users', 'email')
|
||||
],
|
||||
'role' => ['required', new Enum(UserRolesEnum::class)],
|
||||
'tenants' => 'required|nullable|array|min:1',
|
||||
'tenants.*' => 'required|nullable|array|min:1',
|
||||
'tenants.*.id' => 'required|nullable|exists:tenants,id',
|
||||
'tenants.*.*' => 'required|nullable|string|min:1',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'first_name' => trans('validation.attributes.first_name'),
|
||||
'last_name' => trans('validation.attributes.last_name'),
|
||||
'email' => trans('validation.attributes.email'),
|
||||
'role' => trans('validation.attributes.role'),
|
||||
];
|
||||
}
|
||||
}
|
||||
42
app/Http/Requests/Bo/Users/UpdateUserRequest.php
Normal file
42
app/Http/Requests/Bo/Users/UpdateUserRequest.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Users;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
class UpdateUserRequest extends StoreUserRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return Gate::check('update', $this->route('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var \App\Models\User $userModel */
|
||||
$userModel = request()->route()->parameter('user');
|
||||
$rules = [
|
||||
'email' => [
|
||||
'required',
|
||||
'string',
|
||||
'unique:users,email,' . $userModel->getKey(),
|
||||
'email:rfc,strict,dns,spoof,filter',
|
||||
'max:255'
|
||||
],
|
||||
'role' => ['sometimes', new Enum(UserRolesEnum::class)],
|
||||
];
|
||||
return \array_merge(parent::rules(), $rules);
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ class DocumentResource extends JsonResource
|
|||
'id' => $document->id,
|
||||
'uuid' => $document->uuid,
|
||||
'title' => $document->title,
|
||||
'type' => $document->type->value,
|
||||
'type' => $document->type,
|
||||
'directory' => $document->directory_id,
|
||||
'path' => $document->path,
|
||||
'lang' => $document->lang->value,
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ class ToolboxHelper
|
|||
* @param string $table
|
||||
* @param string $field
|
||||
* @param string|integer|float|boolean|null|array $value
|
||||
* @param integer|null $id
|
||||
* @param integer|string|null $id
|
||||
* @param callable|null $query
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If the field is not unique.
|
||||
|
|
@ -287,8 +287,8 @@ class ToolboxHelper
|
|||
public static function assertFieldIsUnique(
|
||||
string $table,
|
||||
string $field,
|
||||
string|int|float|bool|null|array $value,
|
||||
?int $id = null,
|
||||
string|int|float|bool|array|null $value,
|
||||
int|string|null $id = null,
|
||||
?callable $query = null
|
||||
) {
|
||||
if (!$query) {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ use Stancl\Tenancy\Database\Concerns\BelongsToTenant;
|
|||
* @property string $firstname App user first name.
|
||||
* @property string $email App user email.
|
||||
* @property string $password App user password.
|
||||
* @property integer $tenant_id Tenant key associated.
|
||||
* @property \App\Enums\AppUserRolesEnum $role App user role.
|
||||
* @property string|null $tenant_id Associated tenant.
|
||||
* @property boolean $status App user status.
|
||||
* @property \App\Enums\AppUserRolesEnum $role App user role.
|
||||
* @property integer $order App user order.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
|
|
@ -116,7 +116,9 @@ class AppUser extends Model
|
|||
*/
|
||||
private static function setOrder(self $model): void
|
||||
{
|
||||
$model->order = \intval(self::query()->max('order')) + 1;
|
||||
$model->order = \intval(
|
||||
self::query()->where('tenant_id', \tenant() ?? Tenant::first()->getKey())->max('order')
|
||||
) + 1;
|
||||
}
|
||||
|
||||
// * RELATIONSHIPS
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use Stancl\Tenancy\Database\Concerns\BelongsToTenant;
|
|||
/**
|
||||
* @property integer $id Directory id.
|
||||
* @property array<string,string> $name Directory name.
|
||||
* @property string|null $tenant_id Associated tenant.
|
||||
* @property integer|null $directory_id Associated directory.
|
||||
* @property integer $order Directory order.
|
||||
* @property boolean $needAuthorization Directory authorization.
|
||||
|
|
@ -73,7 +74,9 @@ class Directory extends Model
|
|||
*/
|
||||
private static function setOrder(self $model): void
|
||||
{
|
||||
$model->order = \intval(self::query()->max('order')) + 1;
|
||||
$model->order = \intval(
|
||||
self::query()->where('tenant_id', \tenant() ?? Tenant::first()->getKey())->max('order')
|
||||
) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
namespace App\Models;
|
||||
|
||||
use App\Enums\Documents\LangEnum;
|
||||
use App\Enums\Documents\TypeEnum;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
|
@ -14,9 +13,10 @@ use Stancl\Tenancy\Database\Concerns\BelongsToTenant;
|
|||
* @property integer $id Document id.
|
||||
* @property integer $uuid Document uuid.
|
||||
* @property string $title Document title.
|
||||
* @property \App\Enums\Documents\TypeEnum $type Document type.
|
||||
* @property string $type Document type.
|
||||
* @property string|null $tenant_id Associated tenant.
|
||||
* @property integer $directory_id Associated directory.
|
||||
* @property integer $document_id Associated document.
|
||||
* @property integer|null $document_id Associated document.
|
||||
* @property string $path Document path.
|
||||
* @property \App\Enums\Documents\LangEnum $lang Document lang.
|
||||
* @property boolean $status Document status.
|
||||
|
|
@ -54,7 +54,6 @@ class Document extends Model
|
|||
protected $casts = [
|
||||
'status' => 'bool',
|
||||
'lang' => LangEnum::class,
|
||||
'type' => TypeEnum::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -103,7 +102,9 @@ class Document extends Model
|
|||
*/
|
||||
private static function setOrder(self $model): void
|
||||
{
|
||||
$model->order = \intval(self::query()->max('order')) + 1;
|
||||
$model->order = \intval(
|
||||
self::query()->where('tenant_id', \tenant() ?? Tenant::first()->getKey())->max('order')
|
||||
) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -114,7 +115,7 @@ class Document extends Model
|
|||
*/
|
||||
public static function removeDocument(self $model): void
|
||||
{
|
||||
$path = \ltrim(\urldecode("storage/docs/{$model->uuid}.{$model->type->label()}"), '/');
|
||||
$path = \ltrim(\urldecode("storage/docs/{$model->uuid}.{$model->type}"), '/');
|
||||
if (\strpos($path, 'storage') !== 0) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,18 +10,19 @@ use Illuminate\Support\Str;
|
|||
use Stancl\Tenancy\Database\Concerns\BelongsToTenant;
|
||||
|
||||
/**
|
||||
* @property integer $id Formulary id.
|
||||
* @property \App\Enums\Formularies\InputTypeEnum $type Formulary type.
|
||||
* @property string $name Formulary name.
|
||||
* @property string $slug Formulary slug.
|
||||
* @property array<string,string> $placeholder Formulary placeholders.
|
||||
* @property array<string,array<string,string>> $details Formuary details.
|
||||
* @property boolean $is_visible Formulary visibility.
|
||||
* @property boolean $required Formulary required status.
|
||||
* @property \App\Enums\Formularies\InputStatusEnum $status Formulary status.
|
||||
* @property integer $order Formulary order.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
* @property integer $id Formulary id.
|
||||
* @property \App\Enums\Formularies\InputTypeEnum $type Formulary type.
|
||||
* @property string $name Formulary name.
|
||||
* @property string $slug Formulary slug.
|
||||
* @property array<string,string> $placeholder Formulary placeholders.
|
||||
* @property array<string,array<string,string>>|null $details Formuary details.
|
||||
* @property string|null $tenant_id Associated tenant.
|
||||
* @property boolean $is_visible Formulary visibility.
|
||||
* @property boolean $required Formulary required status.
|
||||
* @property \App\Enums\Formularies\InputStatusEnum $status Formulary status.
|
||||
* @property integer $order Formulary order.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
*/
|
||||
class Formulary extends Model
|
||||
{
|
||||
|
|
@ -125,6 +126,71 @@ class Formulary extends Model
|
|||
*/
|
||||
private static function setOrder(self $model): void
|
||||
{
|
||||
$model->order = \intval(self::query()->max('order')) + 1;
|
||||
$model->order = \intval(
|
||||
self::query()->where('tenant_id', \tenant() ?? Tenant::first()->getKey())->max('order')
|
||||
) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default settings for a specific tenant.
|
||||
*
|
||||
* @param \App\Models\Tenant $tenant
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultFormularies(Tenant $tenant): void
|
||||
{
|
||||
// @phpcs:disable Generic.Files.LineLength.TooLong
|
||||
$array = [
|
||||
[
|
||||
'name' => 'e-mail',
|
||||
'placeholder' => ['fr' => 'E-mail'],
|
||||
'details' => null,
|
||||
'type' => InputTypeEnum::email,
|
||||
'status' => InputStatusEnum::system,
|
||||
'is_visible' => true,
|
||||
'required' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'firstname',
|
||||
'placeholder' => ['fr' => 'Prénom'],
|
||||
'details' => null,
|
||||
'type' => InputTypeEnum::text,
|
||||
'status' => InputStatusEnum::locked,
|
||||
'is_visible' => true,
|
||||
'required' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'lastname',
|
||||
'placeholder' => ['fr' => 'Nom'],
|
||||
'details' => null,
|
||||
'type' => InputTypeEnum::text,
|
||||
'status' => InputStatusEnum::locked,
|
||||
'is_visible' => true,
|
||||
'required' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'phone',
|
||||
'placeholder' => ['fr' => 'Téléphone'],
|
||||
'details' => null,
|
||||
'type' => InputTypeEnum::phone,
|
||||
'status' => InputStatusEnum::locked,
|
||||
'is_visible' => true,
|
||||
'required' => true,
|
||||
],
|
||||
];
|
||||
// @phpcs:enable
|
||||
collect($array)->map(function (array $item) use ($tenant) {
|
||||
$setting = new self();
|
||||
$setting->name = $item['name'];
|
||||
$setting->slug = Str::of($item['name'])->slug();
|
||||
$setting->placeholder = $item['placeholder'];
|
||||
$setting->details = $item['details'];
|
||||
$setting->type = $item['type'];
|
||||
$setting->status = $item['status'];
|
||||
$setting->is_visible = $item['is_visible'];
|
||||
$setting->required = $item['required'];
|
||||
$setting->tenant_id = $tenant->getKey();
|
||||
$setting->saveOrFail();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use Stancl\Tenancy\Database\Concerns\BelongsToTenant;
|
|||
* @property integer $id Settings id.
|
||||
* @property string $key Settings key.
|
||||
* @property string $value Settings value.
|
||||
* @property string|null $tenant_id Associated tenant.
|
||||
* @property \App\Enums\SettingTypesEnum $type Settings type.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
|
|
@ -52,6 +53,16 @@ class Setting extends Model
|
|||
*/
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
if (
|
||||
$model->key === "SquaredLogo" ||
|
||||
$model->key === "RectangleLogo" ||
|
||||
$model->key === "BackgroundImage" ||
|
||||
$model->key === "HomeButtonImage"
|
||||
) {
|
||||
$model->value = FileStorageHelper::storeFile($model, $model->value, true);
|
||||
}
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
if (
|
||||
$model->key === "SquaredLogo" ||
|
||||
|
|
@ -73,4 +84,42 @@ class Setting extends Model
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Set default settings for a specific tenant.
|
||||
*
|
||||
* @param \App\Models\Tenant $tenant
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultSettings(Tenant $tenant): void
|
||||
{
|
||||
// @phpcs:disable Generic.Files.LineLength.TooLong
|
||||
$array = [
|
||||
['key' => 'version', 'value' => '1', 'type' => SettingTypesEnum::numeric],
|
||||
['key' => 'ShowIsActive', 'value' => '0', 'type' => SettingTypesEnum::boolean],
|
||||
['key' => 'MainColor', 'value' => '#FFF', 'type' => SettingTypesEnum::color],
|
||||
['key' => 'SquaredLogo', 'value' => new \SplFileInfo(\resource_path('assets/settings/SquaredLogo.png')), 'type' => SettingTypesEnum::picture],
|
||||
['key' => 'RectangleLogo', 'value' => new \SplFileInfo(\resource_path('assets/settings/RectangleLogo.png')), 'type' => SettingTypesEnum::picture],
|
||||
['key' => 'BackgroundImage', 'value' => new \SplFileInfo(\resource_path('assets/settings/BackgroundImage.png')), 'type' => SettingTypesEnum::picture],
|
||||
['key' => 'HomeButtonImage', 'value' => new \SplFileInfo(\resource_path('assets/settings/HomeButtonImage.png')), 'type' => SettingTypesEnum::picture],
|
||||
['key' => 'Button1', 'value' => null, 'type' => SettingTypesEnum::directory],
|
||||
['key' => 'Button2', 'value' => null, 'type' => SettingTypesEnum::directory],
|
||||
['key' => 'Button3', 'value' => null, 'type' => SettingTypesEnum::directory],
|
||||
['key' => 'AppStoreUUID', 'value' => 'c4ac09fd-3992-47bc-bdee-0b7f5505e873', 'type' => SettingTypesEnum::string],
|
||||
['key' => 'FormSelect1', 'value' => '{"title":{"fr":"Travaille avec","en":"Work with","de":"Arbeit mit"},"values":{"pole-sable":{"fr":"P\u00f4le Sabl\u00e9","en":"P\u00f4le Sabl\u00e9","de":"P\u00f4le Sabl\u00e9"},"snv":{"fr":"SNV","en":"SNV","de":"SNV"},"pole-sud-est":{"fr":"P\u00f4le Sud-Est","en":"P\u00f4le Sud-Est","de":"P\u00f4le Sud-Est"},"aquitaine":{"fr":"Aquitaine","en":"Aquitaine","de":"Aquitaine"},"sbv":{"fr":"SBV","en":"SBV","de":"SBV"},"arrive":{"fr":"Arriv\u00e9","en":"Arriv\u00e9","de":"Arriv\u00e9"},"plusieurs-filiales":{"fr":"Plusieurs filiales","en":"Several subsidiaries","de":"Mehrere Filialen"},"autre":{"fr":"Autre","en":"Other","de":"Andere"}}}', 'type' => SettingTypesEnum::json],
|
||||
['key' => 'FormSelect2', 'value' => '{"title":{"fr":"Type de commerce","en":"Type of business","de":"Art des Gesch\u00e4fts"},"values":{"commerce-de-detail":{"fr":"Commerce de d\u00e9tail","en":"Retail trade","de":"Einzelhandel"},"restauration-commerciale":{"fr":"Restauration Commerciale","en":"Commercial catering","de":"Kommerzielle Restauration"},"restauration-collective":{"fr":"Restauration Collective","en":"Collective catering","de":"Kollektiv Restauration"},"grossiste-distributeur-cash":{"fr":"Grossiste Distributeur Cash","en":"Wholesale Distributor Cash","de":"Gro\u00dfh\u00e4ndler H\u00e4ndler Cash"},"pai":{"fr":"PAI","en":"PAI","de":"PAI"},"home-freezer-center":{"fr":"Home Freezer Center","en":"Home Freezer Center","de":"Home Gefrierzentrum"},"autres":{"fr":"Autre","en":"Other","de":"Andere"}}}', 'type' => SettingTypesEnum::json],
|
||||
['key' => 'FormCheck', 'value' => '[{"fr":"Frais","en":"Fresh","de":"Frisch"},{"fr":"Surgel\u00e9s","en":"Frozen food","de":"Tiefk\u00fchlkost"},{"fr":"Volailles crues","en":"Raw poultry","de":"Rohes Gefl\u00fcgel"},{"fr":"\u00c9labor\u00e9s crus","en":"Prepared raw","de":"Roh ausgearbeitet"},{"fr":"\u00c9labor\u00e9s cuits","en":"Cooked products","de":"Gekochte Elaborate"},{"fr":"Bio et Label Rouge","en":"Bio and Label Rouge","de":"Bio und Label Rouge"},{"fr":"BBC","en":"BBC","de":"BBC"},{"fr":"Halal","en":"Halal","de":"Halal"},{"fr":"Autre","en":"Other","de":"Andere"}]', 'type' => SettingTypesEnum::json],
|
||||
];
|
||||
// @phpcs:enable
|
||||
collect($array)->map(function (array $item) use ($tenant) {
|
||||
$setting = new self();
|
||||
$setting->key = $item['key'];
|
||||
$setting->value = $item['value'];
|
||||
$setting->type = $item['type'];
|
||||
$setting->tenant_id = $tenant->getKey();
|
||||
$setting->saveOrFail();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,15 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Stancl\Tenancy\Database\Concerns\BelongsToTenant;
|
||||
|
||||
/**
|
||||
* @property integer $id Tag id.
|
||||
* @property string $slug Tag slug.
|
||||
* @property string $name Tag name.
|
||||
* @property string|null $tenant_id Associated tenant.
|
||||
* @property integer $order Tag order.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
|
|
@ -39,13 +38,8 @@ class Tag extends Model
|
|||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $tag) {
|
||||
self::setSlug($tag);
|
||||
self::assertFieldIsUnique($tag->slug);
|
||||
self::setOrder($tag);
|
||||
});
|
||||
static::updating(function (self $tag) {
|
||||
self::assertFieldIsUnique($tag->slug, $tag->id);
|
||||
});
|
||||
static::deleting(function (self $tag) {
|
||||
$tag->documents()->detach();
|
||||
});
|
||||
|
|
@ -53,32 +47,6 @@ class Tag extends Model
|
|||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Set the slug.
|
||||
*
|
||||
* @param \App\Models\Tag $tag
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function setSlug(Tag $tag): void
|
||||
{
|
||||
$tag->slug = Str::slug($tag->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts using validation that the field is unique.
|
||||
*
|
||||
* @param string $slug
|
||||
* @param integer|null $id
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If field already exists.
|
||||
*/
|
||||
private static function assertFieldIsUnique(string $slug, ?int $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'slug', $slug, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set order after the last element of the list.
|
||||
*
|
||||
|
|
@ -87,7 +55,9 @@ class Tag extends Model
|
|||
*/
|
||||
private static function setOrder(Tag $tag): void
|
||||
{
|
||||
$tag->order = \intval(self::query()->max('order')) + 1;
|
||||
$tag->order = \intval(
|
||||
self::query()->where('tenant_id', \tenant() ?? Tenant::first()->getKey())->max('order')
|
||||
) + 1;
|
||||
}
|
||||
|
||||
// * RELATIONSHIPS
|
||||
|
|
|
|||
|
|
@ -40,17 +40,15 @@ class Tenant extends BaseTenant implements TenantContract
|
|||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
// * ASSERTIONS
|
||||
self::assertNameIsUnique($model->name);
|
||||
|
||||
// * TRANSFORMATIONS
|
||||
$model->id = Str::slug($model->name);
|
||||
});
|
||||
static::created(function (self $model) {
|
||||
(new Setting())->setDefaultSettings($model);
|
||||
(new Formulary())->setDefaultFormularies($model);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
// * ASSERTIONS
|
||||
self::assertNameIsUnique($model->name, $model->id);
|
||||
|
||||
// * TRANSFORMATIONS
|
||||
self::assertNameIsUnique($model->name, $model->getKey());
|
||||
$model->id = Str::slug($model->name);
|
||||
});
|
||||
}
|
||||
|
|
@ -60,15 +58,67 @@ class Tenant extends BaseTenant implements TenantContract
|
|||
/**
|
||||
* Asserts using validation that the name is unique
|
||||
*
|
||||
* @param string|null $name
|
||||
* @param integer|null $id
|
||||
* @param string|null $name
|
||||
* @param string|null $id
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If name already exists.
|
||||
*/
|
||||
private static function assertNameIsUnique(string|null $name, ?int $id = null): void
|
||||
private static function assertNameIsUnique(string|null $name, ?string $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'name', $name, $id);
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'id', Str::slug($name), $id);
|
||||
}
|
||||
|
||||
// * RELATIONSHIPS
|
||||
|
||||
/**
|
||||
* Has Many Relationship Method.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function appUsers(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(AppUser::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Many Relationship Method.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function directories(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Directory::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Many Relationship Method.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function documents(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Document::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Many Relationship Method.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function formularies(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Formulary::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Many Relationship Method.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function settings(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Setting::class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,25 +5,19 @@ namespace App\Models;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use App\Enums\UserRolesEnum;
|
||||
use Stancl\Tenancy\Database\Concerns\BelongsToTenant;
|
||||
|
||||
/**
|
||||
* @property integer $firstname User first name.
|
||||
* @property string $lastname User last name.
|
||||
* @property integer $first_name User first name.
|
||||
* @property string $last_name User last name.
|
||||
* @property string $email User email.
|
||||
* @property string $email_verified_at Email verified date.
|
||||
* @property string $password User password.
|
||||
* @property string $remember_token User token remember.
|
||||
* @property integer $tenant_id Tenant key associated.
|
||||
* @property \App\Enums\UserRolesEnum $role User role.
|
||||
* @property \Carbon\Carbon $last_connection Last connection date.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
*/
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use BelongsToTenant;
|
||||
use HasFactory;
|
||||
use Notifiable;
|
||||
|
||||
|
|
@ -33,65 +27,23 @@ class User extends Authenticatable
|
|||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'firstname',
|
||||
'lastname',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'email_verified_at',
|
||||
'password',
|
||||
'last_connection',
|
||||
'role',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
'role' => UserRolesEnum::class
|
||||
'last_connection' => 'datetime',
|
||||
'role' => UserRolesEnum::class
|
||||
];
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted(): void
|
||||
{
|
||||
// * EVENT CLOSURES.
|
||||
static::creating(function (self $model) {
|
||||
self::updatePassword($model);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
self::updatePassword($model);
|
||||
});
|
||||
}
|
||||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Update password.
|
||||
*
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
private static function updatePassword(self $model): void
|
||||
{
|
||||
if (Hash::needsRehash($model->password)) {
|
||||
$model->password = Hash::make($model->password);
|
||||
}
|
||||
}
|
||||
|
||||
// * RELATIONSHIPS
|
||||
|
||||
/**
|
||||
|
|
@ -103,4 +55,14 @@ class User extends Authenticatable
|
|||
{
|
||||
return $this->morphToMany(Directory::class, 'directorables');
|
||||
}
|
||||
|
||||
/**
|
||||
* The tenants that belong to the user.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function tenants(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Tenant::class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,20 +2,85 @@
|
|||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserStaticRules;
|
||||
|
||||
class AppUserPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can publish/unpublish the model.
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function viewAny(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function view(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function create(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can change order of the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function changeOrder(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can duplicate the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function duplicate(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
75
app/Policies/ContactPolicy.php
Normal file
75
app/Policies/ContactPolicy.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserStaticRules;
|
||||
|
||||
class ContactPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function viewAny(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function view(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function create(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can change order of the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function changeOrder(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
}
|
||||
78
app/Policies/DirectoryPolicy.php
Normal file
78
app/Policies/DirectoryPolicy.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Directory;
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserStaticRules;
|
||||
|
||||
class DirectoryPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function viewAny(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function view(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function create(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @param \App\Models\Directory $directory
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(User $authUser, Directory $directory): bool
|
||||
{
|
||||
return !$directory->is_system && UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @param \App\Models\Directory $directory
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete(User $authUser, Directory $directory): bool
|
||||
{
|
||||
return !$directory->is_system && UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can change order of the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function changeOrder(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,20 +2,74 @@
|
|||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserStaticRules;
|
||||
|
||||
class DocumentPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can publish/unpublish the model.
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function viewAny(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function view(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function create(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can change order of the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function changeOrder(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,20 +2,97 @@
|
|||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use App\Enums\Formularies\InputStatusEnum;
|
||||
use App\Models\Formulary;
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserStaticRules;
|
||||
|
||||
class FormularyPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can publish/unpublish the model.
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function viewAny(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @param \App\Models\Formulary $formulary
|
||||
* @return boolean
|
||||
*/
|
||||
public function view(User $authUser, Formulary $formulary): bool
|
||||
{
|
||||
return !$formulary->status->equals(InputStatusEnum::system) &&
|
||||
UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function create(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @param \App\Models\Formulary $formulary
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(User $authUser, Formulary $formulary): bool
|
||||
{
|
||||
return !$formulary->status->equals(InputStatusEnum::system) &&
|
||||
UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @param \App\Models\Formulary $formulary
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete(User $authUser, Formulary $formulary): bool
|
||||
{
|
||||
return !$formulary->status->equals(InputStatusEnum::system) &&
|
||||
!$formulary->status->equals(InputStatusEnum::locked) &&
|
||||
UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can duplicate the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @param \App\Models\Formulary $formulary
|
||||
* @return boolean
|
||||
*/
|
||||
public function duplicate(User $authUser, Formulary $formulary): bool
|
||||
{
|
||||
return !$formulary->status->equals(InputStatusEnum::system) &&
|
||||
!$formulary->status->equals(InputStatusEnum::locked) &&
|
||||
UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can change order of the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function changeOrder(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Policies\Rules;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
|
|
@ -41,7 +42,19 @@ abstract class UserStaticRules
|
|||
*/
|
||||
public static function atLeastRole(Model $authModel, UserRolesEnum $minRole): bool
|
||||
{
|
||||
// phpcs:enable
|
||||
return isset($authModel->role) && $authModel->role->value() <= $minRole->value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow client users associated to the tenant OR admin users.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public static function restrictTenant(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::client) &&
|
||||
\in_array(\tenant()->getKey(), $authUser->tenants->pluck('id')->toArray()) ||
|
||||
UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
42
app/Policies/SettingPolicy.php
Normal file
42
app/Policies/SettingPolicy.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserStaticRules;
|
||||
|
||||
class SettingPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function viewAny(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function view(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,20 +2,85 @@
|
|||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserStaticRules;
|
||||
|
||||
class TagPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can publish/unpublish the model.
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function viewAny(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function view(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function create(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can duplicate the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function duplicate(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can change order of the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function changeOrder(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
return UserStaticRules::restrictTenant($authUser);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
namespace App\Policies;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use App\Models\Tenant;
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserStaticRules;
|
||||
|
||||
|
|
@ -19,6 +18,18 @@ class TenantPolicy
|
|||
{
|
||||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function view(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
|
|
@ -30,17 +41,36 @@ class TenantPolicy
|
|||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @param \App\Models\Tenant $tenant
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
|
||||
*/
|
||||
public function delete(User $authUser, Tenant $tenant): bool
|
||||
public function delete(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can duplicate the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function duplicate(User $authUser): bool
|
||||
{
|
||||
// phpcs:enable
|
||||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
88
app/Policies/UserPolicy.php
Normal file
88
app/Policies/UserPolicy.php
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserStaticRules;
|
||||
|
||||
class UserPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function viewAny(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @param \App\Models\User $user
|
||||
* @return boolean
|
||||
*/
|
||||
public function view(User $authUser, User $user): bool
|
||||
{
|
||||
return $authUser->getRouteKey() === $user->getRouteKey() ||
|
||||
UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function create(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @param \App\Models\User $user
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(User $authUser, User $user): bool
|
||||
{
|
||||
return (
|
||||
UserStaticRules::atLeastRole($authUser, UserRolesEnum::client) &&
|
||||
$authUser->getRouteKey() === $user->getRouteKey()
|
||||
) || UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @param \App\Models\User $user
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete(User $authUser, User $user): bool
|
||||
{
|
||||
return $authUser->getRouteKey() !== $user->getRouteKey() &&
|
||||
UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can duplicate the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @param \App\Models\User $user
|
||||
* @return boolean
|
||||
*/
|
||||
public function duplicate(User $authUser, User $user): bool
|
||||
{
|
||||
return (
|
||||
UserStaticRules::atLeastRole($authUser, UserRolesEnum::client) &&
|
||||
$authUser->getRouteKey() === $user->getRouteKey()
|
||||
) || UserStaticRules::atLeastRole($authUser, UserRolesEnum::admin);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
namespace App\Providers;
|
||||
|
||||
use App\Enums\UserRolesEnum;
|
||||
use App\Models\Directory;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
|
@ -19,14 +18,6 @@ class AuthServiceProvider extends ServiceProvider
|
|||
{
|
||||
$this->registerPolicies();
|
||||
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
Gate::define('edit', function (User $user, Directory $directory) {
|
||||
return !$directory->is_system;
|
||||
});
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
Gate::define('delete', function (User $user, Directory $directory) {
|
||||
return !$directory->is_system;
|
||||
});
|
||||
Gate::define('isAdmin', function (User $user) {
|
||||
return $user->role->equals(UserRolesEnum::admin);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,26 +15,32 @@ use Stancl\Tenancy\Middleware;
|
|||
|
||||
class TenancyServiceProvider extends ServiceProvider
|
||||
{
|
||||
// By default, no namespace is used to support the callable array syntax.
|
||||
/**
|
||||
* By default, no namespace is used to support the callable array syntax.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static string $controllerNamespace = '';
|
||||
|
||||
public function events()
|
||||
/** @return array */
|
||||
public function events(): array
|
||||
{
|
||||
return [
|
||||
// Tenant events
|
||||
// Tenant events.
|
||||
Events\CreatingTenant::class => [],
|
||||
Events\TenantCreated::class => [
|
||||
JobPipeline::make([
|
||||
Jobs\CreateDatabase::class,
|
||||
Jobs\MigrateDatabase::class,
|
||||
// Jobs\SeedDatabase::class,
|
||||
|
||||
// Your own jobs to prepare the tenant.
|
||||
// Provision API keys, create S3 buckets, anything you want!
|
||||
|
||||
])->send(function (Events\TenantCreated $event) {
|
||||
return $event->tenant;
|
||||
})->shouldBeQueued(false), // `false` by default, but you probably want to make this `true` for production.
|
||||
// Provision API keys, create S3 buckets, anything you want !
|
||||
])
|
||||
->send(function (Events\TenantCreated $event) {
|
||||
return $event->tenant;
|
||||
})
|
||||
// `false` by default, but you probably want to make this `true` for production.
|
||||
->shouldBeQueued(false),
|
||||
],
|
||||
Events\SavingTenant::class => [],
|
||||
Events\TenantSaved::class => [],
|
||||
|
|
@ -44,12 +50,15 @@ class TenancyServiceProvider extends ServiceProvider
|
|||
Events\TenantDeleted::class => [
|
||||
JobPipeline::make([
|
||||
Jobs\DeleteDatabase::class,
|
||||
])->send(function (Events\TenantDeleted $event) {
|
||||
return $event->tenant;
|
||||
})->shouldBeQueued(false), // `false` by default, but you probably want to make this `true` for production.
|
||||
])
|
||||
->send(function (Events\TenantDeleted $event) {
|
||||
return $event->tenant;
|
||||
})
|
||||
// `false` by default, but you probably want to make this `true` for production.
|
||||
->shouldBeQueued(false),
|
||||
],
|
||||
|
||||
// Domain events
|
||||
// Domain events.
|
||||
Events\CreatingDomain::class => [],
|
||||
Events\DomainCreated::class => [],
|
||||
Events\SavingDomain::class => [],
|
||||
|
|
@ -59,14 +68,14 @@ class TenancyServiceProvider extends ServiceProvider
|
|||
Events\DeletingDomain::class => [],
|
||||
Events\DomainDeleted::class => [],
|
||||
|
||||
// Database events
|
||||
// Database events.
|
||||
Events\DatabaseCreated::class => [],
|
||||
Events\DatabaseMigrated::class => [],
|
||||
Events\DatabaseSeeded::class => [],
|
||||
Events\DatabaseRolledBack::class => [],
|
||||
Events\DatabaseDeleted::class => [],
|
||||
|
||||
// Tenancy events
|
||||
// Tenancy events.
|
||||
Events\InitializingTenancy::class => [],
|
||||
Events\TenancyInitialized::class => [
|
||||
Listeners\BootstrapTenancy::class,
|
||||
|
|
@ -82,22 +91,25 @@ class TenancyServiceProvider extends ServiceProvider
|
|||
Events\RevertingToCentralContext::class => [],
|
||||
Events\RevertedToCentralContext::class => [],
|
||||
|
||||
// Resource syncing
|
||||
// Resource syncing.
|
||||
Events\SyncedResourceSaved::class => [
|
||||
Listeners\UpdateSyncedResource::class,
|
||||
],
|
||||
|
||||
// Fired only when a synced resource is changed in a different DB than the origin DB (to avoid infinite loops)
|
||||
// Fired only when a synced resource is changed in a different DB
|
||||
// than the origin DB (to avoid infinite loops).
|
||||
Events\SyncedResourceChangedInForeignDatabase::class => [],
|
||||
];
|
||||
}
|
||||
|
||||
public function register()
|
||||
/** @return void */
|
||||
public function register(): void
|
||||
{
|
||||
//
|
||||
// Silence is golden.
|
||||
}
|
||||
|
||||
public function boot()
|
||||
/** @return void */
|
||||
public function boot(): void
|
||||
{
|
||||
$this->bootEvents();
|
||||
$this->mapRoutes();
|
||||
|
|
@ -105,7 +117,8 @@ class TenancyServiceProvider extends ServiceProvider
|
|||
$this->makeTenancyMiddlewareHighestPriority();
|
||||
}
|
||||
|
||||
protected function bootEvents()
|
||||
/** @return void */
|
||||
protected function bootEvents(): void
|
||||
{
|
||||
foreach ($this->events() as $event => $listeners) {
|
||||
foreach ($listeners as $listener) {
|
||||
|
|
@ -118,7 +131,8 @@ class TenancyServiceProvider extends ServiceProvider
|
|||
}
|
||||
}
|
||||
|
||||
protected function mapRoutes()
|
||||
/** @return void */
|
||||
protected function mapRoutes(): void
|
||||
{
|
||||
$this->app->booted(function () {
|
||||
if (file_exists(base_path('routes/tenant.php'))) {
|
||||
|
|
@ -128,10 +142,11 @@ class TenancyServiceProvider extends ServiceProvider
|
|||
});
|
||||
}
|
||||
|
||||
protected function makeTenancyMiddlewareHighestPriority()
|
||||
/** @return void */
|
||||
protected function makeTenancyMiddlewareHighestPriority(): void
|
||||
{
|
||||
$tenancyMiddleware = [
|
||||
// Even higher priority than the initialization middleware
|
||||
// Even higher priority than the initialization middleware.
|
||||
Middleware\PreventAccessFromCentralDomains::class,
|
||||
|
||||
Middleware\InitializeTenancyByDomain::class,
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ namespace App\Providers;
|
|||
|
||||
use App\Models\Tenant;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class ViewServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
@ -25,7 +26,8 @@ class ViewServiceProvider extends ServiceProvider
|
|||
Paginator::useBootstrap();
|
||||
}
|
||||
}
|
||||
|
||||
View::share('tenantModels', Tenant::get());
|
||||
if (Schema::hasTable('tenants')) {
|
||||
View::share('tenantsGlobal', Tenant::get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ trait ChangesModelOrder
|
|||
$paramNames = collect(request()->route()->parameterNames);
|
||||
$className = Str::of($paramNames->get($paramNames->count() - 2))->lower()->studly();
|
||||
$className = "\\App\\Models\\{$className}";
|
||||
$model = Arr::get($params, $paramNames->count() - 2);
|
||||
$model = Arr::get($params, $paramNames->count() - 3);
|
||||
|
||||
if (!class_exists($className)) {
|
||||
throw new \RuntimeException("The {$className} class doesn't exist.");
|
||||
|
|
@ -39,7 +39,7 @@ trait ChangesModelOrder
|
|||
|
||||
/** @var \Illuminate\Database\Eloquent\Model|null */
|
||||
$model = $className::query()
|
||||
->where('tenant_id', \tenant())
|
||||
->where('tenant_id', \tenant()->getKey())
|
||||
->where($model->getRouteKeyName(), $model->getRouteKey())
|
||||
->first();
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ trait ChangesModelOrder
|
|||
return DB::transaction(function () use ($request, $className, $model) {
|
||||
/** @var \Illuminate\Database\Eloquent\Model|null */
|
||||
$tmp = $className::query()
|
||||
->where('tenant_id', \tenant())
|
||||
->where('tenant_id', \tenant()->getKey())
|
||||
->where('order', $request->direction ? '<' : '>', $model->getOriginal('order'))
|
||||
->orderBy('order', $request->direction ? 'DESC' : 'ASC')->first();
|
||||
|
||||
|
|
|
|||
77
config/breadcrumbs.php
Normal file
77
config/breadcrumbs.php
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| View Name
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Choose a view to display when Breadcrumbs::render() is called.
|
||||
| Built in templates are:
|
||||
|
|
||||
| - 'breadcrumbs::bootstrap5' - Bootstrap 5
|
||||
| - 'breadcrumbs::bootstrap4' - Bootstrap 4
|
||||
| - 'breadcrumbs::bulma' - Bulma
|
||||
| - 'breadcrumbs::foundation6' - Foundation 6
|
||||
| - 'breadcrumbs::json-ld' - JSON-LD Structured Data
|
||||
| - 'breadcrumbs::materialize' - Materialize
|
||||
| - 'breadcrumbs::tailwind' - Tailwind CSS
|
||||
| - 'breadcrumbs::uikit' - UIkit
|
||||
|
|
||||
| Or a custom view, e.g. '_partials/breadcrumbs'.
|
||||
|
|
||||
*/
|
||||
|
||||
'view' => 'modules/breadcrumbs/breadcrumb-layout',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Breadcrumbs File(s)
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The file(s) where breadcrumbs are defined. e.g.
|
||||
|
|
||||
| - base_path('routes/breadcrumbs.php')
|
||||
| - glob(base_path('breadcrumbs/*.php'))
|
||||
|
|
||||
*/
|
||||
|
||||
'files' => [
|
||||
base_path('routes/breadcrumbs-bo.php'),
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Exceptions
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Determine when to throw an exception.
|
||||
|
|
||||
*/
|
||||
|
||||
// * When route-bound breadcrumbs are used but the current route doesn't have a name (UnnamedRouteException)
|
||||
'unnamed-route-exception' => true,
|
||||
|
||||
// * When route-bound breadcrumbs are used and the matching breadcrumb doesn't exist (InvalidBreadcrumbException)
|
||||
'missing-route-bound-breadcrumb-exception' => true,
|
||||
|
||||
// * When a named breadcrumb is used but doesn't exist (InvalidBreadcrumbException)
|
||||
'invalid-named-breadcrumb-exception' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Classes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Subclass the default classes for more advanced customisations.
|
||||
|
|
||||
*/
|
||||
|
||||
// * Manager
|
||||
'manager-class' => Diglactic\Breadcrumbs\Manager::class,
|
||||
|
||||
// * Generator
|
||||
'generator-class' => Diglactic\Breadcrumbs\Generator::class,
|
||||
|
||||
];
|
||||
|
|
@ -29,7 +29,6 @@ return [
|
|||
// * For iframes
|
||||
'URI.SafeIframeRegexp' => "%^(http://|https://|//)(www.youtube.com/embed/|player.vimeo.com/video/|vimeo.com/)%",
|
||||
'HTML.Doctype' => 'HTML 4.01 Transitional',
|
||||
// TODO: Rules en FULL CKEDITOR.
|
||||
// * Legacy filter en full avec safe legacy.
|
||||
// 'HTML.Allowed' => 'h1[style],h2[style],h3[style],h4[style],h5[style],h6[style],figure[class|style],oembed[url],div[style],b,strong,i,em,u,a[href|title|target|rel],ul[style],ol[style],dl[style],li,p[style],br,span[style|class],img[width|height|alt|src|style|class|title],iframe[src|width|height|class|frameborder|style],table[style|align|border|cellspacing|cellpadding|width],thead,tbody,th[colspan|align|valign|style],tr[align|valign|style],td[style|colspan|rowspan|scope|align|valign],hr,dl,dt',
|
||||
// * Restricted basics.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
// phpcs:disable Squiz.PHP.CommentedOutCode.Found,Squiz.Commenting.InlineComment.InvalidEndChar
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Stancl\Tenancy\Database\Models\Domain;
|
||||
|
|
@ -70,7 +72,8 @@ return [
|
|||
* Disable the pgsql manager above, and enable the one below if you
|
||||
* want to separate tenant DBs by schemas rather than databases.
|
||||
*/
|
||||
// 'pgsql' => Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLSchemaManager::class, // Separate by schema instead of database
|
||||
// Separate by schema instead of database
|
||||
// 'pgsql' => Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLSchemaManager::class,
|
||||
],
|
||||
],
|
||||
|
||||
|
|
@ -86,7 +89,8 @@ return [
|
|||
* You can clear cache selectively by specifying the tag.
|
||||
*/
|
||||
'cache' => [
|
||||
'tag_base' => 'tenant', // This tag_base, followed by the tenant_id, will form a tag that will be applied on each cache call.
|
||||
// This tag_base, followed by the tenant_id, will form a tag that will be applied on each cache call.
|
||||
'tag_base' => 'tenant',
|
||||
],
|
||||
|
||||
/**
|
||||
|
|
@ -147,8 +151,10 @@ return [
|
|||
* either using the Redis facade or by injecting it as a dependency.
|
||||
*/
|
||||
'redis' => [
|
||||
'prefix_base' => 'tenant', // Each key in Redis will be prepended by this prefix_base, followed by the tenant id.
|
||||
'prefixed_connections' => [ // Redis connections whose keys are prefixed, to separate one tenant's keys from another.
|
||||
// Each key in Redis will be prepended by this prefix_base, followed by the tenant id.
|
||||
'prefix_base' => 'tenant',
|
||||
// Redis connections whose keys are prefixed, to separate one tenant's keys from another.
|
||||
'prefixed_connections' => [
|
||||
// 'default',
|
||||
],
|
||||
],
|
||||
|
|
@ -165,8 +171,10 @@ return [
|
|||
// Stancl\Tenancy\Features\UserImpersonation::class,
|
||||
// Stancl\Tenancy\Features\TelescopeTags::class,
|
||||
// Stancl\Tenancy\Features\UniversalRoutes::class,
|
||||
// Stancl\Tenancy\Features\TenantConfig::class, // https://tenancyforlaravel.com/docs/v3/features/tenant-config
|
||||
// Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect
|
||||
// https://tenancyforlaravel.com/docs/v3/features/tenant-config
|
||||
// Stancl\Tenancy\Features\TenantConfig::class,
|
||||
// https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect
|
||||
// Stancl\Tenancy\Features\CrossDomainRedirect::class,
|
||||
// Stancl\Tenancy\Features\ViteBundler::class,
|
||||
],
|
||||
|
||||
|
|
@ -183,7 +191,8 @@ return [
|
|||
* Parameters used by the tenants:migrate command.
|
||||
*/
|
||||
'migration_parameters' => [
|
||||
'--force' => true, // This needs to be true to run migrations in production.
|
||||
// This needs to be true to run migrations in production.
|
||||
'--force' => true,
|
||||
'--path' => [database_path('migrations/tenant')],
|
||||
'--realpath' => true,
|
||||
],
|
||||
|
|
@ -192,7 +201,9 @@ return [
|
|||
* Parameters used by the tenants:seed command.
|
||||
*/
|
||||
'seeder_parameters' => [
|
||||
'--class' => 'DatabaseSeeder', // root seeder class
|
||||
// '--force' => true, // This needs to be true to seed tenant databases in production
|
||||
// Root seeder class.
|
||||
'--class' => 'DatabaseSeeder',
|
||||
// This needs to be true to seed tenant databases in production.
|
||||
// '--force' => true,
|
||||
],
|
||||
];
|
||||
|
|
|
|||
BIN
resources/assets/settings/BackgroundImage.png
Normal file
BIN
resources/assets/settings/BackgroundImage.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
BIN
resources/assets/settings/HomeButtonImage.png
Normal file
BIN
resources/assets/settings/HomeButtonImage.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1 KiB |
BIN
resources/assets/settings/RectangleLogo.png
Normal file
BIN
resources/assets/settings/RectangleLogo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/assets/settings/SquaredLogo.png
Normal file
BIN
resources/assets/settings/SquaredLogo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
return [
|
||||
'home' => 'Home',
|
||||
'admin' => 'Administration',
|
||||
'admin' => 'Avanced',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
return [
|
||||
'classes' => [
|
||||
'app_users' => 'Application\'s users',
|
||||
'directories' => 'Directories',
|
||||
'documents' => 'Documents',
|
||||
'users' => 'Users',
|
||||
'settings' => 'Settings',
|
||||
'tags' => 'Tags',
|
||||
'formularies' => 'Formularies',
|
||||
'contacts' => 'Contacts',
|
||||
'tenants' => 'Tenants',
|
||||
'app_user' => 'App. user',
|
||||
'directory' => 'Directory',
|
||||
'document' => 'Document',
|
||||
'user' => 'User',
|
||||
'setting' => 'Setting',
|
||||
'tag' => 'Tag',
|
||||
'formulary' => 'Formulary',
|
||||
'contact' => 'Contact',
|
||||
'tenant' => 'Tenant',
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -125,77 +125,93 @@ return [
|
|||
'url' => 'The :attribute format is invalid.',
|
||||
'uuid' => 'The :attribute must be a valid UUID.',
|
||||
'attributes' => [
|
||||
'address' => 'address',
|
||||
'age' => 'age',
|
||||
'amount' => 'amount',
|
||||
'area' => 'area',
|
||||
'available' => 'available',
|
||||
'birthday' => 'birthday',
|
||||
'body' => 'body',
|
||||
'city' => 'city',
|
||||
'content' => 'content',
|
||||
'country' => 'country',
|
||||
'created_at' => 'created at',
|
||||
'creator' => 'creator',
|
||||
'current_password' => 'current password',
|
||||
'date' => 'date',
|
||||
'date_of_birth' => 'date of birth',
|
||||
'day' => 'day',
|
||||
'deleted_at' => 'deleted at',
|
||||
'description' => 'description',
|
||||
'district' => 'district',
|
||||
'duration' => 'duration',
|
||||
'email' => 'email address',
|
||||
'excerpt' => 'excerpt',
|
||||
'filter' => 'filter',
|
||||
'first_name' => 'first name',
|
||||
'gender' => 'gender',
|
||||
'group' => 'group',
|
||||
'hour' => 'hour',
|
||||
'image' => 'image',
|
||||
'last_name' => 'last name',
|
||||
'lesson' => 'lesson',
|
||||
'line_address_1' => 'address line 1',
|
||||
'line_address_2' => 'address line 2',
|
||||
'message' => 'message',
|
||||
'middle_name' => 'middle name',
|
||||
'minute' => 'minute',
|
||||
'mobile' => 'mobile',
|
||||
'month' => 'month',
|
||||
'name' => 'name',
|
||||
'national_code' => 'national code',
|
||||
'number' => 'number',
|
||||
'password' => 'password',
|
||||
'password_confirmation' => 'password confirmation',
|
||||
'phone' => 'phone',
|
||||
'photo' => 'photo',
|
||||
'postal_code' => 'postal code',
|
||||
'price' => 'price',
|
||||
'province' => 'province',
|
||||
'address' => 'address',
|
||||
'age' => 'age',
|
||||
'amount' => 'amount',
|
||||
'area' => 'area',
|
||||
'available' => 'available',
|
||||
'birthday' => 'birthday',
|
||||
'body' => 'body',
|
||||
'city' => 'city',
|
||||
'content' => 'content',
|
||||
'country' => 'country',
|
||||
'created_at' => 'created at',
|
||||
'creator' => 'creator',
|
||||
'current_password' => 'current password',
|
||||
'date' => 'date',
|
||||
'date_of_birth' => 'date of birth',
|
||||
'day' => 'day',
|
||||
'deleted_at' => 'deleted at',
|
||||
'description' => 'description',
|
||||
'district' => 'district',
|
||||
'duration' => 'duration',
|
||||
'email' => 'email address',
|
||||
'excerpt' => 'excerpt',
|
||||
'filter' => 'filter',
|
||||
'first_name' => 'first name',
|
||||
'gender' => 'gender',
|
||||
'group' => 'group',
|
||||
'hour' => 'hour',
|
||||
'image' => 'image',
|
||||
'last_name' => 'last name',
|
||||
'lesson' => 'lesson',
|
||||
'line_address_1' => 'address line 1',
|
||||
'line_address_2' => 'address line 2',
|
||||
'message' => 'message',
|
||||
'middle_name' => 'middle name',
|
||||
'minute' => 'minute',
|
||||
'mobile' => 'mobile',
|
||||
'month' => 'month',
|
||||
'name' => 'name',
|
||||
'national_code' => 'national code',
|
||||
'number' => 'number',
|
||||
'password' => 'password',
|
||||
'password_confirmation' => 'password confirmation',
|
||||
'phone' => 'phone',
|
||||
'photo' => 'photo',
|
||||
'postal_code' => 'postal code',
|
||||
'price' => 'price',
|
||||
'province' => 'province',
|
||||
'recaptcha_response_field' => 'recaptcha response field',
|
||||
'remember' => 'remember',
|
||||
'restored_at' => 'restored at',
|
||||
'result_text_under_image' => 'result text under image',
|
||||
'role' => 'role',
|
||||
'second' => 'second',
|
||||
'sex' => 'sex',
|
||||
'short_text' => 'short text',
|
||||
'size' => 'size',
|
||||
'state' => 'state',
|
||||
'street' => 'street',
|
||||
'student' => 'student',
|
||||
'subject' => 'subject',
|
||||
'teacher' => 'teacher',
|
||||
'terms' => 'terms',
|
||||
'test_description' => 'test description',
|
||||
'test_locale' => 'test locale',
|
||||
'test_name' => 'test name',
|
||||
'text' => 'text',
|
||||
'time' => 'time',
|
||||
'title' => 'title',
|
||||
'updated_at' => 'updated at',
|
||||
'username' => 'username',
|
||||
'year' => 'year',
|
||||
'zipcode' => 'zipcode',
|
||||
'remember' => 'remember',
|
||||
'restored_at' => 'restored at',
|
||||
'result_text_under_image' => 'result text under image',
|
||||
'role' => 'role',
|
||||
'second' => 'second',
|
||||
'sex' => 'sex',
|
||||
'short_text' => 'short text',
|
||||
'size' => 'size',
|
||||
'state' => 'state',
|
||||
'street' => 'street',
|
||||
'student' => 'student',
|
||||
'subject' => 'subject',
|
||||
'teacher' => 'teacher',
|
||||
'terms' => 'terms',
|
||||
'test_description' => 'test description',
|
||||
'test_locale' => 'test locale',
|
||||
'test_name' => 'test name',
|
||||
'text' => 'text',
|
||||
'time' => 'time',
|
||||
'title' => 'title',
|
||||
'updated_at' => 'updated at',
|
||||
'username' => 'username',
|
||||
'year' => 'year',
|
||||
'zipcode' => 'zipcode',
|
||||
],
|
||||
'custom' => [
|
||||
'authorization' => 'authorization',
|
||||
'detail' => 'detail',
|
||||
'key' => 'key',
|
||||
'lang' => 'lang',
|
||||
'order' => 'order',
|
||||
'path' => 'path',
|
||||
'placeholder' => 'placeholder',
|
||||
'required' => 'required',
|
||||
'role' => 'role',
|
||||
'slug' => 'slug',
|
||||
'status' => 'status',
|
||||
'type' => 'type',
|
||||
'value' => 'value',
|
||||
'visibility' => 'visibility',
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
return [
|
||||
'home' => 'Accueil',
|
||||
'admin' => 'Administration',
|
||||
'admin' => 'Avancé',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
return [
|
||||
'classes' => [
|
||||
'app_users' => 'Application utilisateurs',
|
||||
'directories' => 'Dossiers',
|
||||
'documents' => 'Documents',
|
||||
'users' => 'Utilisateurs',
|
||||
'settings' => 'Paramètres',
|
||||
'tags' => 'Étiquettes',
|
||||
'formularies' => 'Formulaires',
|
||||
'contacts' => 'Contacts',
|
||||
'tenants' => 'Tenants',
|
||||
'app_user' => 'App. utilisateur',
|
||||
'directory' => 'Dossier',
|
||||
'document' => 'Document',
|
||||
'user' => 'Utilisateur',
|
||||
'setting' => 'Paramètre',
|
||||
'tag' => 'Étiquette',
|
||||
'formulary' => 'Formulaire',
|
||||
'contact' => 'Contact',
|
||||
'tenant' => 'Tenant',
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -199,4 +199,20 @@ return [
|
|||
'year' => 'année',
|
||||
'zipcode' => 'code postal'
|
||||
],
|
||||
'custom' => [
|
||||
'authorization' => 'autorisation',
|
||||
'detail' => 'détail',
|
||||
'key' => 'clé',
|
||||
'lang' => 'langue',
|
||||
'order' => 'ordre',
|
||||
'path' => 'chemin',
|
||||
'placeholder' => 'placeholder',
|
||||
'required' => 'requis',
|
||||
'role' => 'rôle',
|
||||
'slug' => 'slug',
|
||||
'status' => 'statut',
|
||||
'type' => 'type',
|
||||
'value' => 'valeur',
|
||||
'visibility' => 'visibilité',
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,16 +1,23 @@
|
|||
.need-word-counter {
|
||||
position: relative;
|
||||
border-radius: 0 0 0.375rem 0.375rem;
|
||||
// * LAYOUT
|
||||
|
||||
&-password {
|
||||
border-radius: 0 0 0 0.375rem !important;
|
||||
body {
|
||||
.navbar-brand > .logo {
|
||||
max-width: 9rem;
|
||||
}
|
||||
|
||||
&-btn {
|
||||
border-radius: 0 0 0.375rem !important;
|
||||
}
|
||||
> main {
|
||||
min-height: calc(100vh - (#{$bo-header-height} + #{$bo-footer-height}));
|
||||
margin-top: $bo-header-height;
|
||||
}
|
||||
|
||||
> footer {
|
||||
height: $bo-footer-height;
|
||||
box-shadow: 0 -0.125rem 0.25rem rgb(0 0 0 / 7.5%) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// * OTHERS
|
||||
|
||||
.table {
|
||||
&.fix-action {
|
||||
th:last-child,
|
||||
|
|
@ -39,25 +46,33 @@
|
|||
max-height: 5rem;
|
||||
}
|
||||
|
||||
.w-fit {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.btn-md {
|
||||
height: 38px;
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
height: 31px;
|
||||
}
|
||||
|
||||
.pagination-custom .dropdown-menu {
|
||||
overflow: auto;
|
||||
min-width: 5rem;
|
||||
max-height: 178px;
|
||||
}
|
||||
|
||||
.btn-md {
|
||||
min-width: 38px;
|
||||
height: 38px;
|
||||
}
|
||||
.need-word-counter {
|
||||
position: relative;
|
||||
border-radius: 0 0 0.375rem 0.375rem;
|
||||
|
||||
.w-fit {
|
||||
width: fit-content;
|
||||
}
|
||||
&-password {
|
||||
border-radius: 0 0 0 0.375rem !important;
|
||||
|
||||
.table-col-sorter {
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
main {
|
||||
min-height: calc(100vh - 56px - 40px);
|
||||
&-btn {
|
||||
border-radius: 0 0 0.375rem !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,3 +15,7 @@ $font-default-family-base: system-ui, -apple-system, 'Segoe UI', 'Roboto',
|
|||
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; // - The default site font family.
|
||||
$font-default-size-base: 1rem; // Assumes the browser default, typically `16px`
|
||||
$line-default-height-base: 1.5;
|
||||
|
||||
// * DIMENSIONS
|
||||
$bo-header-height: 4.8rem;
|
||||
$bo-footer-height: 2rem;
|
||||
|
|
|
|||
1
resources/sass/bo/vendor/_bootstrap.scss
vendored
1
resources/sass/bo/vendor/_bootstrap.scss
vendored
|
|
@ -17,6 +17,7 @@
|
|||
@import "bootstrap/scss/reboot";
|
||||
@import "bootstrap/scss/accordion";
|
||||
@import "bootstrap/scss/alert";
|
||||
@import "bootstrap/scss/badge";
|
||||
@import "bootstrap/scss/breadcrumb";
|
||||
@import "bootstrap/scss/button-group";
|
||||
@import "bootstrap/scss/buttons";
|
||||
|
|
|
|||
|
|
@ -273,10 +273,14 @@ onMounted(() => {
|
|||
intDirectories.value = data.directories;
|
||||
intModel.value = data.model;
|
||||
if (intModel.value != null) {
|
||||
intDocumentDatas.value.path = String(intModel.value.path);
|
||||
intDocumentDatas.value.uuid = String(intModel.value.uuid);
|
||||
intDocumentDatas.value.type = String(intModel.value.type);
|
||||
intIsDocFR.value = intModel.value.lang === 1 ? true : false;
|
||||
if (intModel.value.lang === undefined) {
|
||||
intIsDocFR.value = true;
|
||||
} else {
|
||||
intDocumentDatas.value.path = String(intModel.value.path);
|
||||
intDocumentDatas.value.uuid = String(intModel.value.uuid);
|
||||
intDocumentDatas.value.type = String(intModel.value.type);
|
||||
intIsDocFR.value = intModel.value.lang === 1 ? true : false;
|
||||
}
|
||||
}
|
||||
intCsrf.value = data.csrf;
|
||||
nextTick(() => {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
}"
|
||||
>
|
||||
<vue-nestable-handle
|
||||
class="d-flex justify-content-between align-items-center border rounded px-2 py-1"
|
||||
class="d-flex justify-content-between align-items-center border rounded p-1"
|
||||
>
|
||||
<div class="d-flex justify-content-start align-items-center">
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import {
|
|||
faCircleCheck,
|
||||
faCircleNotch,
|
||||
faCircleXmark,
|
||||
faCopy,
|
||||
faCrop,
|
||||
faEraser,
|
||||
faEye,
|
||||
|
|
@ -94,6 +95,7 @@ library.add(faEraser,
|
|||
faFile,
|
||||
faGear,
|
||||
faBan,
|
||||
faCopy,
|
||||
);
|
||||
|
||||
// Front
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import type { SweetAlertResult } from "sweetalert2";
|
|||
import confirm from "./sweetalertConfirm";
|
||||
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
let elements = document.getElementsByClassName("confirmDeleteJS");
|
||||
let elements = document.getElementsByClassName("confirmDeleteTS");
|
||||
for (const element of elements) {
|
||||
element.addEventListener("submit", function (e) {
|
||||
e.preventDefault();
|
||||
|
|
|
|||
|
|
@ -8,11 +8,24 @@
|
|||
<body>
|
||||
@include('bo.layouts.header')
|
||||
|
||||
<main class="container py-3">
|
||||
{{-- Show a message when an action is performed --}}
|
||||
@include('modules.flash-messages')
|
||||
{{-- Main content --}}
|
||||
@yield('content')
|
||||
<!-- Main content -->
|
||||
<main class="container-fluid">
|
||||
<div class="row justify-content-center p-3 pt-0">
|
||||
<!-- Show a message when an action is performed -->
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-10 col-lg-8 px-2">
|
||||
@include('modules.flash-messages')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Main content -->
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-10 col-lg-8 p-md-0 pt-3">
|
||||
@yield('content')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
<footer class="bg-body-tertiary px-0 text-center" id="footer">
|
||||
<div class="p-2 text-center">
|
||||
@if (isset($cpsr_name) && isset($cpsr_version))
|
||||
<span class="text-reset">{{ $cpsr_name }} - {{ $cpsr_version }}</span>
|
||||
<span>-</span>
|
||||
@endif
|
||||
<span class="text-reset fw-bold">{{ __('UWIL') }}</span>
|
||||
© {{ date('Y') }}
|
||||
</div>
|
||||
<footer id="footer" class="d-flex justify-content-center align-items-center bg-body-tertiary text-center w-100 px-0">
|
||||
@if (isset($cpsr_name) && isset($cpsr_version))
|
||||
<span class="text-reset">{{ $cpsr_name }} - {{ $cpsr_version }}</span>
|
||||
<span>-</span>
|
||||
@endif
|
||||
<span class="text-reset fw-bold">{{ __('UWIL') }}</span>
|
||||
© {{ date('Y') }}
|
||||
</footer>
|
||||
|
|
|
|||
|
|
@ -31,10 +31,11 @@
|
|||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
@include('modules.breadcrumb.breadcrumb-head')
|
||||
@include('modules.breadcrumbs.breadcrumb-head')
|
||||
|
||||
<!-- STYLES -->
|
||||
@vite(['resources/sass/bo/bo.scss'])
|
||||
@stack('styles')
|
||||
|
||||
@if(config('app.debug'))
|
||||
<script nonce="{{ $nonce }}">window.vueDebug = true;</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<nav class="navbar navbar-expand-lg position-fixed fixed-top bg-body-tertiary shadow-sm" id="top-navbar">
|
||||
<nav class="navbar navbar-expand-xxl position-fixed fixed-top bg-body-tertiary shadow-sm" id="top-navbar">
|
||||
<div class="container">
|
||||
<a class="navbar-brand text-center" data-bs-toggle="tooltip" data-bs-placement="bottom" href="{{ route('bo.default-tenant') }}"
|
||||
<a class="navbar-brand text-center" data-bs-toggle="tooltip" data-bs-placement="bottom" href="{{ route('bo.dashboard') }}"
|
||||
title="{{ __('Accéder au front du projet') }}">
|
||||
{{ config('app.name') }}
|
||||
</a>
|
||||
|
|
@ -21,36 +21,38 @@
|
|||
@auth
|
||||
@php
|
||||
$user = auth('backend')->user();
|
||||
$tenantModels = $user->can('isAdmin') ? $tenantModels : $user->tenants;
|
||||
$tenantsGlobal = $user->can('isAdmin') ? $tenantsGlobal : $user->tenants;
|
||||
@endphp
|
||||
<!-- Tenant switchs -->
|
||||
<li class="nav-item dropdown @auth border-end @endauth">
|
||||
<button class="btn nav-link dropdown-toggle d-flex align-items-center h-100 flex-row border-0 px-3"
|
||||
data-bs-toggle="dropdown" type="button" aria-expanded="false">
|
||||
{{ tenant('name') }}
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-end">
|
||||
@foreach ($tenantModels as $tenantModel)
|
||||
<a class="dropdown-item @if (tenant()->getKey() === $tenantModel->getKey()) active @endif" href="{{ route('bo.dashboard', ['tenant' => $tenantModel]) }}">
|
||||
{{ $tenantModel->name }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</li>
|
||||
@if (!request()->routeIs('bo.dashboard') && !request()->routeIs('bo.tenants.*') && !request()->routeIs('bo.users.*') && $tenantsGlobal->count() > 1)
|
||||
<!-- Tenant switchs -->
|
||||
<li class="nav-item dropdown @auth border-end @endauth">
|
||||
<button class="btn nav-link dropdown-toggle d-flex align-items-center h-100 flex-row border-0 pe-3"
|
||||
data-bs-toggle="dropdown" type="button" aria-expanded="false">
|
||||
{{ tenant('name') }}
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-end">
|
||||
@foreach ($tenantsGlobal as $tenantModel)
|
||||
<a class="dropdown-item @if (tenant()->getKey() === $tenantModel->getKey()) active @endif"
|
||||
href="{{ route(request()->route()->getName(), array_merge(['tenant' => $tenantModel], request()->route()->parameters())) }}">
|
||||
{{ $tenantModel->name }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</li>
|
||||
@endif
|
||||
<!-- Profile -->
|
||||
<li class="nav-item dropdown">
|
||||
<button class="btn nav-link dropdown-toggle d-flex align-items-center h-100 flex-row border-0 ps-3" id="navbarDropdown"
|
||||
<button class="btn nav-link dropdown-toggle d-flex align-items-center h-100 flex-row border-0 ps-xxl-3" id="navbarDropdown"
|
||||
data-bs-toggle="dropdown" type="button">
|
||||
<div class="d-flex flex-column align-items-end lh-1">
|
||||
<span
|
||||
class="fw-bold">{{ auth('backend')->user()->first_name }} {{ auth('backend')->user()->last_name }}</span>
|
||||
<small class="text-secondary-body">{{ Str::of(auth('backend')->user()->role->label())->ucFirst() }}</small>
|
||||
<div class="d-flex flex-column align-items-start align-items-xxl-end lh-1">
|
||||
<span class="fw-bold">{{ $user->first_name }} {{ $user->last_name }}</span>
|
||||
<small class="text-secondary-body">{{ Str::of($user->role->label())->ucFirst() }}</small>
|
||||
</div>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-end m-0 text-center" aria-labelledby="navbarDropdown">
|
||||
<a class="dropdown-item w-100 text-decoration-none p-2" data-bs-toggle="tooltip" data-bs-placement="left"
|
||||
href="{{ route('bo.users.edit', ['tenant' => tenant(), 'user' => auth('backend')->user()->getKey()]) }}"
|
||||
title="{{ __('Accéder à son profile') }}">
|
||||
<a class="dropdown-item w-100 text-decoration-none p-2 @if(request()->routeIs('bo.users.edit') && request()->route('user')->getKey() === $user->getKey()) active @endif"
|
||||
data-bs-toggle="tooltip" data-bs-placement="left" title="{{ __('Accéder à son profile') }}"
|
||||
href="{{ route('bo.users.edit', ['user' => $user->getKey()]) }}">
|
||||
{{ __('Profile') }}
|
||||
</a>
|
||||
<hr class="dropdown-divider m-0">
|
||||
|
|
|
|||
78
resources/views/bo/layouts/nav-list.blade.php
Normal file
78
resources/views/bo/layouts/nav-list.blade.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
@auth('backend')
|
||||
<ul class="navbar-nav me-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.dashboard')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.dashboard') }}"
|
||||
title="{{ __('Revenir au :model', ['model' => __('back.home')]) }}">
|
||||
{{ __('back.home') }}
|
||||
</a>
|
||||
</li>
|
||||
@php $user = auth('backend')->user(); @endphp
|
||||
@if (($tenantsGlobal->count() && $user->can('isAdmin')) || ($user->tenants->count() && !$user->can('isAdmin')))
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.app_users.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.app_users.index', ['tenant' => tenant()]) }}" title="{{ __('Liste des :model', ['model' => str(__('models.classes.app_user'))->plural()]) }}">
|
||||
{{ str(__('models.classes.app_user'))->plural() }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.directories.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.directories.index', ['tenant' => tenant()]) }}" title="{{ __('Liste des :model', ['model' => str(__('models.classes.directory'))->plural()]) }}">
|
||||
{{ str(__('models.classes.directory'))->plural() }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.documents.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.documents.index', ['tenant' => tenant()]) }}" title="{{ __('Liste des :model', ['model' => str(__('models.classes.document'))->plural()]) }}">
|
||||
{{ str(__('models.classes.document'))->plural() }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.tags.*')) active @endif" data-bs-toggle="tooltip" href="{{ route('bo.tags.index', ['tenant' => tenant()]) }}"
|
||||
title="{{ __('Liste des :model', ['model' => str(__('models.classes.tag'))->plural()]) }}">
|
||||
{{ str(__('models.classes.tag'))->plural() }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.formularies.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.formularies.index', ['tenant' => tenant()]) }}"
|
||||
title="{{ __('Liste des champs du :model', ['model' => __('models.classes.formulary')]) }}">
|
||||
{{ __('models.classes.formulary') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.contacts.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.contacts.index', ['tenant' => tenant()]) }}" title="{{ __('Liste des :model', ['model' => str(__('models.classes.contact'))->plural()]) }}">
|
||||
{{ str(__('models.classes.contact'))->plural() }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.settings.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.settings.index', ['tenant' => tenant()]) }}" title="{{ __('Liste des :model', ['model' => str(__('models.classes.setting'))->plural()]) }}">
|
||||
{{ str(__('models.classes.setting'))->plural() }}
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@can('isAdmin')
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle @if (request()->routeIs('bo.users.*') || request()->routeIs('bo.tenants.*')) active @endif" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{__('back.admin') }}
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a class="dropdown-item @if (request()->routeIs('bo.users.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.users.index') }}" title="{{ __('Liste des :model', ['model' => str(__('models.classes.user'))->plural()]) }}">
|
||||
{{ str(__('models.classes.user'))->plural() }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item @if (request()->routeIs('bo.tenants.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.tenants.index') }}" title="{{ __('Liste des :model', ['model' => str(__('models.classes.tenant'))->plural()]) }}">
|
||||
{{ str(__('models.classes.tenant'))->plural() }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
@endcan
|
||||
</ul>
|
||||
@endauth
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
@auth('backend')
|
||||
<ul class="navbar-nav me-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.dashboard')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.dashboard', ['tenant' => tenant()]) }}"
|
||||
title="{{ __('Revenir au :model', ['model' => __('back.home')]) }}">
|
||||
{{ __('back.home') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.app-users.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.app-users.index', ['tenant' => tenant()]) }}" title="{{ __('Liste des :model', ['model' => __('models.classes.users')]) }}">
|
||||
{{ __('models.classes.app_users') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.directories.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.directories.index', ['tenant' => tenant()]) }}" title="{{ __('Liste des :model', ['model' => __('models.classes.directories')]) }}">
|
||||
{{ __('models.classes.directories') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.documents.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.documents.index', ['tenant' => tenant()]) }}" title="{{ __('Liste des :model', ['model' => __('models.classes.documents')]) }}">
|
||||
{{ __('models.classes.documents') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.tags.*')) active @endif" data-bs-toggle="tooltip" href="{{ route('bo.tags.index', ['tenant' => tenant()]) }}"
|
||||
title="{{ __('Liste des :model', ['model' => __('models.classes.tags')]) }}">
|
||||
{{ __('models.classes.tags') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.formularies.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.formularies.index', ['tenant' => tenant()]) }}"
|
||||
title="{{ __('Liste des champs du :model', ['model' => Str::singular(__('models.classes.formularies'))]) }}">
|
||||
{{ Str::singular(__('models.classes.formularies')) }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.contacts.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.contacts.index', ['tenant' => tenant()]) }}" title="{{ __('Liste des :model', ['model' => __('models.classes.contacts')]) }}">
|
||||
{{ __('models.classes.contacts') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.settings.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.settings.index', ['tenant' => tenant()]) }}" title="{{ __('Liste des :model', ['model' => __('models.classes.settings')]) }}">
|
||||
{{__('models.classes.settings') }}
|
||||
</a>
|
||||
</li>
|
||||
@can('isAdmin')
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle @if (request()->routeIs('bo.users.*') || request()->routeIs('bo.tenants.*')) active @endif" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{__('back.admin') }}
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a class="dropdown-item @if (request()->routeIs('bo.users.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.users.index', ['tenant' => tenant()]) }}" title="{{ __('Liste des :model', ['model' => __('models.classes.users')]) }}">
|
||||
{{__('models.classes.users') }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item @if (request()->routeIs('bo.tenants.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.tenants.index') }}" title="{{ __('Liste des :model', ['model' => __('models.classes.tenants')]) }}">
|
||||
{{__('models.classes.tenants') }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
@endcan
|
||||
</ul>
|
||||
@endauth
|
||||
|
|
@ -1,24 +1,26 @@
|
|||
<nav class="pagination-custom d-flex justify-content-between align-items-center">
|
||||
{{-- SELECT ITEMS PER PAGE --}}
|
||||
<div class="dropup-center dropup d-flex justify-content-center align-items-center input-group w-fit">
|
||||
<span class="btn-md input-group-text" data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
title="{{ __('crud.pagination.paginate_list') }}">
|
||||
<i class="fa-solid fa-list-ul"></i>
|
||||
</span>
|
||||
<button class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" type="button" aria-expanded="false">
|
||||
{{ Cache::get('pagination.' .Str::slug(request()->route()->getName())) }}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
@foreach (\Uwil\LaravelCommon\Enums\ItemsPerPaginationEnum::toArray() as $itemsPerPaginationEnum)
|
||||
<li>
|
||||
<a class="dropdown-item text-center"
|
||||
href="{{ request()->fullUrlWithQuery(['pagination' => $itemsPerPaginationEnum->value]) }}">
|
||||
{{ $itemsPerPaginationEnum->value }}
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@if ($paginator->total() > \Uwil\LaravelCommon\Enums\ItemsPerPaginationEnum::five->value())
|
||||
<div class="dropup-center dropup d-flex justify-content-center align-items-center input-group w-fit">
|
||||
<span class="btn-md input-group-text" data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
title="{{ __('crud.pagination.paginate_list') }}">
|
||||
<i class="fa-solid fa-list-ul"></i>
|
||||
</span>
|
||||
<button class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" type="button" aria-expanded="false">
|
||||
{{ Cache::get('pagination.' .Str::slug(request()->route()->getName())) }}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
@foreach (\Uwil\LaravelCommon\Enums\ItemsPerPaginationEnum::toArray() as $itemsPerPaginationEnum)
|
||||
<li>
|
||||
<a class="dropdown-item text-center"
|
||||
href="{{ request()->fullUrlWithQuery(['pagination' => $itemsPerPaginationEnum->value]) }}">
|
||||
{{ $itemsPerPaginationEnum->value }}
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
@if ($paginator->hasPages())
|
||||
{{-- PAGINATION --}}
|
||||
<div class="d-flex justify-content-end align-items-center">
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="col-12 my-3">
|
||||
<form id="searchForm" action="{{ request()->url() }}">
|
||||
<div class="input-group">
|
||||
<label class="input-group-text" for="searchField">{{ $searchFields }}</label>
|
||||
<label class="input-group-text" for="searchField">{{ str($searchFields)->ucFirst() }}</label>
|
||||
{{-- CONTACTS FILTER --}}
|
||||
@if (request()->user)
|
||||
<input class="d-none" name="user" type="text" value="{{ request()->user }}">
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
@extends('bo.layout')
|
||||
|
||||
@section('title', sprintf('%s - %s', Str::singular(__('models.classes.app_users')), Str::ucfirst(__('création'))))
|
||||
@section('description', __('Page de création d\'un nouvel utilisateur de l\'application.'))
|
||||
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="text-center text-md-start h2">
|
||||
<a href="{{ route('bo.app-users.index', ['tenant' => \tenant()]) }}"
|
||||
class="btn btn-primary text-decoration-none m-0"
|
||||
data-bs="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ __('Return to the :model list', ['model' => __('models.classes.app_users')]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-arrow-left"></i>
|
||||
</a>
|
||||
<span class="fw-bold">{{ Str::singular(__('models.classes.app_users')) }}</span> <small class="text-muted">{{ Str::ucfirst(__('création')) }}</small>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="col-12 col-md-4 d-flex justify-content-center justify-content-md-end align-items-center">
|
||||
<button id="formSubmitClone"
|
||||
class="btn btn-primary pull-end"
|
||||
title="{{ __('Sauvegarder l\':model', ['model' => Str::singular(__('models.classes.app_users'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-floppy-disk"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body bg-light">
|
||||
<form action="{{ route('bo.app-users.store', ['tenant' => \tenant()]) }}" method="POST">
|
||||
@csrf
|
||||
@include('bo.pages.app-users.form')
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<button id="formSubmit"
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
title="{{ __('Sauvegarder l\':model', ['model' => Str::singular(__('models.classes.app_users'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
{{ __('Sauvegarder') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
@extends('bo.layout', ['brParam' => $app_userModel])
|
||||
|
||||
@section('title', sprintf('%s - %s %s', Str::singular(__('models.classes.app_users')), Str::ucfirst(__('édition')), $app_userModel->lastname))
|
||||
@section('description', __('Page d\'édition d\'un utilisateurs de l\'application.'))
|
||||
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="text-center text-md-start h2">
|
||||
<a href="{{ route('bo.app-users.index', ['tenant' => \tenant()]) }}"
|
||||
class="btn btn-primary text-decoration-none m-0"
|
||||
data-bs="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ __('Retourner sur la liste des :model', ['model' => __('models.classes.app_users')]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-arrow-left"></i>
|
||||
</a>
|
||||
<span class="fw-bold">{{ Str::singular(__('models.classes.app_users')) }}</span> <small class="text-muted">{{ Str::ucfirst(__('édition')) }}</small>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="col-12 col-md-4 d-flex justify-content-center justify-content-md-end align-items-center">
|
||||
<form action="{{ route('bo.app-users.destroy', ['tenant' => \tenant(), 'app_user' => $app_userModel]) }}"
|
||||
method="POST" class="d-inline confirmDeleteJS">
|
||||
@method('DELETE')
|
||||
@csrf
|
||||
<div class="btn-group" role="group">
|
||||
<button id="formSubmitClone"
|
||||
class="btn btn-primary pull-end"
|
||||
title="{{ __('Sauvegarder l\':model', ['model' => Str::singular(__('models.classes.app_users'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-floppy-disk"></i>
|
||||
</button>
|
||||
<button class="btn btn-danger"
|
||||
title="{{ __('Supprimer l\':model', ['model' => Str::singular(__('models.classes.app_users'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body bg-light">
|
||||
<form action="{{ route('bo.app-users.update', ['tenant' => \tenant(), 'app_user' => $app_userModel]) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
@include('bo.pages.app-users.form', ['model' => $app_userModel])
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<button id="formSubmit"
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
title="{{ __('Sauvegarder l\':model', ['model' => Str::singular(__('models.classes.app_users'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
{{ __('Sauvegarder') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
<div class="table-responsive">
|
||||
<table class="table fix-action">
|
||||
<thead>
|
||||
@php
|
||||
$cols = [
|
||||
'lastname' => __('Nom'),
|
||||
'firstname' => __('Prénom'),
|
||||
'email' => __('Email'),
|
||||
'order' => __('Order')
|
||||
];
|
||||
@endphp
|
||||
@include('bo.modules.table-col-sorter', [
|
||||
'cols' => $cols,
|
||||
'mobileHide' => [],
|
||||
])
|
||||
</thead>
|
||||
<tbody>
|
||||
@if ($app_users->count())
|
||||
@foreach ($app_users as $app_usersModel)
|
||||
<tr>
|
||||
<td>
|
||||
<span>{{ $app_usersModel->lastname }}</span>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span>{{ $app_usersModel->firstname }}</span>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span>{{ $app_usersModel->email }}</span>
|
||||
</td>
|
||||
@php $routeName = request()->route()->getName(); @endphp
|
||||
@if (empty(request()->search) && Session::get("$routeName.sort_col") === 'order')
|
||||
@include('bo.modules.change-model-order', [
|
||||
'routeName' => 'appUsers',
|
||||
'models' => $app_users,
|
||||
'model' => $app_usersModel,
|
||||
])
|
||||
@endif
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<form action="{{ route('bo.app-users.destroy', [
|
||||
'tenant' => \tenant(),
|
||||
'app_user' => $app_usersModel
|
||||
]) }}" method="POST" class="d-inline confirmDeleteJS">
|
||||
@method('DELETE')
|
||||
@csrf
|
||||
<div class="btn-group" role="group">
|
||||
<a id="formSubmitClone"
|
||||
href="{{ route('bo.app-users.edit', [
|
||||
'tenant' => \tenant(),
|
||||
'app_user' => $app_usersModel
|
||||
]) }}"
|
||||
class="btn btn-sm btn-primary"
|
||||
role="button"
|
||||
title="{{ __('Modifier l\':model', ['model' => Str::singular(__('models.classes.users'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-pencil"></i>
|
||||
</a>
|
||||
<button class="btn btn-sm btn-danger"
|
||||
title="{{ __('Supprimer l\':model', ['model' => Str::singular(__('models.classes.users'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="{{ count($cols) + 1 }}" class="text-center">
|
||||
<span class="h3">
|
||||
{{ __('Aucun résultat pour les :models', ['models' => __('models.classes.users')]) }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
@extends('bo.layout')
|
||||
|
||||
@section('title', sprintf('%s - %s', __('models.classes.app_users'), Str::ucfirst(__('liste'))))
|
||||
@section('description', __('Page de contôle sur tous les utilisateurs de l\'application.'))
|
||||
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="col h2">
|
||||
<span class="fw-bold">{{ __('models.classes.app_users') }}</span> <small class="text-muted">{{ Str::ucfirst(__('liste')) }}</small>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="col d-flex align-items-center">
|
||||
<form class="input-group"
|
||||
action="{{ route('bo.app-users.import', ['tenant' => tenant()]) }}"
|
||||
method="POST"
|
||||
enctype="multipart/form-data">
|
||||
<input class="form-control" type="file" name="import" accept="text/csv,.csv"
|
||||
title="{{ __('Sélectionner un fichier .csv') }}"
|
||||
data-bs-toggle="tooltip" required>
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-primary"
|
||||
title="{{ __('Importer le fichier .csv') }}"
|
||||
data-bs-toggle="tooltip">
|
||||
{{ __('Importer') }}
|
||||
</button>
|
||||
</form>
|
||||
<div class="ms-1 justify-content-end">
|
||||
<a href="{{ route('bo.app-users.create', ['tenant' => \tenant()]) }}"
|
||||
class="btn btn-primary"
|
||||
title="{{ __('Créer un(e) :model', ['model' => Str::singular(__('models.classes.app_users'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@include('bo.modules.search-bar')
|
||||
<div class="row mt-3">
|
||||
<div class="col">
|
||||
@include('bo.pages.app-users.index-list')
|
||||
</div>
|
||||
</div>
|
||||
{{ $app_users->withQueryString()->onEachSide(1)->links() }}
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -11,7 +11,11 @@
|
|||
@endif
|
||||
<ul>
|
||||
@foreach ($appUser->directories as $directory)
|
||||
<li><a href="{{ route('bo.directories.edit', $directory) }}">{{ $directory->name['fr'] }}</a></li>
|
||||
<li>
|
||||
<a href="{{ route('bo.directories.edit', ['tenant' => \tenant(), 'directory' => $directory]) }}">
|
||||
{{ $directory->name['fr'] }}
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
44
resources/views/bo/pages/app_users/create.blade.php
Normal file
44
resources/views/bo/pages/app_users/create.blade.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
@extends('bo.layout', ['brParam' => $appUserModel])
|
||||
|
||||
@section('title', __('Création d\'un :model', ['model' => __('models.classes.app_user')]))
|
||||
@section('description', __('Création d\'un tout nouveau :model', ['model' => __('models.classes.app_user')]))
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">
|
||||
<div class="d-flex align-items-start flex-row">
|
||||
@can('viewAny', $appUserModel)
|
||||
<a class="btn btn-primary text-decoration-none m-0" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.app_users.index', ['tenant' => \tenant()]) }}"
|
||||
title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.app_user')]) }}">
|
||||
<i class="fa-solid fa-arrow-left"></i>
|
||||
</a>
|
||||
@endcan
|
||||
@include('modules.breadcrumbs.breadcrumb-body', ['brParam' => $appUserModel])
|
||||
</div>
|
||||
<div class="mb-md-0 mb-2">
|
||||
@can('create', $appUserModel)
|
||||
<button class="btn btn-primary" id="formSubmitClone" data-bs-toggle="tooltip" type="submit"
|
||||
title="{{ __('crud.helpers.save_model', ['model' => __('models.classes.app_user')]) }}">
|
||||
{{ str(__('crud.actions.save'))->ucFirst() }}
|
||||
</button>
|
||||
@endcan
|
||||
</div>
|
||||
</div>
|
||||
@can('create', $appUserModel)
|
||||
<form action="{{ route('bo.app_users.store', ['tenant' => \tenant()]) }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@endcan
|
||||
@include('bo.pages.app_users.form')
|
||||
@can('create', $appUserModel)
|
||||
<div class="row">
|
||||
<div class="col-12 text-center">
|
||||
<button class="btn btn-primary" id="formSubmit" data-bs-toggle="tooltip" type="submit"
|
||||
title="{{ __('crud.helpers.save_model', ['model' => __('models.classes.app_user')]) }}">
|
||||
{{ str(__('crud.actions.save'))->ucFirst() }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@endcan
|
||||
@endsection
|
||||
68
resources/views/bo/pages/app_users/edit.blade.php
Normal file
68
resources/views/bo/pages/app_users/edit.blade.php
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
@extends('bo.layout', ['brParam' => $appUserModel])
|
||||
|
||||
@section('title', __('Édition d\'un :model', ['model' => __('models.classes.app_user')]))
|
||||
@section('description', __('Édition d\'un :model déjà existant', ['model' => __('models.classes.app_user')]))
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">
|
||||
<div class="d-flex align-items-start flex-row">
|
||||
@can('viewAny', $appUserModel)
|
||||
<a class="btn btn-primary text-decoration-none m-0" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.app_users.index', ['tenant' => \tenant()]) }}"
|
||||
title="{{ __('crud.helpers.list_all', ['model' => str(__('models.classes.app_user'))->plural()]) }}">
|
||||
<i class="fa-solid fa-arrow-left"></i>
|
||||
</a>
|
||||
@endif
|
||||
@include('modules.breadcrumbs.breadcrumb-body', ['brParam' => $appUserModel])
|
||||
</div>
|
||||
<div class="mb-md-0 mb-2">
|
||||
@can('delete', $appUserModel)
|
||||
<form class="confirmDeleteTS" action="{{ route('bo.app_users.destroy', ['tenant' => \tenant(), 'app_user' => $appUserModel]) }}"
|
||||
method="POST" novalidate>
|
||||
@endcan
|
||||
<div class="btn-group">
|
||||
@can('duplicate', $appUserModel)
|
||||
<a class="btn btn-secondary" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.app_users.duplicate', ['tenant' => \tenant(), 'app_user' => $appUserModel]) }}"
|
||||
title="{{ str(__('crud.actions.duplicate'))->ucFirst() }}">
|
||||
<i class="fa-solid fa-copy"></i>
|
||||
</a>
|
||||
@endcan
|
||||
@can('update', $appUserModel)
|
||||
<button class="btn btn-primary" id="formSubmitClone" data-bs-toggle="tooltip" type="submit"
|
||||
title="{{ __('crud.helpers.save_model', ['model' => __('models.classes.app_user')]) }}">
|
||||
{{ str(__('crud.actions.save'))->ucFirst() }}
|
||||
</button>
|
||||
@endcan
|
||||
@can('delete', $appUserModel)
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button class="btn btn-danger" data-bs-toggle="tooltip" type="submit" title="{{ str(__('crud.actions.delete'))->ucFirst() }}">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
@endcan
|
||||
</div>
|
||||
@can('delete', $appUserModel)
|
||||
</form>
|
||||
@endcan
|
||||
</div>
|
||||
</div>
|
||||
@can('update', $appUserModel)
|
||||
<form action="{{ route('bo.app_users.update', ['tenant' => \tenant(), 'app_user' => $appUserModel]) }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
@endcan
|
||||
@include('bo.pages.app_users.form')
|
||||
@can('update', $appUserModel)
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<button class="btn btn-primary" id="formSubmit" data-bs-toggle="tooltip" type="submit"
|
||||
title="{{ __('crud.helpers.save_model', ['model' => __('models.classes.app_user')]) }}">
|
||||
{{ str(__('crud.actions.save'))->ucFirst() }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@endcan
|
||||
@endsection
|
||||
|
|
@ -7,11 +7,11 @@
|
|||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'app_userSurname',
|
||||
'label' => __('Nom de l\':model', ['model' => Str::singular(__('models.classes.users'))]),
|
||||
'label' => __('Nom de l\':model', ['model' => __('models.classes.user')]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'lastname',
|
||||
'required' => true,
|
||||
'model' => $app_userModel ?? null,
|
||||
'model' => $appUserModel ?? null,
|
||||
'helper' => __('Doit posséder 3 caractères minimum, 255 maximum.'),
|
||||
'placeholder' => 'Un beau nom',
|
||||
])
|
||||
|
|
@ -27,11 +27,11 @@
|
|||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'app_userFirstname',
|
||||
'label' => __('Prénom de l\':model', ['model' => Str::singular(__('models.classes.users'))]),
|
||||
'label' => __('Prénom de l\':model', ['model' => __('models.classes.user')]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'firstname',
|
||||
'required' => true,
|
||||
'model' => $app_userModel ?? null,
|
||||
'model' => $appUserModel ?? null,
|
||||
'helper' => __('Doit posséder 3 caractères minimum, 255 maximum.'),
|
||||
'placeholder' => 'Un beau prénom',
|
||||
])
|
||||
|
|
@ -47,11 +47,11 @@
|
|||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar-email', [
|
||||
'id' => 'app_userEmail',
|
||||
'label' => __('Email de l\':model', ['model' => Str::singular(__('models.classes.users'))]),
|
||||
'label' => __('Email de l\':model', ['model' => __('models.classes.user')]),
|
||||
'name' => 'email',
|
||||
'hasWordCounter' => true,
|
||||
'required' => true,
|
||||
'model' => $app_userModel ?? null,
|
||||
'model' => $appUserModel ?? null,
|
||||
'helper' => __(
|
||||
'Tapez votre e-mail en respectant la convention d\'appellation des e-mails (ex: firstname.lastname@yourdomain.com).'),
|
||||
'placeholder' => 'firstname.lastname@yourdomain.com',
|
||||
|
|
@ -68,7 +68,7 @@
|
|||
<div class="col-12 col-md-6 mb-3">
|
||||
@include('bo.partials.inputs.varchar-password', [
|
||||
'id' => 'app_userPassword',
|
||||
'label' => __('Mot de passe de l\':model', ['model' => Str::singular(__('models.classes.users'))]),
|
||||
'label' => __('Mot de passe de l\':model', ['model' => __('models.classes.user')]),
|
||||
'name' => 'password',
|
||||
'hasWordCounter' => false,
|
||||
'required' => false,
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
@include('bo.partials.inputs.varchar-password', [
|
||||
'id' => 'app_userPassword_confirmation',
|
||||
'label' => __('Confirmation du mot de passe de l\':model', [
|
||||
'model' => Str::singular(__('models.classes.users')),
|
||||
'model' => __('models.classes.user'),
|
||||
]),
|
||||
'name' => 'password_confirmation',
|
||||
'hasWordCounter' => false,
|
||||
|
|
@ -102,7 +102,7 @@
|
|||
'id' => 'app_userAuthorizedFolders',
|
||||
'name' => 'directories',
|
||||
'label' => __('Dossiers autorisés'),
|
||||
'model' => $app_userModel ?? null,
|
||||
'model' => $appUserModel ?? null,
|
||||
'itemsList' => $directories,
|
||||
'placeholder' => __('Recherchez un dossier'),
|
||||
'helper' => __('Dossiers autorisés de l\'utilisateur.'),
|
||||
|
|
@ -119,11 +119,11 @@
|
|||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.tinyint-enum', [
|
||||
'id' => 'app_userRole',
|
||||
'label' => __('Rôle de l\':model', ['model' => Str::singular(__('models.classes.users'))]),
|
||||
'label' => __('Rôle de l\':model', ['model' => __('models.classes.user')]),
|
||||
'name' => 'role',
|
||||
'model' => $app_userModel ?? null,
|
||||
'model' => $appUserModel ?? null,
|
||||
'required' => true,
|
||||
'associatedDatas' => \App\Enums\AppUserRolesEnum::toArray(),
|
||||
'itemsList' => \App\Enums\AppUserRolesEnum::toArray(),
|
||||
'helper' => __('Rôle de l\'utilisateur.'),
|
||||
])
|
||||
</div>
|
||||
|
|
@ -140,7 +140,7 @@
|
|||
'id' => 'app_userStatus',
|
||||
'name' => 'status',
|
||||
'label' => __('L\'utilisateur est-il activé ?'),
|
||||
'model' => $app_userModel ?? null,
|
||||
'model' => $appUserModel ?? null,
|
||||
'helper' => __('Activation de l\'utilisateur de l\'application.'),
|
||||
])
|
||||
</div>
|
||||
92
resources/views/bo/pages/app_users/index-list.blade.php
Normal file
92
resources/views/bo/pages/app_users/index-list.blade.php
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<div class="table-responsive">
|
||||
<table class="table fix-action">
|
||||
<thead>
|
||||
@php
|
||||
$cols = [
|
||||
'lastname' => str(__('validation.attributes.last_name'))->ucFirst(),
|
||||
'firstname' => str(__('validation.attributes.first_name'))->ucFirst(),
|
||||
'email' => str(__('validation.attributes.email'))->ucFirst(),
|
||||
'order' => str(__('validation.custom.order'))->ucFirst(),
|
||||
];
|
||||
@endphp
|
||||
@include('bo.modules.table-col-sorter', [
|
||||
'cols' => $cols,
|
||||
'mobileHide' => [],
|
||||
])
|
||||
</thead>
|
||||
<tbody>
|
||||
@if ($appUserModels->count())
|
||||
@foreach ($appUserModels as $appUserModel)
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
{{ $appUserModel->lastname }}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
{{ $appUserModel->firstname }}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
{{ $appUserModel->email }}
|
||||
</td>
|
||||
@php $routeName = request()->route()->getName(); @endphp
|
||||
@if (empty(request()->search) && Session::get("$routeName.sort_col") === 'order')
|
||||
@include('bo.modules.change-model-order', [
|
||||
'routeName' => 'app_users',
|
||||
'models' => $appUserModels,
|
||||
'model' => $appUserModel,
|
||||
])
|
||||
@endif
|
||||
<td>
|
||||
@can('delete', $appUserModel)
|
||||
<form action="{{ route('bo.app_users.destroy', [
|
||||
'tenant' => \tenant(),
|
||||
'app_user' => $appUserModel,
|
||||
]) }}" method="POST" class="d-inline confirmDeleteTS">
|
||||
@endcan
|
||||
<div class="btn-group" role="group">
|
||||
@can('duplicate', $appUserModel)
|
||||
<a class="btn btn-sm btn-secondary" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.app_users.duplicate', ['tenant' => \tenant(), 'app_user' => $appUserModel]) }}"
|
||||
title="{{ __('Dupliquer l\':model', ['model' => __('models.classes.app_user')]) }}">
|
||||
<i class="fa-solid fa-copy"></i>
|
||||
</a>
|
||||
@endcan
|
||||
@can('update', $appUserModel)
|
||||
<a id="formSubmitClone"
|
||||
href="{{ route('bo.app_users.edit', [
|
||||
'tenant' => \tenant(),
|
||||
'app_user' => $appUserModel,
|
||||
]) }}"
|
||||
class="btn btn-sm btn-primary" role="button"
|
||||
title="{{ __('Modifier l\':model', ['model' => __('models.classes.app_user')]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-pencil"></i>
|
||||
</a>
|
||||
@endcan
|
||||
@can('delete', $appUserModel)
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button class="btn btn-sm btn-danger"
|
||||
title="{{ __('Supprimer l\':model', ['model' => __('models.classes.app_user')]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
@endcan
|
||||
</div>
|
||||
@can('delete', $appUserModel)
|
||||
</form>
|
||||
@endcan
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="{{ count($cols) + 1 }}" class="text-center">
|
||||
<span class="h3">
|
||||
{{ __('Aucun résultat pour les :models', ['models' => str(__('models.classes.app_user'))->plural()]) }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
33
resources/views/bo/pages/app_users/index.blade.php
Normal file
33
resources/views/bo/pages/app_users/index.blade.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
@extends('bo.layout')
|
||||
|
||||
@section('title', sprintf('%s - %s', str(__('models.classes.app_user'))->plural(), str(__('liste'))->ucFirst()))
|
||||
@section('description', __('Page de contôle de tous les :model de l\'application.', ['model' => str(__('models.classes.app_user'))->plural()]))
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap">
|
||||
@include('modules.breadcrumbs.breadcrumb-body')
|
||||
<form class="input-group me-1" action="{{ route('bo.app_users.import', ['tenant' => tenant()]) }}" method="POST"
|
||||
enctype="multipart/form-data">
|
||||
<input class="form-control" type="file" name="import" accept="text/csv,.csv"
|
||||
title="{{ __('Sélectionner un fichier .csv') }}" data-bs-toggle="tooltip" required>
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-primary" title="{{ __('Importer le fichier .csv') }}"
|
||||
data-bs-toggle="tooltip">
|
||||
{{ __('Importer') }}
|
||||
</button>
|
||||
</form>
|
||||
@can('create', \App\Models\User::class)
|
||||
<a class="btn btn-primary float-right" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.app_users.create', ['tenant' => \tenant()]) }}"
|
||||
title="{{ __('crud.helpers.create_model', ['model' => __('models.classes.app_user')]) }}">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
@endcan
|
||||
</div>
|
||||
@include('bo.modules.search-bar')
|
||||
<div class="table-responsive">
|
||||
@include('bo.pages.app_users.index-list')
|
||||
</div>
|
||||
{{ $appUserModels->links() }}
|
||||
@endsection
|
||||
|
|
@ -3,11 +3,11 @@
|
|||
<thead>
|
||||
@php
|
||||
$cols = [
|
||||
'lastname' => __('Nom'),
|
||||
'email' => __('Email'),
|
||||
'phone' => __('Téléphone'),
|
||||
'app_user_id' => __('Commercial'),
|
||||
'updated_at' => __('Mis à jour'),
|
||||
'lastname' => str(__('validation.attributes.last_name'))->ucFirst(),
|
||||
'email' => str(__('validation.attributes.email'))->ucFirst(),
|
||||
'phone' => str(__('validation.attributes.phone'))->ucFirst(),
|
||||
'app_user_id' => str(__('models.classes.app_user'))->ucFirst(),
|
||||
'updated_at' => str(__('validation.attributes.updated_at'))->ucFirst(),
|
||||
];
|
||||
@endphp
|
||||
@include('bo.modules.table-col-sorter', [
|
||||
|
|
@ -16,29 +16,37 @@
|
|||
])
|
||||
</thead>
|
||||
<tbody>
|
||||
@if ($contactModelList->count())
|
||||
@foreach ($contactModelList as $contactModel)
|
||||
@if ($contactModels->count())
|
||||
@foreach ($contactModels as $contactModel)
|
||||
<tr>
|
||||
<td class="align-middle">
|
||||
<span>{{ $contactModel->lastname }} {{ $contactModel->firsname }}</span>
|
||||
<td class="text-center align-middle">
|
||||
@if ($contactModel->firstname || $contactModel->lastname)
|
||||
{{ $contactModel->lastname }} {{ $contactModel->firstname }}
|
||||
@else
|
||||
<small class="text-secondary fst-italic">{{ __('Non renseigné') }}</small>
|
||||
@endif
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<td class="text-center align-middle">
|
||||
<a href="mailto:{{ $contactModel->email }}">{{ $contactModel->email }}</a>
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<a href="tel:{{ $contactModel->phone }}">{{ $contactModel->phone }}</a>
|
||||
<td class="text-center align-middle">
|
||||
@if ($contactModel->phone)
|
||||
<a href="tel:{{ $contactModel->phone }}">{{ $contactModel->phone }}</a>
|
||||
@else
|
||||
<small class="text-secondary fst-italic">{{ __('Non renseigné') }}</small>
|
||||
@endif
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<span>{{ $contactModel->appUser->lastname }} {{ $contactModel->appUser->firstname }}</span>
|
||||
<td class="text-center align-middle">
|
||||
{{ $contactModel->appUser->lastname }} {{ $contactModel->appUser->firstname }}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<span>{{ $contactModel->updated_at->isoFormat('\L\e DD/MM/YYYY \à HH:mm') }}</span>
|
||||
<td class="text-center align-middle">
|
||||
<span class="badge bg-secondary">{{ $contactModel->updated_at->isoFormat('LLLL') }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-sm btn-warning" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.contacts.show', ['tenant' => \tenant(), 'contact' => $contactModel]) }}"
|
||||
title="{{ __('Visualiser le :model', ['model' => Str::singular(__('models.classes.contacts'))]) }}"
|
||||
title="{{ __('Visualiser le :model', ['model' => __('models.classes.contact')]) }}"
|
||||
role="button">
|
||||
<i class="fa-solid fa-eye"></i>
|
||||
</a>
|
||||
|
|
@ -50,7 +58,7 @@
|
|||
<tr>
|
||||
<td class="text-center" colspan="{{ count($cols) + 1 }}">
|
||||
<span class="h3">
|
||||
{{ __('Aucun résultat pour les :models', ['models' => __('models.classes.documents')]) }}
|
||||
{{ __('Aucun résultat pour les :models', ['models' => str(__('models.classes.contact'))->plural()]) }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -1,61 +1,45 @@
|
|||
@extends('bo.layout')
|
||||
|
||||
@section('title', sprintf('%s - %s', __('models.classes.contacts'), Str::ucfirst(__('liste'))))
|
||||
@section('description', __('Page de contôle sur tous les contacts de l\'application.'))
|
||||
|
||||
@section('title', sprintf('%s - %s', str(__('models.classes.contact'))->plural(), str(__('liste'))->ucFirst()))
|
||||
@section('description', __('Page de contôle de tous les :model de l\'application.', ['model' => str(__('models.classes.contact'))->plural()]))
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="col h2">
|
||||
<span class="fw-bold">{{ __('models.classes.contacts') }}</span> <small
|
||||
class="text-muted">{{ Str::ucfirst(__('liste')) }}</small>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="col d-flex justify-content-end align-items-center">
|
||||
<div class="justify-content-end ms-1">
|
||||
<div class="input-group mb-3">
|
||||
<label class="input-group-text" for="filter-app-user-field">{{ __('Filtrer') }}</label>
|
||||
<select class="form-select" id="filter-app-user-field">
|
||||
<option @if (!request()->user) selected @endif>{{ __('Choisir un commercial') }}</option>
|
||||
@foreach ($appUsers as $appUser)
|
||||
<option data-id="{{ $appUser->id }}" @if (request()->user == $appUser->id) selected @endif>
|
||||
{{ __($appUser->lastname) }} {{ __($appUser->firstname) }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<button class="btn btn-outline-secondary" id="reset-app-user-filter" type="button">
|
||||
<i class="fa fa-delete-left"></i>
|
||||
</button>
|
||||
</div>
|
||||
@push('scripts')
|
||||
<script nonce="{{ $nonce ?? null }}">
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const appUserFilter = document.getElementById('filter-app-user-field');
|
||||
const appUserFilterReset = document.getElementById('reset-app-user-filter');
|
||||
appUserFilterReset.addEventListener('click', () => window.location = '{{ route('bo.contacts.index', ['tenant' => \tenant()]) }}')
|
||||
appUserFilter.addEventListener('change', (e) =>
|
||||
window.location = '{{ route('bo.contacts.index', ['tenant' => \tenant(), 'user' => 'USER']) }}'.replace('USER', appUserFilter.options[
|
||||
appUserFilter.options.selectedIndex].dataset.id ?? '')
|
||||
)
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap">
|
||||
@include('modules.breadcrumbs.breadcrumb-body')
|
||||
<div class="col-12 col-md-6 col-xl-5 col-xxl-4">
|
||||
<div class="input-group">
|
||||
<label class="input-group-text" for="filter-app-user-field">{{ __('Filtrer') }}</label>
|
||||
<select class="form-select" id="filter-app-user-field">
|
||||
<option @if (!request()->user) selected @endif>{{ __('Choisir un commercial') }}</option>
|
||||
@foreach ($appUsers as $appUser)
|
||||
<option data-id="{{ $appUser->id }}" @if (request()->user == $appUser->id) selected @endif>
|
||||
{{ __($appUser->lastname) }} {{ __($appUser->firstname) }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<button class="btn btn-outline-secondary" id="reset-app-user-filter" type="button">
|
||||
<i class="fa fa-delete-left"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@include('bo.modules.search-bar')
|
||||
<div class="row mt-3">
|
||||
<div class="col">
|
||||
@include('bo.pages.contacts.index-list')
|
||||
</div>
|
||||
</div>
|
||||
{{ $contactModelList->withQueryString()->onEachSide(1)->links() }}
|
||||
@push('scripts')
|
||||
<script nonce="{{ $nonce ?? null }}">
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const appUserFilter = document.getElementById('filter-app-user-field');
|
||||
const appUserFilterReset = document.getElementById('reset-app-user-filter');
|
||||
appUserFilterReset.addEventListener('click', () => window.location = '{{ route('bo.contacts.index', ['tenant' => \tenant()]) }}')
|
||||
appUserFilter.addEventListener('change', (e) =>
|
||||
window.location = '{{ route('bo.contacts.index', ['tenant' => \tenant(), 'user' => 'USER']) }}'.replace('USER', appUserFilter.options[
|
||||
appUserFilter.options.selectedIndex].dataset.id ?? '')
|
||||
)
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
</div>
|
||||
</div>
|
||||
@include('bo.modules.search-bar')
|
||||
<div class="table-responsive">
|
||||
@include('bo.pages.contacts.index-list')
|
||||
</div>
|
||||
{{ $contactModels->links() }}
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
@extends('bo.layout')
|
||||
|
||||
@section('title', sprintf('%s - %s', __('models.classes.contacts'), Str::ucfirst(__('liste'))))
|
||||
@section('title', sprintf('%s - %s', str(__('models.classes.contact'))->plural(), Str::ucfirst(__('liste'))))
|
||||
@section('description', __('Page de contôle sur tous les contacts de l\'application.'))
|
||||
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
|
@ -13,10 +13,10 @@
|
|||
<h1 class="text-md-start h2 text-center">
|
||||
<a class="btn btn-primary text-decoration-none m-0" data-bs="tooltip" data-bs-placement="top" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.contacts.index', ['tenant' => \tenant()]) }}"
|
||||
title="{{ __('Retourner sur la liste des :model', ['model' => __('models.classes.contacts')]) }}">
|
||||
title="{{ __('Retourner sur la liste des :model', ['model' => str(__('models.classes.contact'))->plural()]) }}">
|
||||
<i class="fa-solid fa-arrow-left"></i>
|
||||
</a>
|
||||
<span class="fw-bold">{{ Str::singular(__('models.classes.contacts')) }}</span> <small
|
||||
<span class="fw-bold">{{ __('models.classes.contact') }}</span> <small
|
||||
class="text-muted">{{ Str::ucfirst(__('voir')) }}</small>
|
||||
</h1>
|
||||
</div>
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
</div>
|
||||
<div class="accordion-collapse collapse" id="collapseAppUser" data-bs-parent="#appUserAccordion">
|
||||
<div class="accordion-body">
|
||||
@include('bo.pages.app-users.card', ['appUser' => $contactModel->appUser])
|
||||
@include('bo.pages.app_users.card', ['appUser' => $contactModel->appUser])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,27 +7,54 @@
|
|||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@php $user = auth('backend')->user(); @endphp
|
||||
@if (!$tenantsGlobal->count() && $user->can('isAdmin'))
|
||||
<div class="col-12 mb-3">
|
||||
<div class="card text-center border-danger">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-center text-danger">
|
||||
<b>
|
||||
{{ __('Vous devez administrer au moins un tenant pour le bon fonctionnement de l\'appli/back-office.', [
|
||||
'role' => $user->role->label(),
|
||||
]) }}
|
||||
</b>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<a href="{{ route('bo.tenants.create') }}"
|
||||
class="btn btn-danger">
|
||||
{{ __('Créer le premier tenant') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="col-12">
|
||||
<div class="card text-center">
|
||||
<div class="card-header fw-bold">
|
||||
<h1 class="h2 fw-bold">{{ __('Dashboard') }}</h1>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
{{ __('Bonjour :firstname :lastname !', [
|
||||
'firstname' => Auth::user()->firstname,
|
||||
'lastname' => Auth::user()->lastname,
|
||||
<h5 class="card-title text-center">
|
||||
<b>
|
||||
{{ __('Bonjour :first_name :last_name !', [
|
||||
'first_name' => $user->first_name,
|
||||
'last_name' => $user->last_name,
|
||||
]) }}
|
||||
</b>
|
||||
</h5>
|
||||
<p class="card-text m-0">
|
||||
<p class="card-text">
|
||||
{{ __('Bienvenue dans le back-office, où vous pouvez gérer votre application web.') }}
|
||||
</p>
|
||||
<p class="card-text">
|
||||
<p class="card-text mt-4">
|
||||
<b>
|
||||
{{ __('Pour accéder à vos statistiques') }} :
|
||||
<a data-bs-toggle="tooltip" href="https://report.uwil.fr" title="{{ __('Accéder à notre outil de reporting') }}"
|
||||
target="_blank">https://report.uwil.fr</a><br>
|
||||
{{ __('Pour tout problème ou évolution souhaitée, veuillez nous contacter via notre outil : ') }}
|
||||
<a data-bs-toggle="tooltip" href="https://support.uwil.fr" title="{{ __('Accéder à notre outil de ticketing') }}"
|
||||
target="blank">
|
||||
https://support.uwil.fr
|
||||
</a>.
|
||||
<a data-bs-toggle="tooltip" href="https://support.uwil.fr/" title="{{ __('Accéder à notre outil de ticketing') }}"
|
||||
target="blank">https://support.uwil.fr/</a>.
|
||||
</b>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,65 +1,68 @@
|
|||
@extends('bo.layout', ['brParam' => $directoryModel])
|
||||
|
||||
@section('title', sprintf('%s - %s %s', Str::singular(__('models.classes.directories')), Str::ucfirst(__('édition')), $directoryModel->lastname))
|
||||
@section('description', __('Page d\'édition d\'un dossier de l\'application.'))
|
||||
|
||||
@section('title', __('Édition d\'un :model', ['model' => __('models.classes.directory')]))
|
||||
@section('description', __('Édition d\'un :model déjà existant', ['model' => __('models.classes.directory')]))
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="text-center text-md-start h2">
|
||||
<a href="{{ route('bo.directories.index', ['tenant' => \tenant()]) }}"
|
||||
class="btn btn-primary text-decoration-none m-0"
|
||||
data-bs="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ __('Retourner sur la liste des :model', ['model' => __('models.classes.directories')]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-arrow-left"></i>
|
||||
</a>
|
||||
<span class="fw-bold">{{ Str::singular(__('models.classes.directories')) }}</span> <small class="text-muted">{{ Str::ucfirst(__('édition')) }}</small>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="col-12 col-md-4 d-flex justify-content-center justify-content-md-end align-items-center">
|
||||
<form action="{{ route('bo.directories.destroy', ['tenant' => \tenant(), 'directory' => $directoryModel]) }}" method="POST" class="d-inline confirmDeleteJS">
|
||||
@method('POST')
|
||||
@csrf
|
||||
<div class="btn-group" role="group">
|
||||
<button id="formSubmitClone"
|
||||
class="btn btn-primary pull-end"
|
||||
title="{{ __('Sauvegarder le :model', ['model' => Str::singular(__('models.classes.directories'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-floppy-disk"></i>
|
||||
</button>
|
||||
<button class="btn btn-danger"
|
||||
title="{{ __('Supprimer le :model', ['model' => Str::singular(__('models.classes.directories'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">
|
||||
<div class="d-flex align-items-start flex-row">
|
||||
@can('viewAny', $directoryModel)
|
||||
<a class="btn btn-primary text-decoration-none m-0" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.directories.index', ['tenant' => \tenant()]) }}"
|
||||
title="{{ __('crud.helpers.list_all', ['model' => str(__('models.classes.directory'))->plural()]) }}">
|
||||
<i class="fa-solid fa-arrow-left"></i>
|
||||
</a>
|
||||
@endcan
|
||||
@include('modules.breadcrumbs.breadcrumb-body', ['brParam' => $directoryModel])
|
||||
</div>
|
||||
<div class="card-body bg-light">
|
||||
<form action="{{ route('bo.directories.update', ['tenant' => \tenant(), 'directory' => $directoryModel]) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
@include('bo.pages.directories.form', ['model' => $directoryModel])
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<button id="formSubmit"
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
title="{{ __('Sauvegarder :model', ['model' => Str::singular(__('models.classes.directories'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
{{ __('Sauvegarder') }}
|
||||
<div class="mb-md-0 mb-2">
|
||||
@can('delete', $directoryModel)
|
||||
<form class="confirmDeleteTS" action="{{ route('bo.directories.destroy', ['tenant' => \tenant(), 'directory' => $directoryModel]) }}"
|
||||
method="POST" novalidate>
|
||||
@endcan
|
||||
<div class="btn-group">
|
||||
@can('duplicate', $directoryModel)
|
||||
<a class="btn btn-secondary" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.directories.duplicate', ['tenant' => \tenant(), 'directory' => $directoryModel]) }}"
|
||||
title="{{ str(__('crud.actions.duplicate'))->ucFirst() }}">
|
||||
<i class="fa-solid fa-copy"></i>
|
||||
</a>
|
||||
@endcan
|
||||
@can('update', $directoryModel)
|
||||
<button class="btn btn-primary" id="formSubmitClone" data-bs-toggle="tooltip" type="submit"
|
||||
title="{{ __('crud.helpers.save_model', ['model' => __('models.classes.directory')]) }}">
|
||||
{{ str(__('crud.actions.save'))->ucFirst() }}
|
||||
</button>
|
||||
</div>
|
||||
@endcan
|
||||
@can('delete', $directoryModel)
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button class="btn btn-danger" data-bs-toggle="tooltip" type="submit" title="{{ str(__('crud.actions.delete'))->ucFirst() }}">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
@endcan
|
||||
</div>
|
||||
@can('delete', $directoryModel)
|
||||
</form>
|
||||
@endcan
|
||||
</div>
|
||||
</div>
|
||||
@can('update', $directoryModel)
|
||||
<form action="{{ route('bo.directories.update', ['tenant' => \tenant(), 'directory' => $directoryModel]) }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
@endcan
|
||||
@include('bo.pages.directories.form')
|
||||
@can('update', $directoryModel)
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<button class="btn btn-primary" id="formSubmit" data-bs-toggle="tooltip" type="submit"
|
||||
title="{{ __('crud.helpers.save_model', ['model' => __('models.classes.directory')]) }}">
|
||||
{{ str(__('crud.actions.save'))->ucFirst() }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@endcan
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'directoryNameFR',
|
||||
'label' => __('Nom du :model en français', ['model' => Str::singular(__('models.classes.directories'))]),
|
||||
'label' => __('Nom du :model en français', ['model' => __('models.classes.directory')]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'name[fr]',
|
||||
'value' => $directoryModel->name['fr'] ?? "",
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'directoryNameEN',
|
||||
'label' => __('Nom du :model en anglais', ['model' => Str::singular(__('models.classes.directories'))]),
|
||||
'label' => __('Nom du :model en anglais', ['model' => __('models.classes.directory')]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'name[en]',
|
||||
'value' => $directoryModel->name['en'] ?? "",
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'directoryNameDE',
|
||||
'label' => __('Nom du :model en allemand', ['model' => Str::singular(__('models.classes.directories'))]),
|
||||
'label' => __('Nom du :model en allemand', ['model' => __('models.classes.directory')]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'name[de]',
|
||||
'value' => $directoryModel->name['de'] ?? "",
|
||||
|
|
@ -70,7 +70,7 @@
|
|||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'directoryNameNL',
|
||||
'label' => __('Nom du :model en néerlandais', ['model' => Str::singular(__('models.classes.directories'))]),
|
||||
'label' => __('Nom du :model en néerlandais', ['model' => __('models.classes.directory')]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'name[nl]',
|
||||
'value' => $directoryModel->name['nl'] ?? "",
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue