diff --git a/README.md b/README.md index 00b8bf779b84b892b2db262cbea1b6dee51e6cea..5d0533d9de65b46e32cf1ccca0932bd956559096 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,19 @@ sib-notifications is a component that displays all elements of an inbox, i.e. a When the user clicks one of the notifications, a 'navigate' event is triggered with the object of the notification given as the resource parameter. -The component listens to 'read' events. These events details contain a resource and a type. When such an event is triggered, it sets all notifications with that resource and type as read, and saves these notifications back to the container. \ No newline at end of file +The component listens to 'read' events. These events details contain a resource. When such an event is triggered, it sets all notifications with that resource as read, and saves these notifications back to the container. +To send an event, you can dispatch it like this: +```javascript +window.dispatchEvent(new CustomEvent('read', {detail: {resource: resource}})) +``` + +## Usage +In your template, insert the following line where you want to display the component. +```html + +``` + +If you want to use the `bind-user` attribute, do not forget to use `sib-oidc` for authentication. + + + diff --git a/css/main.css b/css/main.css new file mode 100644 index 0000000000000000000000000000000000000000..c64909917364570b5850855d4ed7f8eb14f219ec --- /dev/null +++ b/css/main.css @@ -0,0 +1,82 @@ +.sib-notifications{ + box-sizing: border-box; + font-family: sans-serif; +} + +.sib-notifications__container{ } + +/* Counter */ +.sib-notifications__counter{ + position: absolute; + top: -5px; + right: -5px; + width: 20px; + height: 20px; + line-height: 20px; + background-color: #ffd759; + border-radius: 50%; + font-size: 12px; +} + +/* Button */ +.sib-notifications__button{ + display: block; + position: relative; + width: 30px; + height: 30px; + line-height: 30px; + padding: 5px; + text-align: center; + cursor: pointer; +} +.sib-notifications__button::-webkit-details-marker { + display: none +} +.sib-notifications__button:hover{ + background: #EEE; +} +.sib-notifications__button:active, +.sib-notifications__button:focus{ + background: #EDEDED; +} + +/* List */ +.sib-notifications__list{ + width: 300px; + max-height: 500px; + margin-top: 5px; + overflow: scroll; + background: white; + border: 1px solid #DDD; + border-radius: 5px; +} + +/* Notification */ +.sib-notifications__items sib-display{ + display: block; + cursor: pointer; +} +.sib-notifications__items sib-display:hover{ + background: rgba(0,0,0,0.02); +} +.sib-notifications__items sib-display:active, +.sib-notifications__items sib-display:focus{ + background: rgba(0,0,0,0.03); +} + +.sib-notifications__items sib-display div[name=content]{ + padding: 10px; + border-bottom: 1px solid #DDD; +} +.sib-notifications__items sib-display [data-read=read] + div[name=content]{ + opacity: .6; +} +.sib-notifications__items sib-display [data-read=unread] + div[name=content]{ + background: rgba(255, 215, 89, 0.14) +} + +/* Fields */ +.sib-notifications__items sib-display-div[name="date"]{ + color: #999; + font-size: 80%; +} \ No newline at end of file diff --git a/img/notification-icon.svg b/img/notification-icon.svg new file mode 100644 index 0000000000000000000000000000000000000000..7dca1fc8c5f63aac0a91659e38eb7f3c80134342 --- /dev/null +++ b/img/notification-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000000000000000000000000000000000000..9cc8c707af7de8d9527567e25543d1268d41907b --- /dev/null +++ b/index.html @@ -0,0 +1,26 @@ + + + + + + SIB Notifications - Demo + + + + + + +

SIB Notifications - Demo

+ + + + + diff --git a/sib-notifications.js b/sib-notifications.js new file mode 100644 index 0000000000000000000000000000000000000000..9751620c4a283417e8283a09c93f3d3df700bf0e --- /dev/null +++ b/sib-notifications.js @@ -0,0 +1,94 @@ +import { SIBTemplateElement, SIBDisplay, store } from 'https://unpkg.com/@startinblox/core@0.5'; +import { importCSS } from 'https://cdn.happy-dev.fr/sib-core/helpers.js' + +const base_url = import.meta.url.replace(/\/[^\/]*$/, ''); +importCSS(`${base_url}/css/main.css`) + +class SIBNotifications extends SIBTemplateElement { + constructor() { + super() + + window.addEventListener('read', event => { + if(event.detail && event.detail.resource && event.detail.resource['@id']) { + this._onReadResource(event.detail.resource['@id']) + } else { + this._printError('Resource parameter is missing. Check the documentation: https://git.happy-dev.fr/startinblox/framework/sib-notifications') + } + }) + + this.addEventListener("click", event => { + let notif = event.target.closest('sib-display') + if (notif && notif.classList.length === 0) { // TODO: classList can be improved + this._onClickNotification(notif) + } + }) + } + + static get propsDefinition() { + return { + dataSrc: 'data-src', + idSuffix: 'id-suffix' + } + } + + _onClickNotification(target) { + window.dispatchEvent(new CustomEvent('requestNavigation', {detail: {resource: target.resource.object}})) // TODO: implement requestNavigation withtout routeName + } + + _onReadResource(resourceId) { + let markedAsRead = 0 + this._getNotificationsList().forEach(notification => { + if (notification.object === resourceId) { + store.patch(notification['@id'], { read: true }) + .then((e) => console.log('Notification marked as read', e)) + .catch((error) => this._printError(error)) + markedAsRead++ + } + }) + if (markedAsRead) { + this.render() + } + } + + _getNotificationsList() { + return document.querySelector('#notifications-list').resource['ldp:contains'] + } + + _printError(error) { + console.error(error) + } + + template({ dataSrc, idSuffix }) { + if (dataSrc) { + let sourceUrl = dataSrc + (idSuffix ? idSuffix + '/' : '') + return ` +
+
+ + + + +
+ +
+ +
+
+ `; + } + } +} + +customElements.define('sib-notifications', SIBNotifications); \ No newline at end of file