diff --git a/assets/controllers/vocabs_controller.js b/assets/controllers/vocabs_controller.js new file mode 100644 index 0000000..310925e --- /dev/null +++ b/assets/controllers/vocabs_controller.js @@ -0,0 +1,74 @@ +import { Controller } from '@hotwired/stimulus'; + +export default class extends Controller { + static targets = [ + 'row', + 'term', + 'input', + 'save', + 'edit', + 'cancel', + ]; + + static values = { + saveUrl: String, + }; + + /** + * @todo Simpler way? + */ + edit(event) { + const id = event.currentTarget.getAttribute('data-vocabs-id-value'); + + this.saveTargets.forEach((btn, index) => { + if (btn.getAttribute('data-vocabs-id-value') === id) { + btn.classList.toggle('is-hidden'); + this.inputTargets[index].disabled = false; + this.cancelTargets[index].classList.toggle('is-hidden'); + } + }); + + event.currentTarget.classList.add('is-hidden'); + } + + async save(event) { + const id = event.currentTarget.getAttribute('data-vocabs-id-value'); + let term = ''; + + for (let input of this.inputTargets) { + if (input.getAttribute('data-vocabs-id-value') === id) { + term = input.value; + } + } + + let data = new FormData; + data.append("_id", id); + data.append("_new_term", term); + + const res = await fetch(this.saveUrlValue, { + method: "POST", + body: data, + }); + + // TODO: show notification + if (res.status === 200) { + console.log('Saved...'); + }; + } + + delete() { + } + + cancel(event) { + const id = event.currentTarget.getAttribute('data-vocabs-id-value'); + + this.editTargets.forEach((btn, index) => { + if (btn.getAttribute('data-vocabs-id-value') === id) { + btn.classList.toggle('is-hidden'); + this.inputTargets[index].disabled = true; + this.saveTargets[index].classList.toggle('is-hidden'); + this.cancelTargets[index].classList.toggle('is-hidden'); + } + }); + } +} diff --git a/src/Controller/BibliographyController.php b/src/Controller/BibliographyController.php index 0169ef9..a6571e9 100644 --- a/src/Controller/BibliographyController.php +++ b/src/Controller/BibliographyController.php @@ -12,6 +12,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Core\Exception\AccessDeniedException; +use DateTimeImmutable; class BibliographyController extends AbstractController { @@ -92,7 +93,7 @@ class BibliographyController extends AbstractController } /** - * @todo Permissions! Return JSON with 403 when AJAX + * @todo Move clone logic to __clone() in Entity or Repository */ #[Route('/bibliography/copy/{id<\d+>}', name: 'app_bibliography_copy')] public function copy(Bibliography $bibliography, EntityManagerInterface $em): Response @@ -108,24 +109,26 @@ class BibliographyController extends AbstractController $user = $this->getUser(); $editor = "{$user->getFirstname()} {$user->getLastName()}"; - // TODO Move clone logic to __clone() in Entity or Repository $copy = clone $bibliography; $copy->setEditor($editor); $copy->setOwner($editor); $copy->setCreator($user->getUsername()); $repo = $em->getRepository(Collection::class); $copy->setCollections( - $repo->findAllByBibliography($bibliography->getId()) + $repo->findAllByBibliography($bibliography->getId()) ); $repo = $em->getRepository(Collector::class); $copy->setCollectors( - $repo->findAllByBibliography($bibliography->getId()) + $repo->findAllByBibliography($bibliography->getId()) ); $copy->setCitation("{$bibliography->getCitation()} - Copy"); + $copy->setModifiedAt(new DateTimeImmutable()); $em->persist($copy); $em->flush(); + $this->addFlash('notice', 'Record copied successfully'); + return $this->redirectToRoute('app_bibliography', ['id' => $copy->getId()]); } } diff --git a/src/Controller/CollectionController.php b/src/Controller/CollectionController.php index 2d99403..10fbaf9 100644 --- a/src/Controller/CollectionController.php +++ b/src/Controller/CollectionController.php @@ -4,6 +4,7 @@ namespace App\Controller; use App\Entity\Collection; use App\Entity\Bibliography; +use App\Entity\Collector; use App\Security\Voter\RecordVoter; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -61,4 +62,45 @@ class CollectionController extends AbstractController return $this->redirectToRoute('app_collection_landing'); } + /** + * @todo Move clone logic to __clone() in Entity or Repository + */ + #[Route('/collection/copy/{id<\d+>}', name: 'app_collection_copy')] + public function copy(Collection $collection, EntityManagerInterface $em): Response + { + try { + $this->denyAccessUnlessGranted(RecordVoter::EDIT, $collection); + } + catch (AccessDeniedException) { + $this->addFlash('warning', 'You are not authorized to copy this record'); + return $this->redirectToRoute('app_home'); + } + + $user = $this->getUser(); + $editor = "{$user->getFirstname()} {$user->getLastName()}"; + + $copy = clone $collection; + $copy->setEditor($editor); + $copy->setOwner($editor); + $copy->setCreator($user->getUsername()); + $repo = $em->getRepository(Bibliography::class); + $copy->setBibliographies( + $repo->findAllByCollection($collection->getId()) + ); + /* + $repo = $em->getRepository(Collector::class); + $copy->setCollectors( + $repo->findAllByBibliography($bibliography->getId()) + ); + */ + $copy->setTitle("{$collection->getTitle()} - Copy"); + $copy->setModifiedAt(new \DateTimeImmutable()); + + $em->persist($copy); + $em->flush(); + + $this->addFlash('notice', 'Record copied successfully'); + + return $this->redirectToRoute('app_collection', ['id' => $copy->getId()]); + } } diff --git a/templates/bibliography/index.html.twig b/templates/bibliography/index.html.twig index 51e00cd..e349e8a 100644 --- a/templates/bibliography/index.html.twig +++ b/templates/bibliography/index.html.twig @@ -7,6 +7,15 @@

Bibliography

{{ record.citation }}

+ {% for message in app.flashes('notice') %} +
+ + {{ message }} +
+ {% endfor %} +

diff --git a/templates/bibliography/landing.html.twig b/templates/bibliography/landing.html.twig index 33c8c3b..945dd25 100644 --- a/templates/bibliography/landing.html.twig +++ b/templates/bibliography/landing.html.twig @@ -8,11 +8,14 @@

Choose action

{% for message in app.flashes('notice') %} -
- +
+ {{ message }}
{% endfor %} +
@@ -100,12 +103,4 @@
- {% endblock %} diff --git a/templates/collection/index.html.twig b/templates/collection/index.html.twig index b1ec457..a8cfdae 100644 --- a/templates/collection/index.html.twig +++ b/templates/collection/index.html.twig @@ -7,6 +7,15 @@

Collection

{{ record.title }}

+ {% for message in app.flashes('notice') %} +
+ + {{ message }} +
+ {% endfor %} +
- {% endblock %} diff --git a/templates/collector/landing.html.twig b/templates/collector/landing.html.twig index 6a3ca55..c6db268 100644 --- a/templates/collector/landing.html.twig +++ b/templates/collector/landing.html.twig @@ -8,10 +8,12 @@

Choose action

{% for message in app.flashes('notice') %} -
- +
+ {{ message }} -
+
{% endfor %}
@@ -100,12 +102,4 @@
- {% endblock %} diff --git a/templates/login/index.html.twig b/templates/login/index.html.twig index 768bf0f..ece15a7 100644 --- a/templates/login/index.html.twig +++ b/templates/login/index.html.twig @@ -12,7 +12,8 @@
{% if error %} -
+
Wrong user name and/or password. Please retry
diff --git a/templates/vocab_func_context/index.html.twig b/templates/vocab_func_context/index.html.twig index 95e8d0f..94338ff 100644 --- a/templates/vocab_func_context/index.html.twig +++ b/templates/vocab_func_context/index.html.twig @@ -28,38 +28,63 @@ {% endif %} - + {% for message in app.flashes('notice') %} -
- +
+ {{ message }}
{% endfor %}

Terms in vocabulary

- +
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}{% endif %} {% for term in terms %} - + {% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}
TermActions
- +
- - + -
- + {% endblock %} \ No newline at end of file