Merge remote-tracking branch 'origin/master' into issue706_cc_in_workflow-2

This commit is contained in:
2023-04-13 09:53:23 +02:00
154 changed files with 3079 additions and 2666 deletions

View File

@@ -0,0 +1,35 @@
import {Address, GeographicalUnitLayer, SimpleGeographicalUnit} from "../../types";
import {fetchResults, makeFetch} from "./apiMethods";
export const getAddressById = async (address_id: number): Promise<Address> =>
{
const url = `/api/1.0/main/address/${address_id}.json`;
const response = await fetch(url);
if (response.ok) {
return response.json();
}
throw Error('Error with request resource response');
};
export const getGeographicalUnitsByAddress = async (address: Address): Promise<SimpleGeographicalUnit[]> => {
return fetchResults<SimpleGeographicalUnit>(`/api/1.0/main/geographical-unit/by-address/${address.address_id}.json`);
}
export const getAllGeographicalUnitLayers = async (): Promise<GeographicalUnitLayer[]> => {
return fetchResults<GeographicalUnitLayer>(`/api/1.0/main/geographical-unit-layer.json`);
}
export const syncAddressWithReference = async (address: Address): Promise<Address> => {
return makeFetch<null, Address>("POST", `/api/1.0/main/address/reference-match/${address.address_id}/sync-with-reference`);
}
export const markAddressReviewed = async (address: Address): Promise<Address> => {
return makeFetch<null, Address>("POST", `/api/1.0/main/address/reference-match/${address.address_id}/set/reviewed`);
}
export const markAddressToReview = async (address: Address): Promise<Address> => {
return makeFetch<null, Address>("POST", `/api/1.0/main/address/reference-match/${address.address_id}/set/to_review`);
}

View File

@@ -67,9 +67,6 @@ export const makeFetch = <Input, Output>(method: 'POST'|'GET'|'PUT'|'PATCH'|'DEL
},
};
console.log('for url '+url, body);
console.log('for url '+url, body !== null);
if (body !== null && typeof body !== 'undefined') {
Object.assign(opts, {body: JSON.stringify(body)})
}
@@ -77,9 +74,6 @@ export const makeFetch = <Input, Output>(method: 'POST'|'GET'|'PUT'|'PATCH'|'DEL
if (typeof options !== 'undefined') {
opts = Object.assign(opts, options);
}
console.log('will fetch', url);
console.log('content for ' + url, opts);
return fetch(url, opts)
.then(response => {
if (response.ok) {

View File

@@ -0,0 +1,39 @@
import AddressDetailsButton from "../../vuejs/_components/AddressDetails/AddressDetailsButton.vue";
import {createApp} from "vue";
import {createI18n} from "vue-i18n";
import {_createI18n} from "../../vuejs/_js/i18n";
import {Address} from "../../types";
const i18n = _createI18n({});
document.querySelectorAll<HTMLSpanElement>('span[data-address-details]').forEach((el) => {
const dataset = el.dataset as {
addressId: string,
addressRefStatus: string,
};
const app = createApp({
components: {AddressDetailsButton},
data() {
return {
addressId: Number.parseInt(dataset.addressId),
addressRefStatus: dataset.addressRefStatus,
}
},
template: '<address-details-button :address_id="addressId" :address_ref_status="addressRefStatus" @update-address="onUpdateAddress"></address-details-button>',
methods: {
onUpdateAddress: (address: Address): void => {
if (address.refStatus === 'to_review' || address.refStatus === 'reviewed') {
// in this two case, the address content do not change
return;
}
if (window.confirm("L'adresse a été modifiée. Vous pouvez continuer votre travail. Cependant, pour afficher les données immédiatement, veuillez recharger la page. \n\n Voulez-vous recharger la page immédiatement ?")) {
window.location.reload();
}
}
}
});
app.use(i18n);
app.mount(el);
});

View File

@@ -18,6 +18,7 @@ function loadDynamicPicker(element) {
isMultiple = parseInt(el.dataset.multiple) === 1,
uniqId = el.dataset.uniqid,
input = element.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'),
// the "picked" will always be an array, even if multiple is false
picked = isMultiple ?
JSON.parse(input.value) : (
(input.value === '[]' || input.value === '') ?
@@ -54,15 +55,11 @@ function loadDynamicPicker(element) {
},
computed: {
notPickedSuggested() {
if (this.multiple) {
const pickedIds = new Set();
for (const p of this.picked) {
pickedIds.add(`${p.type}${p.id}`);
}
return this.suggested.filter(e => !pickedIds.has(`${e.type}${e.id}`))
const pickedIds = new Set();
for (const p of this.picked) {
pickedIds.add(`${p.type}${p.id}`);
}
return this.suggested.filter(e => e.type !== this.picked.type && e.id !== e.picked.id);
return this.suggested.filter(e => !pickedIds.has(`${e.type}${e.id}`))
}
},
methods: {
@@ -90,7 +87,11 @@ function loadDynamicPicker(element) {
this.suggested.push(entity);
}
this.picked = this.picked.filter(e => !(e.type === entity.type && e.id === entity.id));
input.value = JSON.stringify(this.picked);
if (this.multiple) {
input.value = JSON.stringify(this.picked);
} else {
input.value = "";
}
},
}
})

View File

@@ -70,6 +70,8 @@ export interface Country {
code: string;
}
export type AddressRefStatus = 'match'|'to_review'|'reviewed';
export interface Address {
type: "address";
address_id: number;
@@ -90,6 +92,13 @@ export interface Address {
addressReference: AddressReference | null;
validFrom: DateTime;
validTo: DateTime | null;
point: Point | null;
refStatus: AddressRefStatus;
isNoAddress: boolean;
}
export interface AddressWithPoint extends Address {
point: Point
}
export interface AddressReference {
@@ -106,6 +115,19 @@ export interface AddressReference {
updatedAt: DateTime | null;
}
export interface SimpleGeographicalUnit {
id: number;
layerId: number;
unitName: string;
unitRefId: string;
}
export interface GeographicalUnitLayer {
id: number;
name: TranslatableString;
refId: string;
}
export interface Location {
type: "location";
id: number;

View File

@@ -1,3 +1,5 @@
import {getAddressById} from 'ChillMainAssets/lib/api/address';
/**
* Endpoint chill_api_single_country__index
* method GET, get Country Object
@@ -188,13 +190,7 @@ const postPostalCode = (postalCode) => { //<--
* @returns {Promise} a promise containing a Address object
*/
const getAddress = (id) => {
//console.log('<< get address');
const url = `/api/1.0/main/address/${id}.json`;
return fetch(url)
.then(response => {
if (response.ok) { return response.json(); }
throw Error('Error with request resource response');
});
return getAddressById(id);
};
export {

View File

@@ -59,7 +59,7 @@
v-bind:insideModal="false"
@pick-address="this.pickAddress"
ref="suggestAddress">
<template v-slot:before v-if="!bypassFirstStep">
<a class="btn btn-cancel" @click="resetPane">
{{ $t('action.cancel') }}
@@ -73,7 +73,7 @@
</button>
</li>
</template>
</suggest-pane>
</div>
</template>
@@ -133,7 +133,7 @@
v-bind:insideModal="false"
@getCities="getCities"
@getReferenceAddresses="getReferenceAddresses">
<template v-slot:before>
<a class="btn btn-cancel" @click="resetPane">
{{ $t('action.cancel') }}
@@ -152,7 +152,7 @@
</button>
</li>
</template>
</edit-pane>
</div>
</template>
@@ -206,7 +206,7 @@
v-bind:flag="this.flag"
v-bind:insideModal="false"
ref="dateAddress">
<template v-slot:before>
<button class="btn btn-misc" @click="openEditPane">
<i class="fa fa-fw fa-arrow-left"></i>
@@ -220,7 +220,7 @@
</button>
</li>
</template>
</date-pane>
</div>
</template>
@@ -580,15 +580,15 @@ export default {
this.entity.selected.city = this.context.edit ? this.entity.address.postcode : {};
this.entity.selected.address = {};
this.entity.selected.address.street = this.context.edit ? this.entity.address.street: null;
this.entity.selected.address.streetNumber = this.context.edit ? this.entity.address.streetNumber: null;
this.entity.selected.address.floor = this.context.edit ? this.entity.address.floor: null;
this.entity.selected.address.corridor = this.context.edit ? this.entity.address.corridor: null;
this.entity.selected.address.steps = this.context.edit ? this.entity.address.steps: null;
this.entity.selected.address.flat = this.context.edit ? this.entity.address.flat: null;
this.entity.selected.address.buildingName = this.context.edit ? this.entity.address.buildingName: null;
this.entity.selected.address.distribution = this.context.edit ? this.entity.address.distribution: null;
this.entity.selected.address.extra = this.context.edit ? this.entity.address.extra: null;
this.entity.selected.address.street = this.context.edit ? this.entity.address.street: '';
this.entity.selected.address.streetNumber = this.context.edit ? this.entity.address.streetNumber: '';
this.entity.selected.address.floor = this.context.edit ? this.entity.address.floor: '';
this.entity.selected.address.corridor = this.context.edit ? this.entity.address.corridor: '';
this.entity.selected.address.steps = this.context.edit ? this.entity.address.steps: '';
this.entity.selected.address.flat = this.context.edit ? this.entity.address.flat: '';
this.entity.selected.address.buildingName = this.context.edit ? this.entity.address.buildingName: '';
this.entity.selected.address.distribution = this.context.edit ? this.entity.address.distribution: '';
this.entity.selected.address.extra = this.context.edit ? this.entity.address.extra: '';
this.entity.selected.writeNew.address = this.context.edit && this.entity.address.addressReference === null && this.entity.address.street.length > 0
this.entity.selected.writeNew.postcode = false // NB: this used to be this.context.edit, but think it was erroneous;

View File

@@ -0,0 +1,68 @@
<template>
<span v-if="data.working_ref_status === 'to_review'" class="badge bg-danger address-details-button-warning">L'adresse de référence a été modifiée</span>
<a v-if="data.loading === false" @click.prevent="clickOrOpen" class="btn btn-sm btn-misc">
<span class="fa fa-map address-details-button"></span>
</a>
<span v-if="data.loading" class="fa fa-spin fa-spinner "></span>
<AddressModal :address="data.working_address" @update-address="onUpdateAddress" ref="address_modal"></AddressModal>
</template>
<script lang="ts" setup>
import {Address, AddressRefStatus} from "../../../types";
import {onMounted, reactive, ref} from "vue";
import {getAddressById} from "../../../lib/api/address";
import AddressModal from "./AddressModal.vue";
export interface AddressModalContentProps {
address_id: number;
address_ref_status: AddressRefStatus | null;
}
const data = reactive<{
loading: boolean,
working_address: Address | null,
working_ref_status: AddressRefStatus | null,
}>({
loading: false,
working_address: null,
working_ref_status: null,
});
const props = defineProps<AddressModalContentProps>();
const emit = defineEmits<{
(e: 'update-address', value: Address): void
}>();
const address_modal = ref<InstanceType<typeof AddressModal> | null>(null);
onMounted(() => {
data.working_ref_status = props.address_ref_status;
});
async function clickOrOpen(): Promise<void> {
if (data.working_address === null) {
data.loading = true;
data.working_address = await getAddressById(props.address_id);
data.working_ref_status = data.working_address.refStatus;
data.loading = false;
}
// open the modal
address_modal.value?.open();
}
const onUpdateAddress = (address: Address): void => {
data.working_address = address;
data.working_ref_status = address.refStatus;
emit('update-address', address);
}
</script>
<style scoped lang="scss">
.address-details-button-warning {
display: inline-block;
margin-right: 0.3rem;
}
</style>

View File

@@ -0,0 +1,33 @@
<template>
<address-render-box :address="props.address" :show-button-details="false"></address-render-box>
<address-details-ref-matching :address="props.address" @update-address="onUpdateAddress"></address-details-ref-matching>
<address-details-map :address="props.address"></address-details-map>
<address-details-geographical-layers :address="props.address"></address-details-geographical-layers>
</template>
<script lang="ts" setup>
import {Address} from "../../../types";
import AddressDetailsMap from "./Parts/AddressDetailsMap.vue";
import AddressRenderBox from "../Entity/AddressRenderBox.vue";
import AddressDetailsGeographicalLayers from "./Parts/AddressDetailsGeographicalLayers.vue";
import AddressDetailsRefMatching from "./Parts/AddressDetailsRefMatching.vue";
interface AddressModalContentProps {
address: Address,
}
const props = defineProps<AddressModalContentProps>();
const emit = defineEmits<{
(e: 'update-address', value: Address): void
}>();
const onUpdateAddress = (address: Address): void => {
emit('update-address', address);
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,57 @@
<template>
<teleport to="body">
<modal v-if="state.show_modal" @close="close">
<template v-slot:header>
<h2>Détails d'une adresse</h2>
</template>
<template v-slot:body>
<address-details-content :address="props.address" @update-address="onUpdateAddress"></address-details-content>
</template>
</modal>
</teleport>
</template>
<script lang="ts" setup>
import {reactive, ref} from "vue";
import Modal from 'ChillMainAssets/vuejs/_components/Modal.vue';
import {Address} from "../../../types";
import AddressDetailsContent from "./AddressDetailsContent.vue";
interface AddressModalProps {
address: Address
}
interface AddressModalState {
show_modal: boolean,
}
const props = defineProps<AddressModalProps>();
const emit = defineEmits<{
(e: 'update-address', value: Address): void
}>();
const state: AddressModalState = reactive({show_modal: false});
const open = (): void => {
state.show_modal = true;
}
const close = (): void => {
state.show_modal = false;
}
const onUpdateAddress = (address: Address): void => {
emit('update-address', address);
}
defineExpose({
close,
open,
});
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,55 @@
<template>
<template v-for="container in data.containers">
<h4>{{ container.layer.name.fr }}</h4>
<ul>
<li v-for="unit in container.units">{{ unit.unitName }} ({{ unit.unitRefId }})</li>
</ul>
</template>
</template>
<script lang="ts" setup>
import {Address, GeographicalUnitLayer, SimpleGeographicalUnit} from "../../../../types";
import {getGeographicalUnitsByAddress, getAllGeographicalUnitLayers} from "../../../../lib/api/address";
import {onMounted, reactive} from "vue";
export interface AddressDetailsGeographicalLayersProp {
address: Address
};
interface GeographicalUnitContainer {
layer: GeographicalUnitLayer;
units: SimpleGeographicalUnit[];
}
const props = defineProps<AddressDetailsGeographicalLayersProp>();
const data: {
containers: GeographicalUnitContainer[]
} = reactive({
containers: []
});
onMounted(async () => {
const [units, layers] = await Promise.all([
getGeographicalUnitsByAddress(props.address),
getAllGeographicalUnitLayers()
]) as [SimpleGeographicalUnit[], GeographicalUnitLayer[]];
for (let layer of layers) {
let us = units.filter((u) => u.layerId === layer.id);
if (us.length > 0) {
data.containers.push({
layer,
units: us
});
}
}
})
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,90 @@
<template>
<div v-if="props.address.isNoAddress" class="alert alert-info">
Cette adresse est incomplète. La position géographique est approximative.
</div>
<div v-if="props.address.point !== null" class="address_details_map" ref="map_div"></div>
<p>Voir sur <a :href="makeUrlGoogleMap(props.address)" target="_blank">Google Maps</a> <a :href="makeUrlOsm(props.address)" target="_blank">OSM</a></p>
</template>
<script lang="ts" setup>
import {onMounted, ref} from "vue";
import 'leaflet/dist/leaflet.css';
import markerIconPng from "leaflet/dist/images/marker-icon.png";
import L, {LatLngExpression, LatLngTuple} from "leaflet";
import {Address, Point} from "../../../../types";
const lonLatForLeaflet = (point: Point): LatLngTuple => {
return [point.coordinates[1], point.coordinates[0]];
}
export interface MapProps {
address: Address,
}
const props = defineProps<MapProps>();
const map_div = ref<HTMLDivElement | null>(null)
let map: L.Map|null = null;
let marker: L.Marker|null = null;
onMounted(() => {
if (map_div.value === null) {
// there is no map div when the address does not have any Point
return;
}
if (props.address.point !== null) {
map = L.map(map_div.value);
map.setView(lonLatForLeaflet(props.address.point), 18);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
const markerIcon = L.icon({
iconUrl: markerIconPng,
iconAnchor: [12, 41],
});
marker = L.marker(lonLatForLeaflet(props.address.point), {icon: markerIcon});
marker.addTo(map);
}
});
const makeUrlGoogleMap = (address: Address): string => {
const params = new URLSearchParams();
params.append('api', '1');
if (address.point !== null && address.addressReference !== null) {
params.append('query', `${address.point.coordinates[1]} ${address.point.coordinates[0]}`);
} else {
params.append('query', address.lines.join(', '));
}
return `https://www.google.com/maps/search/?${params.toString()}`;
}
const makeUrlOsm = (address: Address): string => {
if (address.point !== null && address.addressReference !== null) {
const params = new URLSearchParams();
params.append('mlat', `${address.point.coordinates[1]}`);
params.append('mlon', `${address.point.coordinates[0]}`);
const hashParams = new URLSearchParams();
hashParams.append('map', `18/${address.point.coordinates[1]}/${address.point.coordinates[0]}`);
return `https://www.openstreetmap.org/?${params.toString()}#${hashParams.toString()}`;
}
const params = new URLSearchParams();
params.append('query', address.lines.join(', '));
return `https://www.openstreetmap.org/search?${params.toString()}`;
}
</script>
<style scoped>
div.address_details_map {
height: 250px;
}
</style>

View File

@@ -0,0 +1,96 @@
<template>
<template v-if="props.address.refStatus !== 'match'">
<div v-if="props.address.refStatus === 'to_review' || props.address.refStatus === 'reviewed'" :class="{alert: true, 'alert-danger': props.address.refStatus === 'to_review', 'alert-warning': props.address.refStatus === 'reviewed'}">
<p v-if="props.address.refStatus === 'to_review'"><i class="fa fa-warning"></i> L'adresse de référence a été modifiée.</p>
<p v-if="props.address.refStatus === 'reviewed'">L'adresse est conservée, mais diffère de l'adresse de référence.</p>
<template v-if="props.address.addressReference.street !== props.address.street || props.address.addressReference.streetNumber !== props.address.streetNumber">
<template v-if="props.address.country.code === 'BE'">
<div class="difference">
<span class="old">{{ props.address.street }} {{props.address.streetNumber}}</span>
<span class="new">{{ props.address.addressReference.street }} {{ props.address.addressReference.streetNumber }}</span>
</div>
</template>
<template v-else>
<div class="difference">
<span class="old">{{props.address.streetNumber}} {{ props.address.street }}</span>
<span class="new">{{ props.address.addressReference.streetNumber }} {{ props.address.addressReference.street }}</span>
</div>
</template>
</template>
<template v-if="props.address.addressReference.postcode.id !== props.address.postcode.id">
<div class="difference">
<span class="old">{{ props.address.postcode.code }} {{props.address.postcode.name }}</span>
<span class="new">{{ props.address.addressReference.postcode.code }} {{ props.address.addressReference.postcode.name }}</span>
</div>
</template>
<template v-if="props.address.point !== null && (props.address.point.coordinates[0] !== props.address.addressReference.point.coordinates[0] || props.address.point.coordinates[1] !== props.address.addressReference.point.coordinates[1])">
<div class="difference">
<span class="old">{{ props.address.point.coordinates[0] }} {{ props.address.point.coordinates[1]}}</span>
<span class="new">{{ props.address.addressReference.point.coordinates[0] }} {{ props.address.addressReference.point.coordinates[1]}}</span>
</div>
</template>
<ul class="record_actions">
<li v-if="props.address.refStatus === 'to_review'"><button class="btn btn-sm btn-update" @click="applyUpdate">Appliquer les modifications</button></li>
<li v-if="props.address.refStatus === 'to_review'"><button class="btn btn-sm btn-primary" @click="keepCurrentAddress">Conserver</button></li>
<li v-if="props.address.refStatus === 'reviewed'"><button class="btn btn-sm btn-primary" @click="backToReview">-examiner</button></li>
</ul>
</div>
</template>
</template>
<script lang="ts" setup>
import {Address} from "../../../../types";
import {markAddressReviewed, markAddressToReview, syncAddressWithReference} from "../../../../lib/api/address";
export interface AddressDetailsRefMatchingProps {
address: Address;
}
const props = defineProps<AddressDetailsRefMatchingProps>();
const emit = defineEmits<{
(e: 'update-address', value: Address): void
}>();
const applyUpdate = async () => {
const new_address = await syncAddressWithReference(props.address);
emit('update-address', new_address);
}
const keepCurrentAddress = async () => {
const new_address = await markAddressReviewed(props.address);
emit("update-address", new_address);
}
const backToReview = async () => {
const new_address = await markAddressToReview(props.address);
emit("update-address", new_address);
}
</script>
<style scoped lang="scss">
.difference {
margin-bottom: 0.5rem;
span {
display: block;
}
.old {
text-decoration: red line-through;
}
.new {
font-weight: bold;
color: green;
}
}
</style>

View File

@@ -11,17 +11,18 @@
<p v-for="(l, i) in address.lines" :key="`line-${i}`">
{{ l }}
</p>
<p v-if="showButtonDetails"><address-details-button :address_id="address.address_id" :address_ref_status="address.refStatus"></address-details-button></p>
</div>
<div v-else>
<p v-if="address.text"
<p v-if="'' !== address.text"
class="street">
{{ address.text }}
</p>
<p v-if="address.postcode"
<p v-if="null !== address.postcode"
class="postcode">
{{ address.postcode.code }} {{ address.postcode.name }}
</p>
<p v-if="address.country"
<p v-if="null !== address.country"
class="country">
{{ address.country.name.fr }}
</p>
@@ -35,11 +36,12 @@
<p v-for="(l, i) in address.lines" :key="`line-${i}`">
{{ l }}
</p>
<p v-if="showButtonDetails"><address-details-button :address_id="address.address_id" :address_ref_status="address.refStatus"></address-details-button></p>
</div>
<div v-else>
<p v-if="address.text"
class="street">
{{ address.text }}
{{ address.text }} <template v-if="showButtonDetails"><address-details-button :address_id="address.address_id" :address_ref_status="address.refStatus"></address-details-button></template>
</p>
</div>
</div>
@@ -65,11 +67,13 @@
<script>
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
import AddressDetailsButton from "ChillMainAssets/vuejs/_components/AddressDetails/AddressDetailsButton.vue";
export default {
name: 'AddressRenderBox',
components: {
Confidential
Confidential,
AddressDetailsButton,
},
props: {
address: {
@@ -82,6 +86,10 @@ export default {
useDatePane: {
default: false,
type: Boolean
},
showButtonDetails: {
default: true,
type: Boolean
}
},
computed: {

View File

@@ -69,6 +69,7 @@
<i class="fa fa-li fa-map-marker"></i>
{% endif %}
{{ _self.inline(address, options, streetLine, lines) }}
<span data-address-details="1" data-address-id="{{ address.id|escape('html_attr') }}" data-address-ref-status="{{ address.refStatus|escape('html_attr') }}" ></span>
</li>
{%- endif -%}
@@ -78,6 +79,7 @@
<i class="fa fa-fw fa-map-marker"></i>
{% endif %}
{{ _self.inline(address, options, streetLine, lines) }}
<span data-address-details="1" data-address-id="{{ address.id|escape('html_attr') }}" data-address-ref-status="{{ address.refStatus|escape('html_attr') }}"></span>
</span>
{%- endif -%}
@@ -102,6 +104,7 @@
<div class="noaddress">
{{ 'address.consider homeless'|trans }}
</div>
<p><span data-address-details="1" data-address-id="{{ address.id|escape('html_attr') }}" data-address-ref-status="{{ address.refStatus|escape('html_attr') }}" ></span></p>
{% else %}
<div class="address{% if options['multiline'] %} multiline{% endif %}{% if options['with_delimiter'] %} delimiter{% endif %}">
@@ -109,6 +112,7 @@
<i class="fa fa-fw fa-map-marker"></i>
{% endif %}
{{ _self.raw(lines) }}
<p><span data-address-details="1" data-address-id="{{ address.id|escape('html_attr') }}" data-address-ref-status="{{ address.refStatus|escape('html_attr') }}"></span></p>
</div>
{% endif %}
{{ _self.validity(address, options) }}

View File

@@ -68,6 +68,7 @@
{{ form_row(transition_form.future_cc_users) }}
{{ form_row(transition_form.future_dest_emails) }}
{{ form_errors(transition_form.future_dest_users) }}
</div>
<p>{{ form_label(transition_form.comment) }}</p>

View File

@@ -20,6 +20,7 @@
{{ encore_entry_link_tags('chill') }}
{{ encore_entry_link_tags('mod_blur') }}
{{ encore_entry_link_tags('vue_onthefly') }}
{{ encore_entry_link_tags('mod_address_details') }}
{% block css %}<!-- nothing added to css -->{% endblock %}
</head>
@@ -112,6 +113,7 @@
{{ encore_entry_script_tags('mod_blur') }}
{{ encore_entry_script_tags('chill') }}
{{ encore_entry_script_tags('vue_onthefly') }}
{{ encore_entry_script_tags('mod_address_details') }}
<script type="text/javascript">
window.addEventListener('DOMContentLoaded', function(e) {