design notification box in post menu area

This commit is contained in:
Mathieu Jaumotte 2022-01-05 14:39:00 +01:00
parent 1e0c62b09d
commit f5f5d66f3d
9 changed files with 174 additions and 44 deletions

View File

@ -1,13 +1,18 @@
import {createApp} from "vue"; import {createApp} from "vue";
import NotificationReadToggle from "ChillMainAssets/vuejs/_components/Notification/NotificationReadToggle.vue"; import NotificationReadToggle from "ChillMainAssets/vuejs/_components/Notification/NotificationReadToggle.vue";
import { _createI18n } from "ChillMainAssets/vuejs/_js/i18n";
const i18n = _createI18n({});
window.addEventListener('DOMContentLoaded', function (e) { window.addEventListener('DOMContentLoaded', function (e) {
document.querySelectorAll('.notification_toggle_read_status') document.querySelectorAll('.notification_toggle_read_status')
.forEach(function (el) { .forEach(function (el) {
console.log('app', el); createApp({
const App = {
template: '<notification-read-toggle ' + template: '<notification-read-toggle ' +
':notificationId="notificationId" ' + ':notificationId="notificationId" ' +
':buttonClass="buttonClass" ' +
':buttonNoText="buttonNoText" ' +
':showUrl="showUrl" ' +
':isRead="isRead"' + ':isRead="isRead"' +
'@markRead="onMarkRead" @markUnread="onMarkUnread"' + '@markRead="onMarkRead" @markUnread="onMarkUnread"' +
'></notification-read-toggle>', '></notification-read-toggle>',
@ -17,6 +22,9 @@ window.addEventListener('DOMContentLoaded', function (e) {
data() { data() {
return { return {
notificationId: +el.dataset.notificationId, notificationId: +el.dataset.notificationId,
buttonClass: el.dataset.buttonClass,
buttonNoText: 'true' === el.dataset.buttonNoText,
showUrl: el.dataset.showUrl,
isRead: 1 === +el.dataset.notificationCurrentIsRead, isRead: 1 === +el.dataset.notificationCurrentIsRead,
} }
}, },
@ -28,8 +36,8 @@ window.addEventListener('DOMContentLoaded', function (e) {
this.isRead = true; this.isRead = true;
}, },
} }
} })
.use(i18n)
createApp(App).mount(el); .mount(el);
}); });
}) })

View File

@ -1,13 +1,13 @@
import { createApp } from 'vue'; import { createApp } from 'vue';
import PickEntity from 'ChillMainAssets/vuejs/PickEntity/PickEntity.vue'; import PickEntity from 'ChillMainAssets/vuejs/PickEntity/PickEntity.vue';
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n' import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'
import {activityMessages} from "../../../../../ChillActivityBundle/Resources/public/vuejs/Activity/i18n";
window.addEventListener('DOMContentLoaded', function(e) { window.addEventListener('DOMContentLoaded', function(e) {
let
apps = document.querySelectorAll('[data-module="pick-dynamic"]'); let apps = document.querySelectorAll('[data-module="pick-dynamic"]');
apps.forEach(function(el) { apps.forEach(function(el) {
const const
isMultiple = parseInt(el.dataset.multiple) === 1, isMultiple = parseInt(el.dataset.multiple) === 1,
input = document.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'), input = document.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'),
@ -15,7 +15,13 @@ window.addEventListener('DOMContentLoaded', function(e) {
i18n = _createI18n({}); i18n = _createI18n({});
createApp({ createApp({
template: '<pick-entity :multiple="multiple" :types="types" :picked="picked" :uniqid="uniqid" @addNewEntity="addNewEntity" @removeEntity="removeEntity"></pick-entity>', template: '<pick-entity ' +
':multiple="multiple" ' +
':types="types" ' +
':picked="picked" ' +
':uniqid="uniqid" ' +
'@addNewEntity="addNewEntity" ' +
'@removeEntity="removeEntity"></pick-entity>',
components: { components: {
PickEntity, PickEntity,
}, },
@ -54,6 +60,8 @@ window.addEventListener('DOMContentLoaded', function(e) {
input.value = JSON.stringify(this.picked); input.value = JSON.stringify(this.picked);
}, },
} }
}).use(i18n).mount(el); })
.use(i18n)
.mount(el);
}); });
}); });

View File

@ -91,7 +91,3 @@ export default {
}, },
} }
</script> </script>
<style scoped>
</style>

View File

@ -1,10 +1,42 @@
<template> <template>
<button v-if="isRead" @click="markAsUnread">Marquer non-lu</button> <div class="btn-group btn-group-sm float-end"
<button v-if="!isRead" @click="markAsRead">Marquer lu</button> role="group" aria-label="Notification actions">
<button v-if="isRead"
class="btn"
:class="overrideClass"
type="button"
:title="$t('markAsUnread')"
@click="markAsUnread"
>
<i class="fa fa-sm fa-envelope-o"></i>
<template v-if="!buttonNoText">
{{ $t('markAsUnread') }}
</template>
</button>
<button v-if="!isRead"
class="btn"
:class="overrideClass"
type="button"
:title="$t('markAsRead')"
@click="markAsRead"
>
<i class="fa fa-sm fa-envelope-open-o"></i>
<template v-if="!buttonNoText">
{{ $t('markAsRead') }}
</template>
</button>
<a v-if="showButton"
type="button" class="btn btn-outline-primary"
:href="showUrl">
<i class="fa fa-sm fa-eye"></i>
</a>
</div>
</template> </template>
<script> <script>
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods.js'; import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods.js';
export default { export default {
@ -17,9 +49,33 @@ export default {
notificationId: { notificationId: {
required: true, required: true,
type: Number, type: Number,
},
buttonClass: {
required: false,
type: String
},
buttonNoText: {
required: false,
type: Boolean,
},
showUrl: {
required: false,
type: String
} }
}, },
emits: ['markRead', 'markUnread'], emits: ['markRead', 'markUnread'],
computed: {
overrideClass() {
console.log('button', this.buttonClass);
return this.buttonClass ? this.buttonClass : 'btn-misc'
},
buttonHideText() {
return this.buttonNoText;
},
showButton() {
return !!this.showUrl
}
},
methods: { methods: {
markAsUnread() { markAsUnread() {
makeFetch('POST', `/api/1.0/main/notification/${this.notificationId}/mark/unread`, []).then(response => { makeFetch('POST', `/api/1.0/main/notification/${this.notificationId}/mark/unread`, []).then(response => {
@ -32,9 +88,41 @@ export default {
}) })
}, },
}, },
i18n: {
messages: {
fr: {
markAsUnread: 'Marquer comme non-lu',
markAsRead: 'Marquer comme lu'
}
}
}
} }
</script> </script>
<style scoped> <style lang="scss">
.notification {
h6 {
&::before {
font-family: "ForkAwesome";
font-size: 80%;
}
}
.read {
h6 {
font-weight: 500;
&::before {
//content: "\f2b6"; //envelope-open
content: "\f2b7"; //envelope-open-o
}
}
}
.unread {
h6 {
&::before {
//content: "\f0e0"; //envelope
content: "\f003"; //envelope-o
}
}
}
}
</style> </style>

View File

@ -1,25 +1,43 @@
<div class="list_notification_for"> <div class="list-group notification my-2">
<div class="list-group-item">
<h4>{{ 'notification.Sent'|trans }}</h4>
</div>
{# TODO pagination or limit #}
{% for notification in notifications %} {% for notification in notifications %}
<div class="notification {% if notification.isReadBy(app.user) %}read{% else %}unread{% endif %}"> <div class="list-group-item {% if notification.isReadBy(app.user) %}read{% else %}unread{% endif %}">
{% if not notification.isSystem %} {% if not notification.isSystem %}
{% if notification.sender == app.user %} {% if notification.sender == app.user %}
<div>You sent notification to: {% for a in notification.addressees %}{{ a|chill_entity_render_string }}{% if not loop.last %}, {% endif %}{% endfor %}</div>
<h6>
<abbr title="{{ 'le ' ~ notification.date|format_date('long') }}">
{{ notification.date|format_datetime('short','short') }}
</abbr>
<span class="notification_toggle_read_status"
data-notification-id="{{ notification.id }}"
data-notification-current-is-read="{{ notification.isReadBy(app.user) }}"
data-show-url="{{ chill_path_add_return_path('chill_main_notification_show', {'id': notification.id}) }}"
data-button-class="btn-outline-primary"
data-button-no-text="true"
></span>
</h6>
{% if notification.addressees|length > 0 %}
<abbr title="{{ 'notification.sentto'|trans }}">{{ 'notification.to'|trans }}:</abbr>
{% endif %}
{% for a in notification.addressees %}
<span class="badge-user">
{{ a|chill_entity_render_string }}
</span>
{% endfor %}
{% else %} {% else %}
<div>{{ 'notification.you were notified by %sender%'|trans({'%sender%': notification.sender|chill_entity_render_string }) }}</div> <div>{{ 'notification.you were notified by %sender%'|trans({'%sender%': notification.sender|chill_entity_render_string }) }}</div>
{% endif %} {% endif %}
{% else %} {% else %}
<div>{{ 'notification.you were notified by system'|trans }}</div> <div>{{ 'notification.you were notified by system'|trans }}</div>
{% endif %} {% endif %}
<div>
<ul class="record_actions_small">
<li>
<span class="notification_toggle_read_status" data-notification-id="{{ notification.id }}" data-notification-current-is-read="{{ notification.isReadBy(app.user) }}"></span>
</li>
<li>
<a href="{{ chill_path_add_return_path('chill_main_notification_show', {'id': notification.id}) }}" class="btn btn-show"></a>
</li>
</ul>
</div>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -353,7 +353,7 @@ Created for: Créé pour
Created by: Créé par Created by: Créé par
notification: notification:
Notify: Notifier Notify: Envoyer une notification
Notification created: Notification envoyée Notification created: Notification envoyée
Any notification received: Aucune notification reçue Any notification received: Aucune notification reçue
Any notification sent: Aucune notification envoyée Any notification sent: Aucune notification envoyée
@ -365,4 +365,9 @@ notification:
is_unread: Non-lue is_unread: Non-lue
is_system: Notification automatique is_system: Notification automatique
list: Notifications list: Notifications
Sent: Envoyé
sentto: Envoyé à
you were notified by %sender%: Vous avez été notifié par %sender%
you were notified by system: Vous avez été notifié automatiquement
to: À

View File

@ -26,9 +26,6 @@
{% block content %} {% block content %}
<div class="accompanyingcourse-resume"> <div class="accompanyingcourse-resume">
{{ chill_list_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', accompanyingCourse.id) }}
<div id="dashboards" class="row g-3" data-masonry='{"percentPosition": true }'> <div id="dashboards" class="row g-3" data-masonry='{"percentPosition": true }'>
{% if 'DRAFT' == accompanyingCourse.step %} {% if 'DRAFT' == accompanyingCourse.step %}
@ -134,10 +131,6 @@
</div> </div>
{% endif %} {% endif %}
<div class="col col-sm-4 col-lg-4 notify mb-4">
<a class="btn btn-notify" href="{{ chill_path_add_return_path('chill_main_notification_create', {'entityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod', 'entityId': accompanyingCourse.id}) }}">{{ 'notification.Notify'|trans }}</a>
</div>
{% if accompanyingCourse.requestorPerson is not null or accompanyingCourse.requestorThirdParty is not null %} {% if accompanyingCourse.requestorPerson is not null or accompanyingCourse.requestorThirdParty is not null %}
<div class="mbloc col col-sm-6 col-lg-4"> <div class="mbloc col col-sm-6 col-lg-4">
<div class="requestor"> <div class="requestor">
@ -189,3 +182,17 @@
</div> </div>
{% endblock %} {% endblock %}
{% block block_post_menu %}
<div class="post-menu pt-4">
<div class="d-grid gap-2">
<a class="btn btn-notify" href="{{ chill_path_add_return_path('chill_main_notification_create', {'entityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod', 'entityId': accompanyingCourse.id}) }}">
{{ 'notification.Notify'|trans }}
</a>
</div>
{{ chill_list_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', accompanyingCourse.id) }}
</div>
{% endblock %}

View File

@ -3,7 +3,7 @@
{% block title 'household.Household summary'|trans %} {% block title 'household.Household summary'|trans %}
{% block block_post_menu %} {% block block_post_menu %}
<div class="block-post-menu"></div> <div class="post-menu"></div>
{% endblock %} {% endblock %}
{% block content %} {% block content %}

View File

@ -38,7 +38,7 @@
}) }} }) }}
{% block block_post_menu %} {% block block_post_menu %}
<div class="block-post-menu"> <div class="post-menu">
{{ chill_delegated_block('person_post_vertical_menu', { 'person': person } ) }} {{ chill_delegated_block('person_post_vertical_menu', { 'person': person } ) }}
</div> </div>
{% endblock %} {% endblock %}