Merge branch 'blur_confidential_info' into 'master'

Blur confidential info

See merge request Chill-Projet/chill-bundles!172
This commit is contained in:
Julien Fastré 2021-10-30 00:22:41 +00:00
commit 94e84fbdf0
17 changed files with 273 additions and 70 deletions

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

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

View File

@ -60,6 +60,7 @@ module.exports = function(encore, entries)
encore.addEntry('mod_bootstrap', __dirname + '/Resources/public/module/bootstrap/index.js'); encore.addEntry('mod_bootstrap', __dirname + '/Resources/public/module/bootstrap/index.js');
encore.addEntry('mod_ckeditor5', __dirname + '/Resources/public/module/ckeditor5/index.js'); encore.addEntry('mod_ckeditor5', __dirname + '/Resources/public/module/ckeditor5/index.js');
encore.addEntry('mod_disablebuttons', __dirname + '/Resources/public/module/disable-buttons/index.js'); encore.addEntry('mod_disablebuttons', __dirname + '/Resources/public/module/disable-buttons/index.js');
encore.addEntry('mod_blur', __dirname + '/Resources/public/module/blur/index.js');
encore.addEntry('mod_input_address', __dirname + '/Resources/public/vuejs/Address/mod_input_address_index.js'); encore.addEntry('mod_input_address', __dirname + '/Resources/public/vuejs/Address/mod_input_address_index.js');
// Vue entrypoints // Vue entrypoints

View File

@ -8,7 +8,7 @@
<persons-associated></persons-associated> <persons-associated></persons-associated>
<course-location></course-location> <course-location></course-location>
<origin-demand></origin-demand> <origin-demand></origin-demand>
<requestor></requestor> <requestor v-bind:isAnonymous="accompanyingCourse.requestorAnonymous"></requestor>
<social-issue></social-issue> <social-issue></social-issue>
<scopes></scopes> <scopes></scopes>
<referrer></referrer> <referrer></referrer>

View File

@ -9,6 +9,7 @@
addAltNames: true, addAltNames: true,
addAge : true, addAge : true,
hLevel : 3, hLevel : 3,
isConfidential : false,
}" }"
:person="participation.person" :person="participation.person"
:returnPath="getAccompanyingCourseReturnPath"> :returnPath="getAccompanyingCourseReturnPath">

View File

@ -3,14 +3,15 @@
<h2><a id="section-40"></a>{{ $t('requestor.title') }}</h2> <h2><a id="section-40"></a>{{ $t('requestor.title') }}</h2>
<div v-if="accompanyingCourse.requestor" class="flex-table"> <div v-if="accompanyingCourse.requestor && isAnonymous" class="flex-table">
<label> <label>
<input type="checkbox" v-model="isAnonymous" class="me-2" /> <input type="checkbox" v-model="isAnonymous" class="me-2" />
{{ $t('requestor.is_anonymous') }} {{ $t('requestor.is_anonymous') }}
</label> </label>
<confidential v-if="accompanyingCourse.requestor.type === 'thirdparty'">
<third-party-render-box v-if="accompanyingCourse.requestor.type === 'thirdparty'" <template v-slot:confidential-content>
<third-party-render-box
:thirdparty="accompanyingCourse.requestor" :thirdparty="accompanyingCourse.requestor"
:options="{ :options="{
addLink: false, addLink: false,
@ -18,7 +19,8 @@
addEntity: true, addEntity: true,
addInfo: false, addInfo: false,
hLevel: 3, hLevel: 3,
isMultiline: true isMultiline: true,
isConfidential: true
}" }"
> >
<template v-slot:record-actions> <template v-slot:record-actions>
@ -28,8 +30,12 @@
</ul> </ul>
</template> </template>
</third-party-render-box> </third-party-render-box>
</template>
</confidential>
<person-render-box render="bloc" v-else-if="accompanyingCourse.requestor.type === 'person'" <confidential v-else-if="accompanyingCourse.requestor.type === 'person'">
<template v-slot:confidential-content>
<person-render-box render="bloc"
:person="accompanyingCourse.requestor" :person="accompanyingCourse.requestor"
:options="{ :options="{
addLink: false, addLink: false,
@ -38,7 +44,8 @@
addEntity: true, addEntity: true,
addInfo: true, addInfo: true,
hLevel: 3, hLevel: 3,
isMultiline: true isMultiline: true,
isConfidential: false
}" }"
> >
<template v-slot:record-actions> <template v-slot:record-actions>
@ -48,6 +55,8 @@
</ul> </ul>
</template> </template>
</person-render-box> </person-render-box>
</template>
</confidential>
<ul class="record_actions"> <ul class="record_actions">
<li> <li>
@ -59,6 +68,57 @@
</li> </li>
</ul> </ul>
</div> </div>
<div v-else-if="accompanyingCourse.requestor && !isAnonymous" class="flex-table">
<label>
<input type="checkbox" v-model="isAnonymous" class="me-2" />
{{ $t('requestor.is_anonymous') }}
</label>
<third-party-render-box
v-if="accompanyingCourse.requestor.type === 'thirdparty'"
:thirdparty="accompanyingCourse.requestor"
:options="{
addLink: false,
addId: false,
addEntity: true,
addInfo: false,
hLevel: 3,
isMultiline: true,
isConfidential: true
}"
>
<template v-slot:record-actions>
<ul class="record_actions">
<li><on-the-fly :type="accompanyingCourse.requestor.type" :id="accompanyingCourse.requestor.id" action="show"></on-the-fly></li>
<li><on-the-fly :type="accompanyingCourse.requestor.type" :id="accompanyingCourse.requestor.id" action="edit" @saveFormOnTheFly="saveFormOnTheFly"></on-the-fly></li>
</ul>
</template>
</third-party-render-box>
<person-render-box render="bloc"
v-if="accompanyingCourse.requestor.type === 'person'"
:person="accompanyingCourse.requestor"
:options="{
addLink: false,
addId: false,
addAltNames: false,
addEntity: true,
addInfo: true,
hLevel: 3,
isMultiline: true,
isConfidential: false
}"
>
<template v-slot:record-actions>
<ul class="record_actions">
<li><on-the-fly :type="accompanyingCourse.requestor.type" :id="accompanyingCourse.requestor.id" action="show"></on-the-fly></li>
<li><on-the-fly :type="accompanyingCourse.requestor.type" :id="accompanyingCourse.requestor.id" action="edit" @saveFormOnTheFly="saveFormOnTheFly"></on-the-fly></li>
</ul>
</template>
</person-render-box>
</div>
<div v-else> <div v-else>
<label class="chill-no-data-statement">{{ $t('requestor.counter') }}</label> <label class="chill-no-data-statement">{{ $t('requestor.counter') }}</label>
</div> </div>
@ -82,6 +142,7 @@ import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue'; import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue';
import PersonRenderBox from '../../_components/Entity/PersonRenderBox.vue'; import PersonRenderBox from '../../_components/Entity/PersonRenderBox.vue';
import ThirdPartyRenderBox from 'ChillThirdPartyAssets/vuejs/_components/Entity/ThirdPartyRenderBox.vue'; import ThirdPartyRenderBox from 'ChillThirdPartyAssets/vuejs/_components/Entity/ThirdPartyRenderBox.vue';
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
export default { export default {
name: 'Requestor', name: 'Requestor',
@ -90,7 +151,9 @@ export default {
OnTheFly, OnTheFly,
PersonRenderBox, PersonRenderBox,
ThirdPartyRenderBox, ThirdPartyRenderBox,
Confidential
}, },
props: ['isAnonymous'],
data() { data() {
return { return {
addPersons: { addPersons: {
@ -149,4 +212,8 @@ div.flex-table {
margin-top: 1em; margin-top: 1em;
} }
} }
.confidential {
display: block;
}
</style> </style>

View File

@ -2,7 +2,7 @@
<person-render-box render="bloc" <person-render-box render="bloc"
v-if="resource.resource.type === 'person'" v-if="resource.resource.type === 'person'"
:person="resource.resource" :person="resource.resource"
:options="{ addInfo : true, addId : false, addEntity: true, addLink: false, addAltNames: true, addAge : false, hLevel : 3 }" :options="{ addInfo : true, addId : false, addEntity: true, addLink: false, addAltNames: true, addAge : false, hLevel : 3, isConfidential : true }"
> >
<template v-slot:record-actions> <template v-slot:record-actions>
<ul class="record_actions"> <ul class="record_actions">

View File

@ -138,11 +138,13 @@
<script> <script>
import {dateToISO} from 'ChillMainAssets/chill/js/date.js'; import {dateToISO} from 'ChillMainAssets/chill/js/date.js';
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue'; import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
export default { export default {
name: "PersonRenderBox", name: "PersonRenderBox",
components: { components: {
AddressRenderBox AddressRenderBox,
Confidential
}, },
props: ['person', 'options', 'render', 'returnPath'], props: ['person', 'options', 'render', 'returnPath'],
computed: { computed: {

View File

@ -173,6 +173,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
/** /**
* @var bool * @var bool
* @ORM\Column(name="contact_data_anonymous", type="boolean", options={"default":false}) * @ORM\Column(name="contact_data_anonymous", type="boolean", options={"default":false})
* @Groups({"read"})
*/ */
private bool $contactDataAnonymous = false; private bool $contactDataAnonymous = false;

View File

@ -5,7 +5,6 @@
<div class="item-col"> <div class="item-col">
<div class="entity-label"> <div class="entity-label">
<div :class="'denomination h' + options.hLevel"> <div :class="'denomination h' + options.hLevel">
<a v-if="this.options.addLink === true" href="#"> <a v-if="this.options.addLink === true" href="#">
@ -19,7 +18,7 @@
<span class="badge bg-thirdparty-company" v-else-if="thirdparty.kind == 'company'"> <span class="badge bg-thirdparty-company" v-else-if="thirdparty.kind == 'company'">
{{ $t('thirdparty.company')}} {{ $t('thirdparty.company')}}
</span> </span>
<span class="badge bg-thirdparty-contact" v-else="thirdparty.kind == 'contact'"> <span class="badge bg-thirdparty-contact" v-else>
{{ $t('thirdparty.contact')}} {{ $t('thirdparty.contact')}}
</span> </span>
@ -46,6 +45,8 @@
<div class="action"> <div class="action">
<slot name="record-actions"></slot> <slot name="record-actions"></slot>
</div> </div>
<confidential v-if="thirdparty.contactDataAnonymous">
<template v-slot:confidential-content>
<ul class="list-content fa-ul"> <ul class="list-content fa-ul">
<li v-if="thirdparty.address"> <li v-if="thirdparty.address">
<i class="fa fa-li fa-map-marker"></i> <i class="fa fa-li fa-map-marker"></i>
@ -60,6 +61,22 @@
<a :href="'mailto: ' + thirdparty.email">{{ thirdparty.email }}</a> <a :href="'mailto: ' + thirdparty.email">{{ thirdparty.email }}</a>
</li> </li>
</ul> </ul>
</template>
</confidential>
<ul v-else class="list-content fa-ul">
<li v-if="thirdparty.address">
<i class="fa fa-li fa-map-marker"></i>
<address-render-box :address="thirdparty.address" :isMultiline="isMultiline"></address-render-box>
</li>
<li v-if="thirdparty.phonenumber">
<i class="fa fa-li fa-mobile"></i>
<a :href="'tel: ' + thirdparty.phonenumber">{{ thirdparty.phonenumber }}</a>
</li>
<li v-if="thirdparty.email">
<i class="fa fa-li fa-envelope-o"></i>
<a :href="'mailto: ' + thirdparty.email">{{ thirdparty.email }}</a>
</li>
</ul>
</div> </div>
</div> </div>
</div> </div>
@ -73,6 +90,7 @@
<script> <script>
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue'; import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
import {dateToISO} from 'ChillMainAssets/chill/js/date.js'; import {dateToISO} from 'ChillMainAssets/chill/js/date.js';
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
const i18n = { const i18n = {
messages: { messages: {
@ -88,7 +106,8 @@ const i18n = {
export default { export default {
name: "ThirdPartyRenderBox", name: "ThirdPartyRenderBox",
components: { components: {
AddressRenderBox AddressRenderBox,
Confidential
}, },
i18n, i18n,
props: ['thirdparty', 'options'], props: ['thirdparty', 'options'],

View File

@ -7,6 +7,7 @@
* addEntity bool * addEntity bool
* addId bool * addId bool
* addInfo bool * addInfo bool
* isConfidential bool
* hLevel integer * hLevel integer
* customButtons [ * customButtons [
'before' Twig\Markup, (injected with macro) 'before' Twig\Markup, (injected with macro)
@ -84,6 +85,9 @@
<span class="badge bg-thirdparty-{{ thirdparty.kind }}">{{ ('thirdparty.' ~ thirdparty.kind)|trans }}</span> <span class="badge bg-thirdparty-{{ thirdparty.kind }}">{{ ('thirdparty.' ~ thirdparty.kind)|trans }}</span>
</div> </div>
<div class="item-col"> <div class="item-col">
{% if options['isConfidential'] %}
<div class="confidential">
<div class="confidential-content blur">
<ul class="list-content fa-ul"> <ul class="list-content fa-ul">
<li> <li>
{{ thirdparty.getAddress|chill_entity_render_box({ {{ thirdparty.getAddress|chill_entity_render_box({
@ -106,6 +110,33 @@
</a> </a>
</li> </li>
</ul> </ul>
</div>
</div>
{% else %}
<ul class="list-content fa-ul">
<li>
{{ thirdparty.getAddress|chill_entity_render_box({
'render': 'list',
'with_picto': true,
'multiline': false,
'with_valid_from': false
}) }}
</li>
<li><i class="fa fa-li fa-phone"></i>
{% if thirdparty.telephone %}
<a href="{{ 'tel:' ~ thirdparty.telephone }}">{{ thirdparty.telephone|chill_format_phonenumber }}</a>
{% else %}
<span class="chill-no-data-statement">{{ 'thirdparty.No_phonenumber'|trans }}</span>
{% endif %}
</li>
<li><i class="fa fa-li fa-envelope-o"></i>
<a href="{{ 'mailto:' ~ thirdparty.email }}">
{{ thirdparty.email|chill_print_or_message("thirdparty.No_email") }}
</a>
</li>
</ul>
{%- endif -%}
<ul class="record_actions"> <ul class="record_actions">
{% if options['customButtons']['before'] is defined %} {% if options['customButtons']['before'] is defined %}
{{ options['customButtons']['before'] }} {{ options['customButtons']['before'] }}

View File

@ -22,7 +22,7 @@
<div class="flex-table"> <div class="flex-table">
{% for tp in third_parties %} {% for tp in third_parties %}
<div class="item-bloc"> <div class="item-bloc">
{{ tp|chill_entity_render_box({'render': 'bloc', 'addLink': false, 'showContacts': true }) }} {{ tp|chill_entity_render_box({'render': 'bloc', 'addLink': false, 'showContacts': true, 'isConfidential': (tp.contactDataAnonymous ? true : false) }) }}
<div class="item-row separator"> <div class="item-row separator">
<ul class="record_actions"> <ul class="record_actions">
{% if is_granted('CHILL_3PARTY_3PARTY_UPDATE', tp) %} {% if is_granted('CHILL_3PARTY_3PARTY_UPDATE', tp) %}

View File

@ -34,6 +34,7 @@ class ThirdPartyNormalizer implements NormalizerInterface, NormalizerAwareInterf
$data['isChild'] = $thirdParty->isChild(); $data['isChild'] = $thirdParty->isChild();
$data['parent'] = $this->normalizer->normalize($thirdParty->getParent(), $format, $context); $data['parent'] = $this->normalizer->normalize($thirdParty->getParent(), $format, $context);
$data['civility'] = $this->normalizer->normalize($thirdParty->getCivility(), $format, $context); $data['civility'] = $this->normalizer->normalize($thirdParty->getCivility(), $format, $context);
$data['contactDataAnonymous'] = $thirdParty->isContactDataAnonymous();
return $data; return $data;
} }

View File

@ -63,6 +63,7 @@ class ThirdPartyRender extends AbstractChillEntityRender
'customArea' => $options['customArea'] ?? [], 'customArea' => $options['customArea'] ?? [],
'showContacts' => $options['showContacts'] ?? false, 'showContacts' => $options['showContacts'] ?? false,
'showParent' => $options['showParent'] ?? true, 'showParent' => $options['showParent'] ?? true,
'isConfidential' => $options['isConfidential'] ?? false
]; ];
return return