Create admin interface for the Motive entity with relevant templates + translations

This commit is contained in:
2025-10-07 16:26:30 +02:00
parent a88575463b
commit 37291b2756
10 changed files with 338 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\TicketBundle\Controller\Admin;
use Chill\MainBundle\CRUD\Controller\CRUDController;
use Chill\MainBundle\Pagination\PaginatorInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class MotiveController extends CRUDController
{
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
{
/* @var QueryBuilder $query */
$query->addOrderBy('e.id', 'ASC');
return parent::orderQuery($action, $query, $request, $paginator);
}
}

View File

@@ -11,8 +11,10 @@ declare(strict_types=1);
namespace Chill\TicketBundle\DependencyInjection;
use Chill\TicketBundle\Controller\Admin\MotiveController;
use Chill\TicketBundle\Controller\MotiveApiController;
use Chill\TicketBundle\Entity\Motive;
use Chill\TicketBundle\Form\MotiveType;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
@@ -36,6 +38,7 @@ class ChillTicketExtension extends Extension implements PrependExtensionInterfac
public function prepend(ContainerBuilder $container)
{
$this->prependApi($container);
$this->prependCruds($container);
}
private function prependApi(ContainerBuilder $container): void
@@ -66,4 +69,37 @@ class ChillTicketExtension extends Extension implements PrependExtensionInterfac
],
]);
}
protected function prependCruds(ContainerBuilder $container): void
{
$container->prependExtensionConfig('chill_main', [
'cruds' => [
[
'class' => Motive::class,
'name' => 'motive',
'base_path' => '/admin/ticket/motive',
'form_class' => MotiveType::class,
'controller' => MotiveController::class,
'actions' => [
'index' => [
'template' => '@ChillTicket/Admin/Motive/index.html.twig',
'role' => 'ROLE_ADMIN',
],
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillTicket/Admin/Motive/new.html.twig',
],
'view' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillTicket/Admin/Motive/view.html.twig',
],
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillTicket/Admin/Motive/edit.html.twig',
],
],
],
],
]);
}
}

View File

@@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\TicketBundle\Form;
use Chill\MainBundle\Form\Type\ChillCollectionType;
use Chill\MainBundle\Form\Type\CommentType;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Chill\TicketBundle\Entity\EmergencyStatusEnum;
use Chill\TicketBundle\Entity\Motive;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\EnumType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class MotiveType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('label', TranslatableStringFormType::class, [
'label' => 'Label',
'required' => true,
])
->add('active', CheckboxType::class, [
'label' => 'Active',
'required' => false,
])
->add('makeTicketEmergency', EnumType::class, [
'class' => EmergencyStatusEnum::class,
'label' => 'emergency?',
'required' => false,
'placeholder' => 'Choose an option...',
])
->add('supplementaryComments', ChillCollectionType::class, [
'entry_type' => TextareaType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => true,
'label' => 'Supplementary comments',
'required' => false,
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Motive::class,
]);
}
public function getBlockPrefix(): string
{
return 'chill_ticketbundle_motive';
}
}

View File

@@ -0,0 +1,15 @@
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
{% block title %}
{% include('@ChillMain/CRUD/_edit_title.html.twig') %}
{% endblock %}
{% block js %}
{{ parent() }}
{% endblock %}
{% block admin_content %}
{% embed '@ChillMain/CRUD/_edit_content.html.twig' %}
{% block content_form_actions_save_and_view %}{% endblock %}
{% endembed %}
{% endblock %}

View File

@@ -0,0 +1,64 @@
{% extends '@ChillMain/Admin/layoutWithVerticalMenu.html.twig' %}
{% block title %}{{ 'ticket.admin.title.Motive list'|trans }}{% endblock title %}
{% block admin_content %}
<h1>{{ 'ticket.admin.title.Motive list'|trans }}</h1>
<table class="records_list table table-bordered border-dark">
<thead>
<tr>
<th>{{ 'Label'|trans }}</th>
<th>{{ 'Active'|trans }}</th>
<th>{{ 'emergency?'|trans }}</th>
<th>{{ 'Supplementary comments'|trans }}</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{% for entity in entities %}
<tr>
<td>{{ entity.label|localize_translatable_string }}</td>
<td style="text-align:center;">
{%- if entity.isActive -%}
<i class="fa fa-check-square-o"></i>
{%- else -%}
<i class="fa fa-square-o"></i>
{%- endif -%}
</td>
<td style="text-align:center;">
{%- if entity.makeTicketEmergency -%}
{{ entity.makeTicketEmergency.value|trans }}
{%- else -%}
-
{%- endif -%}
</td>
<td style="text-align:center;">
{{ entity.supplementaryComments|length }}
</td>
<td>
<ul class="record_actions">
<li>
<a href="{{ path('chill_crud_motive_view', { 'id': entity.id }) }}" class="btn btn-show" title="{{ 'show'|trans }}"></a>
</li>
<li>
<a href="{{ path('chill_crud_motive_edit', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'edit'|trans }}"></a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ chill_pagination(paginator) }}
<ul class="record_actions sticky-form-buttons">
<li>
<a href="{{ path('chill_crud_motive_new') }}" class="btn btn-create">
{{ 'ticket.admin.new.Create a new motive'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@@ -0,0 +1,15 @@
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
{% block title %}
{% include('@ChillMain/CRUD/_new_title.html.twig') %}
{% endblock %}
{% block js %}
{{ parent() }}
{% endblock %}
{% block admin_content %}
{% embed '@ChillMain/CRUD/_new_content.html.twig' %}
{% block content_form_actions_save_and_show %}{% endblock %}
{% endembed %}
{% endblock %}

View File

@@ -0,0 +1,78 @@
{% extends '@ChillMain/Admin/layoutWithVerticalMenu.html.twig' %}
{% block title %}{{ 'ticket.admin.title.Motive view'|trans }}{% endblock title %}
{% block admin_content %}
<h1>{{ 'ticket.admin.title.Motive view'|trans }}</h1>
<table class="record_properties table table-bordered">
<tbody>
<tr>
<th>{{ 'Id'|trans }}</th>
<td>{{ entity.id }}</td>
</tr>
<tr>
<th>{{ 'Label'|trans }}</th>
<td>{{ entity.label|localize_translatable_string }}</td>
</tr>
<tr>
<th>{{ 'Active'|trans }}</th>
<td style="text-align:center;">
{%- if entity.isActive -%}
<i class="fa fa-check-square-o"></i> {{ 'Yes'|trans }}
{%- else -%}
<i class="fa fa-square-o"></i> {{ 'No'|trans }}
{%- endif -%}
</td>
</tr>
<tr>
<th>{{ 'emergency?'|trans }}</th>
<td>
{%- if entity.makeTicketEmergency -%}
{{ entity.makeTicketEmergency.value|trans }}
{%- else -%}
-
{%- endif -%}
</td>
</tr>
</tbody>
</table>
{% if entity.supplementaryComments is not empty %}
<h2>{{ 'Supplementary comments'|trans }}</h2>
<div class="supplementary-comments">
{% for comment in entity.supplementaryComments %}
<div class="card mb-3">
<div class="card-body">
<div class="comment-content">
{{ comment.comment|raw }}
</div>
{% if comment.date %}
<div class="comment-meta text-muted mt-2">
<small>
{{ 'Date'|trans }}: {{ comment.date|date('d/m/Y H:i') }}
{% if comment.userId %}
- {{ 'User'|trans }}: {{ comment.userId }}
{% endif %}
</small>
</div>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% else %}
<h2>{{ 'Supplementary comments'|trans }}</h2>
<p class="text-muted">{{ 'No supplementary comments'|trans }}</p>
{% endif %}
<ul class="record_actions sticky-form-buttons">
<li class="cancel">
<a href="{{ path('chill_crud_motive_index') }}" class="btn btn-cancel">{{ 'Back to the list'|trans }}</a>
</li>
<li>
<a href="{{ path('chill_crud_motive_edit', { 'id': entity.id }) }}" class="btn btn-edit">{{ 'Edit'|trans }}</a>
</li>
</ul>
{% endblock %}

View File

@@ -40,3 +40,6 @@ services:
Chill\TicketBundle\DataFixtures\:
resource: '../DataFixtures/'
Chill\TicketBundle\Form\:
resource: '../Form/'

View File

@@ -148,3 +148,28 @@ chill_ticket:
open_new_tab: "Ouvrir dans un nouvel onglet"
iframe_not_supported: "Votre navigateur ne supporte pas les iframes."
click_to_open_pdf: "Cliquez ici pour ouvrir le PDF"
ticket:
admin:
title:
"Motive list": "Liste des motifs"
"Motive view": "Détails du motif"
new:
"Create a new motive": "Créer un nouveau motif"
motive:
label: "Motifs"
"Label": "Libellé"
"Active": "Actif"
"emergency?": "Urgent ?"
"Supplementary comments": "Commentaires supplémentaires"
"edit": "modifier"
"show": "voir"
"Yes": "Oui"
"No": "Non"
"Id": "ID"
"Date": "Date"
"User": "Utilisateur"
"No supplementary comments": "Aucun commentaire supplémentaire"
"Back to the list": "Retour à la liste"
"Edit": "Modifier"