Commit 6ac2d6a1 authored by Mat's avatar Mat

LettreInfos, formulaire LettreSorted pour trier les actualités (Info) dans une Lettre

parent 2e262a1b
......@@ -96,6 +96,7 @@ fos_js_routing:
- api_groupe_*
- api_depot_*
- potage_offre_legumes_ajax_display # tester si utile ??
- potage_lettre_infos_ajax_display
# VichUploaderBundle Configuration
vich_uploader:
......
<?php
namespace APIBundle\Form;
use PotageBundle\Form\Lettre\LettreSortedType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class LettreSortedAPIType extends LettreSortedType
{
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefault('csrf_protection', false);
// TODO temporaire, le temps de régler les validations au niveau des Asserts et des FormType
$resolver->setDefault('attr', array('novalidate' => true));
}
}
<?php
namespace PotageBundle\Controller;
//use APIBundle\Form\InfoAPIType;
use APIBundle\Form\LettreSortedAPIType;
class LettreInfosController extends MasterController
{
/**
* @param $id
* @return \Symfony\Component\HttpFoundation\Response|\Symfony\Component\HttpKernel\Exception\NotFoundHttpException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function ajaxDisplayAction($id)
{
$lettre = $this->getDoctrine()->getManager()
->getRepository('PotageBundle:Lettre')->findOneForLettreInfosAjaxDisplay($id);
if ($lettre === null) {
return $this->createNotFoundException('Non trouvé');
}
//$form = $this->createForm(InfoAPIType::class);
$formSorted = $this->createForm(LettreSortedAPIType::class);
return $this->render('@Potage/LettreInfos/ajaxDisplay.html.twig', array(
'id' => $id,
'lettre' => $lettre,
//'formInfo' => $form->createView(),
'formLettreSorted' => $formSorted->createView()
));
}
}
<?php
namespace PotageBundle\Form\Lettre;
use PotageBundle\Entity\Lettre;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class LettreSortedType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// TODO ajouter un champs sorted dans Lettre
$builder->add('sorted', HiddenType::class, array(
'data' => array(),
));
$builder->add('sauver', SubmitType::class, array(
'label' => 'Sauvegarder',
'attr' => array('class' => 'btn btn-dark mb-2')
));
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefault('data_class', Lettre::class);
$resolver->setDefault('attr', array(
'class' => 'formulaire formulaire_lettre_sorted',
));
}
/**
* @return null|string
*/
public function getBlockPrefix()
{
return "lettre_sorted";
}
}
\ No newline at end of file
......@@ -92,4 +92,20 @@ class LettreRepository extends \Doctrine\ORM\EntityRepository
));
return $qb->getQuery()->getOneOrNullResult();
}
/**
* @param $id
* @return mixed
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function findOneForLettreInfosAjaxDisplay($id)
{
$qb = $this->createQueryBuilder('l')
//->join('l.groupe', 'g')
//->addSelect('g')
->where('l.id = :id')
->setParameter(':id', $id);
return $qb->getQuery()->getOneOrNullResult();
}
}
......@@ -37,6 +37,14 @@ potage_info_ajax_display:
_controller: PotageBundle:Info:ajaxDisplay
methods: [ GET ]
potage_lettre_infos_ajax_display:
path: /admin/lettre/{id}
requirements:
id: \d+
defaults:
_controller: PotageBundle:LettreInfos:ajaxDisplay
methods: [ GET ]
potage_groupe_ajax_display:
path: /admin/groupes
defaults:
......
File mode changed from 100644 to 100755
......@@ -92,6 +92,7 @@ function buildRowLettre(jsonRow)
td6.appendChild(displayEditLettre(jsonRow)) : null;
(jsonRow.status === 'draft') ?
td6.appendChild(displayDeleteLettre(jsonRow)) : null;
td6.appendChild(displayLettreActus(jsonRow));
tr.appendChild(td6);
return tr;
......@@ -234,6 +235,21 @@ function displayDeleteLettre(jsonRow)
}
/*
* Insérer des actualités
*/
function displayLettreActus(jsonRow)
{
let insertBtn = document.createElement('a');
insertBtn.innerHTML = '<i class="fas fa-clipboard-check fa-fw"></i> Contenu';
insertBtn.classList.add('btn', 'btn-info', 'btn-sm', 'mb-1', 'mr-1');
let href = Routing.generate('potage_lettre_infos_ajax_display', {'id': jsonRow.id });
insertBtn.setAttribute('title', "Voir le contenu de l'infolettre");
insertBtn.setAttribute('href', href);
return insertBtn;
}
/*
* =================================
* Initialise l'affichage de la page
......
{% extends '@Potage/layout.html.twig' %}
{% block title %}
{{ lettre.reference }}
{% endblock %}
{% block searchbar %}
<nav class="navbar navbar-expand-lg navbar-light bg-light navbar-search">
<div class="nav-laterale left">
<a href="{{ path('potage_info_ajax_display') }}" class="text-secondary">
<i class="fas fa-long-arrow-alt-up fa-fw" style="transform: rotate(-45deg);"></i>Les actus</a>
<a href="{{ path('potage_lettre_ajax_display') }}" class="text-secondary">
<i class="fas fa-long-arrow-alt-up fa-fw"></i>Toutes les lettres</a>
</div>
<div class="nav-laterale right">
<a href="{{ path('potage_groupe_ajax_display') }}" class="text-secondary">
Les groupes <i class="fas fa-long-arrow-alt-up fa-fw" style="transform: rotate(45deg);"></i></a>
</div>
</nav>
{% endblock %}
{% block headerContent %}
{% endblock %}
{% block sidebarContent %}
<div class="row">
<section class="col-9">
<div class="row">
<div class="col left hd-1">
<h1>{{ block('title') }}</h1>
</div>
<div class="col right hd-1">
<div style="margin-top: 0.65em;">
<a href="javascript: void(0);" class="btn btn-outline-dark mb-2 btn-reload">
<i class="fas fa-sync-alt"></i>
Rafraîchir la liste
</a>
</div>
</div>
</div>
<div id="maingrid" class="grid lettre-infos {{ lettre.status }}">
<div id="sortable">
{#
Il n'y a pas encore d'actualités dans cette lettre !
#}
</div>
<div class="clearfix"></div>
</div>
</section>
{% endblock %}
{% block sectionContent %}
<aside class="col-3">
<div class="card">
<ul class="list-group list-group-flush">
<li class="list-group-item">
<h2>
Lettre # {{ id }}
</h2>
<p>Créée le {{ lettre.createdAt.format('d/m/Y à H:i') }}</p>
<p>Pour: {{ lettre.groupe|length }} aa
{% for groupe in lettre.groupe %}
{{ groupe.id }}
{% endfor %}
</p>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
{{ lettre.subject }}
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
Semaine du {{ lettre.startedAt.format('d/m/Y') }}
au {{ lettre.endedAt.format('d/m/Y') }}
</li>
<li class="list-group-item list-group-item-action {#list-group-item-warning#}">
Statut: {{ lettre.status }}
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
{{ lettre.getInfos|length }}{{ lettre.getInfos|length > 1 ? ' infos' : ' info' }}
</li>
{% if lettre.status == 'draft' %}
<li class="list-group-item">
<p>Sauvegarder la position</p>
{{ form(formLettreSorted) }}
</li>
{% endif %}
</ul>
</div>
</aside>
</div>
{% endblock %}
{% block customJS %}
<script type="text/javascript" src="{{ asset('js/functions.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/ajax_functions.js') }}"></script>
<script>
// Variables Twig
let id_lettre = {{ id }};
let sortForm = document.querySelector('form[name=lettre_sorted]');
let input = sortForm.querySelector('input#lettre_sorted_sorted');
// jQuery-ui Sortable
$( function() {
$( "#sortable" ).sortable();
$( "#sortable" ).disableSelection();
} );
</script>
<script type="text/javascript" src="ajaxDisplay.js"></script>
{% endblock %}
/*
* Recharge la grille LettreInfos
*/
function reloadGridInfos()
{
let grid = document.querySelector('div#maingrid.lettre-infos');
let sortable = grid.querySelector('div#sortable');
sortable.innerHTML = null;
let URL = Routing.generate('api_lettre_read_one', {'id': id_lettre });
AJAX('GET', URL, function(request)
{
let json = JSON.parse(request.responseText);
for(let i = 0; i < json.length; i++ )
{
let div = buildItemLettreInfos(json[i]);
sortable.appendChild(div);
}
});
}
/*
* Construit une rangée du tableau des Lettres
* @param json object jsonRow
*/
function buildItemLettreInfos(jsonRow)
{
//console.log(jsonRow);
let div = document.createElement('div');
div.classList.add('ui-state-default');
div.dataset.lettreInfosId = jsonRow.id;
let logo = document.createElement('div');
logo.classList.add('logo', 'lg');
let crop = document.createElement('div');
crop.classList.add('crop');
let img = document.createElement('img');
img.setAttribute('src', '/web/uploads/images/legumes/' + jsonRow.image);
crop.appendChild(img);
logo.appendChild(crop);
div.appendChild(logo);
let texte = document.createElement('div');
texte.classList.add('texte');
let title = document.createElement('h5');
title.innerHTML = jsonRow.nom;
texte.appendChild(title);
div.appendChild(texte);
let dprix = document.createElement('div');
dprix.classList.add('prix');
let prix = document.createElement('span');
prix.classList.add('prix');
prix.textContent = jsonRow.prixUnitaire;
dprix.appendChild(prix);
let devise = document.createElement('span');
devise.classList.add('devise');
devise.textContent = '';
dprix.appendChild(devise);
let unite = document.createElement('span');
unite.classList.add('unite');
unite.textContent = '/' + jsonRow.unite;
dprix.appendChild(unite);
div.appendChild(dprix);
return div;
}
/*
* =================================
* Initialise l'affichage de la page
* =================================
*/
reloadGridInfos();
reloadButton(function(){ reloadGridInfos(); });
/*
* Un form 'sorted' affiche en console
* un tableau avec l'ordre souhaité
*/
sortForm.addEventListener('submit', function(e)
{
let list = [];
let items = document.querySelectorAll('.ui-state-default');
for (let i=0; i < items.length; i++)
{
list[i] = items[i].dataset.lettreInfosId;
}
input.value = list;
let form = this;
e.preventDefault();
AJAX(
'POST',
Routing.generate('api_lettre_update_sorted', {'id': id_lettre}),
function() {
reloadGridInfos();
alert("La position des blocs d'actualité a bien été sauvegardée");
},
form
);
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment