add pdfme for ticket template editing, unfinished

This commit is contained in:
2023-06-18 20:55:13 +02:00
parent 2412674cb8
commit e3df40067c
9 changed files with 1234 additions and 33 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,8 @@
"build": "vue-cli-service build"
},
"dependencies": {
"@pdfme/generator": "^1.2.3",
"@pdfme/ui": "^1.2.3",
"core-js": "^3.8.3",
"pinia": "^2.0.34",
"vue": "^3.2.13",

View File

@@ -1,8 +1,9 @@
<template>
<div id="notifications" @click="handleNotifications();">
<div class="message-box" :class="messageType">
<div class="message-container">
<span class="material-symbols-outlined types" v-if="messageType == 'ok'" style="background-color: green;">done</span>
<div class="message-box" :class="location">
<div class="message-container" :class="messageType">
<span class="material-symbols-outlined types hide" v-if="messageType == 'hide'">question_mark</span>
<span class="material-symbols-outlined types" v-else-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>
<span class="material-symbols-outlined types" v-else-if="messageType == 'info'" style="background-color: lightblue;">info</span>
@@ -15,6 +16,12 @@
<script>
export default {
name: 'notifications',
props: {
location: {
type: String,
'default': 'topleft',
}
},
data () {
return {
notifications: {},
@@ -32,7 +39,7 @@
methods: {
createNotification( message, showDuration, messageType, priority ) {
/*
Takes a notification options array that contains: message, showDuration (in seconds), messageType (ok, error, progress, info) and priority (low, medium, critical).
Takes a notification options array that contains: message, showDuration (in seconds), messageType (ok, error, progress, info) and priority (low, normal, critical).
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.
*/
@@ -99,22 +106,41 @@
<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;
}
.topleft {
top: 3%;
left: 0.5%;
}
.topright {
top: 3%;
right: 0.5%;
}
.bottomright {
bottom: 3%;
right: 0.5%;
}
.bottomleft {
top: 3%;
right: 0.5%;
}
.message-container {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
opacity: 1;
transition: all 0.5s;
}
.types {

View File

@@ -0,0 +1,131 @@
<template>
<div id="notifications" @click="handleNotifications();">
<div class="message-box" :class="messageType">
<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>
<span class="material-symbols-outlined types" v-else-if="messageType == 'info'" style="background-color: lightblue;">info</span>
<p class="message">{{ message }}</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'notifications',
data () {
return {
notifications: {},
queue: [],
message: '',
messageType: 'hide',
notificationDisplayTime: 1,
notificationPriority: 'normal',
currentlyDisplayedNotificationID: 0,
currentID: { 'critical': 0, 'medium': 1000, 'low': 100000 },
displayTimeCurrentNotification: 0,
notificationScheduler: null,
}
},
methods: {
createNotification( message, showDuration, messageType, priority ) {
/*
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
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 ) {
/*
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>
<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%;
}
</style>

View File

@@ -38,7 +38,7 @@
<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>
</div>
<notifications ref="notification"></notifications>
<notifications ref="notification" location="topleft"></notifications>
</div>
</template>

View File

@@ -96,7 +96,7 @@ export default [
name: 'purchase',
component: () => import( '@/views/PurchaseView.vue' ),
meta: {
title: 'Pay - libreevent',
title: 'Purchase - libreevent',
transition: 'scale'
}
},
@@ -127,4 +127,13 @@ export default [
adminAuthRequired: true,
}
},
{
path: '/admin/ticketEditor',
name: 'adminTicketEditor',
component: () => import( '@/views/admin/events/TicketEditorView.vue' ),
meta: {
title: 'Ticket Editor :: Admin - libreevent',
adminAuthRequired: true,
}
},
]

View File

@@ -10,7 +10,7 @@
import { defineStore } from "pinia";
export const useBackendStore = defineStore ( 'backend', {
state: () => ( { 'visitedSetupPages': {}, 'guestPurchase': false, 'guestPurchaseAllowed': false } ),
state: () => ( { 'visitedSetupPages': {}, 'guestPurchase': false, 'guestPurchaseAllowed': true } ),
getters: {
getVisitedSetupPages: ( state ) => state.visitedSetupPages,
getIsGuestPurchase: ( state ) => state.guestPurchase,

View File

@@ -45,6 +45,7 @@
<h3>Special Settings</h3>
<settings v-model:settings="specialSettings"></settings>
</div>
<notifications ref="notification" location="'topright'"></notifications>
</div>
</template>
@@ -56,11 +57,13 @@
<script>
import settings from '@/components/settings/settings.vue';
import notifications from '@/components/notifications/notifications.vue';
export default {
name: 'TicketsDetailsView',
components: {
settings,
notifications,
},
created () {
if ( !sessionStorage.getItem( 'selectedTicket' ) ) {

View File

@@ -0,0 +1,56 @@
<template>
<div id="ticketEditor">
<h1>Ticket Editor</h1>
<div id="editor">Loading editor...</div>
</div>
</template>
<script>
import { Designer, BLANK_PDF } from '@pdfme/ui';
export default {
name: 'ticketEditor',
created() {
setTimeout( () => {
const domContainer = document.getElementById( 'editor' );
console.log( domContainer );
const template = {
basePdf: BLANK_PDF,
schemas: [
{
a: {
type: 'text',
position: { x: 0, y: 0 },
width: 10,
height: 10,
},
b: {
type: 'text',
position: { x: 10, y: 10 },
width: 10,
height: 10,
},
c: {
type: 'text',
position: { x: 20, y: 20 },
width: 10,
height: 10,
},
},
],
}
const designer = new Designer( { domContainer, template } );
}, 300 );
}
}
</script>
<style>
nav {
display: none;
}
#editor {
height: 90vh;
}
</style>