mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 21:34:24 +00:00
lots of seat plan editor optimisations
This commit is contained in:
@@ -32,6 +32,8 @@
|
|||||||
<h3>Component settings</h3>
|
<h3>Component settings</h3>
|
||||||
<table v-if="active">
|
<table v-if="active">
|
||||||
|
|
||||||
|
<!-- H/W/Y/X for rendering -->
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Position X:</td>
|
<td>Position X:</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -56,19 +58,81 @@
|
|||||||
<input type="number" min="20" v-model="internal[ active ].h" @change="resubmit()">
|
<input type="number" min="20" v-model="internal[ active ].h" @change="resubmit()">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
|
<!-- Starting row for row counting and rendering -->
|
||||||
|
|
||||||
|
<tr v-if="internal[ active ].type == 'seat'">
|
||||||
<td>Starting row:</td>
|
<td>Starting row:</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="number" min="1" max="20" v-model="internal[ active ].startingRow" @change="resubmit()">
|
<input type="number" min="1" max="20" v-model="internal[ active ].startingRow" @change="resubmit()">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<!-- ORIGIN of component for rendering -->
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Origin:</td>
|
<td>Origin:</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="number" min="1" max="4" v-model="internal[ active ].origin" @change="resubmit()">
|
<input type="number" min="1" max="4" v-model="internal[ active ].origin" @change="resubmit()">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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>Seat numbering:</td>
|
||||||
<td>
|
<td>
|
||||||
<select v-model="internal[ active ].seatCountingStartingPoint" @change="resubmit()">
|
<select v-model="internal[ active ].seatCountingStartingPoint" @change="resubmit()">
|
||||||
@@ -78,6 +142,9 @@
|
|||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<!-- Component type selector -->
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Type:</td>
|
<td>Type:</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -85,10 +152,14 @@
|
|||||||
<option value="seat">Seat</option>
|
<option value="seat">Seat</option>
|
||||||
<option value="stand">Stand</option>
|
<option value="stand">Stand</option>
|
||||||
<option value="stage">Stage</option>
|
<option value="stage">Stage</option>
|
||||||
|
<option value="text">Text</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
|
<!-- SHAPE of component if not a text element -->
|
||||||
|
|
||||||
|
<tr v-if="internal[ active ].type != 'text'">
|
||||||
<td>Shape:</td>
|
<td>Shape:</td>
|
||||||
<td>
|
<td>
|
||||||
<select min="20" v-model="internal[ active ].shape" @change="resubmit()">
|
<select min="20" v-model="internal[ active ].shape" @change="resubmit()">
|
||||||
@@ -138,9 +209,11 @@ export default {
|
|||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
internal: {},
|
internal: {},
|
||||||
|
categories: {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// TODO: Load categories from server
|
||||||
loadInternal () {
|
loadInternal () {
|
||||||
for ( let value in this.draggables ) {
|
for ( let value in this.draggables ) {
|
||||||
this.internal[ value ] = {};
|
this.internal[ value ] = {};
|
||||||
@@ -159,7 +232,7 @@ export default {
|
|||||||
ret[ value ] = {};
|
ret[ value ] = {};
|
||||||
for ( let info in this.internal[ value ] ) {
|
for ( let info in this.internal[ value ] ) {
|
||||||
if ( info === 'w' || info === 'h' || info === 'x' || info === 'y' ) {
|
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 {
|
} else {
|
||||||
ret[ value ][ info ] = this.internal[ value ][ info ];
|
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>
|
<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>
|
<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>
|
<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>
|
</Vue3DraggableResizable>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -37,7 +38,6 @@
|
|||||||
<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 [Ctrl + S]" @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>
|
||||||
<button title="Get amount of seats printed to console" @click="getSeatCount()"><span class="material-symbols-outlined">living</span></button>
|
|
||||||
</div>
|
</div>
|
||||||
<notifications ref="notification" location="topleft"></notifications>
|
<notifications ref="notification" location="topleft"></notifications>
|
||||||
</div>
|
</div>
|
||||||
@@ -49,8 +49,9 @@
|
|||||||
import circularSeatplanComponent from '@/components/seatplan/seatplanComponents/seats/circular.vue';
|
import circularSeatplanComponent from '@/components/seatplan/seatplanComponents/seats/circular.vue';
|
||||||
import rectangularSeatplanComponent from '@/components/seatplan/seatplanComponents/seats/rectangular.vue';
|
import rectangularSeatplanComponent from '@/components/seatplan/seatplanComponents/seats/rectangular.vue';
|
||||||
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/stages.vue';
|
||||||
import standingSeatplanComponent from '@/components/seatplan/seatplanComponents/stand/standing.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 notifications from '@/components/notifications/notifications.vue';
|
||||||
import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css';
|
import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css';
|
||||||
|
|
||||||
@@ -64,12 +65,13 @@
|
|||||||
trapezoidSeatplanComponent,
|
trapezoidSeatplanComponent,
|
||||||
stagesSeatplanComponent,
|
stagesSeatplanComponent,
|
||||||
standingSeatplanComponent,
|
standingSeatplanComponent,
|
||||||
|
textFieldSeatplanComponent,
|
||||||
notifications,
|
notifications,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
active: 0,
|
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 },
|
available: { 'redo': false, 'undo': false },
|
||||||
scaleFactor: 1,
|
scaleFactor: 1,
|
||||||
sizePoll: null,
|
sizePoll: null,
|
||||||
@@ -197,7 +199,7 @@
|
|||||||
returnArray[ entry ] = {};
|
returnArray[ entry ] = {};
|
||||||
for ( let attributes in valueArray[ entry ] ) {
|
for ( let attributes in valueArray[ entry ] ) {
|
||||||
if ( allowedAttributes.includes( attributes ) ) {
|
if ( allowedAttributes.includes( attributes ) ) {
|
||||||
returnArray[ entry ][ attributes ] = Math.round( valueArray[ entry ][ attributes ] * this.scaleFactor );
|
returnArray[ entry ][ attributes ] = valueArray[ entry ][ attributes ] * this.scaleFactor;
|
||||||
} else {
|
} else {
|
||||||
returnArray[ entry ][ attributes ] = valueArray[ entry ][ attributes ];
|
returnArray[ entry ][ attributes ] = valueArray[ entry ][ attributes ];
|
||||||
}
|
}
|
||||||
@@ -263,7 +265,7 @@
|
|||||||
let progressNotification = this.$refs.notification.createNotification( 'Saving as draft', 5, 'progress', 'normal' );
|
let progressNotification = this.$refs.notification.createNotification( 'Saving as draft', 5, 'progress', 'normal' );
|
||||||
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' );
|
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 () {
|
deploy () {
|
||||||
// TODO: Save to server
|
// TODO: Save to server
|
||||||
@@ -271,7 +273,7 @@
|
|||||||
this.$refs.notification.createNotification( 'Deployed successfully', 5, 'ok', 'normal' );
|
this.$refs.notification.createNotification( 'Deployed successfully', 5, 'ok', 'normal' );
|
||||||
},
|
},
|
||||||
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, 'sector': 'A', 'text': { 'text': 'TestText', 'textSize': 20, 'colour': '#20FFFF' }, 'ticketCount': 1 };
|
||||||
this.saveHistory();
|
this.saveHistory();
|
||||||
this.$refs.notification.createNotification( 'New component added successfully', 5, 'ok', 'normal' );
|
this.$refs.notification.createNotification( 'New component added successfully', 5, 'ok', 'normal' );
|
||||||
},
|
},
|
||||||
@@ -357,6 +359,7 @@
|
|||||||
height: 90vh;
|
height: 90vh;
|
||||||
top: 7.5vh;
|
top: 7.5vh;
|
||||||
right: 0.5vw;
|
right: 0.5vw;
|
||||||
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-parent {
|
.content-parent {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#rectangular {
|
#rectangular {
|
||||||
border-color: black;
|
border-color: black;
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
|
background-color: var( --popup-color );
|
||||||
}
|
}
|
||||||
|
|
||||||
#circular, #trapezoid {
|
#circular, #trapezoid {
|
||||||
@@ -33,7 +34,7 @@
|
|||||||
#trapezoid-ingredient {
|
#trapezoid-ingredient {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: flex-end;
|
||||||
height: 200%;
|
height: 200%;
|
||||||
width: 200%;
|
width: 200%;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -43,9 +44,10 @@
|
|||||||
|
|
||||||
#trapezoid-line {
|
#trapezoid-line {
|
||||||
border: black solid 1px;
|
border: black solid 1px;
|
||||||
height: 0%;
|
height: 50%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
|
background-color: var( --popup-color );
|
||||||
}
|
}
|
||||||
|
|
||||||
#circular-ingredient {
|
#circular-ingredient {
|
||||||
@@ -54,6 +56,7 @@
|
|||||||
height: 199%;
|
height: 199%;
|
||||||
width: 199%;
|
width: 199%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
background-color: var( --popup-color );
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@@ -43,9 +43,10 @@
|
|||||||
|
|
||||||
#trapezoid-line {
|
#trapezoid-line {
|
||||||
border: black solid 1px;
|
border: black solid 1px;
|
||||||
height: 0%;
|
height: 50%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
|
background-color: var( --popup-color );
|
||||||
}
|
}
|
||||||
|
|
||||||
#circular-ingredient {
|
#circular-ingredient {
|
||||||
@@ -54,6 +55,7 @@
|
|||||||
height: 199%;
|
height: 199%;
|
||||||
width: 199%;
|
width: 199%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
background-color: var( --popup-color );
|
||||||
}
|
}
|
||||||
</style>
|
</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