Feat/disable services 662 (#669)
* disable button for services * add button to disable services --------- Co-authored-by: Sarahshr <sarah@les-tilleuls.coop>
This commit is contained in:
parent
45b25f42c9
commit
a664e9a9bd
20 changed files with 266 additions and 157 deletions
|
|
@ -4,6 +4,8 @@ App\Entity\Configuration:
|
|||
|
||||
features (extends configuration_template):
|
||||
configuration:
|
||||
services:
|
||||
servicesEnabled: true
|
||||
notificationsSender:
|
||||
notificationsSenderEmail: info@example.com
|
||||
notificationsSenderName: Contact
|
||||
|
|
|
|||
|
|
@ -10,14 +10,19 @@ use App\Controller\RequestTrait;
|
|||
use App\Dto\Product\Search;
|
||||
use App\Entity\Product;
|
||||
use App\Entity\User;
|
||||
use App\Enum\Product\ProductType;
|
||||
use App\Form\Type\Product\SearchFormType;
|
||||
use App\Message\Query\Product\GetProductByIdQuery;
|
||||
use App\MessageBus\QueryBus;
|
||||
use App\Repository\ConfigurationRepository;
|
||||
use App\Repository\ProductRepository;
|
||||
use App\Search\Meilisearch;
|
||||
use Knp\Component\Pager\PaginatorInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\GoneHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Messenger\Exception\HandlerFailedException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Requirement\Requirement;
|
||||
|
|
@ -42,6 +47,8 @@ final class ProductController extends AbstractController
|
|||
private readonly QueryBus $queryBus,
|
||||
private readonly PaginatorInterface $paginator,
|
||||
private readonly Meilisearch $meilisearch,
|
||||
private readonly ConfigurationRepository $configurationRepository,
|
||||
private readonly ProductRepository $productRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +71,7 @@ final class ProductController extends AbstractController
|
|||
'objects_pagination' => $this->paginate($this->meilisearch->searchObjects($searchDto)),
|
||||
'services_pagination' => $this->paginate($this->meilisearch->searchServices($searchDto)),
|
||||
'search_form' => $searchForm,
|
||||
'services_enabled' => $this->configurationRepository->getServicesParameter(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -79,13 +87,24 @@ final class ProductController extends AbstractController
|
|||
)]
|
||||
public function show(string $slug, string $id): Response
|
||||
{
|
||||
try {
|
||||
/** @var Product $product */
|
||||
$product = $this->queryBus->query(new GetProductByIdQuery(Uuid::fromString($id)));
|
||||
} catch (HandlerFailedException $e) {
|
||||
throw $this->createNotFoundException($e->getMessage());
|
||||
/** @var ?Product $product */
|
||||
$product = $this->productRepository->find(['id' => $id]);
|
||||
|
||||
if ($product === null) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
return $this->render('pages/product/show.html.twig', compact('slug', 'id', 'product'));
|
||||
if (($product->getType() === ProductType::SERVICE && $this->configurationRepository->getServicesParameter()) || $product->getType() === ProductType::OBJECT) {
|
||||
try {
|
||||
/** @var Product $product */
|
||||
$product = $this->queryBus->query(new GetProductByIdQuery(Uuid::fromString($id)));
|
||||
} catch (HandlerFailedException $e) {
|
||||
throw $this->createNotFoundException($e->getMessage());
|
||||
}
|
||||
|
||||
return $this->render('pages/product/show.html.twig', compact('slug', 'id', 'product'));
|
||||
} else {
|
||||
throw new GoneHttpException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use App\Dto\Product\Search;
|
|||
use App\Entity\User;
|
||||
use App\Message\Query\User\Account\GetUserQuery;
|
||||
use App\MessageBus\QueryBus;
|
||||
use App\Repository\ConfigurationRepository;
|
||||
use App\Search\Meilisearch;
|
||||
use Knp\Component\Pager\PaginatorInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
|
|
@ -33,6 +34,7 @@ final class ProfileAction extends AbstractController
|
|||
private readonly QueryBus $queryBus,
|
||||
private readonly PaginatorInterface $paginator,
|
||||
private readonly Meilisearch $meilisearch,
|
||||
private readonly ConfigurationRepository $configurationRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -59,6 +61,7 @@ final class ProfileAction extends AbstractController
|
|||
'user' => $user,
|
||||
'objects_pagination' => $this->paginate($this->meilisearch->searchObjects($searchDto)),
|
||||
'services_pagination' => $this->paginate($this->meilisearch->searchServices($searchDto)),
|
||||
'services_enabled' => $this->configurationRepository->getServicesParameter(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ final class MyAccountAction extends AbstractController
|
|||
$canCreateGroup = $configuration->isGroupsCreationForAll() || $user->isAdmin();
|
||||
$contactEmail = $configuration->getContactEmail();
|
||||
|
||||
return $this->render('pages/account/index.html.twig', compact('userHasNewLoanMessage', 'userHasNewLendingMessage', 'canCreateGroup', 'contactEmail'));
|
||||
$servicesConfig = $this->configurationRepository->getServicesParameter();
|
||||
|
||||
return $this->render('pages/account/index.html.twig', compact('userHasNewLoanMessage', 'userHasNewLendingMessage', 'canCreateGroup', 'contactEmail', 'servicesConfig'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,12 +11,14 @@ use App\Entity\Product;
|
|||
use App\Entity\User;
|
||||
use App\Form\Type\Product\ServiceFormType;
|
||||
use App\MessageBus\QueryBus;
|
||||
use App\Repository\ConfigurationRepository;
|
||||
use App\Tests\Functional\Controller\Product\ServiceControllerTest;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\GoneHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Requirement\Requirement;
|
||||
use Symfony\Component\Security\Http\Attribute\CurrentUser;
|
||||
|
|
@ -37,6 +39,7 @@ final class ServiceController extends AbstractController
|
|||
public function __construct(
|
||||
private readonly QueryBus $queryBus,
|
||||
private readonly ProductManager $productManager,
|
||||
private readonly ConfigurationRepository $configurationRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -51,18 +54,22 @@ final class ServiceController extends AbstractController
|
|||
], name: 'new')]
|
||||
public function new(Request $request, #[CurrentUser] User $user): Response
|
||||
{
|
||||
$product = $this->productManager->initService($user);
|
||||
$form = $this->getForm($product, $request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
/** @var array<UploadedFile>|null $images */
|
||||
$images = $form->get('images')->getData();
|
||||
$this->productManager->multipleUpload($images, $product);
|
||||
$this->productManager->save($product, true);
|
||||
if ($this->configurationRepository->getServicesParameter()) {
|
||||
$product = $this->productManager->initService($user);
|
||||
$form = $this->getForm($product, $request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
/** @var array<UploadedFile>|null $images */
|
||||
$images = $form->get('images')->getData();
|
||||
$this->productManager->multipleUpload($images, $product);
|
||||
$this->productManager->save($product, true);
|
||||
|
||||
return $this->redirectToRoute('app_product_show', $product->getRoutingParameters());
|
||||
return $this->redirectToRoute('app_product_show', $product->getRoutingParameters());
|
||||
}
|
||||
|
||||
return $this->render('pages/product/new_service.html.twig', compact('form'));
|
||||
} else {
|
||||
throw new GoneHttpException();
|
||||
}
|
||||
|
||||
return $this->render('pages/product/new_service.html.twig', compact('form'));
|
||||
}
|
||||
|
||||
#[Route([
|
||||
|
|
@ -74,17 +81,21 @@ final class ServiceController extends AbstractController
|
|||
)]
|
||||
public function edit(string $id, Request $request): Response
|
||||
{
|
||||
$product = $this->getProductForEdit($id);
|
||||
$form = $this->getForm($product, $request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
/** @var array<UploadedFile>|null $images */
|
||||
$images = $form->get('images')->getData();
|
||||
$this->productManager->multipleUpload($images, $product);
|
||||
$this->productManager->save($product, true);
|
||||
if ($this->configurationRepository->getServicesParameter()) {
|
||||
$product = $this->getProductForEdit($id);
|
||||
$form = $this->getForm($product, $request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
/** @var array<UploadedFile>|null $images */
|
||||
$images = $form->get('images')->getData();
|
||||
$this->productManager->multipleUpload($images, $product);
|
||||
$this->productManager->save($product, true);
|
||||
|
||||
return $this->redirectToRoute('app_product_show', $product->getRoutingParameters());
|
||||
return $this->redirectToRoute('app_product_show', $product->getRoutingParameters());
|
||||
}
|
||||
|
||||
return $this->render('pages/product/edit_service.html.twig', compact('form', 'product'));
|
||||
} else {
|
||||
throw new GoneHttpException();
|
||||
}
|
||||
|
||||
return $this->render('pages/product/edit_service.html.twig', compact('form', 'product'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,12 +15,14 @@ use App\Message\Query\User\GetUserObjectsQuery;
|
|||
use App\Message\Query\User\GetUserServicesQuery;
|
||||
use App\MessageBus\QueryBus;
|
||||
use App\Repository\CategoryRepository;
|
||||
use App\Repository\ConfigurationRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use Knp\Component\Pager\Pagination\PaginationInterface;
|
||||
use Knp\Component\Pager\PaginatorInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\GoneHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Attribute\CurrentUser;
|
||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
|
|
@ -40,6 +42,7 @@ final class UserProductsController extends AbstractController
|
|||
private readonly QueryBus $queryBus,
|
||||
private readonly PaginatorInterface $paginator,
|
||||
public readonly CategoryRepository $categoryRepository,
|
||||
private readonly ConfigurationRepository $configurationRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -89,6 +92,10 @@ final class UserProductsController extends AbstractController
|
|||
$query = $this->queryBus->query(new GetUserServicesQuery($user->getId(), $category?->getId()));
|
||||
$pagination = $this->paginate($query, $this->getPage($request));
|
||||
|
||||
return $this->render('pages/account/product/list.html.twig', compact('pagination', 'form'));
|
||||
if ($this->configurationRepository->getServicesParameter()) {
|
||||
return $this->render('pages/account/product/list.html.twig', compact('pagination', 'form'));
|
||||
} else {
|
||||
throw new GoneHttpException('there is no services');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,24 @@ class Configuration
|
|||
|
||||
/** end of basic getters and setters ------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* @return bool[]
|
||||
*/
|
||||
public function getServices(): array
|
||||
{
|
||||
/** @var array<bool> $services */
|
||||
$services = $this->configuration['services'] ?? [];
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
public function getServicesEnabled(): bool
|
||||
{
|
||||
$services = $this->getServices();
|
||||
|
||||
return $services['servicesEnabled'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -25,10 +25,18 @@ final class ParametersFormType extends AbstractType
|
|||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('servicesEnabled', CheckboxType::class, [
|
||||
'label' => 'parameter.services',
|
||||
'label_attr' => [
|
||||
'class' => 'checkbox-inline checkbox-switch',
|
||||
],
|
||||
])
|
||||
|
||||
->add('notificationsSenderEmail', EmailType::class, [
|
||||
'label' => 'parameter.mail',
|
||||
'label_attr' => ['class' => 'col-sm-2 col-form-label'],
|
||||
])
|
||||
|
||||
->add('notificationsSenderName', TextType::class, [
|
||||
'label' => 'parameter.name',
|
||||
])
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ final class ParametersFormCommand extends AbstractFormCommand
|
|||
final public const ONLY_ADMIN = 'only_admin';
|
||||
final public const ALL = 'all';
|
||||
|
||||
// services section —————————————————————————————————————————————
|
||||
#[Assert\Type('bool')]
|
||||
public bool $servicesEnabled = true;
|
||||
|
||||
// notificationsSender section —————————————————————————————————————————————
|
||||
#[Assert\Email()]
|
||||
#[Assert\NotBlank()]
|
||||
|
|
@ -55,6 +59,7 @@ final class ParametersFormCommand extends AbstractFormCommand
|
|||
protected function getSections(): array
|
||||
{
|
||||
return [
|
||||
'services',
|
||||
'notificationsSender',
|
||||
'contact',
|
||||
'groups',
|
||||
|
|
@ -71,6 +76,7 @@ final class ParametersFormCommand extends AbstractFormCommand
|
|||
public function hydrate(Configuration $configuration): self
|
||||
{
|
||||
$instanceConfiguration = $configuration->getConfiguration();
|
||||
// dd($instanceConfiguration);
|
||||
foreach (array_keys(get_class_vars($this::class)) as $classVar) {
|
||||
$this->{$classVar} = $instanceConfiguration[$this->getSection($classVar)][$classVar]; // @phpstan-ignore-line
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,4 +58,16 @@ final class ConfigurationRepository extends ServiceEntityRepository
|
|||
|
||||
return $cfg;
|
||||
}
|
||||
|
||||
public function getServicesParameter(): bool
|
||||
{
|
||||
/** @var array{configuration: array{ services: array{ servicesEnabled: bool }}} $config */
|
||||
$config = $this
|
||||
->createQueryBuilder('c')
|
||||
->select('c.configuration')
|
||||
->setMaxResults(1)
|
||||
->getQuery()->getOneOrNullResult();
|
||||
|
||||
return $config['configuration']['services']['servicesEnabled'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@
|
|||
{% block main %}
|
||||
{{ form_start(form) }}
|
||||
<div class="row mb-lg-5">
|
||||
<h2 class="h3 fw-bold mt-3">{{ 'parameters.services.h2'|trans }}</h2>
|
||||
<hr/>
|
||||
|
||||
{{ form_widget(form.servicesEnabled) }}
|
||||
|
||||
<h2 class="h3 fw-bold mt-3">{{ 'parameters.senders.h2'|trans }}</h2>
|
||||
<hr/>
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
</div>
|
||||
<p class="ms-3 mb-0 fs-6 fw-bolder">{{ name }}</p>
|
||||
</div>
|
||||
{% if isPlace %}
|
||||
{% if isPlace and address is not null %}
|
||||
<div class="row mt-3">
|
||||
<div class="col">
|
||||
<p class="fw-bold fs-6 mb-0">{{ 'templates.components.product.lender.address'|trans }}</p>
|
||||
|
|
|
|||
|
|
@ -11,16 +11,18 @@
|
|||
{{ 'product.list_type_objects'|trans }} ({{ objects_pagination.totalItemCount }})
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item product-type w-50" role="presentation">
|
||||
<button class="nav-link rounded-0 w-100 {% if index == 1 %}active{% endif %}"
|
||||
id="pills-services-tab"
|
||||
data-bs-toggle="pill"
|
||||
data-bs-target="#pills-services" type="button" role="tab" aria-controls="pills-services"
|
||||
aria-selected="true">
|
||||
{{ 'product.list_type_services'|trans }}
|
||||
({{ services_pagination.totalItemCount }})
|
||||
</button>
|
||||
</li>
|
||||
{% if services_enabled %}
|
||||
<li class="nav-item product-type w-50" role="presentation">
|
||||
<button class="nav-link rounded-0 w-100 {% if index == 1 %}active{% endif %}"
|
||||
id="pills-services-tab"
|
||||
data-bs-toggle="pill"
|
||||
data-bs-target="#pills-services" type="button" role="tab" aria-controls="pills-services"
|
||||
aria-selected="true">
|
||||
{{ 'product.list_type_services'|trans }}
|
||||
({{ services_pagination.totalItemCount }})
|
||||
</button>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
pagination: objects_pagination,
|
||||
} %}
|
||||
</div>
|
||||
{% if services_pagination is defined and services_pagination is not null %}
|
||||
{% if services_pagination is defined and services_pagination is not null and services_enabled %}
|
||||
<div class="tab-pane fade"
|
||||
id="pills-services"
|
||||
role="tabpanel"
|
||||
|
|
|
|||
|
|
@ -19,19 +19,19 @@
|
|||
{
|
||||
section: 'Messagerie',
|
||||
links: [
|
||||
{
|
||||
name: 'Mes emprunts',
|
||||
link: 'app_user_my_loans',
|
||||
icon: null,
|
||||
notification: userHasNewLoanMessage
|
||||
},
|
||||
{
|
||||
name: 'Mes prêts',
|
||||
link: 'app_user_my_lendings',
|
||||
icon: null,
|
||||
notification: userHasNewLendingMessage
|
||||
},
|
||||
],
|
||||
{
|
||||
name: 'Mes emprunts',
|
||||
link: 'app_user_my_loans',
|
||||
icon: null,
|
||||
notification: userHasNewLoanMessage
|
||||
},
|
||||
{
|
||||
name: 'Mes prêts',
|
||||
link: 'app_user_my_lendings',
|
||||
icon: null,
|
||||
notification: userHasNewLendingMessage
|
||||
},
|
||||
],
|
||||
icon: 'bi bi-chat-left-text'
|
||||
},
|
||||
{
|
||||
|
|
@ -53,73 +53,74 @@
|
|||
},
|
||||
{
|
||||
section: 'Mes services',
|
||||
disable: servicesConfig,
|
||||
links: [
|
||||
{
|
||||
name: 'Voir mes services',
|
||||
link: 'app_user_services',
|
||||
icon: null
|
||||
},
|
||||
{
|
||||
name: 'Créer un service',
|
||||
link: 'app_service_new',
|
||||
icon: null,
|
||||
needAddress: app.user.address is null ? true : false
|
||||
},
|
||||
],
|
||||
{
|
||||
name: 'Voir mes services',
|
||||
link: 'app_user_services',
|
||||
icon: null
|
||||
},
|
||||
{
|
||||
name: 'Créer un service',
|
||||
link: 'app_service_new',
|
||||
icon: null,
|
||||
needAddress: app.user.address is null ? true : false
|
||||
},
|
||||
],
|
||||
icon: 'fa-solid fa-shop'
|
||||
},
|
||||
{
|
||||
section: 'Mes groupes',
|
||||
links: [
|
||||
{
|
||||
name: 'Voir mes groupes',
|
||||
link: 'app_user_groups',
|
||||
icon: null
|
||||
},
|
||||
{
|
||||
name: 'Administrer mes groupes',
|
||||
link: 'admin',
|
||||
show: show_my_groups,
|
||||
icon: 'bi bi-box-arrow-up-right'
|
||||
},
|
||||
{
|
||||
name: create_group_label,
|
||||
link: 'app_group_create',
|
||||
icon: create_group_icon,
|
||||
canCreateGroup: canCreateGroup,
|
||||
},
|
||||
],
|
||||
{
|
||||
name: 'Voir mes groupes',
|
||||
link: 'app_user_groups',
|
||||
icon: null
|
||||
},
|
||||
{
|
||||
name: 'Administrer mes groupes',
|
||||
link: 'admin',
|
||||
show: show_my_groups,
|
||||
icon: 'bi bi-box-arrow-up-right'
|
||||
},
|
||||
{
|
||||
name: create_group_label,
|
||||
link: 'app_group_create',
|
||||
icon: create_group_icon,
|
||||
canCreateGroup: canCreateGroup,
|
||||
},
|
||||
],
|
||||
icon: 'fa-solid fa-user-group'
|
||||
},
|
||||
{
|
||||
section: 'Compte',
|
||||
links: [
|
||||
{
|
||||
name: 'Mon adresse',
|
||||
link: 'user_address_step1',
|
||||
icon: null
|
||||
},
|
||||
{
|
||||
name: 'Modifier mon profil',
|
||||
link: 'app_user_edit_profile',
|
||||
icon: null
|
||||
},
|
||||
{
|
||||
name: 'Changer mon adresse e-mail',
|
||||
link: 'app_user_change_login',
|
||||
icon: null
|
||||
},
|
||||
{
|
||||
name: 'Changer mon mot de passe',
|
||||
link: 'app_user_change_password',
|
||||
icon: null
|
||||
},
|
||||
{
|
||||
name: vacation_mode_link,
|
||||
link: 'user_toggle_vacation_mode',
|
||||
icon: vacation_mode_icon
|
||||
},
|
||||
],
|
||||
{
|
||||
name: 'Mon adresse',
|
||||
link: 'user_address_step1',
|
||||
icon: null
|
||||
},
|
||||
{
|
||||
name: 'Modifier mon profil',
|
||||
link: 'app_user_edit_profile',
|
||||
icon: null
|
||||
},
|
||||
{
|
||||
name: 'Changer mon adresse e-mail',
|
||||
link: 'app_user_change_login',
|
||||
icon: null
|
||||
},
|
||||
{
|
||||
name: 'Changer mon mot de passe',
|
||||
link: 'app_user_change_password',
|
||||
icon: null
|
||||
},
|
||||
{
|
||||
name: vacation_mode_link,
|
||||
link: 'user_toggle_vacation_mode',
|
||||
icon: vacation_mode_icon
|
||||
},
|
||||
],
|
||||
icon: 'fa-solid fa-user fa-xl text-white'
|
||||
},
|
||||
] %}
|
||||
|
|
@ -133,56 +134,58 @@
|
|||
} %}
|
||||
<div class="row flex-wrap">
|
||||
{% for my_account_link in my_account_links %}
|
||||
<div class="col-12 col-md-4">
|
||||
<nav class="myAccount d-flex flex-column mt-3 mt-md-5">
|
||||
<div class="myAccount-header w-100 rounded-2">
|
||||
<i class="{{ my_account_link.icon }}"></i>
|
||||
<h5 class="mb-1 ms-3 fw-bolder fs-5 text-black">{{ my_account_link.section }}</h5>
|
||||
</div>
|
||||
<div class="myAccount-body pb-4">
|
||||
{% for link in my_account_link.links %}
|
||||
{% if link.show ?? true %}
|
||||
<div class="mt-3 d-flex align-items-center">
|
||||
{% if link.canCreateGroup is defined and not link.canCreateGroup %}
|
||||
<a
|
||||
href="mailto:{{ contactEmail ~ "?Subject=" ~ (i18n_prefix ~ '.mail.subject')|trans ~ "&body=" ~ (i18n_prefix ~ '.mail.mail_adress')|trans ~ "%0A" ~ (i18n_prefix ~ '.mail.group')|trans ~ "%0A" ~ (i18n_prefix ~ '.mail.type')|trans ~ "%0A" ~ (i18n_prefix ~ '.mail.membership')|trans ~ "%0A" ~ (i18n_prefix ~ '.mail.info')|trans }}"
|
||||
class="text-decoration-none text-primary ms-2">
|
||||
{% if link.icon is not empty %}
|
||||
<i class="{{ link.icon }} ~ me-1"></i>
|
||||
{% endif %}
|
||||
{{ link.name }}
|
||||
</a>
|
||||
{% else %}
|
||||
{% if link.needAddress is defined and link.needAddress == true %}
|
||||
{% include 'components/product/_modal.html.twig' with {
|
||||
menu_action: true,
|
||||
button: link.name,
|
||||
title: (i18n_prefix ~ '.no-address-title')|trans,
|
||||
message: (i18n_prefix ~ '.no-address-message')|trans({
|
||||
'%product%': link.link == 'app_object_new' ? 'objet' : 'service'
|
||||
}),
|
||||
action: (i18n_prefix ~ '.no-address-add')|trans
|
||||
} %}
|
||||
{% else %}
|
||||
<a href="{{ path(link.link) }}"
|
||||
class="text-decoration-none text-primary ms-2 position-relative pe-1">
|
||||
{% if my_account_link.disable is not defined %}
|
||||
<div class="col-12 col-md-4">
|
||||
<nav class="myAccount d-flex flex-column mt-3 mt-md-5">
|
||||
<div class="myAccount-header w-100 rounded-2">
|
||||
<i class="{{ my_account_link.icon }}"></i>
|
||||
<h5 class="mb-1 ms-3 fw-bolder fs-5 text-black">{{ my_account_link.section }}</h5>
|
||||
</div>
|
||||
<div class="myAccount-body pb-4">
|
||||
{% for link in my_account_link.links %}
|
||||
{% if link.show ?? true %}
|
||||
<div class="mt-3 d-flex align-items-center">
|
||||
{% if link.canCreateGroup is defined and not link.canCreateGroup %}
|
||||
<a
|
||||
href="mailto:{{ contactEmail ~ "?Subject=" ~ (i18n_prefix ~ '.mail.subject')|trans ~ "&body=" ~ (i18n_prefix ~ '.mail.mail_adress')|trans ~ "%0A" ~ (i18n_prefix ~ '.mail.group')|trans ~ "%0A" ~ (i18n_prefix ~ '.mail.type')|trans ~ "%0A" ~ (i18n_prefix ~ '.mail.membership')|trans ~ "%0A" ~ (i18n_prefix ~ '.mail.info')|trans }}"
|
||||
class="text-decoration-none text-primary ms-2">
|
||||
{% if link.icon is not empty %}
|
||||
<i class="{{ link.icon }} ~ me-1"></i>
|
||||
{% endif %}
|
||||
{{ link.name }}
|
||||
{% if link.notification is defined and link.notification %}
|
||||
<span
|
||||
class="position-absolute top-0 start-100 translate-middle p-1 rounded-circle bg-danger"></span>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% else %}
|
||||
{% if link.needAddress is defined and link.needAddress == true %}
|
||||
{% include 'components/product/_modal.html.twig' with {
|
||||
menu_action: true,
|
||||
button: link.name,
|
||||
title: (i18n_prefix ~ '.no-address-title')|trans,
|
||||
message: (i18n_prefix ~ '.no-address-message')|trans({
|
||||
'%product%': link.link == 'app_object_new' ? 'objet' : 'service'
|
||||
}),
|
||||
action: (i18n_prefix ~ '.no-address-add')|trans
|
||||
} %}
|
||||
{% else %}
|
||||
<a href="{{ path(link.link) }}"
|
||||
class="text-decoration-none text-primary ms-2 position-relative pe-1">
|
||||
{% if link.icon is not empty %}
|
||||
<i class="{{ link.icon }} ~ me-1"></i>
|
||||
{% endif %}
|
||||
{{ link.name }}
|
||||
{% if link.notification is defined and link.notification %}
|
||||
<span
|
||||
class="position-absolute top-0 start-100 translate-middle p-1 rounded-circle bg-danger"></span>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="d-grid col-12 col-md-6 mx-auto mt-5">
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
<div class="px-3 px-lg-0">
|
||||
{% include 'components/layout/_title_3.html.twig' with {name: 'product.list_name'|trans} %}
|
||||
{% include 'components/product/_search.html.twig' with {form: search_form} %}
|
||||
{% include 'components/product/_section.html.twig'with {objects_pagination, services_pagination} %}
|
||||
{% include 'components/product/_tab_content.html.twig' with {objects_pagination, services_pagination} %}
|
||||
{% include 'components/product/_section.html.twig'with {objects_pagination, services_pagination, services_enabled} %}
|
||||
{% include 'components/product/_tab_content.html.twig' with {objects_pagination, services_pagination, services_enabled} %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
<span>{{ (i18n_prefix ~ '.no_result')|trans }}</span>
|
||||
</div>
|
||||
{% else %}
|
||||
{% include 'components/product/_section.html.twig' %}
|
||||
{% include 'components/product/_section.html.twig' with {services_enabled} %}
|
||||
{% include 'components/product/_tab_content.html.twig' with {objects_pagination, services_pagination} %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ final class ParametersControllerTest extends WebTestCase
|
|||
|
||||
$form = $crawler->selectButton('parameters_form_submit')->form();
|
||||
|
||||
self::assertSame(5, $crawler->filter('input:checked')->count());
|
||||
self::assertSame(6, $crawler->filter('input:checked')->count());
|
||||
|
||||
/** @var FormField $notificationsSenderEmailField */
|
||||
$notificationsSenderEmailField = $form->get('parameters_form[notificationsSenderEmail]');
|
||||
|
|
@ -69,7 +69,7 @@ final class ParametersControllerTest extends WebTestCase
|
|||
$crawler = $client->followRedirect();
|
||||
self::assertResponseIsSuccessful();
|
||||
|
||||
self::assertSame(1, $crawler->filter('input:checked')->count());
|
||||
self::assertSame(2, $crawler->filter('input:checked')->count());
|
||||
|
||||
$form = $crawler->selectButton('parameters_form_submit')->form();
|
||||
/** @var FormField $groupsCreationModeField */
|
||||
|
|
|
|||
|
|
@ -260,6 +260,11 @@
|
|||
<target>Paramètres de l'instance</target>
|
||||
</trans-unit>
|
||||
|
||||
<trans-unit id="e1qNBMp" resname="parameters.services.h2">
|
||||
<source>parameters.services.h2</source>
|
||||
<target>Services</target>
|
||||
</trans-unit>
|
||||
|
||||
<trans-unit id="eNqNAUs" resname="parameters.senders.h2">
|
||||
<source>parameters.senders.h2</source>
|
||||
<target>Expéditeur·rice des notifications</target>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,12 @@
|
|||
</header>
|
||||
<body>
|
||||
|
||||
<!-- notification sender section -->
|
||||
<trans-unit id="qlPbwB3" resname="parameter.services">
|
||||
<source>parameter.services</source>
|
||||
<target>Services activés</target>
|
||||
</trans-unit>
|
||||
|
||||
<!-- notification sender section -->
|
||||
<trans-unit id="qqTbwBV" resname="parameter.mail">
|
||||
<source>parameter.mail</source>
|
||||
|
|
|
|||
Loading…
Reference in a new issue