mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-23 16:13:50 +00:00
Merge branch 'master' into admin-permissionsgroup-templates
This commit is contained in:
@@ -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`);
|
||||
}
|
@@ -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) {
|
||||
|
@@ -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);
|
||||
});
|
@@ -18,12 +18,13 @@ 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 === '') ?
|
||||
null : [ JSON.parse(input.value) ]
|
||||
)
|
||||
;
|
||||
suggested = JSON.parse(el.dataset.suggested)
|
||||
|
||||
if (!isMultiple) {
|
||||
if (input.value === '[]'){
|
||||
@@ -37,6 +38,7 @@ function loadDynamicPicker(element) {
|
||||
':types="types" ' +
|
||||
':picked="picked" ' +
|
||||
':uniqid="uniqid" ' +
|
||||
':suggested="notPickedSuggested" ' +
|
||||
'@addNewEntity="addNewEntity" ' +
|
||||
'@removeEntity="removeEntity"></pick-entity>',
|
||||
components: {
|
||||
@@ -48,16 +50,27 @@ function loadDynamicPicker(element) {
|
||||
types: JSON.parse(el.dataset.types),
|
||||
picked: picked === null ? [] : picked,
|
||||
uniqid: el.dataset.uniqid,
|
||||
suggested: suggested
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
notPickedSuggested() {
|
||||
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}`))
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addNewEntity(entity) {
|
||||
addNewEntity({entity}) {
|
||||
if (this.multiple) {
|
||||
if (!this.picked.some(el => {
|
||||
return el.type === entity.type && el.id === entity.id;
|
||||
})) {
|
||||
this.picked.push(entity);
|
||||
input.value = JSON.stringify(this.picked);
|
||||
console.log(entity)
|
||||
}
|
||||
} else {
|
||||
if (!this.picked.some(el => {
|
||||
@@ -69,9 +82,16 @@ function loadDynamicPicker(element) {
|
||||
}
|
||||
}
|
||||
},
|
||||
removeEntity(entity) {
|
||||
removeEntity({entity}) {
|
||||
if (-1 === this.suggested.findIndex(e => e.type === entity.type && e.id === entity.id)) {
|
||||
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 = "";
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
@@ -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;
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
@@ -46,8 +46,7 @@
|
||||
:class="{'active': activeTab === 'MyTasks'}"
|
||||
@click="selectTab('MyTasks')">
|
||||
{{ $t('my_tasks.tab') }}
|
||||
<tab-counter :count="state.tasks.warning.count"></tab-counter>
|
||||
<tab-counter :count="state.tasks.alert.count"></tab-counter>
|
||||
<tab-counter :count="state.tasks.warning.count + state.tasks.alert.count"></tab-counter>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
@@ -55,7 +54,7 @@
|
||||
:class="{'active': activeTab === 'MyWorkflows'}"
|
||||
@click="selectTab('MyWorkflows')">
|
||||
{{ $t('my_workflows.tab') }}
|
||||
<tab-counter :count="state.workflows.count"></tab-counter>
|
||||
<tab-counter :count="state.workflows.count + state.workflowsCc.count"></tab-counter>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item loading ms-auto py-2" v-if="loading">
|
||||
@@ -150,4 +149,4 @@ export default {
|
||||
a.nav-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@@ -1,88 +1,25 @@
|
||||
<template>
|
||||
<div class="alert alert-light">{{ $t('my_workflows.description') }}</div>
|
||||
<my-workflows-table :workflows="workflows" />
|
||||
|
||||
<div class="alert alert-light">{{ $t('my_workflows.description') }}</div>
|
||||
<span v-if="noResults" class="chill-no-data-statement">{{ $t('no_data') }}</span>
|
||||
<tab-table v-else>
|
||||
<template v-slot:thead>
|
||||
<th scope="col">{{ $t('Object_workflow') }}</th>
|
||||
<th scope="col">{{ $t('Step') }}</th>
|
||||
<th scope="col">{{ $t('concerned_users') }}</th>
|
||||
<th scope="col"></th>
|
||||
</template>
|
||||
<template v-slot:tbody>
|
||||
<tr v-for="(w, i) in workflows.results" :key="`workflow-${i}`">
|
||||
<td>{{ w.title }}</td>
|
||||
<td>
|
||||
<div class="workflow">
|
||||
<div class="breadcrumb">
|
||||
<i class="fa fa-circle me-1 text-chill-yellow mx-2"></i>
|
||||
<span class="mx-2">{{ getStep(w) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td v-if="w.datas.persons !== null">
|
||||
<span v-for="p in w.datas.persons" class="me-1" :key="p.id">
|
||||
<on-the-fly
|
||||
:type="p.type"
|
||||
:id="p.id"
|
||||
:buttonText="p.textAge"
|
||||
:displayBadge="'true' === 'true'"
|
||||
action="show">
|
||||
</on-the-fly>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-show" :href="getUrl(w)">
|
||||
{{ $t('show_entity', { entity: $t('the_workflow') }) }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tab-table>
|
||||
|
||||
<div class="alert alert-light">{{ $t('my_workflows.description_cc') }}</div>
|
||||
<my-workflows-table :workflows="workflowsCc" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import TabTable from "./TabTable";
|
||||
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly';
|
||||
import { mapState } from "vuex";
|
||||
import MyWorkflowsTable from './MyWorkflowsTable.vue';
|
||||
|
||||
export default {
|
||||
name: "MyWorkflows",
|
||||
components: {
|
||||
TabTable,
|
||||
OnTheFly
|
||||
MyWorkflowsTable
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'workflows',
|
||||
'workflowsCc',
|
||||
]),
|
||||
...mapGetters([
|
||||
'isWorkflowsLoaded',
|
||||
]),
|
||||
noResults() {
|
||||
if (!this.isWorkflowsLoaded) {
|
||||
return false;
|
||||
} else {
|
||||
return this.workflows.count === 0;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getUrl(w) {
|
||||
return `/fr/main/workflow/${w.id}/show`;
|
||||
},
|
||||
getStep(w) {
|
||||
const lastStep = w.steps.length - 1
|
||||
return w.steps[lastStep].currentStep.text;
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
span.outdated {
|
||||
font-weight: bold;
|
||||
color: var(--bs-warning);
|
||||
}
|
||||
</style>
|
||||
</script>
|
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<span v-if="hasNoResults(workflows)" class="chill-no-data-statement">{{ $t('no_data') }}</span>
|
||||
<tab-table v-else>
|
||||
<template v-slot:thead>
|
||||
<th scope="col">{{ $t('Object_workflow') }}</th>
|
||||
<th scope="col">{{ $t('Step') }}</th>
|
||||
<th scope="col">{{ $t('concerned_users') }}</th>
|
||||
<th scope="col"></th>
|
||||
</template>
|
||||
<template v-slot:tbody>
|
||||
<tr v-for="(w, i) in workflows.results" :key="`workflow-${i}`">
|
||||
<td>{{ w.title }}</td>
|
||||
<td>
|
||||
<div class="workflow">
|
||||
<div class="breadcrumb">
|
||||
<i class="fa fa-circle me-1 text-chill-yellow mx-2"></i>
|
||||
<span class="mx-2">{{ getStep(w) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td v-if="w.datas.persons !== null">
|
||||
<span v-for="p in w.datas.persons" class="me-1" :key="p.id">
|
||||
<on-the-fly
|
||||
:type="p.type"
|
||||
:id="p.id"
|
||||
:buttonText="p.textAge"
|
||||
:displayBadge="'true' === 'true'"
|
||||
action="show">
|
||||
</on-the-fly>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-show" :href="getUrl(w)">
|
||||
{{ $t('show_entity', { entity: $t('the_workflow') }) }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tab-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import TabTable from "./TabTable";
|
||||
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly';
|
||||
|
||||
export default {
|
||||
name: "MyWorkflows",
|
||||
components: {
|
||||
TabTable,
|
||||
OnTheFly
|
||||
},
|
||||
props: ['workflows'],
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'isWorkflowsLoaded',
|
||||
]),
|
||||
},
|
||||
methods: {
|
||||
hasNoResults(workflows) {
|
||||
if (!this.isWorkflowsLoaded) {
|
||||
return false;
|
||||
} else {
|
||||
return workflows.count === 0;
|
||||
}
|
||||
},
|
||||
getUrl(w) {
|
||||
return `/fr/main/workflow/${w.id}/show`;
|
||||
},
|
||||
getStep(w) {
|
||||
const lastStep = w.steps.length - 1
|
||||
return w.steps[lastStep].currentStep.text;
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
span.outdated {
|
||||
font-weight: bold;
|
||||
color: var(--bs-warning);
|
||||
}
|
||||
</style>
|
@@ -24,7 +24,8 @@ const appMessages = {
|
||||
},
|
||||
my_workflows: {
|
||||
tab: "Mes workflows",
|
||||
description: "Liste des workflows en attente d'une action."
|
||||
description: "Liste des workflows en attente d'une action.",
|
||||
description_cc: "Liste des workflows dont je suis en copie."
|
||||
},
|
||||
opening_date: "Date d'ouverture",
|
||||
social_issues: "Problématiques sociales",
|
||||
|
@@ -22,6 +22,7 @@ const store = createStore({
|
||||
accompanyingCourses: {},
|
||||
notifications: {},
|
||||
workflows: {},
|
||||
workflowsCc: {},
|
||||
errorMsg: [],
|
||||
loading: false
|
||||
},
|
||||
@@ -87,6 +88,9 @@ const store = createStore({
|
||||
addWorkflows(state, workflows) {
|
||||
state.workflows = workflows;
|
||||
},
|
||||
addWorkflowsCc(state, workflows) {
|
||||
state.workflowsCc = workflows;
|
||||
},
|
||||
setLoading(state, bool) {
|
||||
state.loading = bool;
|
||||
},
|
||||
@@ -195,17 +199,23 @@ const store = createStore({
|
||||
case 'MyWorkflows':
|
||||
if (!getters.isWorflowsLoaded) {
|
||||
commit('setLoading', true);
|
||||
const url = '/api/1.0/main/workflow/my';
|
||||
makeFetch('GET', url)
|
||||
.then((response) => {
|
||||
console.log('workflows', response)
|
||||
commit('addWorkflows', response);
|
||||
commit('setLoading', false);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
});
|
||||
makeFetch('GET', '/api/1.0/main/workflow/my')
|
||||
.then((response) => {
|
||||
commit('addWorkflows', response);
|
||||
makeFetch('GET', '/api/1.0/main/workflow/my-cc')
|
||||
.then((response) => {
|
||||
commit('addWorkflowsCc', response);
|
||||
commit('setLoading', false);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@@ -233,7 +233,7 @@ export default {
|
||||
// console.log('data original', data);
|
||||
data.parent = {type: "thirdparty", id: this.parent.id};
|
||||
data.civility = data.civility !== null ? {type: 'chill_main_civility', id: data.civility.id} : null;
|
||||
data.profession = data.profession !== null ? {type: 'third_party_profession', id: data.profession.id} : null;
|
||||
data.profession = data.profession !== '' ? data.profession : '';
|
||||
} else {
|
||||
type = this.$refs.castNew.radioType;
|
||||
data = this.$refs.castNew.castDataByType();
|
||||
@@ -241,8 +241,8 @@ export default {
|
||||
if (typeof data.civility !== 'undefined' && null !== data.civility) {
|
||||
data.civility = data.civility !== null ? {type: 'chill_main_civility', id: data.civility.id} : null;
|
||||
}
|
||||
if (typeof data.profession !== 'undefined' && null !== data.profession) {
|
||||
data.profession = data.profession !== null ? {type: 'third_party_profession', id: data.profession.id} : null;
|
||||
if (typeof data.profession !== 'undefined' && '' !== data.profession) {
|
||||
data.profession = data.profession !== '' ? data.profession : '';
|
||||
}
|
||||
// console.log('onthefly data', data);
|
||||
}
|
||||
|
@@ -17,6 +17,9 @@
|
||||
</add-persons>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="list-suggest add-items inline">
|
||||
<li v-for="s in suggested" :key="s.id" @click="addNewSuggested(s)"><span>{{ s.text }}</span></li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -49,6 +52,10 @@ export default {
|
||||
// display picked entities.
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
suggested: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
emits: ['addNewEntity', 'removeEntity'],
|
||||
@@ -61,55 +68,58 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
addPersonsOptions() {
|
||||
return {
|
||||
uniq: !this.multiple,
|
||||
type: this.types,
|
||||
priority: null,
|
||||
button: {
|
||||
size: 'btn-sm',
|
||||
class: 'btn-submit',
|
||||
},
|
||||
};
|
||||
},
|
||||
translatedListOfTypes() {
|
||||
let trans = [];
|
||||
this.types.forEach(t => {
|
||||
if (this.$props.multiple) {
|
||||
trans.push(appMessages.fr.pick_entity[t].toLowerCase());
|
||||
} else {
|
||||
trans.push(appMessages.fr.pick_entity[t + '_one'].toLowerCase());
|
||||
}
|
||||
})
|
||||
addPersonsOptions() {
|
||||
return {
|
||||
uniq: !this.multiple,
|
||||
type: this.types,
|
||||
priority: null,
|
||||
button: {
|
||||
size: 'btn-sm',
|
||||
class: 'btn-submit',
|
||||
},
|
||||
};
|
||||
},
|
||||
translatedListOfTypes() {
|
||||
let trans = [];
|
||||
this.types.forEach(t => {
|
||||
if (this.$props.multiple) {
|
||||
trans.push(appMessages.fr.pick_entity[t].toLowerCase());
|
||||
} else {
|
||||
trans.push(appMessages.fr.pick_entity[t + '_one'].toLowerCase());
|
||||
}
|
||||
})
|
||||
|
||||
if (this.$props.multiple) {
|
||||
return appMessages.fr.pick_entity.modal_title + trans.join(', ');
|
||||
} else {
|
||||
return appMessages.fr.pick_entity.modal_title_one + trans.join(', ');
|
||||
}
|
||||
},
|
||||
listClasses() {
|
||||
return {
|
||||
'list-suggest': true,
|
||||
'remove-items': this.$props.removableIfSet,
|
||||
};
|
||||
},
|
||||
if (this.$props.multiple) {
|
||||
return appMessages.fr.pick_entity.modal_title + trans.join(', ');
|
||||
} else {
|
||||
return appMessages.fr.pick_entity.modal_title_one + trans.join(', ');
|
||||
}
|
||||
},
|
||||
listClasses() {
|
||||
return {
|
||||
'list-suggest': true,
|
||||
'remove-items': this.$props.removableIfSet,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
addNewEntity({ selected, modal }) {
|
||||
selected.forEach((item) => {
|
||||
this.$emit('addNewEntity', item.result);
|
||||
}, this
|
||||
);
|
||||
this.$refs.addPersons.resetSearch(); // to cast child method
|
||||
modal.showModal = false;
|
||||
},
|
||||
removeEntity(entity) {
|
||||
if (!this.$props.removableIfSet) {
|
||||
return;
|
||||
}
|
||||
this.$emit('removeEntity', entity);
|
||||
}
|
||||
addNewSuggested(entity) {
|
||||
this.$emit('addNewEntity', {entity: entity});
|
||||
},
|
||||
addNewEntity({ selected, modal }) {
|
||||
selected.forEach((item) => {
|
||||
this.$emit('addNewEntity', { entity: item.result});
|
||||
}, this
|
||||
);
|
||||
this.$refs.addPersons.resetSearch(); // to cast child method
|
||||
modal.showModal = false;
|
||||
},
|
||||
removeEntity(entity) {
|
||||
if (!this.$props.removableIfSet) {
|
||||
return;
|
||||
}
|
||||
this.$emit('removeEntity',{ entity: entity });
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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: '© <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>
|
@@ -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">Ré-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>
|
@@ -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: {
|
||||
|
@@ -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) }}
|
||||
|
@@ -41,9 +41,10 @@
|
||||
<h3 class="m-3">{{ 'Center'|trans }}</h3>
|
||||
{{ form_widget(form.centers.center) }}
|
||||
|
||||
<h3 class="m-3">{{ 'Pick aggregated centers'|trans }}</h3>
|
||||
{{ form_widget(form.centers.regroupment) }}
|
||||
|
||||
{% if form.centers.regroupment is defined %}
|
||||
<h3 class="m-3">{{ 'Pick aggregated centers'|trans }}</h3>
|
||||
{{ form_widget(form.centers.regroupment) }}
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
<p>{{ form_widget(form.submit, { 'attr' : { 'class' : 'btn btn-action btn-create' }, 'label' : 'Go to export options' } ) }}</p>
|
||||
|
@@ -68,7 +68,8 @@
|
||||
{{- form_errors(form) -}}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-sm">
|
||||
<div class="col-12 clear">{{- form_label(form) -}}</div>
|
||||
<div class="col-sm-12">
|
||||
{{- form_widget(form, widget_attr) -}}
|
||||
{{- form_help(form) -}}
|
||||
{{- form_errors(form) -}}
|
||||
|
@@ -18,43 +18,48 @@
|
||||
|
||||
{% block form_row %}
|
||||
{% apply spaceless %}
|
||||
{% if form.vars.fullWidth is not defined or form.vars.fullWidth == false %}
|
||||
<div class="mb-2">
|
||||
<div class="row">
|
||||
<div class="{% apply spaceless %}
|
||||
{% if attr.class is defined and ('cf-title' in attr.class or 'cf-fields' in attr.class ) %}
|
||||
col-sm-12
|
||||
{% elseif attr.class is defined and 'multiple-cf-inline' in attr.class %}
|
||||
col-sm-2 col-md-4 clear
|
||||
{% else %}
|
||||
col-sm-4 clear
|
||||
{% if form.vars.fullWidth is not defined or form.vars.fullWidth == false %}
|
||||
<div class="{% apply spaceless %}
|
||||
{% if attr.class is defined and ('cf-title' in attr.class or 'cf-fields' in attr.class ) %}
|
||||
col-sm-12
|
||||
{% elseif attr.class is defined and 'multiple-cf-inline' in attr.class %}
|
||||
col-sm-2 col-md-4 clear
|
||||
{% else %}
|
||||
col-sm-4 clear
|
||||
{% endif %}
|
||||
{% endapply %}">
|
||||
{% if attr.class is not defined or ('cf-title' not in attr.class and 'cf-fields' not in attr.class ) %}
|
||||
{{ form_label(form) }}
|
||||
{% endif %}
|
||||
{% endapply %}">
|
||||
{% if attr.class is not defined or ('cf-title' not in attr.class and 'cf-fields' not in attr.class ) %}
|
||||
{{ form_label(form) }}
|
||||
</div>
|
||||
<div class="{% apply spaceless %}
|
||||
{% if attr.class is defined and 'cf-title' in attr.class %}
|
||||
col-sm-12
|
||||
{% elseif attr.class is defined and 'cf-fields' in attr.class %}
|
||||
col-sm-12 parent
|
||||
{% elseif attr.class is defined and 'multiple-cf-inline' in attr.class %}
|
||||
col-sm-2 col-md-8 multiple-cf-inline
|
||||
{% else %}
|
||||
col-sm-8
|
||||
{% endif %}
|
||||
{% endapply %}">
|
||||
{{ form_widget(form) }}
|
||||
{{ form_errors(form) }}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-12 clear">{{ form_label(form) }}</div>
|
||||
<div class="col-12">{{ form_widget(form) }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="{% apply spaceless %}
|
||||
{% if attr.class is defined and 'cf-title' in attr.class %}
|
||||
col-sm-12
|
||||
{% elseif attr.class is defined and 'cf-fields' in attr.class %}
|
||||
col-sm-12 parent
|
||||
{% elseif attr.class is defined and 'multiple-cf-inline' in attr.class %}
|
||||
col-sm-2 col-md-8 multiple-cf-inline
|
||||
{% else %}
|
||||
col-sm-8
|
||||
{% endif %}
|
||||
{% endapply %}">
|
||||
{{ form_widget(form) }}
|
||||
{{ form_errors(form) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
{{ form_widget(form) }}
|
||||
{% endif %}
|
||||
{% endapply %}
|
||||
{% endblock form_row %}
|
||||
{#
|
||||
The block 'form_row' above may be removed !
|
||||
Read this note: https://gitlab.com/Chill-Projet/chill-bundles/-/merge_requests/502#note_1311993084
|
||||
#}
|
||||
|
||||
{% block choice_widget_expanded %}
|
||||
{% apply spaceless %}
|
||||
@@ -200,7 +205,6 @@
|
||||
|
||||
|
||||
{% block private_comment_row %}
|
||||
{{ form_label(form) }}
|
||||
{{ form_row(form) }}
|
||||
{% endblock %}
|
||||
|
||||
@@ -211,7 +215,6 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block comment_row %}
|
||||
{{ form_label(form) }}
|
||||
{{ form_row(form) }}
|
||||
{% endblock %}
|
||||
|
||||
@@ -249,7 +252,11 @@
|
||||
|
||||
{% block pick_entity_dynamic_widget %}
|
||||
<input type="hidden" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value|escape('html_attr') }}" {% endif %} data-input-uniqid="{{ form.vars['uniqid'] }}"/>
|
||||
<div data-module="pick-dynamic" data-types="{{ form.vars['types']|json_encode }}" data-multiple="{{ form.vars['multiple'] }}" data-uniqid="{{ form.vars['uniqid'] }}"></div>
|
||||
<div data-module="pick-dynamic"
|
||||
data-types="{{ form.vars['types']|json_encode }}"
|
||||
data-multiple="{{ form.vars['multiple'] }}"
|
||||
data-uniqid="{{ form.vars['uniqid'] }}"
|
||||
data-suggested="{{ form.vars['suggested']|json_encode|escape('html_attr') }}"></div>
|
||||
{% endblock %}
|
||||
|
||||
{% block pick_postal_code_widget %}
|
||||
@@ -269,4 +276,4 @@
|
||||
{{ form_errors(form.fixedDate) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
@@ -30,11 +30,27 @@
|
||||
{% endif %}
|
||||
{% if c.notification.addressees|length > 0 %}
|
||||
<li class="notification-to">
|
||||
<span class="item-key">
|
||||
{% if c.notification_cc is defined %}
|
||||
{% if c.notification_cc %}
|
||||
<span class="item-key">
|
||||
<abbr title="{{ 'notification.sent_cc'|trans }}">
|
||||
{{ 'notification.cc'|trans }} :
|
||||
</abbr>
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="item-key">
|
||||
<abbr title="{{ 'notification.sent_to'|trans }}">
|
||||
{{ 'notification.to'|trans }} :
|
||||
</abbr>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="item-key">
|
||||
<abbr title="{{ 'notification.sent_to'|trans }}">
|
||||
{{ 'notification.to'|trans }} :
|
||||
</abbr>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% for a in c.notification.addressees %}
|
||||
<span class="badge-user">
|
||||
{{ a|chill_entity_render_string }}
|
||||
|
@@ -50,7 +50,8 @@
|
||||
{% for data in datas %}
|
||||
{% set notification = data.notification %}
|
||||
{% include 'ChillMainBundle:Notification:_list_item.html.twig' with {
|
||||
'fold_item': true
|
||||
'fold_item': true,
|
||||
'notification_cc': data.template_data.notificationCc is defined ? data.template_data.notificationCc : false
|
||||
} %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
@@ -27,7 +27,8 @@
|
||||
},
|
||||
'action_button': false,
|
||||
'full_content': true,
|
||||
'fold_item': false
|
||||
'fold_item': false,
|
||||
'notification_cc': handler.getTemplateData(notification).notificationCc is defined ? handler.getTemplateData(notification).notificationCc : false
|
||||
} %}
|
||||
</div>
|
||||
|
||||
|
@@ -72,7 +72,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-row column">
|
||||
<table class="obj-res-eval my-3">
|
||||
<table class="obj-res-eval smallfont my-3">
|
||||
<thead>
|
||||
<tr><th class="obj"><h4 class="title_label">Objectif - motif - dispositif</h4></th>
|
||||
<th class="res"><h4 class="title_label">Résultats - orientations</h4></th>
|
||||
|
@@ -65,7 +65,10 @@
|
||||
<div id="futureDests">
|
||||
{{ form_row(transition_form.future_dest_users) }}
|
||||
|
||||
{{ 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>
|
||||
|
@@ -81,6 +81,15 @@
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if step.ccUser|length > 0 %}
|
||||
<p><b>{{ 'workflow.Users put in Cc'|trans }} : </b></p>
|
||||
<ul>
|
||||
{% for u in step.ccUser %}
|
||||
<li>{{ u|chill_entity_render_box }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if entity_workflow.currentStep.destEmail|length > 0 %}
|
||||
<p><b>{{ 'workflow.An access key was also sent to those addresses'|trans }} :</b></p>
|
||||
<ul>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col-10 workflow">
|
||||
<div class="col-12 workflow">
|
||||
|
||||
<h1 class="mb-5">{{ block('title') }}</h1>
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
{{ 'workflow.dest'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="{{ path('chill_main_workflow_list_cc') }}"
|
||||
class="nav-link {% if step == 'cc' %}active{% endif %}">
|
||||
{{ 'workflow.cc'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="{{ path('chill_main_workflow_list_previous_without_reaction') }}"
|
||||
class="nav-link {% if step == 'previous_without_reaction' %}active{% endif %}">
|
||||
|
@@ -15,6 +15,12 @@
|
||||
{% for d in step.destUser %}{{ d|chill_entity_render_string }}{% if not loop.last %}, {% endif %}{% endfor %}
|
||||
</b>
|
||||
</li>
|
||||
<li>
|
||||
<span class="item-key">{{ 'workflow.Cc'|trans ~ ' : ' }}</span>
|
||||
<b>
|
||||
{% for u in step.ccUser %}{{ u|chill_entity_render_string }}{% if not loop.last %}, {% endif %}{% endfor %}
|
||||
</b>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<span class="item-key">{{ 'workflow.Created by'|trans ~ ' : ' }}</span>
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user