mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 05:14:23 +00:00
lots of seat plan editor optimisations
This commit is contained in:
@@ -31,6 +31,8 @@
|
||||
</table>
|
||||
<h3>Component settings</h3>
|
||||
<table v-if="active">
|
||||
|
||||
<!-- H/W/Y/X for rendering -->
|
||||
|
||||
<tr>
|
||||
<td>Position X:</td>
|
||||
@@ -56,19 +58,81 @@
|
||||
<input type="number" min="20" v-model="internal[ active ].h" @change="resubmit()">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<!-- Starting row for row counting and rendering -->
|
||||
|
||||
<tr v-if="internal[ active ].type == 'seat'">
|
||||
<td>Starting row:</td>
|
||||
<td>
|
||||
<input type="number" min="1" max="20" v-model="internal[ active ].startingRow" @change="resubmit()">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- ORIGIN of component for rendering -->
|
||||
|
||||
<tr>
|
||||
<td>Origin:</td>
|
||||
<td>
|
||||
<input type="number" min="1" max="4" v-model="internal[ active ].origin" @change="resubmit()">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<!-- TEXT Settings -->
|
||||
|
||||
<tr v-if="internal[ active ].type == 'text'">
|
||||
<td>Text:</td>
|
||||
<td>
|
||||
<input type="text" v-model="internal[ active ].text.text" @change="resubmit()">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr v-if="internal[ active ].type == 'text'">
|
||||
<td>Text Size:</td>
|
||||
<td>
|
||||
<input type="number" min="1" max="100" v-model="internal[ active ].text.textSize" @change="resubmit()">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr v-if="internal[ active ].type == 'text'">
|
||||
<td>Text colour:</td>
|
||||
<td>
|
||||
<input type="text" data-coloris v-model="internal[ active ].text.colour" onkeydown="return false;">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- CATEGORY -->
|
||||
|
||||
<tr v-if="internal[ active ].type == 'seat' || internal[ active ].type == 'stand'">
|
||||
<td>Category:</td>
|
||||
<td>
|
||||
<select v-model="internal[ active ].seatCountingStartingPoint" @change="resubmit()">
|
||||
<option v-for="category in categories" :value="category.value">{{ category.name }}</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- SECTOR -->
|
||||
|
||||
<tr v-if="internal[ active ].type == 'seat' || internal[ active ].type == 'stand'">
|
||||
<td>Sector:</td>
|
||||
<td>
|
||||
<input type="text" min="1" max="4" v-model="internal[ active ].sector" @change="resubmit()">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- TICKET COUNT -->
|
||||
|
||||
<tr v-if="internal[ active ].type == 'stand'">
|
||||
<td>Ticket count:</td>
|
||||
<td>
|
||||
<input type="number" min="1" max="4" v-model="internal[ active ].ticketCount" @change="resubmit()">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- SEAT NUMBERING for seats -->
|
||||
|
||||
<tr v-if="internal[ active ].type == 'seat'">
|
||||
<td>Seat numbering:</td>
|
||||
<td>
|
||||
<select v-model="internal[ active ].seatCountingStartingPoint" @change="resubmit()">
|
||||
@@ -78,6 +142,9 @@
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Component type selector -->
|
||||
|
||||
<tr>
|
||||
<td>Type:</td>
|
||||
<td>
|
||||
@@ -85,10 +152,14 @@
|
||||
<option value="seat">Seat</option>
|
||||
<option value="stand">Stand</option>
|
||||
<option value="stage">Stage</option>
|
||||
<option value="text">Text</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<!-- SHAPE of component if not a text element -->
|
||||
|
||||
<tr v-if="internal[ active ].type != 'text'">
|
||||
<td>Shape:</td>
|
||||
<td>
|
||||
<select min="20" v-model="internal[ active ].shape" @change="resubmit()">
|
||||
@@ -138,9 +209,11 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
internal: {},
|
||||
categories: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// TODO: Load categories from server
|
||||
loadInternal () {
|
||||
for ( let value in this.draggables ) {
|
||||
this.internal[ value ] = {};
|
||||
@@ -159,7 +232,7 @@ export default {
|
||||
ret[ value ] = {};
|
||||
for ( let info in this.internal[ value ] ) {
|
||||
if ( info === 'w' || info === 'h' || info === 'x' || info === 'y' ) {
|
||||
ret[ value ][ info ] = Math.round( this.internal[ value ][ info ] * this.scaleFactor );
|
||||
ret[ value ][ info ] = this.internal[ value ][ info ] * this.scaleFactor;
|
||||
} else {
|
||||
ret[ value ][ info ] = this.internal[ value ][ info ];
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<rectangularSeatplanComponent v-else-if="draggable.shape == 'rectangular' && draggable.type == 'seat'" :scale-factor="scaleFactor" :w="draggable.w" :h="draggable.h" :origin="draggable.origin"></rectangularSeatplanComponent>
|
||||
<stagesSeatplanComponent v-else-if="draggable.type == 'stage'" :origin="draggable.origin" :shape="draggable.shape"></stagesSeatplanComponent>
|
||||
<standingSeatplanComponent v-else-if="draggable.type == 'stand'" :origin="draggable.origin" :shape="draggable.shape"></standingSeatplanComponent>
|
||||
<textFieldSeatplanComponent v-else-if="draggable.type == 'text'" :text="draggable.text.text" :text-size="draggable.text.textSize" :colour="draggable.text.colour" :origin="draggable.origin" :scale-factor="scaleFactor"></textFieldSeatplanComponent>
|
||||
</Vue3DraggableResizable>
|
||||
</div>
|
||||
</div>
|
||||
@@ -37,7 +38,6 @@
|
||||
<button title="Remove selected component [Delete]" @click="deleteSelected()"><span class="material-symbols-outlined">delete</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="Get amount of seats printed to console" @click="getSeatCount()"><span class="material-symbols-outlined">living</span></button>
|
||||
</div>
|
||||
<notifications ref="notification" location="topleft"></notifications>
|
||||
</div>
|
||||
@@ -49,8 +49,9 @@
|
||||
import circularSeatplanComponent from '@/components/seatplan/seatplanComponents/seats/circular.vue';
|
||||
import rectangularSeatplanComponent from '@/components/seatplan/seatplanComponents/seats/rectangular.vue';
|
||||
import trapezoidSeatplanComponent from '@/components/seatplan/seatplanComponents/seats/trapezoid.vue';
|
||||
import stagesSeatplanComponent from '@/components/seatplan/seatplanComponents/stage/stages.vue';
|
||||
import standingSeatplanComponent from '@/components/seatplan/seatplanComponents/stand/standing.vue';
|
||||
import stagesSeatplanComponent from '@/components/seatplan/seatplanComponents/stages.vue';
|
||||
import standingSeatplanComponent from '@/components/seatplan/seatplanComponents/standing.vue';
|
||||
import textFieldSeatplanComponent from '@/components/seatplan/seatplanComponents/textField.vue';
|
||||
import notifications from '@/components/notifications/notifications.vue';
|
||||
import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css';
|
||||
|
||||
@@ -64,12 +65,13 @@
|
||||
trapezoidSeatplanComponent,
|
||||
stagesSeatplanComponent,
|
||||
standingSeatplanComponent,
|
||||
textFieldSeatplanComponent,
|
||||
notifications,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: 0,
|
||||
draggables: { 1: { 'x': 100, 'y':100, 'h': 100, 'w': 250, 'active': false, 'draggable': true, 'resizable': true, 'id': 1, 'origin': 1, 'shape':'rectangular', 'type': 'seat', 'startingRow': 1, 'seatCountingStartingPoint': 0 } },
|
||||
draggables: { 1: { 'x': 100, 'y':100, 'h': 100, 'w': 250, 'active': false, 'draggable': true, 'resizable': true, 'id': 1, 'origin': 1, 'shape':'rectangular', 'type': 'seat', 'startingRow': 1, 'seatCountingStartingPoint': 1, 'sector': 'A', 'text': { 'text': 'TestText', 'textSize': 20, 'colour': '#20FFFF' } }, 'ticketCount': 1 },
|
||||
available: { 'redo': false, 'undo': false },
|
||||
scaleFactor: 1,
|
||||
sizePoll: null,
|
||||
@@ -197,7 +199,7 @@
|
||||
returnArray[ entry ] = {};
|
||||
for ( let attributes in valueArray[ entry ] ) {
|
||||
if ( allowedAttributes.includes( attributes ) ) {
|
||||
returnArray[ entry ][ attributes ] = Math.round( valueArray[ entry ][ attributes ] * this.scaleFactor );
|
||||
returnArray[ entry ][ attributes ] = valueArray[ entry ][ attributes ] * this.scaleFactor;
|
||||
} else {
|
||||
returnArray[ entry ][ attributes ] = valueArray[ entry ][ attributes ];
|
||||
}
|
||||
@@ -263,7 +265,7 @@
|
||||
let progressNotification = this.$refs.notification.createNotification( 'Saving as draft', 5, 'progress', 'normal' );
|
||||
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 and add warning if no component has a seat start point if any component is a seat component
|
||||
},
|
||||
deploy () {
|
||||
// TODO: Save to server
|
||||
@@ -271,7 +273,7 @@
|
||||
this.$refs.notification.createNotification( 'Deployed successfully', 5, 'ok', 'normal' );
|
||||
},
|
||||
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, 'sector': 'A', 'text': { 'text': 'TestText', 'textSize': 20, 'colour': '#20FFFF' }, 'ticketCount': 1 };
|
||||
this.saveHistory();
|
||||
this.$refs.notification.createNotification( 'New component added successfully', 5, 'ok', 'normal' );
|
||||
},
|
||||
@@ -357,6 +359,7 @@
|
||||
height: 90vh;
|
||||
top: 7.5vh;
|
||||
right: 0.5vw;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.content-parent {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#rectangular {
|
||||
border-color: black;
|
||||
border-width: 2px;
|
||||
background-color: var( --popup-color );
|
||||
}
|
||||
|
||||
#circular, #trapezoid {
|
||||
@@ -33,7 +34,7 @@
|
||||
#trapezoid-ingredient {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
align-items: flex-end;
|
||||
height: 200%;
|
||||
width: 200%;
|
||||
position: relative;
|
||||
@@ -43,9 +44,10 @@
|
||||
|
||||
#trapezoid-line {
|
||||
border: black solid 1px;
|
||||
height: 0%;
|
||||
height: 50%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
background-color: var( --popup-color );
|
||||
}
|
||||
|
||||
#circular-ingredient {
|
||||
@@ -54,6 +56,7 @@
|
||||
height: 199%;
|
||||
width: 199%;
|
||||
position: relative;
|
||||
background-color: var( --popup-color );
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -43,9 +43,10 @@
|
||||
|
||||
#trapezoid-line {
|
||||
border: black solid 1px;
|
||||
height: 0%;
|
||||
height: 50%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
background-color: var( --popup-color );
|
||||
}
|
||||
|
||||
#circular-ingredient {
|
||||
@@ -54,6 +55,7 @@
|
||||
height: 199%;
|
||||
width: 199%;
|
||||
position: relative;
|
||||
background-color: var( --popup-color );
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<!--
|
||||
* libreevent - textField.vue
|
||||
*
|
||||
* Created by Janis Hutz 07/01/2023, Licensed under the GPL V3 License
|
||||
* https://janishutz.com, development@janishutz.com
|
||||
*
|
||||
*
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div id="textFields">
|
||||
<p :style="style">{{ text }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'textFieldSeatplanComponent',
|
||||
props: {
|
||||
origin: {
|
||||
type: Number,
|
||||
"default": 1,
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
"default": "Untitled",
|
||||
},
|
||||
textSize: {
|
||||
type: Number,
|
||||
"default": 20,
|
||||
},
|
||||
scaleFactor: {
|
||||
type: Number,
|
||||
"default": 1,
|
||||
},
|
||||
colour: {
|
||||
type: String,
|
||||
"default": '#000000',
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
style: 'font-size: 20pt; rotate: 0deg; color: #000000',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateStyle () {
|
||||
this.style = `font-size: ${ this.scaleFactor * this.textSize }pt; rotate: ${ 90 * this.origin - 90 }deg; color: ${this.colour}`;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
origin ( value ) {
|
||||
this.updateStyle();
|
||||
},
|
||||
scaleFactor ( value ) {
|
||||
this.updateStyle();
|
||||
},
|
||||
colour ( value ) {
|
||||
this.updateStyle();
|
||||
},
|
||||
textSize ( value ) {
|
||||
this.updateStyle();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.updateStyle();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user