From 4f952a89cae331c7cc33f6058dcaf5a405b68d3e Mon Sep 17 00:00:00 2001 From: Alexis Gousseau Date: Thu, 25 Apr 2024 11:48:49 +0200 Subject: [PATCH] add text_color and published fields on the menu configuration --- .../UpdateGeneralSettingRequest.php | 73 ++- .../UpdateMenuNodeDataRequest.php | 5 + app/Lib/Definitions/MenuNode.php | 20 +- app/Models/MenuNodeData.php | 4 + database/factories/MenuNodeDataFactory.php | 1 + ...8_100253_create_general_settings_table.php | 6 - ..._11_093924_create_menu_node_data_table.php | 5 - ...105607_alter_comments_general_settings.php | 31 ++ ...5_105925_add_text_color_menu_node_data.php | 32 ++ database/seeders/MandatorySeeder.php | 4 +- resources/lang/en/validation.php | 2 + resources/lang/fr/crud.php | 2 +- resources/lang/fr/validation.php | 2 + resources/ts/bo/components/MainMenu.vue | 217 +++++---- .../bo/components/MainMenuNodeDataEditor.vue | 416 +++++++++++++----- .../ts/bo/components/MainMenuNodeEditor.vue | 126 ++++-- resources/ts/types/models/MenuNode.d.ts | 1 + resources/ts/types/models/MenuNodeData.d.ts | 1 + .../fo/layouts/main-menu/links.blade.php | 58 +-- .../main-menu/menu-nodes/breedings.blade.php | 1 + .../main-menu/menu-nodes/ourBrand.blade.php | 1 + .../menu-nodes/ourCommitments.blade.php | 1 + .../menu-nodes/ourProducts.blade.php | 1 + .../main-menu/menu-nodes/ourRecipes.blade.php | 1 + .../partials/collapse-right.blade.php | 2 +- 25 files changed, 737 insertions(+), 276 deletions(-) create mode 100644 database/migrations/2024_04_25_105607_alter_comments_general_settings.php create mode 100644 database/migrations/2024_04_25_105925_add_text_color_menu_node_data.php diff --git a/app/Http/Requests/Bo/GeneralSettings/UpdateGeneralSettingRequest.php b/app/Http/Requests/Bo/GeneralSettings/UpdateGeneralSettingRequest.php index 7ee91b74..89289479 100644 --- a/app/Http/Requests/Bo/GeneralSettings/UpdateGeneralSettingRequest.php +++ b/app/Http/Requests/Bo/GeneralSettings/UpdateGeneralSettingRequest.php @@ -2,10 +2,13 @@ namespace App\Http\Requests\Bo\GeneralSettings; +use App\Enums\Settings\MenuNodeType; use App\Enums\Settings\SettingsType; use App\Traits\Requests\HasPicture; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Support\Facades\Gate; +use Illuminate\Support\Facades\Route; +use Illuminate\Validation\Rules\Enum; class UpdateGeneralSettingRequest extends FormRequest { @@ -41,7 +44,10 @@ class UpdateGeneralSettingRequest extends FormRequest return; } $this->merge([ - 'value' => json_decode($this->input('jsonValue', '[]')) + 'value' => collect(json_decode($this->input('jsonValue', '[]'), true))->map(function ($element) { + $element['published'] = (array_key_exists('published', $element)) ? $element['published'] : false; + return $element; + })->toArray() ]); } @@ -65,11 +71,44 @@ class UpdateGeneralSettingRequest extends FormRequest $this->pictureRules('picture', 200, 100, 200, 100, false), ); } else { + /** @var array $routesName Get all front routes name */ + $routesName = collect(Route::getRoutes())->map(function ($route) { + if (preg_match('/fo.([a-zA-Z])+.([a-zA-Z])+/', $route->getName())) { + return $route->getName(); + } + })->filter()->toArray(); + + /** @var int $count Count all node published */ + $count = collect($this->value)->filter(function ($element) { + if ($element['published']) { + return $element; + } + })->count(); + return [ - 'jsonValue' => 'required|json', - 'value' => 'required' + 'jsonValue' => 'required|json', + 'value' => [ + // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed + 'present', 'array', function ($attribute, array $value, $fail) use ($count) { + if ($count > 8) { + $fail(\trans('Maximum 8 liens doivent être présents dans le menu')); + } + } + ], + 'value.*.type' => ['required', new Enum(MenuNodeType::class)], + 'value.*.published' => 'required|boolean', + 'value.*.title' => 'required|string|between:3,100', + 'value.*.link.url' => 'nullable|string|url:https', + 'value.*.link.routeName' => [ + // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed + 'nullable', 'string', function ($attribute, string $value, $fail) use ($routesName) { + if (!in_array($value, $routesName)) { + $fail(\trans('Doît être un lien front existant')); + } + } + ], ]; - } + } //end if } /** @@ -80,7 +119,31 @@ class UpdateGeneralSettingRequest extends FormRequest public function attributes(): array { return [ - 'value' => trans('validation.custom.value') + 'text' => trans('validation.attributes.text'), + 'picture' => trans('validation.attributes.image'), + 'picture_alt' => trans('validation.custom.attribute_alt'), + 'picture_title' => trans('validation.custom.attribute_title'), + 'value' => trans('validation.custom.value'), + 'value.*.type' => trans(':field :internoeud', [ + 'field' => trans('validation.custom.type'), + 'inter' => trans('validation.custom.of_the.male'), + ]), + 'value.*.published' => trans(':field :internoeud', [ + 'field' => trans('validation.custom.published'), + 'inter' => trans('validation.custom.of_the.male'), + ]), + 'value.*.title' => trans(':field :internoeud', [ + 'field' => trans('validation.attributes.title'), + 'inter' => trans('validation.custom.of_the.male'), + ]), + 'value.*.link.url' => trans(':field :internoeud', [ + 'field' => trans('validation.custom.url'), + 'inter' => trans('validation.custom.of_the.male'), + ]), + 'value.*.link.routeName' => trans(':field :internoeud', [ + 'field' => trans('validation.custom.route_name'), + 'inter' => trans('validation.custom.of_the.male'), + ]), ]; } } diff --git a/app/Http/Requests/Bo/MenuNodeData/UpdateMenuNodeDataRequest.php b/app/Http/Requests/Bo/MenuNodeData/UpdateMenuNodeDataRequest.php index f77357c6..823c66f2 100644 --- a/app/Http/Requests/Bo/MenuNodeData/UpdateMenuNodeDataRequest.php +++ b/app/Http/Requests/Bo/MenuNodeData/UpdateMenuNodeDataRequest.php @@ -5,6 +5,7 @@ namespace App\Http\Requests\Bo\MenuNodeData; use App\Traits\Requests\HasPicture; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Support\Facades\Gate; +use LVR\Colour\Hex; class UpdateMenuNodeDataRequest extends FormRequest { @@ -30,6 +31,9 @@ class UpdateMenuNodeDataRequest extends FormRequest if ($this->has('text')) { $this->merge(['text' => str($this->input('text'))->value()]); } + if ($this->has('text_color')) { + $this->merge(['text_color' => str($this->input('text_color'))->value()]); + } if ($this->has('link_target')) { $this->merge(['link_target' => $this->boolean('link_target')]); } @@ -58,6 +62,7 @@ class UpdateMenuNodeDataRequest extends FormRequest 'sub_label' => 'sometimes|required|string|min:4|max:255', 'title' => 'sometimes|required|string|min:4|max:255', 'text' => 'sometimes|required|string|max:255', + 'text_color' => ['sometimes', 'required', new Hex()], 'link_url' => 'sometimes|required|string|max:255', 'link_title' => 'sometimes|required|string|between:3,255', 'link_target' => 'sometimes|present|boolean', diff --git a/app/Lib/Definitions/MenuNode.php b/app/Lib/Definitions/MenuNode.php index e1a2ed1f..8a3722d3 100644 --- a/app/Lib/Definitions/MenuNode.php +++ b/app/Lib/Definitions/MenuNode.php @@ -6,9 +6,10 @@ use App\Enums\Settings\MenuNodeType; use App\Lib\Link; /** - * @property-read string $type The node menu type. - * @property-read string $title The node menu title. - * @property-read \App\Lib\Link $link The node menu link. + * @property-read string $type The node menu type. + * @property-read string $title The node menu title. + * @property-read \App\Lib\Link $link The node menu link. + * @property-read boolean $published The node menu publish status. * @package App\Lib\Definitions */ class MenuNode extends \stdClass @@ -22,7 +23,7 @@ class MenuNode extends \stdClass */ public function __get(string $name) { - if (in_array($name, ['type', 'title', 'link'])) { + if (in_array($name, ['type', 'title', 'link', 'published'])) { return $this->{$name}; } throw new \TypeError("undefined property {$name}"); @@ -31,13 +32,14 @@ class MenuNode extends \stdClass /** * Make and instance * - * @param integer $type The node menu type. - * @param string $title The node menu title. - * @param array $link The node menu link. + * @param integer $type The node menu type. + * @param boolean $published The node menu published. + * @param string $title The node menu title. + * @param array $link The node menu link. * @return \App\Lib\Definitions\MenuNode * @throws \RuntimeException If $type or $data is wrong. */ - public static function make(int $type, string $title, array $link): self + public static function make(int $type, bool $published, string $title, array $link): self { self::assertTypeIsCorrect($type); @@ -45,6 +47,8 @@ class MenuNode extends \stdClass // @phpstan-ignore-next-line $menuNode->type = MenuNodeType::make($type); // @phpstan-ignore-next-line + $menuNode->published = $published; + // @phpstan-ignore-next-line $menuNode->title = $title; // @phpstan-ignore-next-line $menuNode->link = new Link(...$link); diff --git a/app/Models/MenuNodeData.php b/app/Models/MenuNodeData.php index b85718a1..6c538179 100644 --- a/app/Models/MenuNodeData.php +++ b/app/Models/MenuNodeData.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Casts\HtmlColor; use App\Enums\Settings\MenuNodeType; use App\Lib\Helpers\FileStorageHelper; use App\Traits\Models\IsCachedAsCollection; @@ -13,6 +14,7 @@ use Illuminate\Database\Eloquent\Model; * @property string $sub_label (Left part) Link label. * @property string $title (Right part) Sub title. * @property string $text (Right part) Sub text. + * @property string $text_color (Right part) Sub text color. * @property string $link_url (Right part) Link url. * @property string $link_title (Right part) Link title. * @property boolean $link_target (Right part) Link target. @@ -62,6 +64,7 @@ class MenuNodeData extends Model 'sub_label', 'title', 'text', + 'text_color', 'link_url', 'link_title', 'link_target', @@ -82,6 +85,7 @@ class MenuNodeData extends Model */ protected $casts = [ 'type' => MenuNodeType::class, + 'text_color' => HtmlColor::class, 'link_target' => 'boolean', 'link_status' => 'boolean', 'picture_status' => 'boolean', diff --git a/database/factories/MenuNodeDataFactory.php b/database/factories/MenuNodeDataFactory.php index 46a92b19..7be9b8f4 100644 --- a/database/factories/MenuNodeDataFactory.php +++ b/database/factories/MenuNodeDataFactory.php @@ -17,6 +17,7 @@ class MenuNodeDataFactory extends Factory 'sub_label' => fake()->sentence(), 'title' => fake()->sentence(), 'text' => fake()->sentence(), + 'text_color' => fake()->unique()->safeHexColor(), 'link_url' => fake()->url(), 'link_title' => fake()->sentence(), 'link_target' => fake()->boolean(), diff --git a/database/migrations/2024_04_08_100253_create_general_settings_table.php b/database/migrations/2024_04_08_100253_create_general_settings_table.php index 042c0c3d..cef7ba7b 100644 --- a/database/migrations/2024_04_08_100253_create_general_settings_table.php +++ b/database/migrations/2024_04_08_100253_create_general_settings_table.php @@ -1,9 +1,7 @@ json('value')->comment('The actual setting value'); $table->timestamps(); }); - - Artisan::call('db:seed', [ - 'class' => GeneralSettingSeeder::class - ]); } /** diff --git a/database/migrations/2024_04_11_093924_create_menu_node_data_table.php b/database/migrations/2024_04_11_093924_create_menu_node_data_table.php index 19830454..5a152e38 100644 --- a/database/migrations/2024_04_11_093924_create_menu_node_data_table.php +++ b/database/migrations/2024_04_11_093924_create_menu_node_data_table.php @@ -1,9 +1,7 @@ timestamps(); }); - Artisan::call('db:seed', [ - 'class' => MenuNodeDataSeeder::class - ]); } /** diff --git a/database/migrations/2024_04_25_105607_alter_comments_general_settings.php b/database/migrations/2024_04_25_105607_alter_comments_general_settings.php new file mode 100644 index 00000000..412da96c --- /dev/null +++ b/database/migrations/2024_04_25_105607_alter_comments_general_settings.php @@ -0,0 +1,31 @@ +unsignedBigInteger('text_color')->comment('(Right part) Sub text color')->after('text'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down(): void + { + Schema::table('menu_node_data', function (Blueprint $table) { + $table->dropColumn('text_color'); + }); + } +}; diff --git a/database/seeders/MandatorySeeder.php b/database/seeders/MandatorySeeder.php index 940e12e6..34160acd 100644 --- a/database/seeders/MandatorySeeder.php +++ b/database/seeders/MandatorySeeder.php @@ -3,6 +3,7 @@ namespace Database\Seeders; use Database\Seeders\Mandatory\GeneralSettingSeeder; +use Database\Seeders\Mandatory\MenuNodeDataSeeder; use Database\Seeders\Mandatory\StaticPageSeeder; use Illuminate\Database\Seeder; @@ -17,7 +18,8 @@ class MandatorySeeder extends Seeder { $this->call([ StaticPageSeeder::class, - GeneralSettingSeeder::class + GeneralSettingSeeder::class, + MenuNodeDataSeeder::class, ]); } } diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php index 871bb9f7..d8928790 100644 --- a/resources/lang/en/validation.php +++ b/resources/lang/en/validation.php @@ -254,6 +254,7 @@ return [ 'publication' => 'publication', 'publish_at' => 'publish at', 'published' => 'published', + 'route_name' => 'name of the route', 'seo_description' => 'seo description', 'seo_title' => 'seo title', 'slug' => 'slug', @@ -262,6 +263,7 @@ return [ 'subtitle' => 'subtitle', 'sustitle' => 'sustitle', 'target' => 'target', + 'type' => 'type', 'unpublish_at' => 'unpublish at', 'unpublished' => 'unpublished', 'url' => 'url', diff --git a/resources/lang/fr/crud.php b/resources/lang/fr/crud.php index e936a952..d2670403 100644 --- a/resources/lang/fr/crud.php +++ b/resources/lang/fr/crud.php @@ -70,7 +70,7 @@ return [ 'picture_title_label' => 'Attribut du titre de l\'image', 'picture_alt_helper' => 'Doit décrire votre image pour les moteurs de recherche et les aveugles (5 à 6 mots)', 'picture_alt_label' => 'Attribut Alt de l\'image', - 'text_warning' => 'Relisez votre contenu avant de le publier', + 'text_warning' => 'Relisez votre contenu avant de le publier.', ], 'pagination' => [ diff --git a/resources/lang/fr/validation.php b/resources/lang/fr/validation.php index ed484759..1f884b8b 100644 --- a/resources/lang/fr/validation.php +++ b/resources/lang/fr/validation.php @@ -255,6 +255,7 @@ return [ 'publication' => 'publication', 'publish_at' => 'date de publication', 'published' => 'publié', + 'route_name' => 'nom de la route', 'seo_description' => 'description SEO', 'seo_title' => 'titre SEO', 'slug' => 'slug', @@ -263,6 +264,7 @@ return [ 'subtitle' => 'sous-titre', 'sustitle' => 'sous-titre', 'target' => 'cible', + 'type' => 'type', 'unpublish_at' => 'date de fin de publication', 'unpublished' => 'non publié', 'url' => 'lien', diff --git a/resources/ts/bo/components/MainMenu.vue b/resources/ts/bo/components/MainMenu.vue index 059712c9..5f702b13 100644 --- a/resources/ts/bo/components/MainMenu.vue +++ b/resources/ts/bo/components/MainMenu.vue @@ -1,55 +1,67 @@