mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 05:14:23 +00:00
complete notifications handling component
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="notifications">
|
<div id="notifications" @click="handleNotifications();">
|
||||||
<div class="message-box" :class="messageType">
|
<div class="message-box" :class="messageType">
|
||||||
<div class="message-container">
|
<div class="message-container">
|
||||||
<span class="material-symbols-outlined types" v-if="messageType == 'ok'" style="background-color: green;">done</span>
|
<span class="material-symbols-outlined types" v-if="messageType == 'ok'" style="background-color: green;">done</span>
|
||||||
<span class="material-symbols-outlined types" v-else-if="messageType == 'error'" style="background-color: red;">close</span>
|
<span class="material-symbols-outlined types" v-else-if="messageType == 'error'" style="background-color: red;">close</span>
|
||||||
<span class="material-symbols-outlined types progress-spinner" v-else-if="messageType == 'progress'" style="background-color: blue;">progress_activity</span>
|
<span class="material-symbols-outlined types progress-spinner" v-else-if="messageType == 'progress'" style="background-color: blue;">progress_activity</span>
|
||||||
|
<span class="material-symbols-outlined types" v-else-if="messageType == 'info'" style="background-color: lightblue;">info</span>
|
||||||
<p class="message">{{ message }}</p>
|
<p class="message">{{ message }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -18,19 +19,146 @@
|
|||||||
return {
|
return {
|
||||||
notifications: {},
|
notifications: {},
|
||||||
queue: [],
|
queue: [],
|
||||||
|
message: '',
|
||||||
|
messageType: 'hide',
|
||||||
|
notificationDisplayTime: 1,
|
||||||
|
notificationPriority: 'normal',
|
||||||
|
currentlyDisplayedNotificationID: 0,
|
||||||
|
currentID: { 'critical': 0, 'medium': 1000, 'low': 100000 },
|
||||||
|
displayTimeCurrentNotification: 0,
|
||||||
|
notificationScheduler: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
createNotification( options ) {
|
createNotification( message, showDuration, messageType, priority ) {
|
||||||
/*
|
/*
|
||||||
Takes a notification options array that contains: Message, show duration, message type (ok, error, processing) and priority (low, normal, critical).
|
Takes a notification options array that contains: message, showDuration (in seconds), messageType (ok, error, progress, info) and priority (low, medium, critical).
|
||||||
Returns a notification ID which can be used to cancel the notification. The component will throttle notifications and display
|
Returns a notification ID which can be used to cancel the notification. The component will throttle notifications and display
|
||||||
one at a time and prioritize messages with higher priority. Use vue refs to access these methods.
|
one at a time and prioritize messages with higher priority. Use vue refs to access these methods.
|
||||||
*/
|
*/
|
||||||
|
let id = 0;
|
||||||
|
|
||||||
|
if ( priority === 'critical' ) {
|
||||||
|
this.currentID[ 'critical' ] += 1;
|
||||||
|
id = this.currentID[ 'critical' ];
|
||||||
|
} else if ( priority === 'normal' ) {
|
||||||
|
this.currentID[ 'medium' ] += 1;
|
||||||
|
id = this.currentID[ 'medium' ];
|
||||||
|
} else if ( priority === 'low' ) {
|
||||||
|
this.currentID[ 'low' ] += 1;
|
||||||
|
id = this.currentID[ 'low' ];
|
||||||
|
}
|
||||||
|
this.notifications[ id ] = { 'message': message, 'showDuration': showDuration, 'messageType': messageType, 'priority': priority };
|
||||||
|
this.queue.push( id );
|
||||||
|
console.log( 'scheduled notification: ' + id + ' (' + message + ')' );
|
||||||
|
return id;
|
||||||
},
|
},
|
||||||
cancelNotification ( id ) {
|
cancelNotification ( id ) {
|
||||||
|
/*
|
||||||
|
This method deletes a notification and, in case the notification is being displayed, hides it.
|
||||||
|
*/
|
||||||
|
delete notifications[ id ];
|
||||||
|
delete this.queue[ this.queue.findIndex( id ) ];
|
||||||
|
if ( this.currentlyDisplayedNotificationID == id ) {
|
||||||
|
this.handleNotifications();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
handleNotifications () {
|
||||||
|
/*
|
||||||
|
This methods should NOT be called in any other component than this one!
|
||||||
|
*/
|
||||||
|
this.displayTimeCurrentNotification = 0;
|
||||||
|
this.queue.sort();
|
||||||
|
if ( this.queue.length > 0 ) {
|
||||||
|
this.message = this.notifications[ this.queue[ 0 ] ][ 'message' ];
|
||||||
|
this.messageType = this.notifications[ this.queue[ 0 ] ][ 'messageType' ];
|
||||||
|
this.priority = this.notifications[ this.queue[ 0 ] ][ 'priority' ];
|
||||||
|
this.notificationDisplayTime = this.notifications[ this.queue[ 0 ] ][ 'showDuration' ];
|
||||||
|
this.queue.reverse();
|
||||||
|
this.queue.pop();
|
||||||
|
} else {
|
||||||
|
this.messageType = 'hide';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.notificationScheduler = setInterval( () => {
|
||||||
|
if ( this.displayTimeCurrentNotification >= this.notificationDisplayTime ) {
|
||||||
|
this.handleNotifications();
|
||||||
|
} else {
|
||||||
|
this.displayTimeCurrentNotification += 0.5;
|
||||||
|
}
|
||||||
|
}, 500 );
|
||||||
|
},
|
||||||
|
unmounted ( ) {
|
||||||
|
clearInterval( this.notificationScheduler );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.message-box {
|
||||||
|
position: fixed;
|
||||||
|
left: 0.5%;
|
||||||
|
z-index: 5;
|
||||||
|
top: 3%;
|
||||||
|
color: white;
|
||||||
|
height: 10vh;
|
||||||
|
width: 15vw;
|
||||||
|
opacity: 1;
|
||||||
|
transition: all 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.types {
|
||||||
|
color: white;
|
||||||
|
border-radius: 100%;
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: 5%;
|
||||||
|
font-size: 200%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
margin-right: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ok {
|
||||||
|
background-color: rgb(1, 71, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
background-color: rgb(114, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
background-color: rgb(44, 112, 151);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
background-color: rgb(0, 0, 99);
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-spinner {
|
||||||
|
animation: spin 2s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
from {
|
||||||
|
transform: rotate( 0deg );
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate( 720deg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -35,17 +35,10 @@
|
|||||||
<button title="Zoom out [-]" @click="zoom( -0.2 )"><span class="material-symbols-outlined">zoom_out</span></button>
|
<button title="Zoom out [-]" @click="zoom( -0.2 )"><span class="material-symbols-outlined">zoom_out</span></button>
|
||||||
<button title="Add component [Ctrl + I]" @click="addNewElement()"><span class="material-symbols-outlined">add</span></button>
|
<button title="Add component [Ctrl + I]" @click="addNewElement()"><span class="material-symbols-outlined">add</span></button>
|
||||||
<button title="Remove selected component [Delete]" @click="deleteSelected()"><span class="material-symbols-outlined">delete</span></button>
|
<button title="Remove selected component [Delete]" @click="deleteSelected()"><span class="material-symbols-outlined">delete</span></button>
|
||||||
<button title="Save this seatplan as a draft" @click="saveDraft()"><span class="material-symbols-outlined">save</span></button>
|
<button title="Save this seatplan as a draft [Ctrl + S]" @click="saveDraft()"><span class="material-symbols-outlined">save</span></button>
|
||||||
<button title="Deploy this seatplan (save it for use)" @click="deploy()"><span class="material-symbols-outlined">system_update_alt</span></button>
|
<button title="Deploy this seatplan (save it for use)" @click="deploy()"><span class="material-symbols-outlined">system_update_alt</span></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="message-box" :class="messageType">
|
<notifications ref="notification"></notifications>
|
||||||
<div class="message-container">
|
|
||||||
<span class="material-symbols-outlined types" v-if="messageType == 'ok'" style="background-color: green;">done</span>
|
|
||||||
<span class="material-symbols-outlined types" v-else-if="messageType == 'error'" style="background-color: red;">close</span>
|
|
||||||
<span class="material-symbols-outlined types progress-spinner" v-else-if="messageType == 'progress'" style="background-color: blue;">progress_activity</span>
|
|
||||||
<p class="message">{{ message }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -57,6 +50,7 @@
|
|||||||
import trapezoidSeatplanComponent from '@/components/seatplan/seatplanComponents/seats/trapezoid.vue';
|
import trapezoidSeatplanComponent from '@/components/seatplan/seatplanComponents/seats/trapezoid.vue';
|
||||||
import stagesSeatplanComponent from '@/components/seatplan/seatplanComponents/stage/stages.vue';
|
import stagesSeatplanComponent from '@/components/seatplan/seatplanComponents/stage/stages.vue';
|
||||||
import standingSeatplanComponent from '@/components/seatplan/seatplanComponents/stand/standing.vue';
|
import standingSeatplanComponent from '@/components/seatplan/seatplanComponents/stand/standing.vue';
|
||||||
|
import notifications from '@/components/notifications/notifications.vue';
|
||||||
import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css';
|
import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -69,6 +63,7 @@
|
|||||||
trapezoidSeatplanComponent,
|
trapezoidSeatplanComponent,
|
||||||
stagesSeatplanComponent,
|
stagesSeatplanComponent,
|
||||||
standingSeatplanComponent,
|
standingSeatplanComponent,
|
||||||
|
notifications,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -81,8 +76,6 @@
|
|||||||
zoomFactor: 1,
|
zoomFactor: 1,
|
||||||
historyPos: 0,
|
historyPos: 0,
|
||||||
generalSettings: { 'namingScheme': 'numeric' },
|
generalSettings: { 'namingScheme': 'numeric' },
|
||||||
message: 'Test message',
|
|
||||||
messageType: 'hide',
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -267,29 +260,18 @@
|
|||||||
},
|
},
|
||||||
saveDraft () {
|
saveDraft () {
|
||||||
sessionStorage.setItem( 'seatplan', JSON.stringify( this.scaleDown( this.draggables ) ) );
|
sessionStorage.setItem( 'seatplan', JSON.stringify( this.scaleDown( this.draggables ) ) );
|
||||||
|
this.$refs.notification.createNotification( 'Saved as draft', 5, 'ok', 'normal' );
|
||||||
// TODO: Save to server
|
// TODO: Save to server
|
||||||
this.message = 'Saved as draft';
|
|
||||||
this.messageType = 'ok';
|
|
||||||
setTimeout( () => {
|
|
||||||
this.messageType = 'hide';
|
|
||||||
}, 5000 );
|
|
||||||
},
|
},
|
||||||
deploy () {
|
deploy () {
|
||||||
// TODO: Save to server
|
// TODO: Save to server
|
||||||
this.message = 'Deploying...';
|
this.$refs.notification.createNotification( 'Deploying...', 5, 'progress', 'normal' );
|
||||||
this.messageType = 'progress';
|
this.$refs.notification.createNotification( 'Deployed successfully', 5, 'ok', 'normal' );
|
||||||
setTimeout( () => {
|
|
||||||
this.messageType = 'ok';
|
|
||||||
this.message = 'Deployed successfully';
|
|
||||||
}, 5000 );
|
|
||||||
setTimeout( () => {
|
|
||||||
this.messageType = 'hide';
|
|
||||||
this.message = '';
|
|
||||||
}, 10000 );
|
|
||||||
},
|
},
|
||||||
addNewElement () {
|
addNewElement () {
|
||||||
this.draggables[ Object.keys( this.draggables ).length + 1 ] = { 'x': 100, 'y':100, 'h': 100, 'w': 250, 'active': false, 'draggable': true, 'resizable': true, 'id': Object.keys( this.draggables ).length + 1, 'origin': 1, 'shape':'rectangular', 'type': 'seat', 'startingRow': 1, 'seatCountingStartingPoint': 0 };
|
this.draggables[ Object.keys( this.draggables ).length + 1 ] = { 'x': 100, 'y':100, 'h': 100, 'w': 250, 'active': false, 'draggable': true, 'resizable': true, 'id': Object.keys( this.draggables ).length + 1, 'origin': 1, 'shape':'rectangular', 'type': 'seat', 'startingRow': 1, 'seatCountingStartingPoint': 0 };
|
||||||
this.saveHistory();
|
this.saveHistory();
|
||||||
|
this.$refs.notification.createNotification( 'New component added successfully', 5, 'ok', 'normal' );
|
||||||
},
|
},
|
||||||
deleteSelected () {
|
deleteSelected () {
|
||||||
if ( this.active ) {
|
if ( this.active ) {
|
||||||
@@ -298,9 +280,10 @@
|
|||||||
delete this.draggables[ this.active ];
|
delete this.draggables[ this.active ];
|
||||||
this.saveHistory();
|
this.saveHistory();
|
||||||
this.active = 0;
|
this.active = 0;
|
||||||
|
this.$refs.notification.createNotification( 'Successfully deleted component', 5, 'ok', 'normal' );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert( 'Please select a component first!' );
|
this.$refs.notification.createNotification( 'Please select a seat first!', 5, 'error', 'normal' );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleUpdate ( value ) {
|
handleUpdate ( value ) {
|
||||||
@@ -315,17 +298,9 @@
|
|||||||
} else {
|
} else {
|
||||||
if ( ( this.zoomFactor < 0.3 && scale < 0 ) || ( this.zoomFactor > 2.9 && scale > 0 ) ) {
|
if ( ( this.zoomFactor < 0.3 && scale < 0 ) || ( this.zoomFactor > 2.9 && scale > 0 ) ) {
|
||||||
if ( this.zoomFactor < 0.3 ) {
|
if ( this.zoomFactor < 0.3 ) {
|
||||||
this.message = 'Minimum zoom factor reached';
|
this.$refs.notification.createNotification( 'Minimum zoom factor reached', 5, 'error', 'normal' );
|
||||||
this.messageType = 'error';
|
|
||||||
setTimeout( () => {
|
|
||||||
this.messageType = 'hide';
|
|
||||||
}, 5000 );
|
|
||||||
} else {
|
} else {
|
||||||
this.message = 'Maximum zoom factor reached';
|
this.$refs.notification.createNotification( 'Maximum zoom factor reached', 5, 'error', 'normal' );
|
||||||
this.messageType = 'error';
|
|
||||||
setTimeout( () => {
|
|
||||||
this.messageType = 'hide';
|
|
||||||
}, 5000 );
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.zoomFactor += scale;
|
this.zoomFactor += scale;
|
||||||
@@ -401,65 +376,4 @@
|
|||||||
.toolbar button:disabled {
|
.toolbar button:disabled {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-box {
|
|
||||||
position: fixed;
|
|
||||||
left: 0.5%;
|
|
||||||
z-index: 5;
|
|
||||||
top: 3%;
|
|
||||||
color: white;
|
|
||||||
height: 10vh;
|
|
||||||
width: 15vw;
|
|
||||||
opacity: 1;
|
|
||||||
transition: all 0.5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.types {
|
|
||||||
color: white;
|
|
||||||
border-radius: 100%;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-left: 5%;
|
|
||||||
font-size: 200%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message {
|
|
||||||
margin-right: 5%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ok {
|
|
||||||
background-color: rgb(1, 71, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
background-color: rgb(114, 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hide {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress {
|
|
||||||
background-color: rgb(0, 0, 99);
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-spinner {
|
|
||||||
animation: spin 2s infinite linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
from {
|
|
||||||
transform: rotate( 0deg );
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: rotate( 720deg );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user