diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f42ef5..59e7308 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +### 04.2023 -> 1.3.0 +- Update Status Enum +- Update TicketStatusChanged event +- Update TicketStatus Changed messages +- Add DutyHours +- Add Informations +### 15.12.2022 +- Add Sentry ### 12.10.2022 -> 1.2.3 - Hotfixed regular users could not create tickets anymore diff --git a/IDEAS.md b/IDEAS.md index a652181..f2b8d87 100644 --- a/IDEAS.md +++ b/IDEAS.md @@ -1,11 +1,3 @@ -- Permettre à un user de suivre un projet -- ~~permettre d'insérer des @user dans le texte avec lien vers user~~ - ~~pas de liens vers user mais mise en form~~ -- ~~parse de @user + envoie de mail si un seul user est trouvé~~ -- ~~permettre de modifier son mot de passe ? (je crois que ça n'as pas été mis exprès)~~ -- ~~parser les liens http~~ - - Algorithme charge de travail ticket diff --git a/app/Enums/InfoColors.php b/app/Enums/InfoColors.php new file mode 100644 index 0000000..8fba3d7 --- /dev/null +++ b/app/Enums/InfoColors.php @@ -0,0 +1,90 @@ + 0, + 'secondary' => 1, + 'success' => 2, + 'danger' => 3, + 'warning' => 4, + 'info' => 5, + 'light' => 6, + 'dark' => 7, + 'white' => 8 + ]; + } + + /** + * Enum labels + * + * @return array + */ + protected static function labels(): array + { + return [ + 'primary' => trans('Primary'), + 'secondary' => trans('Secondary'), + 'success' => trans('Success'), + 'danger' => trans('Danger'), + 'warning' => trans('Warning'), + 'info' => trans('Info'), + 'light' => trans('Light'), + 'dark' => trans('Dark'), + 'white' => trans('white') + ]; + } + + /** + * Enum classes + * + * @return array + */ + protected static function classes(): array + { + return [ + 'primary' => 'primary', + 'secondary' => 'secondary', + 'success' => 'success', + 'danger' => 'danger', + 'warning' => 'warning', + 'info' => 'info', + 'light' => 'light', + 'dark' => 'dark', + ]; + } + + /** + * @param string $attribute + * @return integer|string + */ + public function __get(string $attribute) + { + if ($attribute === 'class') { + return $this->classes()[$this->getDefinition()]; + } + return parent::__get($attribute); + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index efa4c3d..9a02c7e 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -10,6 +10,8 @@ use App\Enums\TicketStatus; use App\Models\Ticket; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Schema; +use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\View; class Controller extends BaseController @@ -130,4 +132,43 @@ class Controller extends BaseController } return $query; } + + /** + * Sort columns with a query + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param array $ignore + * @return \Illuminate\Database\Eloquent\Builder + */ + protected function sortQuery(Builder $query, array $ignore = []): Builder + { + $rName = request()->route()->getName(); + $table = $query->getModel()->getTable(); + if (request()->sort_col) { + Session::put("$rName.sort_col", request()->sort_col); + Session::put("$rName.sorted", true); + } + if (request()->sort_way) { + Session::put("$rName.sort_way", request()->sort_way); + Session::put("$rName.sorted", true); + } + if (request()->rst) { + Session::remove("$rName.sorted"); + Session::remove("$rName.sort_col"); + Session::remove("$rName.sort_way"); + } + if (request()->sort_col and request()->sort_way and Schema::hasColumn($table, request()->sort_col)) { + if ( + !isset($ignore) or + (isset($ignore) and !in_array(request()->sort_col, $ignore)) + ) { + $query = $query->orderBy(\sprintf("$table.%s", request()->sort_col), request()->sort_way); + } + } elseif (Schema::hasColumn($table, 'order')) { + $query = $query->orderBy('order', 'ASC'); + Session::put("$rName.sort_col", 'order'); + Session::put("$rName.sort_way", 'asc'); + } + return $query; + } } diff --git a/app/Http/Controllers/DutyhourController.php b/app/Http/Controllers/DutyhourController.php new file mode 100644 index 0000000..921fb3b --- /dev/null +++ b/app/Http/Controllers/DutyhourController.php @@ -0,0 +1,22 @@ +', now()->modify('-1 day'))->orderBy('date', 'asc')->limit(10)->get(); + return view('home', compact('dutyhourModels')); } } diff --git a/app/Http/Controllers/InformationController.php b/app/Http/Controllers/InformationController.php new file mode 100644 index 0000000..5b05001 --- /dev/null +++ b/app/Http/Controllers/InformationController.php @@ -0,0 +1,52 @@ +put('infos', Information::all(), 3600); + } + + /** + * After update model middleware + * + * @return void + */ + public function updatedModel() + { + cache()->put('infos', Information::all(), 3600); + } + + /** + * After delete model middleware + * + * @return void + */ + public function deletedModel() + { + cache()->put('infos', Information::all(), 3600); + } +} diff --git a/app/Models/Dutyhour.php b/app/Models/Dutyhour.php new file mode 100644 index 0000000..66f6864 --- /dev/null +++ b/app/Models/Dutyhour.php @@ -0,0 +1,123 @@ + 'date' + ]; + + /** + * Package + * + * @param array $attributes + */ + public function __construct(array $attributes = []) + { + self::$editableProperties = [ + 'date' => [ + 'label' => trans('Date'), + 'type' => CrudType::date(), + 'validate' => [ + 'date', + 'after_or_equal:today', + // @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed + function ($attribute, $value, $fail) { + $q = static::query(); + if (request()->dutyhour) { + $q = $q->where('id', '!=', $this->id); + } + if ($q->where('date', $value)->exists()) { + $fail(__('La :attribute est déjà utilisée', [ + 'attribute' => $attribute + ])); + } + } + ], + 'nullable' => false, + 'actions' => [ + CrudAction::viewAny(), + CrudAction::view(), + CrudAction::update(), + CrudAction::create() + ] + ], + 'person' => [ + 'label' => trans('Personne présente'), + 'type' => CrudType::string(), + 'validate' => [ + 'string', + 'max:255' + ], + 'nullable' => false, + 'actions' => [ + CrudAction::viewAny(), + CrudAction::view(), + CrudAction::update(), + CrudAction::create() + ] + ], + 'place' => [ + 'label' => trans('Lieu'), + 'type' => CrudType::string(), + 'validate' => [ + 'string', + 'max:255' + ], + 'nullable' => false, + 'actions' => [ + CrudAction::viewAny(), + CrudAction::view(), + CrudAction::update(), + CrudAction::create() + ] + ], + ]; + parent::__construct($attributes); + } +} diff --git a/app/Models/Information.php b/app/Models/Information.php new file mode 100644 index 0000000..b3393b6 --- /dev/null +++ b/app/Models/Information.php @@ -0,0 +1,120 @@ + InfoColors::class, + ]; + + /** + * Package + * + * @param array $attributes + */ + public function __construct(array $attributes = []) + { + self::$editableProperties = [ + 'title' => [ + 'label' => trans('Titre'), + 'type' => CrudType::string(), + 'validate' => [ + 'string', + 'max:255' + ], + 'nullable' => false, + 'actions' => [ + CrudAction::viewAny(), + CrudAction::view(), + CrudAction::update(), + CrudAction::create() + ] + ], + 'message' => [ + 'label' => trans('Message'), + 'type' => CrudType::string(), + 'validate' => [ + 'string', + 'max:255' + ], + 'nullable' => false, + 'actions' => [ + CrudAction::viewAny(), + CrudAction::view(), + CrudAction::update(), + CrudAction::create() + ] + ], + 'type' => [ + 'label' => trans('Type d\'annonce'), + 'type' => CrudType::enum(), + 'enum' => InfoColors::class, + 'nullable' => false, + 'actions' => [ + CrudAction::viewAny(), + CrudAction::view(), + CrudAction::update(), + CrudAction::create() + ] + ], + ]; + parent::__construct($attributes); + } +} diff --git a/app/Policies/DutyhourPolicy.php b/app/Policies/DutyhourPolicy.php new file mode 100644 index 0000000..c77cadd --- /dev/null +++ b/app/Policies/DutyhourPolicy.php @@ -0,0 +1,38 @@ +policies = [ + 'dutyhour' => [ + 'viewAny' => URR::make('userIsAdmin', $user), + 'create' => URR::make('userIsAdmin', $user), + 'update' => URR::make('userIsAdmin', $user), + 'delete' => URR::make('userIsAdmin', $user) + ] + ]; + } +} diff --git a/app/Policies/InformationPolicy.php b/app/Policies/InformationPolicy.php new file mode 100644 index 0000000..25d254d --- /dev/null +++ b/app/Policies/InformationPolicy.php @@ -0,0 +1,38 @@ +policies = [ + 'information' => [ + 'viewAny' => URR::make('userIsAdmin', $user), + 'create' => URR::make('userIsAdmin', $user), + 'update' => URR::make('userIsAdmin', $user), + 'delete' => URR::make('userIsAdmin', $user) + ] + ]; + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 780fcc7..4a02499 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use App\Models\Information; use App\Models\MacroSchedule\Marker; use Illuminate\Pagination\Paginator; use Illuminate\Support\Carbon; @@ -27,16 +28,16 @@ class AppServiceProvider extends ServiceProvider // * LOCAL FORCE eg: for Carbon // * Remove numeric to prevent float seperator to breaking numeric transactions \collect([\LC_TIME, \LC_MESSAGES, \LC_COLLATE, \LC_CTYPE, \LC_MONETARY]) - ->map(function ($contant) { - setlocale( - $contant, - \sprintf( - '%s_%s.UTF-8', - config('app.locale'), - \strtoupper(config('app.locale')) - ) - ); - }); + ->map(function ($contant) { + setlocale( + $contant, + \sprintf( + '%s_%s.UTF-8', + config('app.locale'), + \strtoupper(config('app.locale')) + ) + ); + }); Carbon::setLocale(config('app.locale')); // * Force bootstrap paginator @@ -51,17 +52,21 @@ class AppServiceProvider extends ServiceProvider }); if (!app()->runningInConsole()) { - $appInfos = Cache::remember('composer', 360, function () { + $appInfos = Cache::remember('composer', 3600, function () { return json_decode(File::get(\app_path('../composer.json'))); }); View::share('name', $appInfos->name); View::share('version', $appInfos->version); View::share('license', $appInfos->license); - // * Groups View::share('markerLabels', Cache::rememberForever('markerLabels', function () { return Marker::getCachedLabels() ?? []; })); - }//end if + // * Informations + $infos = Cache::remember('infos', 3600, function () { + return Information::all(); + }); + View::share('informations', $infos); + } //end if } } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 8c5438b..93c881b 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -6,7 +6,9 @@ use App\Models\Brand; use App\Models\Company; use App\Models\Credit\Account; use App\Models\Credit\CreditLog; +use App\Models\Dutyhour; use App\Models\File; +use App\Models\Information; use App\Models\Invoice; use App\Models\Label; use App\Models\Log; @@ -91,6 +93,8 @@ class RouteServiceProvider extends ServiceProvider Route::model('label', Label::class); Route::model('marker', Marker::class); Route::model('package', Package::class); + Route::model('dutyhour', Dutyhour::class); + Route::model('information', Information::class); Route::model('company', Company::class); Route::model('invoice', Invoice::class); Route::model('file', File::class); diff --git a/composer.json b/composer.json index a741bb7..0db9ae0 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "ldcweb/supportweb", - "version": "1.2.3", + "version": "1.3.0", "type": "project", "description": "The Laravel Framework.", "keywords": [ diff --git a/database/migrations/2023_04_18_123853_create_dutyhours_table.php b/database/migrations/2023_04_18_123853_create_dutyhours_table.php new file mode 100644 index 0000000..1d8ccb9 --- /dev/null +++ b/database/migrations/2023_04_18_123853_create_dutyhours_table.php @@ -0,0 +1,34 @@ +id(); + $table->date('date')->unique(); + $table->string('person'); + $table->string('place'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('dutyhours'); + } +} diff --git a/database/migrations/2023_04_18_150623_create_informations_table.php b/database/migrations/2023_04_18_150623_create_informations_table.php new file mode 100644 index 0000000..f31e292 --- /dev/null +++ b/database/migrations/2023_04_18_150623_create_informations_table.php @@ -0,0 +1,34 @@ +id(); + $table->string('title'); + $table->string('message'); + $table->unsignedTinyInteger('type')->comment('Defined by the InfoColors enum.'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('informations'); + } +} diff --git a/public/robots.txt b/public/robots.txt index eb05362..1f53798 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -1,2 +1,2 @@ User-agent: * -Disallow: +Disallow: / diff --git a/resources/lang/en/models.php b/resources/lang/en/models.php index e4446c6..b0edf88 100644 --- a/resources/lang/en/models.php +++ b/resources/lang/en/models.php @@ -16,5 +16,7 @@ return [ 'packages' => 'Packages', 'invoices' => 'Invoices', 'companies' => 'Companies', + 'dutyhours' => 'Duty Hours', + 'informations' => 'Informations', ] ]; diff --git a/resources/lang/fr/models.php b/resources/lang/fr/models.php index de9519d..bb6d649 100644 --- a/resources/lang/fr/models.php +++ b/resources/lang/fr/models.php @@ -16,5 +16,7 @@ return [ 'packages' => 'Forfaits', 'invoices' => 'Devis', 'companies' => 'Sociétés', + 'dutyhours' => 'Permanences', + 'informations' => 'Informations', ] ]; diff --git a/resources/views/dutyhours/index.blade.php b/resources/views/dutyhours/index.blade.php new file mode 100644 index 0000000..4dc6f09 --- /dev/null +++ b/resources/views/dutyhours/index.blade.php @@ -0,0 +1,112 @@ +@extends($viewLayout) + +@section('title', sprintf('%s - %s', transFb(sprintf('models.classes.%s', strtolower(Str::plural(class_basename($modelClass)))), Str::plural(class_basename($modelClass))), __('crud-policies::crud.viewAny'))) +@section('description', sprintf('%s %s', __('crud-policies::crud.viewAny'), trans(Str::plural(class_basename($modelClass))))) +@section('metaIndex', 'noindex,nofollow') + +@section('content') +
+ @include('crud-policies::crud.modules.flashMessage') +
+ @include('crud-policies::crud.modules.breadcrumb', ['action' => CrudAction::viewAny()]) + @include('crud-policies::crud.modules.actionbar.bar', ['action' => CrudAction::viewAny()]) +
+
+
+
+ {{ $models->links() }} +
+
+
+
+ + + + {{ __('crud-policies::crud.reset') }} + +
+
+
+
+ + + @include('crud-policies::crud.modules.sorter') + + + @if(count($models)) + + {{-- INIT QUERIES for OPTIMIZING --}} + @foreach ($modelClass::getEditableProperties() as $fieldName => $prop) + @if($prop['type']->equals(CrudType::order())) + @php ${"$modelTable$fieldName"} = $modelClass::max($fieldName); @endphp + @endif + @if($prop['type']->equals(CrudType::belongsTo())) + @php try { $models->load(Str::singular((new $prop['belongsTo']())->getTable())); } catch(\Exception $e) {} @endphp + @endif + @if($prop['type']->equals(CrudType::belongsToMany())) + @php $models->load("$fieldName"); @endphp + @endif + @endforeach + + {{-- DISPLAY MODELS --}} + @foreach($models as $model) + + @foreach ($modelClass::getEditableProperties() as $fieldName => $prop) + @if(in_array(CrudAction::viewAny(), $prop['actions'])) + @switch($prop['type']) + @case(CrudType::password()) + {{-- Ignore --}} + @break + @default + + @endswitch + @endif + @endforeach + + {{-- MODEL ACTIONS --}} + + + @endforeach + @else + + + + @endif + +
@include('crud-policies::crud.printfield', [ + 'action' => CrudAction::viewAny(), + 'field' => $model->{$fieldName}, + 'props' => $prop, + "$modelTable$fieldName" => ${"$modelTable$fieldName"} ?? null + ]) +
+ @can('view', $model) + {{ __('crud-policies::crud.view') }} + @endcan + @can('update', $model) + {{ __('crud-policies::crud.edit') }} + @endcan + @can('delete', $model) +
+ @csrf + @method('DELETE') + +
+ @endcan + @can('viewAny', \App\Models\Log::class) + {{ __('models.classes.logs') }} + @endcan + @can('viewAny', \App\Models\File::class) + {{ __('models.classes.files') }} + @endcan +
+
+ {{ __('crud-policies::crud.nothingtoshow') }} +
+ {{ $models->links() }} +
+
+@include('crud-policies::crud.modules.scriptConstants') +@endsection diff --git a/resources/views/errors/layout.blade.php b/resources/views/errors/layout.blade.php index c43a0f4..01e28d4 100644 --- a/resources/views/errors/layout.blade.php +++ b/resources/views/errors/layout.blade.php @@ -150,7 +150,7 @@
- {{ config('app.name') }} + {{ config('app.name') }}
@yield('message') diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index 2dbc80f..beb7ff7 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -2,17 +2,51 @@ @section('content')
-
-
-

Bienvenue sur le support LDC WEB.

-
-
- +
+
+

+ {{ __('models.classes.dutyhours') . __(' à venir') }} +

+
+
+
+
+
+ + + + + + + + + + @if($dutyhourModels->count()) + @foreach ($dutyhourModels as $dutyhourModel) + + + + + + @endforeach + @else + + + + @endif + +
{{ __('Date') }}{{ __('Personne présente') }}{{ __('Lieu de la permanence') }}
{{ $dutyhourModel->date->formatLocalized('%d/%m/%Y') }}{{ $dutyhourModel->person }}{{ $dutyhourModel->place }}
+ {{ __('Aucune :model prévue prochainement', ['model' => Str::singular(__('models.classes.dutyhours')) ])}} +
+
+
+
-@endsection +@endsection \ No newline at end of file diff --git a/resources/views/informations/index.blade.php b/resources/views/informations/index.blade.php new file mode 100644 index 0000000..dc28d2e --- /dev/null +++ b/resources/views/informations/index.blade.php @@ -0,0 +1,112 @@ +@extends($viewLayout) + +@section('title', sprintf('%s - %s', transFb(sprintf('models.classes.%s', strtolower(Str::plural(class_basename($modelClass)))), Str::plural(class_basename($modelClass))), __('crud-policies::crud.viewAny'))) +@section('description', sprintf('%s %s', __('crud-policies::crud.viewAny'), trans(Str::plural(class_basename($modelClass))))) +@section('metaIndex', 'noindex,nofollow') + +@section('content') +
+ @include('crud-policies::crud.modules.flashMessage') +
+ @include('crud-policies::crud.modules.breadcrumb', ['action' => CrudAction::viewAny()]) + @include('crud-policies::crud.modules.actionbar.bar', ['action' => CrudAction::viewAny()]) +
+
+
+
+ {{ $models->links() }} +
+
+
+
+ + + + {{ __('crud-policies::crud.reset') }} + +
+
+
+
+ + + @include('crud-policies::crud.modules.sorter') + + + @if(count($models)) + + {{-- INIT QUERIES for OPTIMIZING --}} + @foreach ($modelClass::getEditableProperties() as $fieldName => $prop) + @if($prop['type']->equals(CrudType::order())) + @php ${"$modelTable$fieldName"} = $modelClass::max($fieldName); @endphp + @endif + @if($prop['type']->equals(CrudType::belongsTo())) + @php try { $models->load(Str::singular((new $prop['belongsTo']())->getTable())); } catch(\Exception $e) {} @endphp + @endif + @if($prop['type']->equals(CrudType::belongsToMany())) + @php $models->load("$fieldName"); @endphp + @endif + @endforeach + + {{-- DISPLAY MODELS --}} + @foreach($models as $model) + + @foreach ($modelClass::getEditableProperties() as $fieldName => $prop) + @if(in_array(CrudAction::viewAny(), $prop['actions'])) + @switch($prop['type']) + @case(CrudType::password()) + {{-- Ignore --}} + @break + @default + + @endswitch + @endif + @endforeach + + {{-- MODEL ACTIONS --}} + + + @endforeach + @else + + + + @endif + +
@include('crud-policies::crud.printfield', [ + 'action' => CrudAction::viewAny(), + 'field' => $model->{$fieldName}, + 'props' => $prop, + "$modelTable$fieldName" => ${"$modelTable$fieldName"} ?? null + ]) +
+ @can('view', $model) + {{ __('crud-policies::crud.view') }} + @endcan + @can('update', $model) + {{ __('crud-policies::crud.edit') }} + @endcan + @can('delete', $model) +
+ @csrf + @method('DELETE') + +
+ @endcan + @can('viewAny', \App\Models\Log::class) + {{ __('models.classes.logs') }} + @endcan + @can('viewAny', \App\Models\File::class) + {{ __('models.classes.files') }} + @endcan +
+
+ {{ __('crud-policies::crud.nothingtoshow') }} +
+ {{ $models->links() }} +
+
+@include('crud-policies::crud.modules.scriptConstants') +@endsection diff --git a/resources/views/layout/app.blade.php b/resources/views/layout/app.blade.php index 6694e30..9d5db9d 100644 --- a/resources/views/layout/app.blade.php +++ b/resources/views/layout/app.blade.php @@ -1,9 +1,10 @@ + - Support LDCWEB + Support @@ -18,16 +19,26 @@ - + @crudPoliciesCSS @stack('styles') + @include('layout.nav')
+ @auth + @foreach ($informations as $information) + + @endforeach + @endauth + @if(!isset($modelClass)) {{-- Dont use for crud-policies --}} @include('modules.flashMessage') @@ -40,12 +51,15 @@ @include('layout.footer') @stack('scriptsConstants') @include('modules.scriptConstants') - + @stack('scripts') @crudPoliciesJS() @auth {{-- JS SESSION ALERT IF SESSION TIMEOUT --}} - + @endauth - + + \ No newline at end of file diff --git a/resources/views/layout/footer.blade.php b/resources/views/layout/footer.blade.php index 655fdc7..0e34c1e 100644 --- a/resources/views/layout/footer.blade.php +++ b/resources/views/layout/footer.blade.php @@ -1,6 +1,6 @@