Create address on the fly field in event form

This commit is contained in:
Julie Lenaerts 2025-04-29 14:31:39 +02:00
parent 1836e24acd
commit 4e4d7cfc10
15 changed files with 386 additions and 100 deletions

View File

@ -41,6 +41,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
/** /**
@ -59,6 +60,8 @@ final class EventController extends AbstractController
private readonly PaginatorFactory $paginator, private readonly PaginatorFactory $paginator,
private readonly Security $security, private readonly Security $security,
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry, 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'])] #[\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()]); 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', [ return $this->render('@ChillEvent/Event/new.html.twig', [
'entity' => $entity, 'entity' => $entity,
'form' => $form->createView(), 'form' => $form->createView(),
'entity_json' => $entity_array,
]); ]);
} }

View File

@ -27,6 +27,7 @@ use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation as Serializer;
/** /**
* Class Event. * Class Event.
@ -58,6 +59,7 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
private ?User $moderator = null; private ?User $moderator = null;
#[Assert\NotBlank] #[Assert\NotBlank]
#[Serializer\Groups(['read'])]
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 150)] #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 150)]
private ?string $name = null; private ?string $name = null;
@ -65,13 +67,19 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
* @var Collection<int, Participation> * @var Collection<int, Participation>
*/ */
#[ORM\OneToMany(mappedBy: 'event', targetEntity: Participation::class)] #[ORM\OneToMany(mappedBy: 'event', targetEntity: Participation::class)]
#[Serializer\Groups(['read'])]
private Collection $participations; private Collection $participations;
#[Assert\NotNull] #[Assert\NotNull]
#[Serializer\Groups(['read'])]
#[ORM\ManyToOne(targetEntity: EventType::class)] #[ORM\ManyToOne(targetEntity: EventType::class)]
private ?EventType $type = null; private ?EventType $type = null;
/**
* @var Collection<int, EventTheme>
*/
#[ORM\ManyToMany(targetEntity: EventTheme::class)] #[ORM\ManyToMany(targetEntity: EventTheme::class)]
#[Serializer\Groups(['read'])]
#[ORM\JoinTable('chill_event_eventtheme')] #[ORM\JoinTable('chill_event_eventtheme')]
private Collection $themes; private Collection $themes;
@ -79,6 +87,7 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
private CommentEmbeddable $comment; private CommentEmbeddable $comment;
#[ORM\ManyToOne(targetEntity: Location::class)] #[ORM\ManyToOne(targetEntity: Location::class)]
#[Serializer\Groups(['read'])]
#[ORM\JoinColumn(nullable: true)] #[ORM\JoinColumn(nullable: true)]
private ?Location $location = null; private ?Location $location = null;

View File

@ -14,29 +14,27 @@ namespace Chill\EventBundle\Form;
use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Form\StoredObjectType; use Chill\DocStoreBundle\Form\StoredObjectType;
use Chill\EventBundle\Entity\Event; use Chill\EventBundle\Entity\Event;
use Chill\EventBundle\Entity\EventTheme;
use Chill\EventBundle\Form\Type\PickEventThemeType; use Chill\EventBundle\Form\Type\PickEventThemeType;
use Chill\EventBundle\Form\Type\PickEventTypeType; use Chill\EventBundle\Form\Type\PickEventTypeType;
use Chill\EventBundle\Repository\EventThemeRepository;
use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Form\DataTransformer\IdToLocationDataTransformer;
use Chill\MainBundle\Form\Type\ChillCollectionType; use Chill\MainBundle\Form\Type\ChillCollectionType;
use Chill\MainBundle\Form\Type\ChillDateTimeType; use Chill\MainBundle\Form\Type\ChillDateTimeType;
use Chill\MainBundle\Form\Type\CommentType; use Chill\MainBundle\Form\Type\CommentType;
use Chill\MainBundle\Form\Type\PickUserDynamicType; use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\MainBundle\Form\Type\PickUserLocationType;
use Chill\MainBundle\Form\Type\ScopePickerType; 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\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType; use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Contracts\Translation\TranslatorInterface;
class EventType extends AbstractType 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) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
@ -63,9 +61,6 @@ class EventType extends AbstractType
->add('moderator', PickUserDynamicType::class, [ ->add('moderator', PickUserDynamicType::class, [
'label' => 'Pick a moderator', 'label' => 'Pick a moderator',
]) ])
->add('location', PickUserLocationType::class, [
'label' => 'event.fields.location',
])
->add('comment', CommentType::class, [ ->add('comment', CommentType::class, [
'label' => 'Comment', 'label' => 'Comment',
'required' => false, 'required' => false,
@ -85,6 +80,10 @@ class EventType extends AbstractType
'label' => 'event.fields.organizationCost', 'label' => 'event.fields.organizationCost',
'help' => 'event.form.organisationCost_help', 'help' => 'event.form.organisationCost_help',
]); ]);
$builder->add('location', HiddenType::class)
->get('location')
->addModelTransformer($this->idToLocationDataTransformer);
} }
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
@ -103,6 +102,7 @@ class EventType extends AbstractType
*/ */
public function getBlockPrefix() 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';
} }
} }

View 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>

View File

@ -0,0 +1,6 @@
import { createApp } from "vue";
import App from "./App.vue";
import store from "./store";
createApp(App).use(store).mount("#event");

View 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;

View File

@ -1,19 +1,19 @@
{% extends '@ChillEvent/layout.html.twig' %} {% block js %} {% extends '@ChillEvent/layout.html.twig' %}
{{ encore_entry_script_tags("mod_async_upload") }}
{{ encore_entry_script_tags("mod_pickentity_type") }}
{% endblock %} {% block css %} {% block css %}
{{ encore_entry_link_tags("mod_async_upload") }} {{ encore_entry_link_tags("mod_async_upload") }}
{{ encore_entry_link_tags("mod_pickentity_type") }} {{ 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"> <div class="col-10">
<h1>{{ "Event creation" | trans }}</h1> <h1>{{ "Event creation" | trans }}</h1>
{{ form_start(form) }} {{ form_start(form) }}
{{ form_errors(form) }} {{ form_errors(form) }}
{# {{ form_row(form.circle) }}#}
{{ form_row(form.name) }} {{ form_row(form.name) }}
{{ form_row(form.circle) }} {{ form_row(form.circle) }}
{{ form_row(form.date) }} {{ form_row(form.date) }}
@ -21,6 +21,7 @@
{{ form_row(form.themes) }} {{ form_row(form.themes) }}
{{ form_row(form.moderator) }} {{ form_row(form.moderator) }}
{{ form_row(form.location) }} {{ form_row(form.location) }}
<div id="location"></div>
{{ form_row(form.organizationCost) }} {{ form_row(form.organizationCost) }}
{{ form_row(form.comment) }} {{ form_row(form.comment) }}
{{ form_row(form.documents) }} {{ form_row(form.documents) }}
@ -42,5 +43,18 @@
</ul> </ul>
{{ form_end(form) }} {{ form_end(form) }}
<div id="event"></div>
</div> </div>
{% endblock %} {% 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 %}

View File

@ -1,3 +1,10 @@
module.exports = function (encore, entries) { module.exports = function (encore, entries) {
entries.push(__dirname + "/Resources/public/chill/index.js"); entries.push(__dirname + "/Resources/public/chill/index.js");
encore.addEntry(
"vue_event",
__dirname + "/Resources/public/vuejs/index.js",
);
}; };

View File

@ -21,10 +21,10 @@
> >
<template #header> <template #header>
<h2 class="modal-title"> <h2 class="modal-title">
{{ $t(getTextTitle) }} {{ trans(getTextTitle) }}
<span v-if="flag.loading" class="loading"> <span v-if="flag.loading" class="loading">
<i class="fa fa-circle-o-notch fa-spin fa-fw" /> <i class="fa fa-circle-o-notch fa-spin fa-fw" />
<span class="sr-only">{{ $t("loading") }}</span> <span class="sr-only">{{ trans(ADDRESS_LOADING) }}</span>
</span> </span>
</h2> </h2>
</template> </template>
@ -43,7 +43,7 @@
<template #footer> <template #footer>
<button @click="openEditPane" class="btn btn-create"> <button @click="openEditPane" class="btn btn-create">
{{ $t("create_a_new_address") }} {{ trans(CREATE_A_NEW_ADDRESS) }}
</button> </button>
</template> </template>
</modal> </modal>
@ -62,13 +62,13 @@
> >
<template #before v-if="!bypassFirstStep"> <template #before v-if="!bypassFirstStep">
<a class="btn btn-cancel" @click="resetPane"> <a class="btn btn-cancel" @click="resetPane">
{{ $t("action.cancel") }} {{ trans(CANCEL) }}
</a> </a>
</template> </template>
<template #action> <template #action>
<li> <li>
<button @click="openEditPane" class="btn btn-create"> <button @click="openEditPane" class="btn btn-create">
{{ $t("create_a_new_address") }} {{ trans(CREATE_A_NEW_ADDRESS) }}
</button> </button>
</li> </li>
</template> </template>
@ -85,10 +85,10 @@
> >
<template #header> <template #header>
<h2 class="modal-title"> <h2 class="modal-title">
{{ $t(getTextTitle) }} {{ trans(getTextTitle) }}
<span v-if="flag.loading" class="loading"> <span v-if="flag.loading" class="loading">
<i class="fa fa-circle-o-notch fa-spin fa-fw" /> <i class="fa fa-circle-o-notch fa-spin fa-fw" />
<span class="sr-only">{{ $t("loading") }}</span> <span class="sr-only">{{ trans(ADDRESS_LOADING) }}</span>
</span> </span>
</h2> </h2>
</template> </template>
@ -108,17 +108,17 @@
</template> </template>
<template #footer> <template #footer>
<!--<button class="btn btn-cancel change-icon" @click="resetPane">{{ $t('action.cancel') }}</button>--> <!--<button class="btn btn-cancel change-icon" @click="resetPane">{{ trans(CANCEL) }}</button>-->
<button <button
v-if="!this.context.edit && this.useDatePane" v-if="!this.context.edit && this.useDatePane"
class="btn btn-update change-icon" class="btn btn-update change-icon"
@click="closeEditPane" @click="closeEditPane"
> >
{{ $t("nav.next") }} {{ trans(NEXT) }}
<i class="fa fa-fw fa-arrow-right" /> <i class="fa fa-fw fa-arrow-right" />
</button> </button>
<button v-else class="btn btn-save" @click="closeEditPane"> <button v-else class="btn btn-save" @click="closeEditPane">
{{ $t("action.save") }} {{ trans(SAVE) }}
</button> </button>
</template> </template>
</modal> </modal>
@ -139,7 +139,7 @@
> >
<template #before> <template #before>
<a class="btn btn-cancel" @click="resetPane"> <a class="btn btn-cancel" @click="resetPane">
{{ $t("action.cancel") }} {{ trans(CANCEL) }}
</a> </a>
</template> </template>
<template #action> <template #action>
@ -148,13 +148,13 @@
class="btn btn-update change-icon" class="btn btn-update change-icon"
@click="closeEditPane" @click="closeEditPane"
> >
{{ $t("nav.next") }} {{ trans(NEXT) }}
<i class="fa fa-fw fa-arrow-right" /> <i class="fa fa-fw fa-arrow-right" />
</button> </button>
</li> </li>
<li v-else> <li v-else>
<button class="btn btn-save" @click="closeEditPane"> <button class="btn btn-save" @click="closeEditPane">
{{ $t("action.save") }} {{ trans(SAVE) }}
</button> </button>
</li> </li>
</template> </template>
@ -171,10 +171,10 @@
> >
<template #header> <template #header>
<h2 class="modal-title"> <h2 class="modal-title">
{{ $t(getTextTitle) }} {{ trans(getTextTitle) }}
<span v-if="flag.loading" class="loading"> <span v-if="flag.loading" class="loading">
<i class="fa fa-circle-o-notch fa-spin fa-fw" /> <i class="fa fa-circle-o-notch fa-spin fa-fw" />
<span class="sr-only">{{ $t("loading") }}</span> <span class="sr-only">{{ trans(ADDRESS_LOADING) }}</span>
</span> </span>
</h2> </h2>
</template> </template>
@ -193,10 +193,10 @@
<template #footer> <template #footer>
<button class="btn btn-misc" @click="openEditPane"> <button class="btn btn-misc" @click="openEditPane">
<i class="fa fa-fw fa-arrow-left" /> <i class="fa fa-fw fa-arrow-left" />
{{ $t("nav.previous") }} {{ trans(PREVIOUS) }}
</button> </button>
<button class="btn btn-save" @click="closeDatePane"> <button class="btn btn-save" @click="closeDatePane">
{{ $t("action.save") }} {{ trans(SAVE) }}
</button> </button>
<!-- --> <!-- -->
</template> </template>
@ -216,13 +216,13 @@
<template #before> <template #before>
<button class="btn btn-misc" @click="openEditPane"> <button class="btn btn-misc" @click="openEditPane">
<i class="fa fa-fw fa-arrow-left" /> <i class="fa fa-fw fa-arrow-left" />
{{ $t("nav.previous") }} {{ trans(PREVIOUS) }}
</button> </button>
</template> </template>
<template #action> <template #action>
<li> <li>
<button class="btn btn-save" @click="closeDatePane"> <button class="btn btn-save" @click="closeDatePane">
{{ $t("action.save") }} {{ trans(SAVE) }}
</button> </button>
</li> </li>
</template> </template>
@ -244,9 +244,16 @@ import {
postPostalCode, postPostalCode,
} from "../api"; } from "../api";
import { import {
postAddressToPerson, CREATE_A_NEW_ADDRESS,
postAddressToHousehold, ADDRESS_LOADING,
} from "ChillPersonAssets/vuejs/_api/AddAddress.js"; ACTIVITY_CREATE_ADDRESS,
ACTIVITY_EDIT_ADDRESS,
CANCEL,
SAVE,
PREVIOUS,
NEXT,
trans,
} from "translator";
import ShowPane from "./ShowPane.vue"; import ShowPane from "./ShowPane.vue";
import SuggestPane from "./SuggestPane.vue"; import SuggestPane from "./SuggestPane.vue";
import EditPane from "./EditPane.vue"; import EditPane from "./EditPane.vue";
@ -254,6 +261,17 @@ import DatePane from "./DatePane.vue";
export default { export default {
name: "AddAddress", name: "AddAddress",
setup() {
return {
trans,
CREATE_A_NEW_ADDRESS,
ADDRESS_LOADING,
CANCEL,
SAVE,
PREVIOUS,
NEXT
};
},
props: ["context", "options", "addressChangedCallback"], props: ["context", "options", "addressChangedCallback"],
components: { components: {
Modal, Modal,
@ -373,9 +391,11 @@ export default {
(this.options.title.edit !== null || (this.options.title.edit !== null ||
this.options.title.create !== null) this.options.title.create !== null)
) { ) {
console.log('this.options.title', this.options.title)
return this.context.edit return this.context.edit
? this.options.title.edit ? ACTIVITY_EDIT_ADDRESS
: this.options.title.create; : ACTIVITY_CREATE_ADDRESS;
} }
return this.context.edit return this.context.edit
? this.defaultz.title.edit ? this.defaultz.title.edit

View File

@ -1,6 +1,6 @@
<template> <template>
<h4 class="h3"> <h4 class="h3">
{{ $t("fill_an_address") }} {{ trans(ADDRESS_FILL_AN_ADDRESS) }}
</h4> </h4>
<div class="row my-3"> <div class="row my-3">
<div class="col-lg-6" v-if="!isNoAddress"> <div class="col-lg-6" v-if="!isNoAddress">
@ -9,40 +9,40 @@
class="form-control" class="form-control"
type="text" type="text"
name="floor" name="floor"
:placeholder="$t('floor')" :placeholder="trans(ADDRESS_FLOOR)"
v-model="floor" v-model="floor"
/> />
<label for="floor">{{ $t("floor") }}</label> <label for="floor">{{ trans(ADDRESS_FLOOR) }}</label>
</div> </div>
<div class="form-floating my-1"> <div class="form-floating my-1">
<input <input
class="form-control" class="form-control"
type="text" type="text"
name="corridor" name="corridor"
:placeholder="$t('corridor')" :placeholder="trans(ADDRESS_CORRIDOR)"
v-model="corridor" v-model="corridor"
/> />
<label for="corridor">{{ $t("corridor") }}</label> <label for="corridor">{{ trans(ADDRESS_CORRIDOR) }}</label>
</div> </div>
<div class="form-floating my-1"> <div class="form-floating my-1">
<input <input
class="form-control" class="form-control"
type="text" type="text"
name="steps" name="steps"
:placeholder="$t('steps')" :placeholder="trans(ADDRESS_STEPS)"
v-model="steps" v-model="steps"
/> />
<label for="steps">{{ $t("steps") }}</label> <label for="steps">{{ trans(ADDRESS_STEPS) }}</label>
</div> </div>
<div class="form-floating my-1"> <div class="form-floating my-1">
<input <input
class="form-control" class="form-control"
type="text" type="text"
name="flat" name="flat"
:placeholder="$t('flat')" :placeholder="trans(ADDRESS_FLAT)"
v-model="flat" v-model="flat"
/> />
<label for="flat">{{ $t("flat") }}</label> <label for="flat">{{ trans(ADDRESS_FLAT) }}</label>
</div> </div>
</div> </div>
<div :class="isNoAddress ? 'col-lg-12' : 'col-lg-6'"> <div :class="isNoAddress ? 'col-lg-12' : 'col-lg-6'">
@ -52,10 +52,10 @@
type="text" type="text"
name="buildingName" name="buildingName"
maxlength="255" maxlength="255"
:placeholder="$t('buildingName')" :placeholder="trans(ADDRESS_BUILDING_NAME)"
v-model="buildingName" v-model="buildingName"
/> />
<label for="buildingName">{{ $t("buildingName") }}</label> <label for="buildingName">{{ trans(ADDRESS_BUILDING_NAME) }}</label>
</div> </div>
<div class="form-floating my-1"> <div class="form-floating my-1">
<input <input
@ -63,10 +63,10 @@
type="text" type="text"
name="extra" name="extra"
maxlength="255" maxlength="255"
:placeholder="$t('extra')" :placeholder="trans(ADDRESS_EXTRA)"
v-model="extra" v-model="extra"
/> />
<label for="extra">{{ $t("extra") }}</label> <label for="extra">{{ trans(ADDRESS_EXTRA) }}</label>
</div> </div>
<div class="form-floating my-1" v-if="!isNoAddress"> <div class="form-floating my-1" v-if="!isNoAddress">
<input <input
@ -74,18 +74,46 @@
type="text" type="text"
name="distribution" name="distribution"
maxlength="255" maxlength="255"
:placeholder="$t('distribution')" :placeholder="trans(ADDRESS_DISTRIBUTION)"
v-model="distribution" v-model="distribution"
/> />
<label for="distribution">{{ $t("distribution") }}</label> <label for="distribution">{{ trans(ADDRESS_DISTRIBUTION) }}</label>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import {
ADDRESS_STREET,
ADDRESS_STREET_NUMBER,
ADDRESS_FLOOR,
ADDRESS_CORRIDOR,
ADDRESS_STEPS,
ADDRESS_FLAT,
ADDRESS_BUILDING_NAME,
ADDRESS_DISTRIBUTION,
ADDRESS_EXTRA,
ADDRESS_FILL_AN_ADDRESS,
trans,
} from "translator";
export default { export default {
name: "AddressMore", name: "AddressMore",
setup() {
return {
ADDRESS_STREET,
ADDRESS_STREET_NUMBER,
ADDRESS_FLOOR,
ADDRESS_CORRIDOR,
ADDRESS_STEPS,
ADDRESS_FLAT,
ADDRESS_BUILDING_NAME,
ADDRESS_DISTRIBUTION,
ADDRESS_EXTRA,
ADDRESS_FILL_AN_ADDRESS,
trans,
};
},
props: ["entity", "isNoAddress"], props: ["entity", "isNoAddress"],
computed: { computed: {
floor: { floor: {

View File

@ -1,16 +1,16 @@
<template> <template>
<div class="my-1"> <div class="my-1">
<label class="col-form-label" for="addressSelector">{{ <label class="col-form-label" for="addressSelector">{{
$t("address") trans(ADDRESS_ADDRESS)
}}</label> }}</label>
<VueMultiselect <VueMultiselect
id="addressSelector" id="addressSelector"
v-model="value" v-model="value"
:placeholder="$t('select_address')" :placeholder="trans(ADDRESS_SELECT_ADDRESS)"
:tag-placeholder="$t('create_address')" :tag-placeholder="trans(ADDRESS_CREATE_ADDRESS)"
:select-label="$t('multiselect.select_label')" :select-label="trans(MULTISELECT_SELECT_LABEL)"
:deselect-label="$t('create_address')" :deselect-label="trans(ADDRESS_CREATE_ADDRESS)"
:selected-label="$t('multiselect.selected_label')" :selected-label="trans(MULTISELECT_SELECTED_LABEL)"
@search-change="listenInputSearch" @search-change="listenInputSearch"
:internal-search="false" :internal-search="false"
ref="addressSelector" ref="addressSelector"
@ -42,10 +42,10 @@
class="form-control" class="form-control"
type="text" type="text"
name="street" name="street"
:placeholder="$t('street')" :placeholder="trans(ADDRESS_STREET)"
v-model="street" v-model="street"
/> />
<label for="street">{{ $t("street") }}</label> <label for="street">{{ trans(ADDRESS_STREET) }}</label>
</div> </div>
</div> </div>
<div class="col-2"> <div class="col-2">
@ -54,10 +54,10 @@
class="form-control" class="form-control"
type="text" type="text"
name="streetNumber" name="streetNumber"
:placeholder="$t('streetNumber')" :placeholder="trans(ADDRESS_STREET_NUMBER)"
v-model="streetNumber" v-model="streetNumber"
/> />
<label for="streetNumber">{{ $t("streetNumber") }}</label> <label for="streetNumber">{{ trans(ADDRESS_STREET_NUMBER) }}</label>
</div> </div>
</div> </div>
</div> </div>
@ -69,10 +69,32 @@ import {
searchReferenceAddresses, searchReferenceAddresses,
fetchReferenceAddresses, fetchReferenceAddresses,
} from "../../api.js"; } from "../../api.js";
import {
ADDRESS_STREET,
ADDRESS_STREET_NUMBER,
ADDRESS_ADDRESS,
MULTISELECT_SELECTED_LABEL,
MULTISELECT_SELECT_LABEL,
ADDRESS_SELECT_ADDRESS,
ADDRESS_CREATE_ADDRESS,
trans,
} from "translator";
export default { export default {
name: "AddressSelection", name: "AddressSelection",
components: { VueMultiselect }, components: { VueMultiselect },
setup() {
return {
ADDRESS_STREET,
ADDRESS_STREET_NUMBER,
ADDRESS_ADDRESS,
MULTISELECT_SELECTED_LABEL,
MULTISELECT_SELECT_LABEL,
ADDRESS_SELECT_ADDRESS,
ADDRESS_CREATE_ADDRESS,
trans,
};
},
props: ["entity", "context", "updateMapCenter", "flag", "checkErrors"], props: ["entity", "context", "updateMapCenter", "flag", "checkErrors"],
data() { data() {
return { return {

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="my-1"> <div class="my-1">
<label class="col-form-label">{{ $t("city") }}</label> <label class="col-form-label">{{ trans(ADDRESS_CITY) }}</label>
<VueMultiselect <VueMultiselect
id="citySelector" id="citySelector"
v-model="value" v-model="value"
@ -12,15 +12,15 @@
track-by="id" track-by="id"
label="value" label="value"
:custom-label="transName" :custom-label="transName"
:placeholder="$t('select_city')" :placeholder="trans(ADDRESS_SELECT_CITY)"
:select-label="$t('multiselect.select_label')" :select-label="trans(MULTISELECT_SELECT_LABEL)"
:deselect-label="$t('create_postal_code')" :deselect-label="trans(ADDRESS_CREATE_POSTAL_CODE)"
:selected-label="$t('multiselect.selected_label')" :selected-label="trans(MULTISELECT_SELECTED_LABEL)"
:taggable="true" :taggable="true"
:multiple="false" :multiple="false"
:internal-search="false" :internal-search="false"
@tag="addPostcode" @tag="addPostcode"
:tag-placeholder="$t('create_postal_code')" :tag-placeholder="trans(ADDRESS_CREATE_POSTAL_CODE)"
:loading="isLoading" :loading="isLoading"
:options="cities" :options="cities"
/> />
@ -36,10 +36,10 @@
class="form-control" class="form-control"
type="text" type="text"
id="code" id="code"
:placeholder="$t('postalCode_code')" :placeholder="trans(ADDRESS_POSTAL_CODE_CODE)"
v-model="code" v-model="code"
/> />
<label for="code">{{ $t("postalCode_code") }}</label> <label for="code">{{ trans(ADDRESS_POSTAL_CODE_CODE) }}</label>
</div> </div>
</div> </div>
<div class="col-8"> <div class="col-8">
@ -48,10 +48,10 @@
class="form-control" class="form-control"
type="text" type="text"
id="name" id="name"
:placeholder="$t('postalCode_name')" :placeholder="trans(ADDRESS_POSTAL_CODE_NAME)"
v-model="name" v-model="name"
/> />
<label for="name">{{ $t("postalCode_name") }}</label> <label for="name">{{ trans(ADDRESS_POSTAL_CODE_NAME) }}</label>
</div> </div>
</div> </div>
</div> </div>
@ -60,10 +60,32 @@
<script> <script>
import VueMultiselect from "vue-multiselect"; import VueMultiselect from "vue-multiselect";
import { searchCities, fetchCities } from "../../api.js"; import { searchCities, fetchCities } from "../../api.js";
import {
MULTISELECT_SELECTED_LABEL,
MULTISELECT_SELECT_LABEL,
ADDRESS_POSTAL_CODE_CODE,
ADDRESS_POSTAL_CODE_NAME,
ADDRESS_CREATE_POSTAL_CODE,
ADDRESS_CITY,
ADDRESS_SELECT_CITY,
trans,
} from "translator";
export default { export default {
name: "CitySelection", name: "CitySelection",
components: { VueMultiselect }, components: { VueMultiselect },
setup() {
return {
MULTISELECT_SELECTED_LABEL,
MULTISELECT_SELECT_LABEL,
ADDRESS_CITY,
ADDRESS_SELECT_CITY,
ADDRESS_POSTAL_CODE_CODE,
ADDRESS_POSTAL_CODE_NAME,
ADDRESS_CREATE_POSTAL_CODE,
trans,
};
},
props: [ props: [
"entity", "entity",
"context", "context",

View File

@ -1,19 +1,19 @@
<template> <template>
<div class="my-1"> <div class="my-1">
<label class="col-form-label" for="countrySelect">{{ <label class="col-form-label" for="countrySelect">{{
$t("country") trans(ADDRESS_COUNTRY)
}}</label> }}</label>
<VueMultiselect <VueMultiselect
id="countrySelect" id="countrySelect"
label="name" label="name"
track-by="id" track-by="id"
:custom-label="transName" :custom-label="transName"
:placeholder="$t('select_country')" :placeholder="trans(ADDRESS_SELECT_COUNTRY)"
:options="sortedCountries" :options="sortedCountries"
v-model="value" v-model="value"
:select-label="$t('multiselect.select_label')" :select-label="trans(MULTISELECT_SELECT_LABEL)"
:deselect-label="$t('multiselect.deselect_label')" :deselect-label="trans(MULTISELECT_DESELECT_LABEL)"
:selected-label="$t('multiselect.selected_label')" :selected-label="trans(MULTISELECT_SELECTED_LABEL)"
@select="selectCountry" @select="selectCountry"
@remove="remove" @remove="remove"
/> />
@ -22,10 +22,28 @@
<script> <script>
import VueMultiselect from "vue-multiselect"; import VueMultiselect from "vue-multiselect";
import {
MULTISELECT_SELECTED_LABEL,
MULTISELECT_SELECT_LABEL,
MULTISELECT_DESELECT_LABEL,
ADDRESS_COUNTRY,
ADDRESS_SELECT_COUNTRY,
trans,
} from "translator";
export default { export default {
name: "CountrySelection", name: "CountrySelection",
components: { VueMultiselect }, components: { VueMultiselect },
setup() {
return {
MULTISELECT_SELECTED_LABEL,
MULTISELECT_SELECT_LABEL,
MULTISELECT_DESELECT_LABEL,
ADDRESS_COUNTRY,
ADDRESS_SELECT_COUNTRY,
trans,
};
},
props: ["context", "entity", "flag", "checkErrors"], props: ["context", "entity", "flag", "checkErrors"],
emits: ["getCities"], emits: ["getCities"],
data() { data() {

View File

@ -18,7 +18,7 @@
</div> </div>
<h4 class="h3"> <h4 class="h3">
{{ $t("select_an_address_title") }} {{ trans(ADDRESS_SELECT_AN_ADDRESS_TITLE) }}
</h4> </h4>
<div class="row my-3"> <div class="row my-3">
<div class="col-lg-6"> <div class="col-lg-6">
@ -31,7 +31,7 @@
:value="valueConfidential" :value="valueConfidential"
/> />
<label class="form-check-label" for="isConfidential"> <label class="form-check-label" for="isConfidential">
{{ $t("isConfidential") }} {{ trans(ADDRESS_IS_CONFIDENTIAL) }}
</label> </label>
</div> </div>
<div class="form-check"> <div class="form-check">
@ -43,7 +43,7 @@
:value="value" :value="value"
/> />
<label class="form-check-label" for="isNoAddress"> <label class="form-check-label" for="isNoAddress">
{{ $t("isNoAddress") }} {{ trans(ADDRESS_IS_NO_ADDRESS) }}
</label> </label>
</div> </div>
@ -108,6 +108,13 @@ import AddressSelection from "./AddAddress/AddressSelection";
import AddressMap from "./AddAddress/AddressMap"; import AddressMap from "./AddAddress/AddressMap";
import AddressMore from "./AddAddress/AddressMore"; import AddressMore from "./AddAddress/AddressMore";
import ActionButtons from "./ActionButtons.vue"; import ActionButtons from "./ActionButtons.vue";
import {
ADDRESS_SELECT_AN_ADDRESS_TITLE,
ADDRESS_IS_CONFIDENTIAL,
ADDRESS_IS_NO_ADDRESS,
trans,
} from "translator";
export default { export default {
name: "EditPane", name: "EditPane",
@ -119,6 +126,14 @@ export default {
AddressMore, AddressMore,
ActionButtons, ActionButtons,
}, },
setup() {
return {
trans,
ADDRESS_SELECT_AN_ADDRESS_TITLE,
ADDRESS_IS_CONFIDENTIAL,
ADDRESS_IS_NO_ADDRESS
};
},
props: [ props: [
"context", "context",
"options", "options",

View File

@ -5,7 +5,7 @@
v-if="flag.loading" v-if="flag.loading"
class="fa fa-circle-o-notch fa-spin fa-2x fa-fw" class="fa fa-circle-o-notch fa-spin fa-2x fa-fw"
/> />
<span class="sr-only">{{ $t("loading") }}</span> <span class="sr-only">{{ trans(ADDRESS_LOADING) }}</span>
</div> </div>
<div v-if="errorMsg && errorMsg.length > 0" class="alert alert-danger"> <div v-if="errorMsg && errorMsg.length > 0" class="alert alert-danger">
@ -13,8 +13,8 @@
</div> </div>
<div v-if="flag.success" class="alert alert-success"> <div v-if="flag.success" class="alert alert-success">
{{ $t(getSuccessText) }} {{ trans(getSuccessText) }}
<span v-if="forceRedirect">{{ $t("wait_redirection") }}</span> <span v-if="forceRedirect">{{ trans(ADDRESS_WAIT_REDIRECTION) }}</span>
</div> </div>
<div <div
@ -28,7 +28,7 @@
<div class="no-address-yet"> <div class="no-address-yet">
<i class="fa fa-map-marker" aria-hidden="true" /> <i class="fa fa-map-marker" aria-hidden="true" />
<p class="chill-no-data-statement"> <p class="chill-no-data-statement">
{{ $t("not_yet_address") }} {{ trans(ADDRESS_NOT_YET_ADDRESS) }}
</p> </p>
<action-buttons <action-buttons
@ -43,10 +43,10 @@
:class="getClassButton" :class="getClassButton"
type="button" type="button"
name="button" name="button"
:title="$t(getTextButton)" :title="trans(getTextButton)"
> >
<span v-if="displayTextButton">{{ <span v-if="displayTextButton">{{
$t(getTextButton) trans(getTextButton)
}}</span> }}</span>
</button> </button>
</template> </template>
@ -71,10 +71,10 @@
:class="getClassButton" :class="getClassButton"
type="button" type="button"
name="button" name="button"
:title="$t(getTextButton)" :title="trans(getTextButton)"
> >
<span v-if="displayTextButton">{{ <span v-if="displayTextButton">{{
$t(getTextButton) trans(getTextButton)
}}</span> }}</span>
</button> </button>
</template> </template>
@ -95,11 +95,11 @@
:class="getClassButton" :class="getClassButton"
type="button" type="button"
name="button" name="button"
:title="$t(getTextButton)" :title="trans(getTextButton)"
> >
<span v-if="displayTextButton">{{ <span v-if="displayTextButton">{{
$t(getTextButton) trans(getTextButton)
}}</span> }}</span>
</button> </button>
</template> </template>
</action-buttons> </action-buttons>
@ -109,13 +109,37 @@
<script> <script>
import AddressRenderBox from "ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue"; import AddressRenderBox from "ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue";
import ActionButtons from "./ActionButtons.vue"; import ActionButtons from "./ActionButtons.vue";
import {
ACTIVITY_CREATE_ADDRESS,
ACTIVITY_EDIT_ADDRESS,
ADDRESS_NOT_YET_ADDRESS,
ADDRESS_WAIT_REDIRECTION,
ADDRESS_LOADING,
ADDRESS_ADDRESS_EDIT_SUCCESS,
ADDRESS_ADDRESS_NEW_SUCCESS,
trans,
} from "translator";
export default { export default {
name: "ShowPane", name: "ShowPane",
methods: {
},
components: { components: {
AddressRenderBox, AddressRenderBox,
ActionButtons, ActionButtons,
}, },
setup() {
return {
trans,
ACTIVITY_CREATE_ADDRESS,
ACTIVITY_EDIT_ADDRESS,
ADDRESS_NOT_YET_ADDRESS,
ADDRESS_WAIT_REDIRECTION,
ADDRESS_LOADING,
ADDRESS_ADDRESS_NEW_SUCCESS,
ADDRESS_ADDRESS_EDIT_SUCCESS
};
},
props: [ props: [
"context", "context",
"defaultz", "defaultz",
@ -156,18 +180,20 @@ export default {
(this.options.button.text.edit !== null || (this.options.button.text.edit !== null ||
this.options.button.text.create !== null) this.options.button.text.create !== null)
) { ) {
// console.log('this.options.button.text', this.options.button.text)
return this.context.edit return this.context.edit
? this.options.button.text.edit ? ACTIVITY_CREATE_ADDRESS
: this.options.button.text.create; : ACTIVITY_EDIT_ADDRESS;
} }
console.log('defaultz', this.defaultz);
return this.context.edit return this.context.edit
? this.defaultz.button.text.edit ? this.defaultz.button.text.edit
: this.defaultz.button.text.create; : this.defaultz.button.text.create;
}, },
getSuccessText() { getSuccessText() {
return this.context.edit return this.context.edit
? "address_edit_success" ? ADDRESS_ADDRESS_EDIT_SUCCESS
: "address_new_success"; : ADDRESS_ADDRESS_NEW_SUCCESS;
}, },
onlyButton() { onlyButton() {
return typeof this.options.onlyButton !== "undefined" return typeof this.options.onlyButton !== "undefined"