base_ui/components/forms/TabForm.vue
2025-02-26 11:23:07 +03:30

338 lines
9.8 KiB
Vue

<template>
<div>
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li
v-for="(groupItem, index) in localMainFormElements"
:key="index"
@click="setTab(index)"
class="nav-item"
role="presentation"
>
<a
class="nav-link position-relative ms-3"
id="home-tab"
data-bs-toggle="tab"
:href="'#' + groupItem.key"
role="tab"
:aria-controls="groupItem.key"
aria-selected="true"
:class="{ active: groupItem.active ?? false }"
>{{ groupItem.title }}
<button-component
classes="d-inline-flex tab-remove-btn"
@click="removeTab(index)"
buttonText=""
>
<span class="tavasi tavasi-Component-21--1"></span>
</button-component>
<button-component
classes="d-inline-flex tab-edit-btn"
@click="openEditTabFormModal(index)"
buttonText=""
title="ویرایش"
>
<span class="tavasi tavasi-Component-242--1"></span>
</button-component>
</a>
</li>
<li class="nav-item" role="presentation">
<!-- add button -->
<button-component
classes="nav-link d-inline-flex"
@click="openNewTabFormModal()"
buttonText="بخش جدید"
>
<span class="tavasi tavasi-Component-220--1 ms-1"
><span class="path1"></span><span class="path2"></span
><span class="path3"></span
></span>
</button-component>
</li>
</ul>
<div
class="tab-content"
id="myTabContent"
v-if="localMainFormElements?.length"
>
<div
class="tab-pane fade show active p-3"
id="home"
role="tabpanel"
aria-labelledby="home-tab"
>
<div
v-if="localMainFormElements[currentTab]?.hasChildren"
class="accordion"
id="accordionExample"
>
<div
v-for="(innerGroupItem, j) in localMainFormElements[currentTab]
?.items"
:key="j"
class="card"
>
<div class="card-header" :id="'heading' + j">
<h2 class="mb-0 d-flex">
<!-- حذف تب داخلی یا فرزند -->
<button-component
classes="d-inline-flex p-0"
@click="removeChildTab(j)"
buttonText=""
title="حذف"
>
<span class="tavasi tavasi-Component-295--1"></span>
</button-component>
<!-- باز کردن مودال ویرایش تب داخلی یا فرزند -->
<button-component
classes="d-inline-flex p-0"
@click="openChildTabEditModal(j)"
buttonText=""
title="ویرایش"
>
<span class="tavasi tavasi-Component-242--1"></span>
</button-component>
<button
class="btn btn-link btn-block has-indicator"
type="button"
data-bs-toggle="collapse"
:data-bs-target="'#collapse' + j"
:aria-expanded="innerGroupItem.active ?? false"
:aria-controls="'collapse' + j"
:class="{ active: innerGroupItem.active ?? false }"
>
{{ innerGroupItem.title }}
</button>
</h2>
</div>
<div
:id="'collapse' + j"
class="collapse"
:class="{ show: innerGroupItem.active ?? false }"
:aria-labelledby="'heading' + j"
data-parent="#accordionExample"
>
<div class="card-body">
<div class="position-relative ms-5">
<my-table
height="auto"
maxHeight="calc(100vh - 15em)"
:isSortable="true"
:isDraggable="true"
:hasSearch="false"
:hasPagination="false"
:fetchingData="fetchingData"
:items="localMainFormElements[currentTab]?.items[j]?.items"
:tableColumns="tableColumns"
:tableActions="formTableActions"
@delete-table-item="deleteChildItem($event, j)"
@edit-table-item="childEditNewFormItem($event, j)"
@onSort="onSort"
@on-linked-title-click="onLinkedTitleClick"
/>
<button-component
classes="d-inline-flex add-new-form-item"
@click="openChildNewFormItem(j)"
buttonText=""
>
<span class="tavasi tavasi-Component-220--1"
><span class="path1"></span><span class="path2"></span
><span class="path3"></span
></span>
</button-component>
</div>
</div>
</div>
</div>
</div>
<div v-else class="position-relative ms-5">
<my-table
height="auto"
maxHeight="calc(100vh - 15em)"
:isSortable="true"
:isDraggable="true"
:hasSearch="false"
:hasPagination="false"
:fetchingData="fetchingData"
:items="localMainFormElements[currentTab]?.items"
:tableColumns="tableColumns"
:tableActions="formTableActions"
@delete-table-item="deleteItem"
@edit-table-item="editNewFormItem"
@onSort="onSort"
@on-linked-title-click="onLinkedTitleClick"
/>
<button-component
classes="d-inline-flex add-new-form-item"
@click="openNewFormItem"
buttonText=""
>
<span class="tavasi tavasi-Component-220--1"
><span class="path1"></span><span class="path2"></span
><span class="path3"></span
></span>
</button-component>
</div>
</div>
</div>
<!-- new tab modal -->
<base-modal
v-if="showNewTabFormModal"
modalSize="modal-md"
modalTitle="فرم جدید"
@close="closeNewTabFormModal"
@save="addTab"
>
<form-builder
ref="tabFormBuilder"
:formElements="formTabElement"
:formData="formTabData"
></form-builder>
</base-modal>
</div>
</template>
<script>
import newFormExtension from "@extensions/newFormExtension";
export default {
extends: newFormExtension,
props: ["newFormItem", "formTitleData"],
mounted() {
this.localMainFormElements = this.formTitleData.meta ?? [];
if (this.localMainFormElements && this.localMainFormElements[0])
this.localMainFormElements[0].active = true;
},
data() {
return {
prevActiveTabIndex: undefined,
localMainFormElements: [],
showNewTabFormModal: false,
// form title elemnets and data.
formTabData: {
title: null,
},
formTabElement: {
title: "",
items: [
{
key: "parent",
label: "والد",
type: "select",
placeholder: "والد را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [],
},
{
key: "title",
label: "عنوان",
type: "string",
placeholder: "عنوان را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [],
},
{
key: "key",
label: "کلیدواژه",
type: "string",
placeholder: "کلیدواژه را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [],
},
// {
// key: "newButtonText",
// label: "عنوان دکمه ایجاد",
// type: "string",
// placeholder: "عنوان دکمه ایجاد را وارد کنید",
// required: "1",
// validation_regex: "{3-100}",
// validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
// multi_select: "0",
// options: [],
// },
],
},
};
},
components: {
LabelComponent: () =>
import(
"@components/forms/LabelComponent.vue"
),
NewTabForm: () =>
import(
"@forms/forms/NewTabForm.vue"
),
},
};
</script>
<style scoped lang="scss">
.tab-remove-btn {
position: absolute;
left: -0.5em;
top: -0.5em;
background-color: #fff;
justify-content: center;
align-items: center;
padding: 0;
span {
color: var(--danger);
}
&:hover {
background-color: var(--danger);
span {
color: #fff;
}
}
}
.tab-edit-btn {
position: absolute;
left: -0.5em;
bottom: 0em;
background-color: #fff;
justify-content: center;
align-items: center;
padding: 0;
&:hover {
background-color: #ddd;
span {
color: #fff;
}
}
}
.add-new-form-item {
position: absolute;
left: -3em;
bottom: 0;
}
</style>
<style>
.accordion .card .card-body .btn::after {
content: none;
}
</style>