mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-25 08:05:00 +00:00
Create address on the fly field in event form
This commit is contained in:
@@ -41,6 +41,7 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
@@ -59,6 +60,8 @@ final class EventController extends AbstractController
|
||||
private readonly PaginatorFactory $paginator,
|
||||
private readonly Security $security,
|
||||
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
|
||||
private readonly SerializerInterface $serializer,
|
||||
|
||||
) {}
|
||||
|
||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{event_id}/delete', name: 'chill_event__event_delete', requirements: ['event_id' => '\d+'], methods: ['GET', 'POST', 'DELETE'])]
|
||||
@@ -202,9 +205,12 @@ final class EventController extends AbstractController
|
||||
return $this->redirectToRoute('chill_event__event_show', ['event_id' => $entity->getId()]);
|
||||
}
|
||||
|
||||
$entity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']);
|
||||
|
||||
return $this->render('@ChillEvent/Event/new.html.twig', [
|
||||
'entity' => $entity,
|
||||
'form' => $form->createView(),
|
||||
'entity_json' => $entity_array,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@@ -27,6 +27,7 @@ use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
|
||||
/**
|
||||
* Class Event.
|
||||
@@ -58,6 +59,7 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
||||
private ?User $moderator = null;
|
||||
|
||||
#[Assert\NotBlank]
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 150)]
|
||||
private ?string $name = null;
|
||||
|
||||
@@ -65,13 +67,19 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
||||
* @var Collection<int, Participation>
|
||||
*/
|
||||
#[ORM\OneToMany(mappedBy: 'event', targetEntity: Participation::class)]
|
||||
#[Serializer\Groups(['read'])]
|
||||
private Collection $participations;
|
||||
|
||||
#[Assert\NotNull]
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\ManyToOne(targetEntity: EventType::class)]
|
||||
private ?EventType $type = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, EventTheme>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: EventTheme::class)]
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\JoinTable('chill_event_eventtheme')]
|
||||
private Collection $themes;
|
||||
|
||||
@@ -79,6 +87,7 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
||||
private CommentEmbeddable $comment;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Location::class)]
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
private ?Location $location = null;
|
||||
|
||||
|
@@ -14,29 +14,27 @@ namespace Chill\EventBundle\Form;
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Form\StoredObjectType;
|
||||
use Chill\EventBundle\Entity\Event;
|
||||
use Chill\EventBundle\Entity\EventTheme;
|
||||
use Chill\EventBundle\Form\Type\PickEventThemeType;
|
||||
use Chill\EventBundle\Form\Type\PickEventTypeType;
|
||||
use Chill\EventBundle\Repository\EventThemeRepository;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Form\DataTransformer\IdToLocationDataTransformer;
|
||||
use Chill\MainBundle\Form\Type\ChillCollectionType;
|
||||
use Chill\MainBundle\Form\Type\ChillDateTimeType;
|
||||
use Chill\MainBundle\Form\Type\CommentType;
|
||||
use Chill\MainBundle\Form\Type\PickUserDynamicType;
|
||||
use Chill\MainBundle\Form\Type\PickUserLocationType;
|
||||
use Chill\MainBundle\Form\Type\ScopePickerType;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class EventType extends AbstractType
|
||||
{
|
||||
public function __construct(private readonly EventThemeRepository $eventThemeRepository, private readonly TranslatorInterface $translator, private readonly TranslatableStringHelperInterface $translatableStringHelper) {}
|
||||
public function __construct(
|
||||
private readonly IdToLocationDataTransformer $idToLocationDataTransformer,
|
||||
) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
@@ -63,9 +61,6 @@ class EventType extends AbstractType
|
||||
->add('moderator', PickUserDynamicType::class, [
|
||||
'label' => 'Pick a moderator',
|
||||
])
|
||||
->add('location', PickUserLocationType::class, [
|
||||
'label' => 'event.fields.location',
|
||||
])
|
||||
->add('comment', CommentType::class, [
|
||||
'label' => 'Comment',
|
||||
'required' => false,
|
||||
@@ -85,6 +80,10 @@ class EventType extends AbstractType
|
||||
'label' => 'event.fields.organizationCost',
|
||||
'help' => 'event.form.organisationCost_help',
|
||||
]);
|
||||
|
||||
$builder->add('location', HiddenType::class)
|
||||
->get('location')
|
||||
->addModelTransformer($this->idToLocationDataTransformer);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
@@ -103,6 +102,7 @@ class EventType extends AbstractType
|
||||
*/
|
||||
public function getBlockPrefix()
|
||||
{
|
||||
return 'chill_eventbundle_event';
|
||||
// as the js shares some hardcoded items from the activity bundle, we have to rewrite block prefix
|
||||
return 'chill_activitybundle_activity';
|
||||
}
|
||||
}
|
||||
|
14
src/Bundle/ChillEventBundle/Resources/public/vuejs/App.vue
Normal file
14
src/Bundle/ChillEventBundle/Resources/public/vuejs/App.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<location />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Location from "ChillActivityAssets/vuejs/Activity/components/Location.vue";
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
components: {
|
||||
Location,
|
||||
},
|
||||
};
|
||||
</script>
|
@@ -0,0 +1,6 @@
|
||||
import { createApp } from "vue";
|
||||
|
||||
import App from "./App.vue";
|
||||
import store from "./store";
|
||||
|
||||
createApp(App).use(store).mount("#event");
|
79
src/Bundle/ChillEventBundle/Resources/public/vuejs/store.js
Normal file
79
src/Bundle/ChillEventBundle/Resources/public/vuejs/store.js
Normal file
@@ -0,0 +1,79 @@
|
||||
import "es6-promise/auto";
|
||||
import { createStore } from "vuex";
|
||||
|
||||
import prepareLocations from "ChillActivityAssets/vuejs/Activity/store.locations";
|
||||
import {whoami} from "ChillMainAssets/lib/api/user";
|
||||
import {mapEntity} from "ChillCalendarAssets/vuejs/Calendar/store/utils";
|
||||
import {postLocation} from "ChillActivityAssets/vuejs/Activity/api";
|
||||
|
||||
const debug = process.env.NODE_ENV !== "production";
|
||||
|
||||
const store = createStore({
|
||||
strict: debug,
|
||||
state: {
|
||||
activity: window.entity, // activity is the event entity in this case (re-using component from activity bundle)
|
||||
currentEvent: null,
|
||||
availableLocations: [],
|
||||
me: null,
|
||||
},
|
||||
getters: {
|
||||
|
||||
},
|
||||
actions: {
|
||||
addAvailableLocationGroup({ commit }, payload) {
|
||||
commit("addAvailableLocationGroup", payload);
|
||||
},
|
||||
updateLocation({ commit }, value) {
|
||||
// console.log("### action: updateLocation", value);
|
||||
let hiddenLocation = document.getElementById(
|
||||
"chill_activitybundle_activity_location",
|
||||
);
|
||||
if (value.onthefly) {
|
||||
const body = {
|
||||
type: "location",
|
||||
name:
|
||||
value.name === "__AccompanyingCourseLocation__" ? null : value.name,
|
||||
locationType: {
|
||||
id: value.locationType.id,
|
||||
type: "location-type",
|
||||
},
|
||||
};
|
||||
if (value.address.id) {
|
||||
Object.assign(body, {
|
||||
address: {
|
||||
id: value.address.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
postLocation(body)
|
||||
.then((location) => (hiddenLocation.value = location.id))
|
||||
.catch((err) => {
|
||||
console.log(err.message);
|
||||
});
|
||||
} else {
|
||||
hiddenLocation.value = value.id;
|
||||
}
|
||||
commit("updateLocation", value);
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
setWhoAmiI(state, me) {
|
||||
state.me = me;
|
||||
},
|
||||
addAvailableLocationGroup(state, group) {
|
||||
state.availableLocations.push(group);
|
||||
},
|
||||
updateLocation(state, value) {
|
||||
// console.log("### mutation: updateLocation", value);
|
||||
state.activity.location = value;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
whoami().then((me) => {
|
||||
store.commit("setWhoAmiI", me);
|
||||
});
|
||||
|
||||
prepareLocations(store);
|
||||
|
||||
export default store;
|
@@ -1,19 +1,19 @@
|
||||
{% extends '@ChillEvent/layout.html.twig' %} {% block js %}
|
||||
{{ encore_entry_script_tags("mod_async_upload") }}
|
||||
{{ encore_entry_script_tags("mod_pickentity_type") }}
|
||||
{% extends '@ChillEvent/layout.html.twig' %}
|
||||
|
||||
{% endblock %} {% block css %}
|
||||
{% block css %}
|
||||
{{ encore_entry_link_tags("mod_async_upload") }}
|
||||
{{ encore_entry_link_tags("mod_pickentity_type") }}
|
||||
{{ encore_entry_link_tags('vue_event') }}
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %} {% block title 'Event creation'|trans %} {% block event_content
|
||||
-%}
|
||||
{% block title 'Event creation'|trans %}
|
||||
|
||||
{% block event_content -%}
|
||||
<div class="col-10">
|
||||
<h1>{{ "Event creation" | trans }}</h1>
|
||||
|
||||
{{ form_start(form) }}
|
||||
{{ form_errors(form) }}
|
||||
{# {{ form_row(form.circle) }}#}
|
||||
{{ form_row(form.name) }}
|
||||
{{ form_row(form.circle) }}
|
||||
{{ form_row(form.date) }}
|
||||
@@ -21,6 +21,7 @@
|
||||
{{ form_row(form.themes) }}
|
||||
{{ form_row(form.moderator) }}
|
||||
{{ form_row(form.location) }}
|
||||
<div id="location"></div>
|
||||
{{ form_row(form.organizationCost) }}
|
||||
{{ form_row(form.comment) }}
|
||||
{{ form_row(form.documents) }}
|
||||
@@ -42,5 +43,18 @@
|
||||
</ul>
|
||||
|
||||
{{ form_end(form) }}
|
||||
|
||||
<div id="event"></div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ encore_entry_script_tags("mod_async_upload") }}
|
||||
{{ encore_entry_script_tags("mod_pickentity_type") }}
|
||||
{{ encore_entry_script_tags('vue_event') }}
|
||||
<script type="text/javascript">
|
||||
window.entity = {{ entity_json|json_encode|raw }};
|
||||
{% if app.user.currentLocation is not null %}window.default_location_id = {{ app.user.currentLocation.id }};{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
@@ -1,3 +1,10 @@
|
||||
module.exports = function (encore, entries) {
|
||||
entries.push(__dirname + "/Resources/public/chill/index.js");
|
||||
|
||||
encore.addEntry(
|
||||
"vue_event",
|
||||
__dirname + "/Resources/public/vuejs/index.js",
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user