From 543ba8fc45e75102161d182138c71f25d2c2b45e Mon Sep 17 00:00:00 2001 From: Mazarin <djaiss@users.noreply.github.com> Date: Sat, 6 May 2023 08:29:02 -0400 Subject: [PATCH] feat: edit and delete a group (monicahq/chandler#484) --- .../Web/Controllers/GroupController.php | 71 ++++++++- .../Web/ViewHelpers/GroupEditViewHelper.php | 37 +++++ .../Web/ViewHelpers/GroupShowViewHelper.php | 13 +- lang/de.json | 5 + lang/de/vault.php | 5 - lang/es.json | 5 + lang/es/vault.php | 5 - lang/fr.json | 5 + lang/fr/vault.php | 5 - lang/it.json | 5 + lang/it/vault.php | 5 - lang/pt.json | 5 + lang/pt/vault.php | 5 - lang/ru.json | 7 +- lang/ru/vault.php | 5 - resources/js/Pages/Vault/Group/Edit.vue | 149 ++++++++++++++++++ resources/js/Pages/Vault/Group/Show.vue | 71 ++++++++- routes/web.php | 3 + .../ViewHelpers/GroupEditViewHelperTest.php | 67 ++++++++ .../ViewHelpers/GroupShowViewHelperTest.php | 12 +- 20 files changed, 445 insertions(+), 40 deletions(-) create mode 100644 app/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupEditViewHelper.php delete mode 100644 lang/de/vault.php delete mode 100644 lang/es/vault.php delete mode 100644 lang/fr/vault.php delete mode 100644 lang/it/vault.php delete mode 100644 lang/pt/vault.php delete mode 100644 lang/ru/vault.php create mode 100644 resources/js/Pages/Vault/Group/Edit.vue create mode 100644 tests/Unit/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupEditViewHelperTest.php diff --git a/app/Domains/Contact/ManageGroups/Web/Controllers/GroupController.php b/app/Domains/Contact/ManageGroups/Web/Controllers/GroupController.php index 7a694260d4b..59acbf95e01 100644 --- a/app/Domains/Contact/ManageGroups/Web/Controllers/GroupController.php +++ b/app/Domains/Contact/ManageGroups/Web/Controllers/GroupController.php @@ -2,19 +2,25 @@ namespace App\Domains\Contact\ManageGroups\Web\Controllers; +use App\Domains\Contact\ManageGroups\Services\DestroyGroup; +use App\Domains\Contact\ManageGroups\Services\UpdateGroup; +use App\Domains\Contact\ManageGroups\Web\ViewHelpers\GroupEditViewHelper; use App\Domains\Contact\ManageGroups\Web\ViewHelpers\GroupIndexViewHelper; use App\Domains\Contact\ManageGroups\Web\ViewHelpers\GroupShowViewHelper; use App\Domains\Vault\ManageVault\Web\ViewHelpers\VaultIndexViewHelper; use App\Http\Controllers\Controller; use App\Models\Group; use App\Models\Vault; +use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Gate; use Inertia\Inertia; +use Inertia\Response; class GroupController extends Controller { - public function index(Request $request, string $vaultId) + public function index(Request $request, string $vaultId): Response { $vault = Vault::findOrFail($vaultId); @@ -24,7 +30,7 @@ public function index(Request $request, string $vaultId) ]); } - public function show(Request $request, string $vaultId, int $groupId) + public function show(Request $request, string $vaultId, int $groupId): Response { $vault = Vault::findOrFail($vaultId); $group = Group::with([ @@ -34,7 +40,66 @@ public function show(Request $request, string $vaultId, int $groupId) return Inertia::render('Vault/Group/Show', [ 'layoutData' => VaultIndexViewHelper::layoutData($vault), - 'data' => GroupShowViewHelper::data($group, Auth::user()), + 'data' => GroupShowViewHelper::data($group), ]); } + + public function edit(Request $request, string $vaultId, int $groupId): Response + { + Gate::authorize('vault-editor', $vaultId); + + $vault = Vault::findOrFail($vaultId); + $group = Group::with([ + 'contacts', + 'groupType', + ])->findOrFail($groupId); + + return Inertia::render('Vault/Group/Edit', [ + 'layoutData' => VaultIndexViewHelper::layoutData($vault), + 'data' => GroupEditViewHelper::data($group), + ]); + } + + public function update(Request $request, string $vaultId, string $groupId) + { + Gate::authorize('vault-editor', $vaultId); + + $data = [ + 'account_id' => Auth::user()->account_id, + 'vault_id' => $vaultId, + 'author_id' => Auth::id(), + 'group_id' => $groupId, + 'group_type_id' => $request->input('group_type_id'), + 'name' => $request->input('name'), + ]; + + $group = (new UpdateGroup())->execute($data); + + return response()->json([ + 'data' => route('group.show', [ + 'vault' => $vaultId, + 'group' => $group, + ]), + ], 200); + } + + public function destroy(Request $request, string $vaultId, string $groupId): JsonResponse + { + Gate::authorize('vault-editor', $vaultId); + + $data = [ + 'account_id' => Auth::user()->account_id, + 'vault_id' => $vaultId, + 'author_id' => Auth::id(), + 'group_id' => $groupId, + ]; + + (new DestroyGroup())->execute($data); + + return response()->json([ + 'data' => route('group.index', [ + 'vault' => $vaultId, + ]), + ], 200); + } } diff --git a/app/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupEditViewHelper.php b/app/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupEditViewHelper.php new file mode 100644 index 00000000000..f5749c8417f --- /dev/null +++ b/app/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupEditViewHelper.php @@ -0,0 +1,37 @@ +<?php + +namespace App\Domains\Contact\ManageGroups\Web\ViewHelpers; + +use App\Models\Group; +use App\Models\GroupType; + +class GroupEditViewHelper +{ + public static function data(Group $group): array + { + $groupTypes = $group->vault->account->groupTypes() + ->orderBy('position') + ->get() + ->map(fn (GroupType $groupType) => [ + 'id' => $groupType->id, + 'name' => $groupType->label, + ]); + + return [ + 'id' => $group->id, + 'name' => $group->name, + 'group_type_id' => $group->group_type_id, + 'group_types' => $groupTypes, + 'url' => [ + 'back' => route('group.show', [ + 'vault' => $group->vault_id, + 'group' => $group->id, + ]), + 'update' => route('group.update', [ + 'vault' => $group->vault_id, + 'group' => $group->id, + ]), + ], + ]; + } +} diff --git a/app/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupShowViewHelper.php b/app/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupShowViewHelper.php index d379cf6b40c..251c3f9df64 100644 --- a/app/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupShowViewHelper.php +++ b/app/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupShowViewHelper.php @@ -5,7 +5,6 @@ use App\Models\Contact; use App\Models\Group; use App\Models\GroupTypeRole; -use App\Models\User; class GroupShowViewHelper { @@ -16,7 +15,7 @@ class GroupShowViewHelper * So we need to group contacts by roles if they exist, or list them * alphabetically otherwise. */ - public static function data(Group $group, User $user): array + public static function data(Group $group): array { $rolesCollection = $group->groupType->groupTypeRoles() ->orderBy('position') @@ -75,6 +74,16 @@ public static function data(Group $group, User $user): array 'label' => $group->groupType->label, ], 'roles' => $rolesCollection, + 'url' => [ + 'edit' => route('group.edit', [ + 'vault' => $group->vault_id, + 'group' => $group->id, + ]), + 'destroy' => route('group.destroy', [ + 'vault' => $group->vault_id, + 'group' => $group->id, + ]), + ], ]; } } diff --git a/lang/de.json b/lang/de.json index 830ffc3a9b9..bfd4ff0a204 100644 --- a/lang/de.json +++ b/lang/de.json @@ -347,6 +347,7 @@ "deleted a note": "hat eine Notiz gelöscht", "deleted a pet": "hat ein Haustier gelöscht", "Deleted author": "Autor gelöscht", + "Delete group": "Gruppe löschen", "Delete journal": "Tagebuch löschen", "Delete Team": "Team löschen", "Delete the address": "Adresse löschen", @@ -379,6 +380,7 @@ "Edit a journal": "Ein Journal bearbeiten", "Edit a post": "Beitrag bearbeiten", "edited a note": "hat eine Notiz bearbeitet", + "Edit group": "Gruppe bearbeiten", "Edit journal": "Tagebuch bearbeiten", "Edit journal information": "Tagebuchinformationen bearbeiten", "Edit journal metrics": "Tagebuch-Metriken bearbeiten", @@ -388,6 +390,7 @@ "Edit post": "Beitrag bearbeiten", "Edit Profile": "Profil bearbeiten", "Edit slice of life": "Schnitzel des Lebens bearbeiten", + "Edit the group": "Die Gruppe bearbeiten", "Edit the slice of life": "Das Schnitzel des Lebens bearbeiten", "Email": "E-Mail", "Email address": "E-Mail-Adresse", @@ -921,6 +924,8 @@ "The goal has been deleted": "Das Ziel wurde gelöscht", "The goal has been edited": "Das Ziel wurde bearbeitet", "The group has been added": "Die Gruppe wurde hinzugefügt", + "The group has been deleted": "Die Gruppe wurde gelöscht", + "The group has been updated": "Die Gruppe wurde aktualisiert", "The group type has been created": "Der Gruppentyp wurde erstellt", "The group type has been deleted": "Der Gruppentyp wurde gelöscht", "The group type has been updated": "Der Gruppentyp wurde aktualisiert", diff --git a/lang/de/vault.php b/lang/de/vault.php deleted file mode 100644 index 3a8fc529724..00000000000 --- a/lang/de/vault.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php - -return [ - 'journal_number_posts' => '', -]; diff --git a/lang/es.json b/lang/es.json index 508ca1cad45..ca73de095dd 100644 --- a/lang/es.json +++ b/lang/es.json @@ -347,6 +347,7 @@ "deleted a note": "eliminó una nota", "deleted a pet": "eliminó una mascota", "Deleted author": "Autor eliminado", + "Delete group": "Eliminar grupo", "Delete journal": "Eliminar diario", "Delete Team": "Borrar equipo", "Delete the address": "Eliminar la dirección", @@ -379,6 +380,7 @@ "Edit a journal": "Editar un diario", "Edit a post": "Editar una publicación.", "edited a note": "editó una nota", + "Edit group": "Editar grupo", "Edit journal": "Editar diario", "Edit journal information": "Editar información del diario", "Edit journal metrics": "Editar métricas del diario", @@ -388,6 +390,7 @@ "Edit post": "Editar publicación.", "Edit Profile": "Editar perfil", "Edit slice of life": "Editar fragmento de vida.", + "Edit the group": "Editar el grupo", "Edit the slice of life": "Editar el fragmento de vida.", "Email": "Correo electrónico", "Email address": "Dirección de correo electrónico", @@ -921,6 +924,8 @@ "The goal has been deleted": "La meta ha sido eliminada", "The goal has been edited": "La meta ha sido editada", "The group has been added": "El grupo ha sido añadido", + "The group has been deleted": "El grupo ha sido eliminado", + "The group has been updated": "El grupo ha sido actualizado", "The group type has been created": "El tipo de grupo ha sido creado", "The group type has been deleted": "El tipo de grupo ha sido eliminado", "The group type has been updated": "El tipo de grupo ha sido actualizado", diff --git a/lang/es/vault.php b/lang/es/vault.php deleted file mode 100644 index 3a8fc529724..00000000000 --- a/lang/es/vault.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php - -return [ - 'journal_number_posts' => '', -]; diff --git a/lang/fr.json b/lang/fr.json index b38057c5b41..34170d6f7e7 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -347,6 +347,7 @@ "deleted a note": "a supprimé une note", "deleted a pet": "a supprimé un animal de compagnie", "Deleted author": "Auteur supprimé", + "Delete group": "Supprimer le groupe", "Delete journal": "Supprimer le journal", "Delete Team": "Supprimer l’équipe", "Delete the address": "Supprimer l’adresse", @@ -379,6 +380,7 @@ "Edit a journal": "Modifier un journal", "Edit a post": "Modifier une publication", "edited a note": "a modifié une note", + "Edit group": "Modifier le groupe", "Edit journal": "Modifier le journal", "Edit journal information": "Modifier les informations du journal", "Edit journal metrics": "Modifier les métriques du journal", @@ -388,6 +390,7 @@ "Edit post": "Modifier la publication", "Edit Profile": "Éditer le profil", "Edit slice of life": "Modifier la tranche de vie", + "Edit the group": "Modifier le groupe", "Edit the slice of life": "Modifier la tranche de vie", "Email": "E-mail", "Email address": "Adresse email", @@ -921,6 +924,8 @@ "The goal has been deleted": "L’objectif a été supprimé", "The goal has been edited": "L’objectif a été modifié", "The group has been added": "Le groupe a été ajouté", + "The group has been deleted": "Le groupe a été supprimé", + "The group has been updated": "Le groupe a été mis à jour", "The group type has been created": "Le type de groupe a été créé", "The group type has been deleted": "Le type de groupe a été supprimé", "The group type has been updated": "Le type de groupe a été mis à jour", diff --git a/lang/fr/vault.php b/lang/fr/vault.php deleted file mode 100644 index 3a8fc529724..00000000000 --- a/lang/fr/vault.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php - -return [ - 'journal_number_posts' => '', -]; diff --git a/lang/it.json b/lang/it.json index 69c7367da96..f6874565c3b 100644 --- a/lang/it.json +++ b/lang/it.json @@ -347,6 +347,7 @@ "deleted a note": "ha eliminato una nota", "deleted a pet": "ha eliminato un animale domestico", "Deleted author": "Autore eliminato", + "Delete group": "Elimina gruppo", "Delete journal": "Elimina diario", "Delete Team": "Elimina Team", "Delete the address": "Elimina l'indirizzo", @@ -379,6 +380,7 @@ "Edit a journal": "Modifica un diario", "Edit a post": "Modifica un post", "edited a note": "ha modificato una nota", + "Edit group": "Modifica gruppo", "Edit journal": "Modifica diario", "Edit journal information": "Modifica informazioni diario", "Edit journal metrics": "Modifica metriche diario", @@ -388,6 +390,7 @@ "Edit post": "Modifica post", "Edit Profile": "Modifica Profilo", "Edit slice of life": "Modifica pezzo di vita", + "Edit the group": "Modifica il gruppo", "Edit the slice of life": "Modifica il pezzo di vita", "Email": "Email", "Email address": "Indirizzo email", @@ -921,6 +924,8 @@ "The goal has been deleted": "L'obiettivo è stato eliminato", "The goal has been edited": "L'obiettivo è stato modificato", "The group has been added": "Il gruppo è stato aggiunto", + "The group has been deleted": "Il gruppo è stato eliminato", + "The group has been updated": "Il gruppo è stato aggiornato", "The group type has been created": "Il tipo di gruppo è stato creato.", "The group type has been deleted": "Il tipo di gruppo è stato eliminato.", "The group type has been updated": "Il tipo di gruppo è stato aggiornato.", diff --git a/lang/it/vault.php b/lang/it/vault.php deleted file mode 100644 index 3a8fc529724..00000000000 --- a/lang/it/vault.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php - -return [ - 'journal_number_posts' => '', -]; diff --git a/lang/pt.json b/lang/pt.json index ca1f455afaa..d43188ab776 100644 --- a/lang/pt.json +++ b/lang/pt.json @@ -347,6 +347,7 @@ "deleted a note": "excluiu uma nota", "deleted a pet": "excluiu um animal de estimação", "Deleted author": "Autor excluído", + "Delete group": "Excluir grupo", "Delete journal": "Excluir diário", "Delete Team": "Eliminar Equipa", "Delete the address": "Excluir o endereço", @@ -379,6 +380,7 @@ "Edit a journal": "Editar um diário", "Edit a post": "Editar um post", "edited a note": "editou uma nota", + "Edit group": "Editar grupo", "Edit journal": "Editar diário", "Edit journal information": "Editar informações do diário", "Edit journal metrics": "Editar métricas do diário", @@ -388,6 +390,7 @@ "Edit post": "Editar post", "Edit Profile": "Editar Perfil", "Edit slice of life": "Editar pedacinho da vida", + "Edit the group": "Editar o grupo", "Edit the slice of life": "Editar o pedacinho da vida", "Email": "E-mail", "Email address": "Endereço de email", @@ -921,6 +924,8 @@ "The goal has been deleted": "A meta foi excluída", "The goal has been edited": "A meta foi editada", "The group has been added": "O grupo foi adicionado", + "The group has been deleted": "O grupo foi excluído", + "The group has been updated": "O grupo foi atualizado", "The group type has been created": "O tipo de grupo foi criado", "The group type has been deleted": "O tipo de grupo foi excluído", "The group type has been updated": "O tipo de grupo foi atualizado", diff --git a/lang/pt/vault.php b/lang/pt/vault.php deleted file mode 100644 index 3a8fc529724..00000000000 --- a/lang/pt/vault.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php - -return [ - 'journal_number_posts' => '', -]; diff --git a/lang/ru.json b/lang/ru.json index c8e66462d82..2b2b89e370e 100644 --- a/lang/ru.json +++ b/lang/ru.json @@ -24,7 +24,7 @@ "+ pronoun": "+ местоимение", "+ suffix": "+ суффикс", ":count contact|:count contacts": ":count контакт|:count контакта|:count контактов", - ":count hours slept": "", + ":count hours slept": ":count часов сна", ":count min read": ":count мин чтения|:count мин чтения|:count мин чтения", ":count post|:count posts": ":count пост|:count поста|:count постов", ":count template section|:count template sections": ":count раздел шаблона|:count раздела шаблона|:count разделов шаблона", @@ -347,6 +347,7 @@ "deleted a note": "Удалена заметка", "deleted a pet": "Удален питомец", "Deleted author": "Удален автор", + "Delete group": "Удалить группу", "Delete journal": "Удалить журнал", "Delete Team": "Удалить команду", "Delete the address": "Удалить адрес", @@ -379,6 +380,7 @@ "Edit a journal": "Редактировать журнал", "Edit a post": "Редактировать пост", "edited a note": "отредактирована заметка", + "Edit group": "Редактировать группу", "Edit journal": "Редактировать журнал", "Edit journal information": "Редактировать информацию журнала", "Edit journal metrics": "Редактировать метрики журнала", @@ -388,6 +390,7 @@ "Edit post": "Редактировать пост", "Edit Profile": "Редактировать профиль", "Edit slice of life": "Редактировать ломтик жизни", + "Edit the group": "Редактировать группу", "Edit the slice of life": "Редактировать ломтик жизни", "Email": "E-Mail адрес", "Email address": "Адрес электронной почты", @@ -921,6 +924,8 @@ "The goal has been deleted": "Цель была удалена", "The goal has been edited": "Цель была изменена", "The group has been added": "Группа была добавлена", + "The group has been deleted": "Группа была удалена", + "The group has been updated": "Группа была обновлена", "The group type has been created": "Тип группы был создан", "The group type has been deleted": "Тип группы был удален", "The group type has been updated": "Тип группы был обновлен", diff --git a/lang/ru/vault.php b/lang/ru/vault.php deleted file mode 100644 index 3a8fc529724..00000000000 --- a/lang/ru/vault.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php - -return [ - 'journal_number_posts' => '', -]; diff --git a/resources/js/Pages/Vault/Group/Edit.vue b/resources/js/Pages/Vault/Group/Edit.vue new file mode 100644 index 00000000000..a5ebbb9bd83 --- /dev/null +++ b/resources/js/Pages/Vault/Group/Edit.vue @@ -0,0 +1,149 @@ +<script setup> +import Layout from '@/Shared/Layout.vue'; +import { Inertia } from '@inertiajs/inertia'; +import { useForm } from '@inertiajs/inertia-vue3'; +import PrettyLink from '@/Shared/Form/PrettyLink.vue'; +import PrettyButton from '@/Shared/Form/PrettyButton.vue'; +import TextInput from '@/Shared/Form/TextInput.vue'; +import Dropdown from '@/Shared/Form/Dropdown.vue'; +import Errors from '@/Shared/Form/Errors.vue'; +import { onMounted, nextTick, ref } from 'vue'; +import { trans } from 'laravel-vue-i18n'; + +const props = defineProps({ + layoutData: Object, + data: Object, +}); + +const form = useForm({ + name: '', + group_type_id: 0, + errors: [], +}); + +const loadingState = ref(null); +const nameField = ref(null); + +onMounted(() => { + form.name = props.data.name; + form.group_type_id = props.data.group_type_id; + + nextTick(() => { + nameField.value.focus(); + }); +}); + +const update = () => { + loadingState.value = 'loading'; + + axios + .put(props.data.url.update, form) + .then((response) => { + loadingState.value = null; + localStorage.success = trans('The group has been updated'); + Inertia.visit(response.data.data); + }) + .catch((error) => { + form.errors = error.response.data; + loadingState.value = null; + }); +}; +</script> + +<template> + <layout :layout-data="layoutData" :inside-vault="true"> + <!-- breadcrumb --> + <nav class="bg-white dark:bg-gray-900 sm:mt-20 sm:border-b"> + <div class="max-w-8xl mx-auto hidden px-4 py-2 sm:px-6 md:block"> + <div class="flex items-baseline justify-between space-x-6"> + <ul class="text-sm"> + <li class="mr-2 inline text-gray-600 dark:text-gray-400"> + {{ $t('You are here:') }} + </li> + <li class="mr-2 inline"> + <inertia-link :href="data.url.back" class="text-blue-500 hover:underline"> + {{ $t('Groups') }} + </inertia-link> + </li> + <li class="relative mr-2 inline"> + <svg + xmlns="http://www.w3.org/2000/svg" + class="icon-breadcrumb relative inline h-3 w-3" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor"> + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /> + </svg> + </li> + <li class="mr-2 inline"> + <inertia-link :href="data.url.back" class="text-blue-500 hover:underline">{{ data.name }}</inertia-link> + </li> + <li class="relative mr-2 inline"> + <svg + xmlns="http://www.w3.org/2000/svg" + class="icon-breadcrumb relative inline h-3 w-3" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor"> + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /> + </svg> + </li> + <li class="inline">{{ $t('Edit group') }}</li> + </ul> + </div> + </div> + </nav> + + <main class="relative sm:mt-16"> + <div class="mx-auto max-w-lg px-2 py-2 sm:px-6 sm:py-6 lg:px-8"> + <form + class="mb-6 rounded-lg border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900" + @submit.prevent="update()"> + <div class="section-head border-b border-gray-200 bg-blue-50 p-5 dark:border-gray-700 dark:bg-blue-900"> + <h1 class="text-center text-2xl font-medium"> + {{ $t('Edit the group') }} + </h1> + </div> + <errors :errors="form.errors" /> + + <!-- name --> + <div class="border-b border-gray-200 p-5 dark:border-gray-700"> + <text-input + v-model="form.name" + :ref="'nameField'" + :autofocus="true" + :div-outer-class="'mb-5'" + :input-class="'block w-full'" + :required="true" + :maxlength="255" + :label="$t('Name')" /> + </div> + + <!-- group type --> + <div class="border-b border-gray-200 p-5 dark:border-gray-700"> + <dropdown + v-model="form.group_type_id" + :data="props.data.group_types" + :required="true" + :placeholder="$t('Choose a value')" + :dropdown-class="'block w-full'" + :label="$t('Group type')" /> + </div> + + <!-- actions --> + <div class="flex justify-between p-5"> + <pretty-link :href="props.data.url.back" :text="$t('Cancel')" :classes="'mr-3'" /> + <pretty-button :text="$t('Save')" :state="loadingState" :icon="'check'" :classes="'save'" /> + </div> + </form> + </div> + </main> + </layout> +</template> + +<style lang="scss" scoped> +.section-head { + border-top-left-radius: 7px; + border-top-right-radius: 7px; +} +</style> diff --git a/resources/js/Pages/Vault/Group/Show.vue b/resources/js/Pages/Vault/Group/Show.vue index 1e2a802ba59..f2a6bff3e75 100644 --- a/resources/js/Pages/Vault/Group/Show.vue +++ b/resources/js/Pages/Vault/Group/Show.vue @@ -1,11 +1,39 @@ <script setup> +import { ref, reactive } from 'vue'; import Layout from '@/Shared/Layout.vue'; import Avatar from '@/Shared/Avatar.vue'; +import { Inertia } from '@inertiajs/inertia'; +import { trans } from 'laravel-vue-i18n'; +import JetConfirmationModal from '@/Components/Jetstream/ConfirmationModal.vue'; +import JetDangerButton from '@/Components/Jetstream/DangerButton.vue'; +import JetSecondaryButton from '@/Components/Jetstream/SecondaryButton.vue'; -defineProps({ +const props = defineProps({ layoutData: Object, data: Object, }); + +const deletingGroup = ref(false); +const deleteGroupForm = reactive({ + processing: false, +}); + +const destroy = () => { + deleteGroupForm.processing = true; + + axios + .delete(props.data.url.destroy) + .then((response) => { + deleteGroupForm.processing = false; + + localStorage.success = trans('The group has been deleted'); + Inertia.visit(response.data.data); + }) + .catch((error) => { + deleteGroupForm.processing = false; + form.errors = error.response.data; + }); +}; </script> <template> @@ -69,7 +97,7 @@ defineProps({ </div> <!-- type --> - <div class="flex items-center"> + <div class="mr-8 flex items-center"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" @@ -85,6 +113,20 @@ defineProps({ <p class="text-center text-gray-600">{{ $t('Group type: :name', { name: data.type.label }) }}</p> </div> + + <!-- actions --> + <div class="flex items-center"> + <ul class="list"> + <li class="mr-4 inline"> + <inertia-link :href="props.data.url.edit" class="text-blue-500 hover:underline">{{ + $t('Edit') + }}</inertia-link> + </li> + <li class="inline" @click="deletingGroup = true"> + <span class="inline cursor-pointer text-red-500 hover:text-red-900">{{ $t('Delete') }}</span> + </li> + </ul> + </div> </div> <!-- contacts by roles --> @@ -108,6 +150,31 @@ defineProps({ </div> </div> </div> + + <!-- Delete Contact Confirmation Modal --> + <JetConfirmationModal :show="deletingGroup" @close="deletingGroup = false"> + <template #title> + {{ $t('Delete group') }} + </template> + + <template #content> + {{ $t('Are you sure? This action cannot be undone.') }} + </template> + + <template #footer> + <JetSecondaryButton @click="deletingGroup = false"> + {{ $t('Cancel') }} + </JetSecondaryButton> + + <JetDangerButton + class="ml-3" + :class="{ 'opacity-25': deleteGroupForm.processing }" + :disabled="deleteGroupForm.processing" + @click="destroy"> + {{ $t('Delete') }} + </JetDangerButton> + </template> + </JetConfirmationModal> </div> </main> </layout> diff --git a/routes/web.php b/routes/web.php index 5ea072ef082..664f75cbbbc 100644 --- a/routes/web.php +++ b/routes/web.php @@ -385,6 +385,9 @@ Route::get('groups', [GroupController::class, 'index'])->name('group.index'); Route::middleware('can:group-owner,vault,group')->prefix('groups')->group(function () { Route::get('{group}', [GroupController::class, 'show'])->name('group.show'); + Route::get('{group}/edit', [GroupController::class, 'edit'])->name('group.edit'); + Route::put('{group}', [GroupController::class, 'update'])->name('group.update'); + Route::delete('{group}', [GroupController::class, 'destroy'])->name('group.destroy'); }); // journal page diff --git a/tests/Unit/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupEditViewHelperTest.php b/tests/Unit/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupEditViewHelperTest.php new file mode 100644 index 00000000000..86c38986894 --- /dev/null +++ b/tests/Unit/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupEditViewHelperTest.php @@ -0,0 +1,67 @@ +<?php + +namespace Tests\Unit\Domains\Contact\ManageGroups\Web\ViewHelpers; + +use App\Domains\Contact\ManageGroups\Web\ViewHelpers\GroupEditViewHelper; +use App\Models\Contact; +use App\Models\Group; +use App\Models\GroupType; +use Illuminate\Foundation\Testing\DatabaseTransactions; +use Tests\TestCase; + +class GroupEditViewHelperTest extends TestCase +{ + use DatabaseTransactions; + + /** @test */ + public function it_gets_the_data_needed_for_the_view(): void + { + $contact = Contact::factory()->create(); + $groupType = GroupType::factory()->create([ + 'account_id' => $contact->vault->account_id, + ]); + $group = Group::factory()->create([ + 'vault_id' => $contact->vault_id, + 'group_type_id' => $groupType->id, + ]); + $array = GroupEditViewHelper::data($group); + + $this->assertCount( + 5, + $array + ); + + $this->assertEquals( + $group->id, + $array['id'] + ); + + $this->assertEquals( + $group->name, + $array['name'] + ); + + $this->assertEquals( + $groupType->id, + $array['group_type_id'] + ); + + $this->assertEquals( + [ + 0 => [ + 'id' => $groupType->id, + 'name' => $groupType->label, + ], + ], + $array['group_types']->toArray() + ); + + $this->assertEquals( + [ + 'back' => env('APP_URL').'/vaults/'.$contact->vault->id.'/groups/'.$group->id, + 'update' => env('APP_URL').'/vaults/'.$contact->vault->id.'/groups/'.$group->id, + ], + $array['url'] + ); + } +} diff --git a/tests/Unit/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupShowViewHelperTest.php b/tests/Unit/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupShowViewHelperTest.php index 835fad910a0..2ffd0815494 100644 --- a/tests/Unit/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupShowViewHelperTest.php +++ b/tests/Unit/Domains/Contact/ManageGroups/Web/ViewHelpers/GroupShowViewHelperTest.php @@ -39,10 +39,10 @@ public function it_gets_all_the_groups_associated_with_the_contact(): void $otherContact->id => ['group_type_role_id' => $sisterRole->id], ]); - $array = GroupShowViewHelper::data($group, $user); + $array = GroupShowViewHelper::data($group); $this->assertCount( - 5, + 6, $array ); @@ -60,5 +60,13 @@ public function it_gets_all_the_groups_associated_with_the_contact(): void 2, $array['contact_count'] ); + + $this->assertEquals( + [ + 'edit' => env('APP_URL').'/vaults/'.$contact->vault->id.'/groups/'.$group->id.'/edit', + 'destroy' => env('APP_URL').'/vaults/'.$contact->vault->id.'/groups/'.$group->id, + ], + $array['url'] + ); } }