<template> <NuxtLayout name="default" :menu="adminMenu"> <div class="container-fluid"> <div class="row justify-content-center"> <template v-if="canView"> <div class="col-12"> <div class="sub-header mb-3"> <div class="d-flex"> <div class="d-flex"> <label class="ms-2" for="form_id">فرم: </label> <select name="form_id" id="form_id" v-model="formId" class="form-control text__14" @change="showFormItem" > <template v-if="forms.length"> <option disabled :value="undefined" selected> انتخاب مورد </option> <option v-for="(form, index) in forms" :key="index" :value="form.id" > {{ form.title }} </option> </template> <option v-else :value="undefined" selected> موردی ثبت نشده است. </option> </select> </div> <div class="select-diplay-mode"> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="displayMode" id="table" :value="0" v-model="selectedForm.listType" /> <label class="form-check-label" for="table">جدولی</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="displayMode" id="list" :value="1" v-model="selectedForm.listType" /> <label class="form-check-label" for="list">فهرستی</label> </div> </div> </div> <div class="subset-sub-header"> <button-component title="ایجاد" classes="btn d-inline-flex px-2 " @click="openForm" buttonText="" > <span class="tavasi tavasi-Component-212--1" ><span class="path1"></span><span class="path2"></span ><span class="path3"></span ></span> </button-component> </div> </div> </div> <div class="col"> <div class="list-and-actions-container"> <my-table :key="changeDetectionCounter" height="auto" maxHeight="calc(100vh - 15em)" :isDraggable="true" :isSortable="true" :items=" selectedForm[LIST_TYPES[selectedForm.listType]]?.items ?? [] " :fetchingData="fetchingData" :tableColumns="tableColumns" :tableActions="tableActions" :paginationInfo="pagination" @edit-table-item="editItem" @delete-table-item="deleteItem" @onSort="onSort" @on-linked-title-click="onLinkedTitleClick" /> <div class="d-flex justify-content-end mt-5 ms-3 form-actions" v-if="showSaveButton" > <!-- <button @click.prevent="resetForm()" type="button" class="btn btn-secondary mx-2" data-dismiss="modal" > باز نشانی </button> --> <button @click.prevent="saveFinalForm()" type="button" class="btn btn-primary" > ذخیره </button> </div> </div> </div> <!-- new form item to create new element --> <div class="col-auto" v-if="shwoPreviewForm"> <table-column-select-form :selectedItem="rowItem" :selectedForm="selectedForm" @close-form-show="closeFormShow" @update-column="updateColumn" ></table-column-select-form> </div> </template> <no-data v-else> <the-content-loading v-if="fetchingData"></the-content-loading> <div v-else class="d-flex justify-content-center align-items-center"> <div class="alert alert-warning d-flex justify-content-center align-items-center" > <span class="tavasi tavasi-warning-circle color-inherit ms-1 text__32" ></span> عدم دسترسی </div> </div> </no-data> </div> </div> </NuxtLayout> </template> <script> import apis from "~/apis/adminApi"; import adminMenu from "~/json/admin/json/menu.json"; import { mapState, mapActions } from "pinia"; import { useCommonStore } from "~/stores/commonStore"; import { defineAsyncComponent } from "vue"; // import HttpService from "@services/httpService"; import tableActions from "~/json/admin/json/selectListColumnAction.json"; // import { mapActions } from "vuex"; const LIST_TYPES = { 0: "table_columns", 1: "list_columns", }; export default { name: "selectListColumnsCreate", setup() { definePageMeta({ name: "selectListColumnsCreate", layout: false, }); }, mounted() { // this.httpService = new HttpService(); this.httpService = useNuxtApp()["$http"]; this.checkPermisionBeforGetList(); }, data() { return { canView: false, adminMenu: adminMenu, changeDetectionCounter: 0, LIST_TYPES: LIST_TYPES, rowItem: {}, shwoPreviewForm: false, httpService: undefined, pagination: { pages: 0, total: 0, page: 1, offset: 0, limit: 100, }, tableColumns: [ { key: "title", title: "عنوان", width: "2", isLink: true }, { key: "key", title: "کلیدواژه", width: "2" }, { key: "width", title: "وزن پهنا", width: "2" }, ], tableActions: tableActions, fetchingData: false, buttonLoading: false, forms: [], formItems: [], formId: undefined, items: [], selectedForm: {}, rowItemIndex: 0, }; }, computed: { computedItems() { return ( this.selectedForm[LIST_TYPES[this.selectedForm.listType]]?.items ?? [] ); }, showSaveButton() { return this.selectedForm.table_columns?.items?.length > 0; }, }, methods: { ...mapActions(useCommonStore, ["checkPermissions"]), // ...mapActions(["checkPermissions"]), checkPermisionBeforGetList() { this.checkPermissions({ permission: "forms_select-list-columns", _this: this, }) .then(() => { this.getForms() .then(() => { this.canView = true; }) .catch(() => { this.canView = false; }) .finally(() => { this.fetchingData = false; }); }) .catch(() => { this.canView = false; }); }, onLinkedTitleClick({ rowItem, tableColumn, index }) { this.editItem(index); }, /* summary: change the sort of form items(elements) description: changing the sort of the form items in the table by drag and drop them. @param {Event} Sortable sort event. @param {newIndex} String dropped into index. @param {oldIndex} String dragged from index. @return void. */ onSort({ newIndex, oldIndex }) { const tempItem = this.selectedForm[this.LIST_TYPES[this.selectedForm.listType]].items[ newIndex ]; this.selectedForm[this.LIST_TYPES[this.selectedForm.listType]].items[ newIndex ] = this.selectedForm[this.LIST_TYPES[this.selectedForm.listType]].items[ oldIndex ]; this.selectedForm[this.LIST_TYPES[this.selectedForm.listType]].items[ oldIndex ] = tempItem; }, saveFinalForm() { if (this.buttonLoading) return; this.buttonLoading = true; const url = this.keyValueMicroServiceName + apis.projectForm.edit; const formData = structuredClone(this.selectedForm); formData.table_columns = JSON.stringify(formData.table_columns); formData.list_columns = JSON.stringify(formData.list_columns); formData.meta = JSON.stringify(formData.meta); this.httpService .postRequest(url, formData) .then((res) => { mySwalToast({ title: res.message, html: null, icon: "success", }); }) .finally(() => { this.buttonLoading = false; }); }, resetForm() {}, async getForms() { const formId = this.$route.params.id; if (this.fetchingData) return; this.fetchingData = true; const formData = { isown: 3, sortby: "created", type: 1, ...this.pagination, }; let url = keyValueUrl() + apis.projectForm.list; return await this.httpService .postRequest(url, formData) .then((response) => { this.forms = response.data; this.forms.forEach((element) => { element.meta = element.meta ? JSON.parse(element.meta) : null; element.table_columns = element.table_columns ? JSON.parse(element.table_columns) : null; // element.list_columns = JSON.parse(element['list_columns']); element.list_columns = { key: "list_columns", items: [], }; element.flatedItems = element.meta ? element.meta.flatMap((item) => item.items) : []; }); if (formId) { this.formId = formId; this.selectedForm = this.forms.find((item) => item.id == formId); } else { this.formId = response.data[0].id; this.selectedForm = response.data[0]; } }) .catch((error) => {}); }, showFormItem($event) { const form = this.forms.find((item) => item.id == $event.target.value); this.selectedForm = form; this.changeDetectionCounter += 1; }, updateColumn(updatedColumn) { if (this.rowItemIndex) this.$set( this.selectedForm[this.LIST_TYPES[this.selectedForm.listType]].items, this.rowItemIndex, updatedColumn ); else { // find new item in the forms table columns items. // if exist => continue // else catch block executs and create new table columns. try { const res = this.selectedForm[ this.LIST_TYPES[this.selectedForm.listType] ].items.filter((item) => item.key == updatedColumn.key); if (res.length) mySwalToast({ title: "ستونی با چنین مشخصاتی قبلا ایجاد شده است.", html: null, icon: "error", }); else { // const items = this.selectedForm[ // this.LIST_TYPES[this.selectedForm.listType] // ].items; // this.$set( // this.selectedForm[this.LIST_TYPES[this.selectedForm.listType]] // .items, // items.length, // updatedColumn // ); this.selectedForm[ this.LIST_TYPES[this.selectedForm.listType] ].items.push(updatedColumn); this.changeDetectionCounter += 1; } } catch (msg) { this.selectedForm[[this.LIST_TYPES[this.selectedForm.listType]]] = { items: [updatedColumn], title: this.selectedForm.title, }; this.changeDetectionCounter += 1; } } }, openForm() { this.rowItem = {}; this.rowItemIndex = undefined; this.shwoPreviewForm = true; }, editItem(formIndex) { this.rowItem = this.selectedForm[this.LIST_TYPES[this.selectedForm.listType]].items[ formIndex ]; this.rowItemIndex = formIndex; this.shwoPreviewForm = true; }, deleteItem(index) { if ( this.selectedForm[this.LIST_TYPES[this.selectedForm.listType]].items .length > 1 ) { mySwalConfirm({ title: "هشدار!!!", html: "از حذف این مورد مطمئن هستید؟", }).then((result) => { if (result.isConfirmed) { this.selectedForm[ this.LIST_TYPES[this.selectedForm.listType] ].items.splice(index, 1); } }); } else mySwalToast({ title: "حداقل تعداد ستون های جدول یک می باشد.", html: null, icon: "error", }); }, closeFormShow() { this.shwoPreviewForm = false; }, }, components: { TableColumnSelectForm: defineAsyncComponent(() => import("@components/forms/TableColumnSelectForm.vue") ), }, }; </script> <style lang="scss"> .list-and-actions-container { position: relative; .form-actions { // position: absolute; // bottom: 1em; // left: 2em; background-image: linear-gradient(to bottom, transparent, #fff); } } </style> height="auto" maxHeight="calc(100vh - 15em)"