From 8388c2ccc6caf81c40c4a2294245e61682d9d3b2 Mon Sep 17 00:00:00 2001 From: Michel <michel@iedsoftworks.com> Date: Fri, 15 Nov 2024 13:41:52 +0100 Subject: [PATCH] Adds delete option --- src/js/pages/keys/index.ts | 5 ++ src/js/pages/keys/modals/delete.ts | 42 ++++++++++++++ src/js/pages/keys/modals/edit.ts | 18 ++++++ src/php/Routing/Api/Web/DeleteKeyList.php | 70 +++++++++++++++++++++++ src/php/Routing/Api/Web/WebAPIRoutes.php | 1 + src/templates/pages/key-manager.php | 69 ++++++++++++++++++++-- 6 files changed, 199 insertions(+), 6 deletions(-) create mode 100644 src/js/pages/keys/modals/delete.ts create mode 100644 src/js/pages/keys/modals/edit.ts create mode 100644 src/php/Routing/Api/Web/DeleteKeyList.php diff --git a/src/js/pages/keys/index.ts b/src/js/pages/keys/index.ts index b22fecc..f1b3d0d 100644 --- a/src/js/pages/keys/index.ts +++ b/src/js/pages/keys/index.ts @@ -7,6 +7,8 @@ import {init as initImport} from "./import"; import {init as initTable} from "./table"; import {init as initUserLists} from "./userlists"; import {initShare} from "./share"; +import {init as initEditModal} from "./modals/edit"; +import {init as initDeleteModal} from "./modals/delete"; document.addEventListener('DOMContentLoaded', () => { const triggerTabList = document.querySelectorAll('#key-tab button') @@ -23,4 +25,7 @@ document.addEventListener('DOMContentLoaded', () => { initTable(); initUserLists(); initShare(); + + initEditModal(); + initDeleteModal(); }) \ No newline at end of file diff --git a/src/js/pages/keys/modals/delete.ts b/src/js/pages/keys/modals/delete.ts new file mode 100644 index 0000000..24286c8 --- /dev/null +++ b/src/js/pages/keys/modals/delete.ts @@ -0,0 +1,42 @@ +import {getCurrentlySelectedList} from "../userlists"; + +export function init() { + const modalElem = document.querySelector<HTMLDivElement>('#delete-list-modal'); + + if (!modalElem) { + return; + } + + modalElem.addEventListener('show.bs.modal', () => { + const listSelect = document.querySelector<HTMLSelectElement>('#list-select'); + const text = listSelect?.selectedOptions[0].text ?? ''; + + const listnameElem = modalElem.querySelector<HTMLSpanElement>('.list-name'); + if (!listnameElem) { + return; + } + listnameElem.textContent = text; + }) + + modalElem.querySelector<HTMLButtonElement>('.js--yes') + ?.addEventListener('click', async () => { + const id = getCurrentlySelectedList(); + + const formData = new FormData(); + formData.append('id', id?.toString() ?? '-1'); + + const response = await fetch( + `/api/web/keys/list/delete`, + { + method: 'POST', + body: formData + } + ); + + if (!response.ok) { + throw new Error(response.statusText); + } + + window.location.reload(); + }) +} diff --git a/src/js/pages/keys/modals/edit.ts b/src/js/pages/keys/modals/edit.ts new file mode 100644 index 0000000..6c79cee --- /dev/null +++ b/src/js/pages/keys/modals/edit.ts @@ -0,0 +1,18 @@ +export function init() { + const modalElem = document.querySelector<HTMLDivElement>('#edit-list-modal'); + + if (!modalElem) { + return; + } + + modalElem.addEventListener('show.bs.modal', () => { + const listSelect = document.querySelector<HTMLSelectElement>('#list-select'); + const text = listSelect?.selectedOptions[0].text ?? ''; + + const listnameElem = modalElem.querySelector<HTMLSpanElement>('.list-name'); + if (!listnameElem) { + return; + } + listnameElem.textContent = text; + }) +} \ No newline at end of file diff --git a/src/php/Routing/Api/Web/DeleteKeyList.php b/src/php/Routing/Api/Web/DeleteKeyList.php new file mode 100644 index 0000000..db550cb --- /dev/null +++ b/src/php/Routing/Api/Web/DeleteKeyList.php @@ -0,0 +1,70 @@ +<?php declare(strict_types=1); + +namespace GamesShop\Routing\Api\Web; + +use Doctrine\ORM\EntityManager; +use GamesShop\Entities\Games\Key; +use GamesShop\Entities\GamesList; +use GamesShop\Login\LoginHandler; +use GamesShop\Login\UserPermission; +use Laminas\Diactoros\Response; +use League\Route\Http\Exception\BadRequestException; +use League\Route\Http\Exception\ForbiddenException; +use League\Route\Http\Exception\UnauthorizedException; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; + +final class DeleteKeyList +{ + + public function __construct( + private readonly LoginHandler $loginHandler, + private readonly EntityManager $entityManager + ) + { + } + + public function __invoke(ServerRequestInterface $request): ResponseInterface + { + if (!$this->loginHandler->isLoggedIn()) { + throw new UnauthorizedException(); + } + + $user = $this->loginHandler->getCurrentUser(); + if (!$user->getPermission()->hasLevel(UserPermission::PROVIDER)) { + throw new ForbiddenException(); + } + + $body = $request->getParsedBody(); + if (!array_key_exists('id', $body)) { + throw new BadRequestException(); + } + + $id = $body['id']; + $list = $this->entityManager->getRepository(GamesList::class)->findOneBy( + [ + 'id' => $id, + 'owner' => $user, + ] + ); + + if ($list === null) { + throw new BadRequestException(); + } + + $this->entityManager->remove($list); + + $keys = $this->entityManager->getRepository(Key::class)->findBy( + [ + 'list' => $list + ] + ); + foreach ($keys as $key) { + $this->entityManager->remove($key); + } + + $this->entityManager->flush(); + + return new Response(); + } +} \ No newline at end of file diff --git a/src/php/Routing/Api/Web/WebAPIRoutes.php b/src/php/Routing/Api/Web/WebAPIRoutes.php index 02f2033..66347f4 100644 --- a/src/php/Routing/Api/Web/WebAPIRoutes.php +++ b/src/php/Routing/Api/Web/WebAPIRoutes.php @@ -14,6 +14,7 @@ final class WebAPIRoutes $group->post('/keys/import/perform', ImportKeysRoute::class); $group->post('/keys/list/create', CreateKeyListRoute::class); + $group->post('/keys/list/delete',DeleteKeyList::class); $group->get('/share/search', SearchForUsers::class); $group->post('/share/add', AddUserToList::class); diff --git a/src/templates/pages/key-manager.php b/src/templates/pages/key-manager.php index 4182414..0248605 100644 --- a/src/templates/pages/key-manager.php +++ b/src/templates/pages/key-manager.php @@ -19,12 +19,17 @@ $this->layout('layout/main', [ 'resourceEntry' => 'keys' ]); </div> <div class="col-sm-6 align-self-center"> <?php if (!empty($usersLists)): ?> - <select name="lists" id="list-select" class="form-select w-100"> - <?php foreach ($usersLists as $list): ?> - <option value="<?= $list->getId() ?>"><?= $list->getName() ?></option> - <?php endforeach; ?> - <option value="_create">+ Create New</option> - </select> + <div class="input-group w-100"> + <select name="lists" id="list-select" class="form-select"> + <?php foreach ($usersLists as $list): ?> + <option value="<?= $list->getId() ?>"><?= $list->getName() ?></option> + <?php endforeach; ?> + <option value="_create">+ Create New</option> + </select> + <button class="btn btn-outline-secondary" data-bs-target="#edit-list-modal" data-bs-toggle="modal"> + <i class="fa-solid fa-gear"></i> + </button> + </div> <?php endif; ?> </div> </div> @@ -151,4 +156,56 @@ $this->layout('layout/main', [ 'resourceEntry' => 'keys' ]); </div> </div> +<div class="modal" id="edit-list-modal"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <h1 class="modal-title h3"> + Edit <span class="list-name"></span> + </h1> + </div> + <div class="modal-body"> + <h2 class="h4 mt-2"> + Actions + </h2> + <button data-bs-toggle="modal" data-bs-target="#delete-list-modal" class="w-100 btn btn-danger">Delete List</button> + </div> + <div class="modal-footer"> + <button data-bs-dismiss="modal" class="flex-grow-1 btn btn-primary"> + Save + </button> + </div> + </div> + </div> +</div> + + +<div class="modal" id="delete-list-modal"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <h1 class="modal-title h3"> + Delete <span class="list-name"></span>? + </h1> + </div> + <div class="modal-body"> + <p> + Are you <b>sure</b> you want to <b class="text-danger">delete</b> this list? + </p> + <p> + Deleting this will remove all the keys you added from the database. + </p> + </div> + <div class="modal-footer"> + <button data-bs-dismiss="modal" class="flex-grow-1 btn btn-outline-primary"> + Cancel + </button> + <button data-bs-dismiss="modal" class="js--yes flex-grow-1 btn btn-danger"> + Yes + </button> + </div> + </div> + </div> +</div> + <?php $this->end() ?>