lots of seat plan editor optimisations

This commit is contained in:
2023-07-01 11:42:28 +02:00
parent 5ae2be0541
commit a06a3ade22
5 changed files with 164 additions and 14 deletions

View File

@@ -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 ];
}

View File

@@ -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 {

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>