Merge remote-tracking branch 'origin/improve_location' into 106_tasks_to_parcours

This commit is contained in:
Julien Fastré 2021-10-27 16:49:34 +02:00
commit aea5e9b1d7
32 changed files with 887 additions and 23 deletions

View File

@ -13,6 +13,10 @@ and this project adheres to
<!-- write down unreleased development here -->
* [person]: accompanying course work: remove creation date display the list of work + handle case when end date is null
* [main]: Add new pages with a menu for managing location and location type in the admin
* [main]: Add some fixtures for location type
* [calendar]: Pass the location when transforming a calendar item (rdv) into an activity
* [calendar]: Add a user menu for "my calendar"
## Test releases

View File

@ -242,6 +242,11 @@ class ActivityController extends AbstractController
}
}
if (array_key_exists('location', $activityData)) {
$location = $em->getRepository(\Chill\MainBundle\Entity\Location::class)->find($activityData['location']);
$entity->setLocation($location);
}
if (array_key_exists('comment', $activityData)) {
$comment = new CommentEmbeddable();
$comment->setComment($activityData['comment']);

View File

@ -234,6 +234,7 @@ class CalendarController extends AbstractController
'professionalsId' => $professionalsId,
'date' => $entity->getStartDate()->format('Y-m-d'),
'durationTime' => $durationTimeInMinutes,
'location' => $entity->getLocation()->getId(),
'comment' => $entity->getComment()->getComment(),
];

View File

@ -0,0 +1,94 @@
<?php
/*
* Copyright (C) 2018 Champs Libres Cooperative <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\CalendarBundle\Menu;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem;
use Chill\TaskBundle\Templating\UI\CountNotificationTask;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
/**
*
* @author Champs-Libres
*/
class UserMenuBuilder implements LocalMenuBuilderInterface
{
/**
*
* @var CountNotificationTask
*/
public $counter;
/*
* @var TokenStorageInterface
*/
public $tokenStorage;
/**
*
* @var TranslatorInterface
*/
public $translator;
/**
*
* @var AuthorizationCheckerInterface
*/
public $authorizationChecker;
public function __construct(
CountNotificationTask $counter,
TokenStorageInterface $tokenStorage,
TranslatorInterface $translator,
AuthorizationCheckerInterface $authorizationChecker
) {
$this->counter = $counter;
$this->tokenStorage = $tokenStorage;
$this->translator = $translator;
$this->authorizationChecker = $authorizationChecker;
}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
$user = $this->tokenStorage->getToken()->getUser();
if ($this->authorizationChecker->isGranted('ROLE_USER')){
$menu->addChild("My calendar list", [
'route' => 'chill_calendar_calendar_list',
'routeParameters' => [
'user_id' => $user->getId(),
]
])
->setExtras([
'order' => 9,
'icon' => 'tasks'
]);
}
}
public static function getMenuIds(): array
{
return [ 'user' ];
}
}

View File

@ -342,13 +342,19 @@ class CRUDController extends AbstractController
*/
protected function buildQueryEntities(string $action, Request $request)
{
return $this->getDoctrine()->getManager()
$query = $this->getDoctrine()->getManager()
->createQueryBuilder()
->select('e')
->from($this->getEntityClass(), 'e')
;
$this->customizeQuery($action, $request, $query);
return $query;
}
protected function customizeQuery(string $action, Request $request, $query): void {}
/**
* Query the entity.
*

View File

@ -41,4 +41,9 @@ class AdminController extends AbstractController
return $this->render('@ChillMain/Admin/layout_permissions.html.twig');
}
public function indexLocationsAction()
{
return $this->render('@ChillMain/Admin/layout_location.html.twig');
}
}

View File

@ -20,7 +20,10 @@ class LocationApiController extends ApiController
$query->expr()->eq('e.createdBy', ':user'),
$query->expr()->gte('e.createdAt', ':dateBefore')
),
$query->expr()->eq('e.availableForUsers', "'TRUE'")
$query->expr()->andX(
$query->expr()->eq('e.availableForUsers', "'TRUE'"),
$query->expr()->eq('e.active', "'TRUE'")
)
))
->setParameters([
'user' => $this->getUser(),

View File

@ -0,0 +1,23 @@
<?php
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;
use Symfony\Component\HttpFoundation\Request;
class LocationController extends CRUDController
{
protected function customizeQuery(string $action, Request $request, $query): void
{
$query->where('e.availableForUsers = true'); //TODO not working
}
protected function createEntity(string $action, Request $request): object
{
$entity = parent::createEntity($action, $request);
$entity->setAvailableForUsers(true);
return $entity;
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;
class LocationTypeController extends CRUDController
{
}

View File

@ -0,0 +1,69 @@
<?php
namespace Chill\MainBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\MainBundle\Entity\LocationType;
/**
* Load location types into database
*
* @author Champs Libres
*/
class LoadLocationType extends AbstractFixture implements ContainerAwareInterface, OrderedFixtureInterface {
/**
*
* @var ContainerInterface
*/
private $container;
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
public function getOrder() {
return 52;
}
public function load(ObjectManager $manager): void {
echo "loading some location type... \n";
$arr = [
[
'name' => ['fr' => 'Mairie'],
'address_required' => LocationType::STATUS_OPTIONAL
],
[
'name' => ['fr' => 'Guichet d\'accueil'],
'address_required' => LocationType::STATUS_OPTIONAL
],
[
'name' => ['fr' => 'Domicile de l\'usager'],
'address_required' => LocationType::STATUS_REQUIRED
],
[
'name' => ['fr' => 'Centre d\'aide sociale'],
'address_required' => LocationType::STATUS_OPTIONAL
],
];
foreach ($arr as $a) {
$locationType = (new LocationType())
->setTitle($a['name'])
->setAvailableForUsers(true)
->setActive(true)
->setAddressRequired($a['address_required']);
$manager->persist($locationType);
}
$manager->flush();
}
}

View File

@ -20,6 +20,8 @@
namespace Chill\MainBundle\DependencyInjection;
use Chill\MainBundle\Controller\AddressApiController;
use Chill\MainBundle\Controller\LocationController;
use Chill\MainBundle\Controller\LocationTypeController;
use Chill\MainBundle\Controller\UserController;
use Chill\MainBundle\Doctrine\DQL\STContains;
use Chill\MainBundle\Doctrine\DQL\StrictWordSimilarityOPS;
@ -44,6 +46,10 @@ use Chill\MainBundle\Doctrine\DQL\Replace;
use Chill\MainBundle\Doctrine\ORM\Hydration\FlatHierarchyEntityHydrator;
use Chill\MainBundle\Doctrine\Type\NativeDateIntervalType;
use Chill\MainBundle\Doctrine\Type\PointType;
use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Entity\LocationType;
use Chill\MainBundle\Form\LocationTypeType;
use Chill\MainBundle\Form\LocationFormType;
use Symfony\Component\HttpFoundation\Request;
/**
@ -319,7 +325,51 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
'template' => '@ChillMain/User/edit.html.twig'
]
]
],
[
'class' => Location::class,
'name' => 'main_location',
'base_path' => '/admin/main/location',
'base_role' => 'ROLE_ADMIN',
'form_class' => LocationFormType::class,
'controller' => LocationController::class,
'actions' => [
'index' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillMain/Location/index.html.twig',
],
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillMain/Location/new.html.twig',
],
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillMain/Location/edit.html.twig',
]
]
],
[
'class' => LocationType::class,
'name' => 'main_location_type',
'base_path' => '/admin/main/location-type',
'base_role' => 'ROLE_ADMIN',
'form_class' => LocationTypeType::class,
'controller' => LocationTypeController::class,
'actions' => [
'index' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillMain/LocationType/index.html.twig',
],
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillMain/LocationType/new.html.twig',
],
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillMain/LocationType/edit.html.twig',
]
]
],
],
'apis' => [
[

View File

@ -76,6 +76,12 @@ class Location implements TrackCreationInterface, TrackUpdateInterface
*/
private bool $availableForUsers = false;
/**
* @ORM\Column(type="boolean", nullable=true)
* @Serializer\Groups({"read"})
*/
private bool $active = true;
/**
* @ORM\ManyToOne(targetEntity=User::class)
* @Serializer\Groups({"read"})
@ -192,6 +198,18 @@ class Location implements TrackCreationInterface, TrackUpdateInterface
return $this;
}
public function getActive(): ?bool
{
return $this->active;
}
public function setActive(bool $active): self
{
$this->active = $active;
return $this;
}
public function getCreatedBy(): ?User
{
return $this->createdBy;

View File

@ -40,6 +40,12 @@ class LocationType
*/
private bool $availableForUsers = true;
/**
* @ORM\Column(type="boolean", nullable=true)
* @Serializer\Groups({"read"})
*/
private bool $active = true;
/**
* @ORM\Column(type="string", length=32, options={"default"="optional"})
* @Serializer\Groups({"read"})
@ -70,6 +76,18 @@ class LocationType
return $this;
}
public function getActive(): ?bool
{
return $this->active;
}
public function setActive(bool $active): self
{
$this->active = $active;
return $this;
}
public function getAvailableForUsers(): ?bool
{
return $this->availableForUsers;

View File

@ -0,0 +1,85 @@
<?php
namespace Chill\MainBundle\Form;
use Chill\MainBundle\Entity\LocationType as EntityLocationType;
use Chill\MainBundle\Form\Type\PickAddressType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
final class LocationFormType extends AbstractType
{
// private TranslatableStringHelper $translatableStringHelper;
// /**
// * @param TranslatableStringHelper $translatableStringHelper
// */
// public function __construct(TranslatableStringHelper $translatableStringHelper)
// {
// $this->translatableStringHelper = $translatableStringHelper;
// }
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('locationType', EntityType::class, [
'class' => EntityLocationType::class,
'choice_attr' => function (EntityLocationType $entity) {
return [
'data-address' => $entity->getAddressRequired(),
'data-contact' => $entity->getContactData(),
];
},
'choice_label' => function (EntityLocationType $entity) {
//return $this->translatableStringHelper->localize($entity->getTitle()); //TODO not working. Cannot pass smthg in the constructor
return $entity->getTitle()['fr'];
},
])
->add('name', TextType::class)
->add('phonenumber1', TextType::class, ['required' => false])
->add('phonenumber2', TextType::class, ['required' => false])
->add('email', TextType::class, ['required' => false])
->add('address', PickAddressType::class, [
'required' => false,
'label' => 'Address',
'use_valid_from' => false,
'use_valid_to' => false,
'mapped' => false,
])
->add('active', ChoiceType::class,
[
'choices' => [
'Yes' => true,
'No' => false
],
'expanded' => true
]);
}
/**
* @param OptionsResolverInterface $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Chill\MainBundle\Entity\Location'
));
}
/**
* @return string
*/
public function getBlockPrefix()
{
return 'chill_mainbundle_location';
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace Chill\MainBundle\Form;
use Chill\MainBundle\Entity\LocationType;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
final class LocationTypeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('title', TranslatableStringFormType::class,
[
'label' => 'Name',
])
->add('availableForUsers', ChoiceType::class,
[
'choices' => [
'Yes' => true,
'No' => false
],
'expanded' => true
])
->add('addressRequired', ChoiceType::class,
[
'choices' => [
'optional' => LocationType::STATUS_OPTIONAL,
'required' => LocationType::STATUS_REQUIRED,
'never' => LocationType::STATUS_NEVER,
],
'expanded' => true
])
->add('contactData', ChoiceType::class,
[
'choices' => [
'optional' => LocationType::STATUS_OPTIONAL,
'required' => LocationType::STATUS_REQUIRED,
'never' => LocationType::STATUS_NEVER,
],
'expanded' => true
])
->add('active', ChoiceType::class,
[
'choices' => [
'Yes' => true,
'No' => false
],
'expanded' => true
]);
}
}

View File

@ -0,0 +1,66 @@
const contactDataBlock = document.querySelector('div.location-form-contact');
const addressBlock = document.querySelector('div.location-form-address');
const locationType = document.getElementById('chill_mainbundle_location_locationType');
const getSelectedAttributes =
(select, attr) => select.selectedOptions[0].getAttribute(attr)
const removeRequired = (formBlock) => {
formBlock.querySelectorAll('label').forEach(
l => l.classList.remove('required')
);
formBlock.querySelectorAll('input').forEach(
i => i.removeAttribute('required')
);
}
const addRequired = (formBlock) => {
formBlock.querySelectorAll('label').forEach(
l => l.classList.add('required')
);
formBlock.querySelectorAll('input').forEach(
i => i.setAttribute('required', '')
);
}
const onLocationTypeChange = () => {
console.log(getSelectedAttributes(locationType, 'data-address'))
console.log(getSelectedAttributes(locationType, 'data-contact'))
switch (getSelectedAttributes(locationType, 'data-address')) {
case 'optional':
default:
removeRequired(addressBlock);
addressBlock.classList.remove('d-none');
break;
case 'required':
addRequired(addressBlock);
addressBlock.classList.remove('d-none');
break;
case 'never':
removeRequired(addressBlock);
addressBlock.classList.add('d-none');
break;
}
switch (getSelectedAttributes(locationType, 'data-contact')) {
case 'optional':
default:
removeRequired(contactDataBlock);
contactDataBlock.classList.remove('d-none');
break;
case 'required':
addRequired(contactDataBlock);
contactDataBlock.classList.remove('d-none');
break;
case 'never':
removeRequired(contactDataBlock);
contactDataBlock.classList.add('d-none');
break;
}
};
document.addEventListener('DOMContentLoaded', _e => {
onLocationTypeChange();
locationType.addEventListener('change', onLocationTypeChange);
});

View File

@ -0,0 +1,33 @@
{#
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
<info@champs-libres.coop> / <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
{% extends "@ChillMain/Admin/layoutWithVerticalMenu.html.twig" %}
{% block vertical_menu_content %}
{{ chill_menu('admin_location', {
'layout': '@ChillMain/Admin/menu_admin_location.html.twig',
}) }}
{% endblock %}
{% block layout_wvm_content %}
{% block admin_content %}
<h1>{{ 'Management of location' |trans }}</h1>
{% endblock %}
{% endblock %}

View File

@ -0,0 +1,20 @@
{#
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
<info@champs-libres.coop> / <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
{% extends "@ChillMain/Menu/verticalMenu.html.twig" %}
{% block v_menu_title %}{{ 'Location Menu'|trans }}{% endblock %}

View File

@ -0,0 +1,39 @@
{% extends '@ChillMain/Admin/layout.html.twig' %}
{% block title %}
{% include('@ChillMain/CRUD/_edit_title.html.twig') %}
{% endblock %}
{% block admin_content %}
{% embed '@ChillMain/CRUD/_edit_content.html.twig' %}
{% block crud_content_form_rows %}
{{ form_row(form.locationType) }}
<div class="location-form-address">
{{ form_row(form.address) }}
</div>
{{ form_row(form.name) }}
<div class="location-form-contact">
{{ form_row(form.phonenumber1) }}
{{ form_row(form.phonenumber2) }}
{{ form_row(form.email) }}
</div>
{% endblock crud_content_form_rows %}
{% block content_form_actions_save_and_show %}{% endblock %}
{% endembed %}
{% endblock %}
{% block js %}
{{ encore_entry_script_tags('mod_input_address') }}
{{ encore_entry_script_tags('page_location') }}
{% endblock %}
{% block css %}
{{ encore_entry_link_tags('mod_input_address') }}
{% endblock %}

View File

@ -0,0 +1,56 @@
{% extends "@ChillMain/Admin/layout_location.html.twig" %}
{% block admin_content %}
<h1>{{ 'Location list'|trans }}</h1>
<table class="records_list table table-bordered border-dark">
<thead>
<tr>
<th>{{ 'Name'|trans }}</th>
<th>{{ 'Phonenumber1'|trans }}</th>
<th>{{ 'Phonenumber2'|trans }}</th>
<th>{{ 'Email'|trans }}</th>
<th>{{ 'Address'|trans }}</th>
<th>{{ 'Active'|trans }}</th>
</tr>
</thead>
<tbody>
{% for entity in entities %}
<tr>
<td>{{ entity.name }}</td>
<td>{{ entity.phonenumber1 }}</td>
<td>{{ entity.phonenumber2 }}</td>
<td>{{ entity.email }}</td>
<td>
{% if entity.address is not null %}
{{ entity.address.street}}, {{ entity.address.streetnumber }}
{% endif %}
</td>
<td style="text-align:center;">
{%- if entity.active -%}
<i class="fa fa-check-square-o"></i>
{%- else -%}
<i class="fa fa-square-o"></i>
{%- endif -%}
</td>
<td>
<ul class="record_actions">
<li>
<a href="{{ path('chill_crud_main_location_edit', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'edit'|trans }}"></a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<ul class="record_actions">
<li>
<a href="{{ path('chill_crud_main_location_new') }}" class="btn btn-create">
{{ 'Create a new location'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,39 @@
{% extends '@ChillMain/Admin/layout.html.twig' %}
{% block title %}
{% include('@ChillMain/CRUD/_new_title.html.twig') %}
{% endblock %}
{% block admin_content %}
{% embed '@ChillMain/CRUD/_new_content.html.twig' %}
{% block crud_content_form_rows %}
{{ form_row(form.locationType) }}
<div class="location-form-address">
{{ form_row(form.address) }}
</div>
{{ form_row(form.name) }}
<div class="location-form-contact">
{{ form_row(form.phonenumber1) }}
{{ form_row(form.phonenumber2) }}
{{ form_row(form.email) }}
</div>
{% endblock crud_content_form_rows %}
{% block content_form_actions_save_and_show %}{% endblock %}
{% endembed %}
{% endblock %}
{% block js %}
{{ encore_entry_script_tags('mod_input_address') }}
{{ encore_entry_script_tags('page_location') }}
{% endblock %}
{% block css %}
{{ encore_entry_link_tags('mod_input_address') }}
{% endblock %}

View File

@ -0,0 +1,14 @@
{% extends '@ChillMain/Admin/layout.html.twig' %}
{% block title %}
{% include('@ChillMain/CRUD/_edit_title.html.twig') %}
{% endblock %}
{% block admin_content %}
{# {% as we are in the admin layout, we override the admin content with the CRUD content %} #}
{% embed '@ChillMain/CRUD/_edit_content.html.twig' %}
{# we do not have "view" page. We empty the corresponding block #}
{% block content_form_actions_view %}{% endblock %}
{% block content_form_actions_save_and_show %}{% endblock %}
{% endembed %}
{% endblock %}

View File

@ -0,0 +1,55 @@
{% extends "@ChillMain/Admin/layout_location.html.twig" %}
{% block admin_content %}
<h1>{{ 'Location type list'|trans }}</h1>
<table class="records_list table table-bordered border-dark">
<thead>
<tr>
<th>{{ 'Title'|trans }}</th>
<th>{{ 'Available for users'|trans }}</th>
<th>{{ 'Address required'|trans }}</th>
<th>{{ 'Contact data'|trans }}</th>
<th>{{ 'Active'|trans }}</th>
</tr>
</thead>
<tbody>
{% for entity in entities %}
<tr>
<td>{{ entity.title | localize_translatable_string }}</td>
<td style="text-align:center;">
{%- if entity.availableForUsers -%}
<i class="fa fa-check-square-o"></i>
{%- else -%}
<i class="fa fa-square-o"></i>
{%- endif -%}
</td>
<td>{{ entity.addressRequired|trans }}</td>
<td>{{ entity.contactData|trans }}</td>
<td style="text-align:center;">
{%- if entity.active -%}
<i class="fa fa-check-square-o"></i>
{%- else -%}
<i class="fa fa-square-o"></i>
{%- endif -%}
</td>
<td>
<ul class="record_actions">
<li>
<a href="{{ path('chill_crud_main_location_type_edit', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'edit'|trans }}"></a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<ul class="record_actions">
<li>
<a href="{{ path('chill_crud_main_location_type_new') }}" class="btn btn-create">
{{ 'Create a new location type'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

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

View File

@ -54,6 +54,15 @@ class AdminSectionMenuBuilder implements LocalMenuBuilderInterface
'order' => 200,
'explain' => "Configure permissions for users"
]);
$menu->addChild('Location and location type', [
'route' => 'chill_main_admin_locations'
])
->setExtras([
'icons' => ['key'],
'order' => 205,
'explain' => "Configure location and location type"
]);
}
public static function getMenuIds(): array

View File

@ -0,0 +1,28 @@
<?php
namespace Chill\MainBundle\Routing\MenuBuilder;
use Knp\Menu\MenuItem;
class LocationMenuBuilder implements \Chill\MainBundle\Routing\LocalMenuBuilderInterface
{
/**
* @inheritDoc
*/
public static function getMenuIds(): array
{
return [ 'admin_location' ];
}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
$menu->addChild('Location type list', [
'route' => 'chill_crud_main_location_type_index'
])->setExtras(['order' => 205]);
$menu->addChild('Location list', [
'route' => 'chill_crud_main_location_index'
])->setExtras(['order' => 206]);
}
}

View File

@ -51,6 +51,7 @@ module.exports = function(encore, entries)
// Page entrypoints
encore.addEntry('page_login', __dirname + '/Resources/public/page/login/index.js');
encore.addEntry('page_location', __dirname + '/Resources/public/page/location/index.js');
buildCKEditor(encore);

View File

@ -66,6 +66,10 @@ chill_main_admin_permissions:
path: /{_locale}/admin/permissions
controller: Chill\MainBundle\Controller\AdminController::indexPermissionsAction
chill_main_admin_locations:
path: /{_locale}/admin/locations
controller: Chill\MainBundle\Controller\AdminController::indexLocationsAction
chill_main_search:
path: /{_locale}/search.{_format}
controller: Chill\MainBundle\Controller\SearchController::searchAction

View File

@ -137,3 +137,7 @@ services:
Chill\MainBundle\Form\DataTransform\AddressToIdDataTransformer:
autoconfigure: true
autowire: true
Chill\MainBundle\Form\Type\LocationFormType:
autowire: true
autoconfigure: true

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace Chill\Migrations\Main;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Add active on Location and LocationType
*/
final class Version20211022094429 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add active on Location and LocationType';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_main_location ADD active BOOLEAN DEFAULT TRUE;');
$this->addSql('ALTER TABLE chill_main_location_type ADD active BOOLEAN DEFAULT TRUE;');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_main_location_type DROP active');
$this->addSql('ALTER TABLE chill_main_location DROP active');
}
}

View File

@ -110,11 +110,16 @@ edit: modifier
Main admin menu: Menu d'administration principal
Actions: Actions
Users and permissions: Utilisateurs et permissions
Location and location type: Localisations et types de localisation
#permissions
Permissions Menu: Gestion des droits
Permissions management of your chill installation: Gestion des permissions de votre instance
#location
Location Menu: Localisations et types de localisation
Management of location: Gestion des localisations et types de localisation
#admin section
"Administration interface": Interface d'administration
Welcome to the admin section !: >
@ -180,6 +185,24 @@ Circle edit: Modification du cercle
Circle creation: Création d'un cercle
Create a new circle: Créer un nouveau cercle
#admin section for location
Location: Localisation
Location type list: Liste des types de localisation
Create a new location type: Créer un nouveau type de localisation
Available for users: Disponible aux utilisateurs
Address required: Adresse requise?
Contact data: Données de contact?
optional: optionnel
required: requis
never: jamais
Create a new location: Créer une nouvelle localisation
Location list: Liste des localisations
Location type: Type de localisation
Phonenumber1: Numéro de téléphone
Phonenumber2: Autre numéro de téléphone
Configure location: Configuration des localisations
Configure location type: Configuration des types de localisations
# circles / scopes
Choose the circle: Choisir le cercle
@ -294,6 +317,12 @@ crud:
add_new: Créer
title_new: Nouveau métier
title_edit: Modifier un métier
main_location_type:
title_new: Nouveau type de localisation
title_edit: Modifier un type de localisation
main_location:
title_new: Nouvelle localisation
title_edit: Modifier une localisation
No entities: Aucun élément

View File

@ -115,26 +115,6 @@ class UserMenuBuilder implements LocalMenuBuilderInterface
'icon' => 'tasks'
]);
// $menu->addChild("My calendar list", [
// 'route' => 'chill_calendar_calendar_list',
// 'routeParameters' => [
// 'user_id' => $user->getId(),
// ]
// ])
// ->setExtras([
// 'order' => -9,
// 'icon' => 'tasks'
// ]);
/*
$menu->addChild("My aside activities", [
'route' => 'chill_crud_aside_activity_index'
])
->setExtras([
'order' => -10,
'icon' => 'tasks'
]);
*/
}
protected function addItemInMenu(MenuItem $menu, User $u, $message, $title, $status, $number, $order)