Compare commits
	
		
			No commits in common. "a622b3c2567351f3306c521439a0fbd7e0d0454e" and "239240360e6659a1cea26fe7e9f1b86f2f23545d" have entirely different histories.
		
	
	
		
			a622b3c256
			...
			239240360e
		
	
		
@ -1,111 +0,0 @@
 | 
			
		||||
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-id');
 | 
			
		||||
 | 
			
		||||
        this.saveTargets.forEach((btn, index) => {
 | 
			
		||||
            if (btn.getAttribute('data-id') === 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-id');
 | 
			
		||||
        let term = '';
 | 
			
		||||
 | 
			
		||||
        for (let input of this.inputTargets) {
 | 
			
		||||
            if (input.getAttribute('data-id') === id) {
 | 
			
		||||
                term = input.value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let data = new FormData;
 | 
			
		||||
        data.append("_id", id);
 | 
			
		||||
        data.append("_new_term", term);
 | 
			
		||||
 | 
			
		||||
        const url = event.currentTarget.getAttribute('data-url');
 | 
			
		||||
 | 
			
		||||
        const res = await fetch(url, {
 | 
			
		||||
            method: "POST",
 | 
			
		||||
            body: data,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (res.status === 200) {
 | 
			
		||||
            let notif = document.getElementById('ajax-saved');
 | 
			
		||||
            notif.classList.toggle('is-hidden');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        this.cancelTargets.find(btn => btn.getAttribute('data-id') === id)
 | 
			
		||||
            .classList.toggle('is-hidden');
 | 
			
		||||
 | 
			
		||||
        this.editTargets.find(btn => btn.getAttribute('data-id') === id)
 | 
			
		||||
            .classList.toggle('is-hidden');
 | 
			
		||||
        const input = this.inputTargets.find(input => input.getAttribute('data-id') === id)
 | 
			
		||||
        input.disabled = true;
 | 
			
		||||
        event.target.classList.toggle('is-hidden');
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * 
 | 
			
		||||
     * @todo Show modal before deleting! Show delete error (500)!
 | 
			
		||||
     */
 | 
			
		||||
    async delete(event) {
 | 
			
		||||
        const id = event.currentTarget.getAttribute('data-id');
 | 
			
		||||
        const url = event.currentTarget.getAttribute('data-url');
 | 
			
		||||
 | 
			
		||||
        let data = new FormData;
 | 
			
		||||
        data.append("_id", id);
 | 
			
		||||
 | 
			
		||||
        const res = await fetch(url, {
 | 
			
		||||
            method: "POST",
 | 
			
		||||
            body: data,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (res.status === 200) {
 | 
			
		||||
            let notif = document.getElementById('ajax-deleted');
 | 
			
		||||
            notif.classList.toggle('is-hidden');
 | 
			
		||||
            this.rowTargets.find(row => row.getAttribute('data-id') === id)
 | 
			
		||||
                .classList.add('is-hidden');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if (res.status === 500) {
 | 
			
		||||
            let notif = document.getElementById('ajax-error');
 | 
			
		||||
            notif.classList.toggle('is-hidden');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cancel(event) {
 | 
			
		||||
        const id = event.currentTarget.getAttribute('data-id');
 | 
			
		||||
 | 
			
		||||
        this.editTargets.forEach((btn, index) => {
 | 
			
		||||
            if (btn.getAttribute('data-id') === 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');
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -12,7 +12,6 @@ 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
 | 
			
		||||
{
 | 
			
		||||
@ -93,7 +92,7 @@ class BibliographyController extends AbstractController
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @todo Move clone logic to __clone() in Entity or Repository
 | 
			
		||||
     * @todo Permissions! Return JSON with 403 when AJAX
 | 
			
		||||
     */
 | 
			
		||||
    #[Route('/bibliography/copy/{id<\d+>}', name: 'app_bibliography_copy')]
 | 
			
		||||
    public function copy(Bibliography $bibliography, EntityManagerInterface $em): Response
 | 
			
		||||
@ -109,6 +108,7 @@ 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);
 | 
			
		||||
@ -122,13 +122,10 @@ class BibliographyController extends AbstractController
 | 
			
		||||
        $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()]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,6 @@ 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;
 | 
			
		||||
@ -62,45 +61,4 @@ 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()]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,15 +7,6 @@
 | 
			
		||||
    <h1 class="is-size-1 mt-0 has-text-centered">Bibliography</h1>
 | 
			
		||||
    <h2 class="is-size-3 mt-3 has-text-centered">{{ record.citation }}</h2>
 | 
			
		||||
 | 
			
		||||
    {% for message in app.flashes('notice') %}
 | 
			
		||||
        <div class=" mt-4 notification is-success"
 | 
			
		||||
            data-controller="notification"
 | 
			
		||||
            data-notification-target="notif">
 | 
			
		||||
            <button class="delete" data-action="click->notification#close"></button>
 | 
			
		||||
            {{ message }}
 | 
			
		||||
        </div>
 | 
			
		||||
    {% endfor %}
 | 
			
		||||
 | 
			
		||||
    <article class="message is-info mt-3">
 | 
			
		||||
        <div class="message-body">
 | 
			
		||||
            <p>
 | 
			
		||||
 | 
			
		||||
@ -8,14 +8,11 @@
 | 
			
		||||
    <h2 class="is-size-3 mt-3 has-text-centered">Choose action</h2>
 | 
			
		||||
 | 
			
		||||
    {% for message in app.flashes('notice') %}
 | 
			
		||||
        <div class=" mt-4 notification is-success"
 | 
			
		||||
            data-controller="notification"
 | 
			
		||||
            data-notification-target="notif">
 | 
			
		||||
            <button class="delete" data-action="click->notification#close"></button>
 | 
			
		||||
        <div class=" mt-4 notification is-success">
 | 
			
		||||
            <button class="delete"></button>
 | 
			
		||||
            {{ message }}
 | 
			
		||||
        </div>
 | 
			
		||||
    {% endfor %}
 | 
			
		||||
 | 
			
		||||
    <div class="card p-5 mt-6 pt-6 pb-6">
 | 
			
		||||
        <div class="columns">
 | 
			
		||||
            <div class="column is-half has-text-centered">
 | 
			
		||||
@ -103,4 +100,12 @@
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
<script type="text/javascript" defer>
 | 
			
		||||
    const delBtns = document.querySelectorAll('.delete');
 | 
			
		||||
    for (let btn of delBtns) {
 | 
			
		||||
        btn.addEventListener('click', function () {
 | 
			
		||||
            this.parentElement.classList.add('is-hidden');
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
@ -7,15 +7,6 @@
 | 
			
		||||
    <h1 class="is-size-1 mt-0 has-text-centered">Collection</h1>
 | 
			
		||||
    <h2 class="is-size-3 mt-3 has-text-centered">{{ record.title }}</h2>
 | 
			
		||||
 | 
			
		||||
    {% for message in app.flashes('notice') %}
 | 
			
		||||
        <div class=" mt-4 notification is-success"
 | 
			
		||||
            data-controller="notification"
 | 
			
		||||
            data-notification-target="notif">
 | 
			
		||||
            <button class="delete" data-action="click->notification#close"></button>
 | 
			
		||||
            {{ message }}
 | 
			
		||||
        </div>
 | 
			
		||||
    {% endfor %}
 | 
			
		||||
 | 
			
		||||
    <article class="message is-info mt-3">
 | 
			
		||||
        <div class="message-body">
 | 
			
		||||
            <p>
 | 
			
		||||
@ -36,13 +27,12 @@
 | 
			
		||||
                        <i class="fa fa-edit"></i>
 | 
			
		||||
                    </span>
 | 
			
		||||
                </button>
 | 
			
		||||
                <a href="{{ path('app_collection_copy', {'id' : record.id}) }}"
 | 
			
		||||
                    class="button is-link">
 | 
			
		||||
                <button class="button is-link">
 | 
			
		||||
                    Copy
 | 
			
		||||
                    <span class="icon ml-2">
 | 
			
		||||
                        <i class="fa fa-copy"></i>
 | 
			
		||||
                    </span>
 | 
			
		||||
                </a>
 | 
			
		||||
                </button>
 | 
			
		||||
                <a href="{{ path('app_collection_del', {'id' : record.id}) }}"
 | 
			
		||||
                    class="button is-danger"
 | 
			
		||||
                    data-delete-record-target="path" data-action="click->delete-record#show">
 | 
			
		||||
 | 
			
		||||
@ -8,10 +8,8 @@
 | 
			
		||||
    <h2 class="is-size-3 mt-3 has-text-centered">Choose action</h2>
 | 
			
		||||
 | 
			
		||||
    {% for message in app.flashes('notice') %}
 | 
			
		||||
       <div class=" mt-4 notification is-success"
 | 
			
		||||
            data-controller="notification"
 | 
			
		||||
            data-notification-target="notif">
 | 
			
		||||
            <button class="delete" data-action="click->notification#close"></button>
 | 
			
		||||
        <div class=" mt-4 notification is-success">
 | 
			
		||||
            <button class="delete"></button>
 | 
			
		||||
            {{ message }}
 | 
			
		||||
        </div>
 | 
			
		||||
    {% endfor %}
 | 
			
		||||
@ -102,4 +100,12 @@
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
<script type="text/javascript" defer>
 | 
			
		||||
    const delBtns = document.querySelectorAll('.delete');
 | 
			
		||||
    for (let btn of delBtns) {
 | 
			
		||||
        btn.addEventListener('click', function () {
 | 
			
		||||
            this.parentElement.classList.add('is-hidden');
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
@ -8,10 +8,8 @@
 | 
			
		||||
    <h2 class="is-size-3 mt-3 has-text-centered">Choose action</h2>
 | 
			
		||||
 | 
			
		||||
    {% for message in app.flashes('notice') %}
 | 
			
		||||
       <div class=" mt-4 notification is-success"
 | 
			
		||||
            data-controller="notification"
 | 
			
		||||
            data-notification-target="notif">
 | 
			
		||||
            <button class="delete" data-action="click->notification#close"></button>
 | 
			
		||||
        <div class=" mt-4 notification is-success">
 | 
			
		||||
            <button class="delete"></button>
 | 
			
		||||
            {{ message }}
 | 
			
		||||
        </div>
 | 
			
		||||
    {% endfor %}
 | 
			
		||||
@ -102,4 +100,12 @@
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
<script type="text/javascript" defer>
 | 
			
		||||
    const delBtns = document.querySelectorAll('.delete');
 | 
			
		||||
    for (let btn of delBtns) {
 | 
			
		||||
        btn.addEventListener('click', function () {
 | 
			
		||||
            this.parentElement.classList.add('is-hidden');
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
@ -12,8 +12,7 @@
 | 
			
		||||
 | 
			
		||||
    <div class="card" style="max-width: 40vw; margin: 0 auto;">
 | 
			
		||||
        {% if error %}
 | 
			
		||||
            <div class="notification is-danger is-light" data-controller="notification"
 | 
			
		||||
                data-notification-target="notif">
 | 
			
		||||
            <div class="notification is-danger is-light" data-controller="notification" data-notification-target="notif">
 | 
			
		||||
                <button class="delete" data-action="click->notification#close"></button>
 | 
			
		||||
                Wrong user name and/or password. Please retry
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
{% block title %}Vocab - Functional context | ArCOA{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block rightpanel %}
 | 
			
		||||
<div class="container" style="max-width: 50vw" data-controller="vocabs">
 | 
			
		||||
<div class="container" style="max-width: 50vw">
 | 
			
		||||
    <h1 class="is-size-1 mt-0 has-text-centered">Vocabulary</h1>
 | 
			
		||||
    <h2 class="is-size-3 mt-4 has-text-centered">Functional context</h2>
 | 
			
		||||
 | 
			
		||||
@ -28,31 +28,11 @@
 | 
			
		||||
        </form>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
 | 
			
		||||
        <div class="notification is-success is-hidden mt-5"
 | 
			
		||||
            data-controller="notification"
 | 
			
		||||
            data-notification-target="notif"
 | 
			
		||||
            id="ajax-saved">
 | 
			
		||||
            <button class="delete" data-action="click->notification#close"></button>
 | 
			
		||||
            Term saved successfully
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="notification is-success is-hidden mt-5"
 | 
			
		||||
            data-controller="notification"
 | 
			
		||||
            data-notification-target="notif"
 | 
			
		||||
            id="ajax-deleted">
 | 
			
		||||
            <button class="delete" data-action="click->notification#close"></button>
 | 
			
		||||
            Term deleted successfully
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="notification is-danger is-light is-hidden mt-5"
 | 
			
		||||
            data-controller="notification"
 | 
			
		||||
            data-notification-target="notif"
 | 
			
		||||
            id="ajax-error">
 | 
			
		||||
            <button class="delete" data-action="click->notification#close"></button>
 | 
			
		||||
            The term could not be deleted because it's related to existing records
 | 
			
		||||
        <div class="notification is-success is-hidden mt-5" id="ajax-success">
 | 
			
		||||
          </div>
 | 
			
		||||
        {% for message in app.flashes('notice') %}
 | 
			
		||||
            <div class="notification is-success mt-5" data-controller="notification"
 | 
			
		||||
                data-notification-target="notif">
 | 
			
		||||
                <button class="delete" data-action="click->notification#close"></button>
 | 
			
		||||
            <div class="notification is-success mt-5" id="server-success">
 | 
			
		||||
                <button class="delete"></button>
 | 
			
		||||
                {{ message }}
 | 
			
		||||
            </div>
 | 
			
		||||
        {% endfor %}
 | 
			
		||||
@ -60,47 +40,26 @@
 | 
			
		||||
        <table class="table is-fullwidth" id="terms">
 | 
			
		||||
            <tr><th>Term</th>{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}<th>Actions</th>{% endif %}</tr>
 | 
			
		||||
        {% for term in terms %}
 | 
			
		||||
            <tr data-vocabs-target="row"
 | 
			
		||||
                data-id="{{ term.id }}">
 | 
			
		||||
            <tr data-row-id="{{ term.id }}">
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input class="input" type="text" value="{{ term.term }}" disabled
 | 
			
		||||
                    data-id="{{ term.id }}" data-vocabs-target="input" />
 | 
			
		||||
                    <input class="input" type="text" value="{{ term.term }}" disabled data-term-id="{{ term.id }}" />
 | 
			
		||||
                </td>
 | 
			
		||||
                {% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}
 | 
			
		||||
                <td>
 | 
			
		||||
                    <div class="buttons">
 | 
			
		||||
                        <button class="button is-primary is-hidden"
 | 
			
		||||
                            data-vocabs-target="save"
 | 
			
		||||
                            data-action="click->vocabs#save"
 | 
			
		||||
                            data-url="{{ path('app_vocab_func_context_upd') }}"
 | 
			
		||||
                            data-id="{{ term.id }}">
 | 
			
		||||
                        <button class="button is-primary is-hidden" data-id-save="{{ term.id }}">
 | 
			
		||||
                            Save
 | 
			
		||||
                            <span class="icon ml-2">
 | 
			
		||||
                                <i class="fa fa-save"></i>
 | 
			
		||||
                            </span>
 | 
			
		||||
                        </button>
 | 
			
		||||
                        <button class="button is-hidden"
 | 
			
		||||
                            data-id="{{ term.id }}"
 | 
			
		||||
                            data-vocabs-target="cancel"
 | 
			
		||||
                            data-action="click->vocabs#cancel">
 | 
			
		||||
                            Cancel
 | 
			
		||||
                            <span class="icon ml-2">
 | 
			
		||||
                                <i class="fa fa-times"></i>
 | 
			
		||||
                            </span>
 | 
			
		||||
                        </button>
 | 
			
		||||
                        <button class="button is-link"
 | 
			
		||||
                            data-vocabs-target="edit"
 | 
			
		||||
                            data-id="{{ term.id }}"
 | 
			
		||||
                            data-action="click->vocabs#edit">
 | 
			
		||||
                        <button class="button is-link" data-id-edit="{{ term.id }}">
 | 
			
		||||
                            Edit
 | 
			
		||||
                            <span class="icon ml-2">
 | 
			
		||||
                                <i class="fa fa-edit"></i>
 | 
			
		||||
                            </span>
 | 
			
		||||
                        </button>
 | 
			
		||||
                        <button class="button is-danger"
 | 
			
		||||
                            data-id="{{ term.id }}"
 | 
			
		||||
                            data-action="click->vocabs#delete"
 | 
			
		||||
                            data-url="{{ path('app_vocab_func_context_del') }}">
 | 
			
		||||
                        <button class="button is-danger" data-id-delete="{{ term.id }}">
 | 
			
		||||
                            Delete
 | 
			
		||||
                            <span class="icon ml-2">
 | 
			
		||||
                                <i class="fa fa-trash"></i>
 | 
			
		||||
@ -112,27 +71,97 @@
 | 
			
		||||
            </tr>
 | 
			
		||||
        {% endfor %}
 | 
			
		||||
        </table>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="modal" data-vocabs-target="modal">
 | 
			
		||||
        <div class="modal-background"></div>
 | 
			
		||||
        <div class="modal-card">
 | 
			
		||||
            <header class="modal-card-head">
 | 
			
		||||
                <span class="icon is-large has-text-warning">
 | 
			
		||||
                    <i class="fa fa-warning fa-2x"></i>
 | 
			
		||||
                </span>
 | 
			
		||||
                <p class="modal-card-title has-text-danger pl-2"><strong>Delete term?</strong></p>
 | 
			
		||||
            <button class="delete" aria-label="close"></button>
 | 
			
		||||
            </header>
 | 
			
		||||
            <section class="modal-card-body">
 | 
			
		||||
                <p class="is-size-5">This term will be permanently deleted. Proceed?</p>
 | 
			
		||||
            </section>
 | 
			
		||||
            <footer class="modal-card-foot">
 | 
			
		||||
                <div class="buttons is-right">
 | 
			
		||||
                    <button class="button is-link" data-action="click->vocabs#delete">Confirm</button>
 | 
			
		||||
                    <button class="button is-light" id="cancel">Cancel</button>
 | 
			
		||||
                </div>
 | 
			
		||||
            </footer>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
<script type="text/javascript" defer>
 | 
			
		||||
    const terms = document.querySelector('#terms');
 | 
			
		||||
    const serverNotice = document.querySelector('#server-success');
 | 
			
		||||
 | 
			
		||||
    if (serverNotice) {
 | 
			
		||||
        serverNotice.querySelector('.delete').addEventListener('click', () => {
 | 
			
		||||
            serverNotice.remove();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    terms.addEventListener('click', async (event) => {
 | 
			
		||||
        const clicked = event.target;
 | 
			
		||||
 | 
			
		||||
        if (clicked.getAttribute('data-id-delete')) {
 | 
			
		||||
            const termId = clicked.getAttribute('data-id-delete');
 | 
			
		||||
 | 
			
		||||
            const data = new FormData;
 | 
			
		||||
            data.append("_id", termId);
 | 
			
		||||
 | 
			
		||||
            const res = await fetch("{{ path('app_vocab_func_context_del') }}", {
 | 
			
		||||
                method: "POST",
 | 
			
		||||
                body: data,
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            const notice = document.querySelector('#ajax-success');
 | 
			
		||||
 | 
			
		||||
            if (res.status === 200) {
 | 
			
		||||
                notice.innerHTML = `
 | 
			
		||||
                    <button class="delete"></button>
 | 
			
		||||
                    Term deleted successfully
 | 
			
		||||
                `;
 | 
			
		||||
                notice.classList.remove('is-hidden');
 | 
			
		||||
                notice.querySelector('.delete').addEventListener('click', () => {
 | 
			
		||||
                    notice.classList.add('is-hidden');
 | 
			
		||||
                });
 | 
			
		||||
                const row = document.querySelector(`tr[data-row-id="${termId}"]`);
 | 
			
		||||
                row.remove();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (clicked.getAttribute('data-id-edit')) {
 | 
			
		||||
            const termId = clicked.getAttribute('data-id-edit');
 | 
			
		||||
            const saveBtn = document.querySelector(`button[data-id-save="${termId}"]`);
 | 
			
		||||
            const input = document.querySelector(`input[data-term-id="${termId}"]`);
 | 
			
		||||
            input.disabled = input.disabled ? false : true;
 | 
			
		||||
            saveBtn.classList.toggle('is-hidden');
 | 
			
		||||
 | 
			
		||||
            clicked.classList.toggle('is-link');
 | 
			
		||||
 | 
			
		||||
            if (!clicked.classList.contains('is-link')) {
 | 
			
		||||
                clicked.innerHTML = `
 | 
			
		||||
                    Cancel
 | 
			
		||||
                    <span class="icon ml-2">
 | 
			
		||||
                        <i class="fa fa-times"></i>
 | 
			
		||||
                    </span>
 | 
			
		||||
                `;
 | 
			
		||||
            } else {
 | 
			
		||||
                clicked.innerHTML = `
 | 
			
		||||
                    Edit
 | 
			
		||||
                    <span class="icon ml-2">
 | 
			
		||||
                        <i class="fa fa-edit"></i>
 | 
			
		||||
                    </span>
 | 
			
		||||
                `;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const data = new FormData;
 | 
			
		||||
            data.append("_id", termId);
 | 
			
		||||
            saveBtn.addEventListener('click', async () => {
 | 
			
		||||
                data.append("_new_term", input.value);
 | 
			
		||||
                const res = await fetch("{{ path('app_vocab_func_context_upd') }}", {
 | 
			
		||||
                    method: "POST",
 | 
			
		||||
                    body: data,
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                const notice = document.querySelector('#ajax-success');
 | 
			
		||||
 | 
			
		||||
                if (res.status === 200) {
 | 
			
		||||
                    notice.innerHTML = `
 | 
			
		||||
                        <button class="delete"></button>
 | 
			
		||||
                        Term updated successfully
 | 
			
		||||
                    `;
 | 
			
		||||
                    notice.classList.remove('is-hidden');
 | 
			
		||||
                    notice.querySelector('.delete').addEventListener('click', () => {
 | 
			
		||||
                        notice.classList.add('is-hidden');
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user