Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <template>
- <div class="seats-group">
- <b-jumbotron
- :header="sectorName"
- >
- <div class="row">
- <div class="col-12 col-xl-6">
- <b-button
- v-if="!isNameChanging"
- variant="primary"
- size="sm"
- @click="showNameChanging"
- >
- Изменить название сектора
- </b-button>
- <template
- v-else
- class="mb-3"
- >
- <b-form-group>
- <b-form-input
- v-model="sectorNameNew"
- type="text"
- />
- </b-form-group>
- <b-button
- variant="success"
- size="sm"
- @click="renameSector"
- >
- Сохранить
- </b-button>
- <b-button
- variant="danger"
- size="sm"
- class="ml-2"
- @click="isNameChanging = !isNameChanging"
- >
- Отмена
- </b-button>
- </template>
- </div>
- </div>
- <div class="row">
- <div class="col-12">
- <div class="h4 my-3">
- Сгенерировать сетку
- </div>
- </div>
- <div class="col-12 col-xl-6">
- <b-form-group
- label-cols-sm="6"
- label="Количество рядов в секторе"
- label-for="rows"
- >
- <b-form-input
- v-model="rows"
- id="rows"
- type="number"
- :disabled="showGrid"
- />
- </b-form-group>
- <b-form-group
- label-cols-sm="6"
- label="Количество мест в ряду"
- label-for="columns"
- >
- <b-form-input
- v-model="columns"
- id="columns"
- type="number"
- :disabled="showGrid"
- />
- </b-form-group>
- <div class="mt-2">
- <b-button
- variant="primary"
- :disabled="showGrid"
- @click="generateGrid"
- >
- Сгенерировать
- </b-button>
- <b-button
- variant="success"
- class="ml-2"
- @click="saveGrid"
- >
- Сохранить
- </b-button>
- </div>
- <div class="mt-4" v-if="showGrid">
- <b-button
- variant="success"
- size="sm"
- class="mr-2"
- @click="addRow"
- >
- Добавить ряд
- </b-button>
- <b-button
- variant="warning"
- size="sm"
- class="mr-2"
- :disabled="disableDivideButton"
- @click="addTypes"
- >
- Разделить на типы
- </b-button>
- <b-button
- variant="primary"
- size="sm"
- class="mr-2"
- @click="rotateSector"
- >
- Вращать
- </b-button>
- <div class="mt-2">
- <b-button
- variant=""
- size="sm"
- @click="$emit('close')"
- class="mr-2"
- >
- К списку секторов
- </b-button>
- <b-button
- variant="info"
- size="sm"
- class="mr-2"
- @click="goToSector('next')"
- >
- Следующий сектор
- </b-button>
- <b-button
- variant="info"
- size="sm"
- @click="goToSector('prev')"
- >
- Предыдущий сектор
- </b-button>
- </div>
- </div>
- </div>
- <div class="col-12 col-xl-6">
- <div
- v-if="showGrid"
- class="grid"
- >
- <div class="row">
- <div
- v-if="Object.keys(grid).length"
- class="col-12 d-flex flex-column-reverse"
- >
- <div
- v-for="row in Object.keys(grid)"
- :key="row"
- class="grid__row d-flex align-items-center"
- >
- <p
- v-if="columns"
- class="text-bold mb-0 mr-2"
- >
- Ряд {{ Number(row) }}
- </p>
- <div
- v-for="col in grid[row]"
- :key="Math.random() * (col + 1)"
- :data-row="Number(row)"
- :data-seat="Number(col)"
- :data-hidden="!col"
- class="grid__seat"
- >
- {{ col }}
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <component
- :is="'ExtendedMenu'"
- :isVisible="showDropDown"
- :name="sectorName"
- :posX="dropDownX"
- :posY="dropDownY"
- >
- <ul class="my-dropdown__list">
- <li
- v-if="Object.keys(groups).length"
- class="no-hover"
- >
- Добавить в группу
- <b-form-select
- v-model="selectedGroup"
- size="sm"
- class="mt-3"
- :options="Object.keys(groups)"
- @change="addSeatToGroup"
- />
- </li>
- <li @click="removeSeatFromGrid">
- Удалить
- </li>
- <li @click="showDropDown = false">
- Закрыть
- </li>
- </ul>
- </component>
- </b-jumbotron>
- <b-modal
- ref="not-saved-warning-modal"
- hide-footer
- content-class="shadow"
- title="Изменения не сохранены"
- >
- <div class="d-block text-center">
- <p>
- Вы изменили данные сектора, но не сохранили изменения.
- <br>
- Сохранить?
- </p>
- </div>
- <div class="d-flex justify-content-center">
- <b-button
- class="mt-3"
- variant="success"
- @click="saveGridFromModal"
- >
- Сохранить
- </b-button>
- <b-button
- class="mt-3 ml-3"
- variant="outline-danger"
- size="sm"
- @click="cancelSaveFromModal"
- >
- Отмена
- </b-button>
- </div>
- </b-modal>
- <b-modal
- ref="one-sector-warning-modal"
- hide-footer
- content-class="shadow"
- title="Другие сектора отсутствуют"
- >
- <div class="d-block text-center">
- <p>
- Отредактируйте другие сектора для перехода к ним.
- </p>
- </div>
- <div class="d-flex justify-content-center">
- <b-button
- class="mt-3"
- variant="outline-danger"
- size="sm"
- @click="$refs['one-sector-warning-modal'].hide()"
- >
- Закрыть
- </b-button>
- </div>
- </b-modal>
- </div>
- </template>
- <script lang="ts">
- import {Component, Prop, Watch, Vue} from 'vue-property-decorator';
- import {Getter, Action} from 'vuex-class';
- import ExtendedMenu from '@/components/Dropdown/ExtendedMenu.vue';
- import {IScheme, ISector} from '@/interfaces/scheme';
- interface VueWithModals extends Vue {
- show: () => void;
- hide: () => void;
- }
- interface IGrid {
- [k: string]: number[];
- }
- const namespace = 'scheme';
- @Component({
- components: {
- ExtendedMenu
- }
- })
- export default class SeatsGroup extends Vue {
- @Prop({required: true}) sector!: ISector;
- @Getter('schemeData', {namespace}) schemeData!: IScheme;
- @Action('changeSectorGrid', {namespace}) changeSectorGrid!:
- (payload: ISector) => Promise<void>;
- sectorToShow: ISector | null = null;
- rows: string = '';
- columns: string = '';
- count: number = 0;
- selectedRow: number = 0;
- selectedSeat: number = 0;
- grid: IGrid = {};
- showGrid: boolean = false;
- rotate: number = 0;
- sectorNameNew: string = '';
- isNameChanging: boolean = false;
- isDivided: boolean = false;
- selectedGroup: string | null = null;
- isSaved: boolean = false;
- direction: null | string = null;
- groups: any = {};
- showDropDown: boolean = false;
- dropDownX: number = 0;
- dropDownY: number = 0;
- @Watch('sectorToShow', {deep: true})
- onSectorToShowChanged(newVal: ISector): void {
- if (newVal) {
- this.init();
- }
- }
- mounted() {
- this.sectorToShow = this.sector;
- this.init();
- document.addEventListener(
- 'click',
- (e: MouseEvent) => this.handleClick(e)
- );
- }
- /**
- * @description Установить свойства сектора
- */
- init(): void {
- if (this.sector) {
- this.resetGrid();
- const {grid, columns, rows, count, rotate} = this.sector;
- this.grid = grid as IGrid;
- if (rows) {
- this.rows = String(rows);
- }
- if (columns) {
- this.columns = String(columns);
- }
- if (count) {
- this.count = count;
- }
- if (rotate) {
- this.rotate = rotate;
- }
- }
- if (this.isNameChanging) {
- this.isNameChanging = false;
- }
- if (this.sectorNameNew) {
- this.sectorNameNew = '';
- }
- if (this.rows && this.columns) {
- this.generateGrid();
- } else {
- this.resetGrid();
- }
- }
- /**
- * @description Сгенерировать сетку мест
- */
- generateGrid(): void {
- const rows = Number(this.rows);
- const columns = Number(this.columns);
- if (rows > 0 && columns > 0) {
- if (Object.keys(this.grid).length) {
- this.grid = {};
- }
- for (let row = 1; row <= rows; row++) {
- this.grid[row] = [];
- for (let col = 1; col <= columns; col++) {
- this.grid[row].push(col);
- }
- }
- this.count = rows * columns;
- this.showGrid = true;
- }
- }
- /**
- * @description Сохранить изменения в объект данных схемы
- */
- async saveGrid(): Promise<void> {
- this.isSaved = true;
- const payload = {
- ...this.sector,
- rows: Number(this.rows),
- columns: Number(this.columns),
- count: this.count,
- grid: this.grid,
- rotate: this.rotate
- };
- if (Object.keys(this.groups).length) {
- payload.groups = this.groups;
- }
- await this.changeSectorGrid(payload);
- }
- /**
- * @description Сбросить данные сетки мест в секторе
- */
- resetGrid(): void {
- this.showGrid = false;
- this.isSaved = false;
- this.grid = {};
- this.rows = '';
- this.columns = '';
- this.rotate = 0;
- }
- /**
- * @description Добавить ряд
- */
- addRow(): void {
- const length = Object.keys(this.grid).length;
- const rows = Number(this.rows);
- const columns = Number(this.columns);
- this.grid[length + 1] = [];
- for (let col = 1; col <= columns; col++) {
- this.grid[length + 1].push(col);
- }
- this.rows = String(rows + 1);
- this.count = this.count + columns;
- }
- /**
- * @description Добавить вращение сектора
- * (в случае, если он должен быть расположен под углом)
- */
- rotateSector(): void {
- if ((this.rotate + 45) < 360) {
- this.rotate += 45;
- } else if (this.rotate === 360) {
- this.rotate = 0;
- } else {
- this.rotate = (this.rotate + 45) - 360;
- }
- this.changeSectorGrid({
- name: this.sectorName,
- rotate: this.rotate
- });
- }
- /**
- * @description Перейти к предыдущему/следующему сектору в схеме
- */
- goToSector(direction: string): void {
- if (this.isSaved || this.grid === {}) {
- const keys: string[] = Object.keys(this.schemeData);
- let index: number = keys.findIndex(
- (k: string) => k === this.sectorName
- );
- let newSector: string | undefined;
- if (keys.length > 1) {
- switch (direction) {
- case 'prev':
- if (index === 0) {
- index = keys.length;
- }
- newSector = keys[index - 1];
- break;
- case 'next':
- if (index === keys.length - 1) {
- index = -1;
- }
- newSector = keys[index + 1];
- break;
- }
- this.sectorToShow = this.schemeData[newSector as string];
- this.$emit('changeSector', newSector);
- } else {
- (this.$refs['one-sector-warning-modal'] as VueWithModals).show();
- }
- } else {
- this.direction = direction;
- this.showModal();
- }
- }
- /**
- * @description Удалить место
- */
- removeSeatFromGrid(): void {
- const target: HTMLElement | null = document.querySelector(
- `[data-row="${this.selectedRow}"][data-seat="${this.selectedSeat}"]`
- );
- target && target.setAttribute('data-hidden', 'true');
- this.grid[this.selectedRow][this.selectedSeat - 1] = 0;
- this.count--;
- this.showDropDown = false;
- }
- /**
- * @description Показать поле для изменения имени сектора
- */
- showNameChanging(): void {
- if (this.sectorName) {
- this.sectorNameNew = this.sectorName === 'Название отсутствует' ? '' : this.sectorName;
- }
- this.isNameChanging = !this.isNameChanging;
- }
- /**
- * @description Изменить название сектора
- */
- renameSector(): void {
- this.sectorToShow = {
- ...this.sectorToShow,
- name: this.sectorNameNew
- };
- }
- /**
- * @description Разделить места в секторе по группам
- */
- addTypes(): void {
- this.isDivided = true;
- const counter = Object.keys(this.groups).length;
- let last;
- if (!counter) {
- this.groups[counter + 1] = {};
- return;
- }
- if (counter > 0) {
- last = this.groups[counter];
- if (last && Object.keys(last).length) {
- this.groups[counter + 1] = {};
- }
- }
- }
- /**
- * @description Определить категорию для места в секторе
- * @param group {string}
- */
- addSeatToGroup(group: string): void {
- const seats = this.groups[group][this.selectedRow] || [];
- seats.push(this.selectedSeat);
- this.groups[group] = {
- ...this.groups[group],
- [this.selectedRow]: seats
- };
- this.selectedGroup = '';
- }
- /**
- * @description Показать модальное окно
- * с предупреждением о несохраненных данных
- */
- showModal(): void {
- (this.$refs['not-saved-warning-modal'] as VueWithModals).show();
- }
- /**
- * @description Вызов сохранения
- * измененного состояния схемы из модального окна
- */
- saveGridFromModal(): void {
- this.saveGrid();
- this.goToSector(this.direction as string);
- (this.$refs['not-saved-warning-modal'] as VueWithModals).hide();
- }
- /**
- * @description Отмена сохранения
- * измененного состояния схемы
- * и переход к следующему/предыдущему сектору
- */
- cancelSaveFromModal(): void {
- this.isSaved = true;
- this.goToSector(this.direction as string);
- (this.$refs['not-saved-warning-modal'] as VueWithModals).hide();
- }
- /**
- * @description Обработчик клика
- * для компонента расширенного меню
- * @param e {MouseEvent}
- */
- handleClick(e: MouseEvent): void {
- const element = e.target as HTMLElement;
- const {row, seat} = element.dataset || {};
- if (row && seat) {
- this.showDropDown = true;
- this.dropDownX = e.clientX;
- this.dropDownY = e.clientY;
- this.selectedRow = Number(row);
- this.selectedSeat = Number(seat);
- } else {
- this.showDropDown = false;
- }
- }
- get sectorName(): string | undefined {
- if (this.sector ) {
- return this.sector.name;
- }
- }
- get disableDivideButton(): boolean {
- let disabled = false;
- const groups = Object.values(this.groups);
- if (groups.length) {
- groups.forEach(
- (group) => disabled = Boolean(!Object.keys(group as {}).length)
- );
- }
- return disabled;
- }
- }
- </script>
- <style lang="scss" scoped>
- .grid {
- &__seat {
- margin: 5px;
- background: #acf;
- cursor: pointer;
- display: flex;
- justify-content: center;
- align-items: center;
- width: 30px;
- height: 30px;
- border-radius: 50%;
- &[data-hidden="true"] {
- opacity: 0;
- pointer-events: none;
- visibility: hidden;
- }
- }
- &__row {
- p {
- font-weight: bold;
- text-align: center;
- width: 70px;
- }
- &.active {
- .grid__seat {
- background: darken(plum, 35%);
- color: white;
- }
- }
- }
- }
- .btn {
- min-width: 160px;
- }
- /deep/ .dropdown-toggle {
- &:after {
- display: none;
- }
- }
- /deep/ .dropdown-menu.show {
- min-width: 300px;
- }
- </style>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement