Merge branch 'master' into household_filiation

This commit is contained in:
2021-11-12 17:20:46 +01:00
298 changed files with 8036 additions and 3185 deletions

View File

@@ -1 +1,5 @@
require("./show_hide.js");
//require("./show_hide.js");
import { ShowHide } from './show_hide.js'
export { ShowHide }

View File

@@ -134,4 +134,4 @@ var ShowHide = function(options) {
};
};
export {ShowHide};
export { ShowHide };

View File

@@ -0,0 +1,13 @@
.confidential{
display: flex;
}
.toggle{
margin-left: 30px;
margin-top: 5px;
cursor: pointer;
}
.blur {
-webkit-filter: blur(5px);
-moz-filter: blur(5px);
filter: blur(5px);
}

View File

@@ -0,0 +1,21 @@
require('./blur.scss');
var toggleBlur = function(e){
var btn = e.target;
btn.previousElementSibling.classList.toggle("blur");
btn.classList.toggle("fa-eye");
btn.classList.toggle("fa-eye-slash");
}
var infos = document.getElementsByClassName("confidential");
for(var i=0; i < infos.length; i++){
infos[i].insertAdjacentHTML('beforeend', '<i class="fa fa-eye toggle" aria-hidden="true"></i>');
}
var toggles = document.getElementsByClassName("toggle");
for(var i=0; i < toggles.length; i++){
toggles[i].addEventListener("click", toggleBlur);
}

View File

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

View File

@@ -68,7 +68,9 @@ export default {
return this.$data.value !== null && typeof this.$data.value.text !== 'undefined';
},
cities() {
return this.entity.loaded.cities;
return this.entity.loaded.cities.sort(
(a, b) => Number(a.code) - Number(b.code) || a.name > b.name
)
},
name: {
set(value) {
@@ -92,7 +94,7 @@ export default {
},
methods: {
transName(value) {
return (value.code && value.name) ? `${value.code}-${value.name}` : '';
return (value.code && value.name) ? `${value.name} (${value.code})` : '';
},
selectCity(value) {
console.log(value)
@@ -103,7 +105,9 @@ export default {
console.log('writeNew.postcode false, in selectCity');
this.$emit('getReferenceAddresses', value);
this.focusOnAddress();
this.updateMapCenter(value.center);
if (value.center) {
this.updateMapCenter(value.center);
}
},
listenInputSearch(query) {
//console.log('listenInputSearch', query, this.isCitySelectorOpen);

View File

@@ -5,82 +5,89 @@ import App from './App.vue';
const i18n = _createI18n(addressMessages);
let inputs = document.querySelectorAll('input[type="hidden"][data-input-address]');
const addAddressInput = (inputs) => {
const isNumeric = function(v) { return !isNaN(v); };
inputs.forEach(el => {
let
addressId = el.value,
uniqid = el.dataset.inputAddress,
container = document.querySelector('div[data-input-address-container="' + uniqid + '"]'),
isEdit = addressId !== '',
addressIdInt = addressId !== '' ? parseInt(addressId) : null
;
inputs.forEach(el => {
let
addressId = el.value,
uniqid = el.dataset.inputAddress,
container = document.querySelector('div[data-input-address-container="' + uniqid + '"]'),
isEdit = addressId !== '',
addressIdInt = addressId !== '' ? parseInt(addressId) : null
;
if (container === null) {
throw Error("no container");
}
console.log('useValidFrom', el.dataset.useValidFrom === '1');
if (container === null) {
throw Error("no container");
}
console.log('useValidFrom', el.dataset.useValidFrom === '1');
const app = createApp({
template: `<app v-bind:addAddress="this.addAddress" @address-created="associateToInput"></app>`,
data() {
return {
addAddress: {
context: {
// for legacy ? can be remove ?
target: {
name: 'input-address',
id: addressIdInt,
},
edit: isEdit,
addressId: addressIdInt,
},
options: {
/// Options override default.
/// null value take default component value defined in AddAddress data()
button: {
text: {
create: el.dataset.buttonTextCreate || null,
edit: el.dataset.buttonTextUpdate || null,
const app = createApp({
template: `<app v-bind:addAddress="this.addAddress" @address-created="associateToInput"></app>`,
data() {
return {
addAddress: {
context: {
// for legacy ? can be remove ?
target: {
name: 'input-address',
id: addressIdInt,
},
size: null,
displayText: true
edit: isEdit,
addressId: addressIdInt,
},
options: {
/// Options override default.
/// null value take default component value defined in AddAddress data()
button: {
text: {
create: el.dataset.buttonTextCreate || null,
edit: el.dataset.buttonTextUpdate || null,
},
size: null,
displayText: true
},
/// Modal title text if create or edit address (trans chain, see i18n)
title: {
create: null,
edit: null,
},
/// Modal title text if create or edit address (trans chain, see i18n)
title: {
create: null,
edit: null,
},
/// Display panes in Modal for step123
openPanesInModal: true,
/// Display panes in Modal for step123
openPanesInModal: true,
/// Display actions buttons of panes in a sticky-form-button navbar
stickyActions: false,
showMessageWhenNoAddress: true,
/// Display actions buttons of panes in a sticky-form-button navbar
stickyActions: false,
showMessageWhenNoAddress: true,
/// Use Date fields
useDate: {
validFrom: el.dataset.useValidFrom === '1' || false, //boolean, default: false
validTo: el.dataset.useValidTo === '1' || false, //boolean, default: false
},
/// Use Date fields
useDate: {
validFrom: el.dataset.useValidFrom === '1' || false, //boolean, default: false
validTo: el.dataset.useValidTo === '1' || false, //boolean, default: false
},
/// Don't display show renderbox Address: showPane display only a button
onlyButton: false,
/// Don't display show renderbox Address: showPane display only a button
onlyButton: false,
}
}
}
},
methods: {
associateToInput(payload) {
el.value = payload.addressId;
}
}
},
methods: {
associateToInput(payload) {
el.value = payload.addressId;
}
}
})
.use(i18n)
.component('app', App)
.mount(container);
});
})
.use(i18n)
.component('app', App)
.mount(container);
});
};
document.addEventListener('DOMContentLoaded', (_e) =>
addAddressInput(document.querySelectorAll('input[type="hidden"][data-input-address]'))
);
window.addEventListener('collection-add-entry', (e) =>
addAddressInput(e.detail.entry.querySelectorAll('input[type="hidden"][data-input-address]'))
);

View File

@@ -0,0 +1,43 @@
<template>
<div class="confidential" v-on:click="toggleBlur">
<div class="confidential-content blur">
<slot name="confidential-content"></slot>
</div>
<i class="fa fa-eye toggle" aria-hidden="true"></i>
</div>
</template>
<script>
export default {
name: "Confidential",
methods : {
toggleBlur: function(e){
if(e.target.matches('.toggle')){
console.log(e);
e.target.previousElementSibling.classList.toggle("blur");
e.target.classList.toggle("fa-eye");
e.target.classList.toggle("fa-eye-slash");
}
},
}
}
</script>
<style scoped lang='scss'>
.confidential{
align-items: center;
display: flex;
}
.toggle{
margin-top: 28px;
cursor: pointer;
display: block;
float: right;
margin-right: 20px;
}
.blur {
-webkit-filter: blur(5px);
-moz-filter: blur(5px);
filter: blur(5px);
}
</style>

View File

@@ -0,0 +1,14 @@
<template>
<span class="chill-entity entity-user">
{{ user.label }}
<span class="user-job" v-if="user.user_job !== null">({{ user.user_job.label.fr }})</span>
<span class="main-scope" v-if="user.main_scope !== null">({{ user.main_scope.name.fr }})</span>
</span>
</template>
<script>
export default {
name: "UserRenderBoxBadge",
props: ['user'],
}
</script>

View File

@@ -39,3 +39,4 @@ assetic:
chill_main:
available_languages: [fr, en]
available_countries: [FR]

View File

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

View File

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

View File

@@ -58,6 +58,13 @@
{% macro inline(address, options) %}
{% if options['has_no_address'] == true and address.isNoAddress == true %}
{% if address.postCode is not empty %}
<p class="postcode">
<span class="code">{{ address.postCode.code }}</span>
<span class="name">{{ address.postCode.name }}</span>
</p>
<p class="country">{{ address.postCode.country.name|localize_translatable_string }}</p>
{% endif %}
<span class="noaddress">
{{ 'address.consider homeless'|trans }}
</span>
@@ -83,6 +90,10 @@
{% endmacro %}
{#
this enclose the rendering inside a "li", which ease the placement operation when the address
must be shown in such list
#}
{%- if render == 'list' -%}
<li class="chill-entity entity-address">
{% if options['with_picto'] %}
@@ -104,9 +115,19 @@
{%- if render == 'bloc' -%}
<div class="chill-entity entity-address">
{% if options['has_no_address'] == true and address.isNoAddress == true %}
{% if address.postCode is not empty %}
<div class="address{% if options['multiline'] %} multiline{% endif %}{% if options['with_delimiter'] %} delimiter{% endif %}">
<p class="postcode">
<span class="code">{{ address.postCode.code }}</span>
<span class="name">{{ address.postCode.name }}</span>
</p>
<p class="country">{{ address.postCode.country.name|localize_translatable_string }}</p>
</div>
{% endif %}
<div class="noaddress">
{{ 'address.consider homeless'|trans }}
</div>
{% else %}
<div class="address{% if options['multiline'] %} multiline{% endif %}{% if options['with_delimiter'] %} delimiter{% endif %}">
{% if options['with_picto'] %}

View File

@@ -0,0 +1,9 @@
<span class="chill-entity entity-user">
{{- user.label }}
{%- if opts['user_job'] and user.userJob is not null %}
<span class="user-job">({{ user.userJob.label|localize_translatable_string }})</span>
{%- endif -%}
{%- if opts['main_scope'] and user.mainScope is not null %}
<span class="main-scope">({{ user.mainScope.name|localize_translatable_string }})</span>
{%- endif -%}
</span>

View File

@@ -1,12 +1,39 @@
{{ form_start(form) }}
<div class="chill_filter_order container">
<div class="row">
<div class="col-md-12">
<div class="input-group mb-3">
{{ form_widget(form.q)}}
<button type="submit" class="btn btn-chill-l-gray"><i class="fa fa-search"></i></button>
{% if form.vars.has_search_box %}
<div class="col-md-12">
<div class="input-group mb-3">
{{ form_widget(form.q)}}
<button type="submit" class="btn btn-chill-l-gray"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
{% endif %}
</div>
{% if form.checkboxes|length > 0 %}
{% for checkbox_name, options in form.checkboxes %}
<div class="row gx-0">
<div class="col-md-12">
{% for c in form['checkboxes'][checkbox_name].children %}
<div class="form-check form-check-inline">
{{ form_widget(c) }}
{{ form_label(c) }}
</div>
{% endfor %}
</div>
</div>
{% if loop.last %}
<div class="row gx-0">
<div class="col-md-12">
<ul class="record_actions">
<li>
<button type="submit" class="btn btn-misc"><i class="fa fa-filter"></i></button>
</li>
</ul>
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
</div>
{{ form_end(form) }}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,7 +8,7 @@
{{ form_start(form) }}
<ul class="record_actions">
<ul class="record_actions sticky-form-buttons">
<li class="cancel">
<a href="{{ path(cancel_route, cancel_parameters|default( { } ) ) }}" class="btn btn-cancel">
{{ 'Cancel'|trans }}
@@ -18,5 +18,5 @@
{{ form_widget(form.submit, { 'attr' : { 'class' : "btn btn-delete" } } ) }}
</li>
</ul>
{{ form_end(form) }}
{{ form_end(form) }}

View File

@@ -12,7 +12,8 @@
{{ encore_entry_link_tags('mod_forkawesome') }}
{{ encore_entry_link_tags('mod_ckeditor5') }}
{{ encore_entry_link_tags('chill') }}
{% block css%}<!-- nothing added to css -->{% endblock %}
{{ encore_entry_link_tags('mod_blur') }}
{% block css %}<!-- nothing added to css -->{% endblock %}
</head>
<body>
@@ -88,6 +89,7 @@
{{ encore_entry_script_tags('mod_bootstrap') }}
{{ encore_entry_script_tags('mod_forkawesome') }}
{{ encore_entry_script_tags('mod_ckeditor5') }}
{{ encore_entry_script_tags('mod_blur') }}
{{ encore_entry_script_tags('chill') }}
<script type="text/javascript">