2025-02-04 12:40:58 +00:00
|
|
|
<template>
|
|
|
|
<section :class="$route.name">
|
|
|
|
<div class="container-fluid mt-3">
|
|
|
|
<div class="row">
|
|
|
|
<div class="col col-md-3 border-start right-panel" v-if="isRightPanel">
|
|
|
|
<div class="pages-content" ref="navigationFilter">
|
|
|
|
<div class="container-fluid">
|
|
|
|
<div class="row">
|
|
|
|
<div class="d-flex justify-content-between w-100">
|
|
|
|
<multiselect
|
|
|
|
:allow-empty="false"
|
|
|
|
:searchable="true"
|
|
|
|
:close-on-select="true"
|
|
|
|
:show-labels="false"
|
|
|
|
label="title"
|
|
|
|
track-by="id"
|
|
|
|
placeholder="انتخاب پروژه"
|
|
|
|
:value="newProjects"
|
|
|
|
:options="projects"
|
|
|
|
@select="selectProject"
|
|
|
|
:hide-selected="false"
|
|
|
|
:max-height="200"
|
|
|
|
style="width: auto"
|
|
|
|
>
|
|
|
|
<template #singleLabel="props">
|
|
|
|
<span class="option__desc"
|
|
|
|
><span
|
|
|
|
class="option__title text-truncate"
|
|
|
|
style="display: block; max-width: 120px"
|
|
|
|
>
|
|
|
|
{{ props.option.title }}
|
|
|
|
</span></span
|
|
|
|
>
|
|
|
|
</template>
|
|
|
|
</multiselect>
|
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
class="close btn-right-panel"
|
|
|
|
aria-label="Close"
|
|
|
|
@click="isRightPanel = false"
|
|
|
|
>
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="row">
|
|
|
|
<ResearchTreeList
|
|
|
|
:treeItems="treeItems"
|
|
|
|
:newProjects="newProjects"
|
|
|
|
@on-click="clickOnTreeItem"
|
|
|
|
></ResearchTreeList>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="col">
|
|
|
|
<div class="row border-bottom mx-0">
|
|
|
|
<div
|
|
|
|
class="col-12 order-1 order-lg-1 col-lg-1 d-flex justify-content-start"
|
|
|
|
>
|
|
|
|
<div
|
|
|
|
class="d-flex position-relative align-items-center"
|
|
|
|
style="top: -0.3em"
|
|
|
|
>
|
|
|
|
<button
|
|
|
|
class="btn btn-right-panel"
|
|
|
|
@click="isRightPanel = true"
|
|
|
|
>
|
|
|
|
<svg class="icon icon-Component-356--1">
|
|
|
|
<use xlink:href="#icon-Component-356--1"></use>
|
|
|
|
</svg>
|
|
|
|
</button>
|
|
|
|
<button
|
|
|
|
name="button"
|
|
|
|
type="button"
|
|
|
|
class="toggle-mobile-nav dropdown-hamburger d-md-none"
|
|
|
|
@click.prevent="toggleSidebarMenu()"
|
|
|
|
>
|
|
|
|
<span class="sr-only">باز کردن منوی کنار</span>
|
|
|
|
<svg class="s18" data-testid="sidebar-icon">
|
|
|
|
<use href="assets/common/img/icons.svg#sidebar"></use>
|
|
|
|
</svg>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="col-12 order-2 order-lg-1 col-lg-10">
|
|
|
|
<div class="nav-tabs-container nav-tabs border-bottom-0">
|
|
|
|
<ul class="nav">
|
|
|
|
<li
|
|
|
|
class="nav-item desktop"
|
|
|
|
v-for="(navItem, index) in myActiveSchema?.tabs"
|
|
|
|
:key="index"
|
|
|
|
>
|
|
|
|
<button
|
|
|
|
:title="navItem.label"
|
|
|
|
type="button"
|
|
|
|
@click.prevent="updateCategoryList(navItem, index)"
|
|
|
|
class="btn nav-link"
|
|
|
|
:class="{ active: activeTab?.key == navItem.key }"
|
|
|
|
>
|
|
|
|
{{ navItem.title }}
|
|
|
|
</button>
|
|
|
|
</li>
|
|
|
|
<li
|
|
|
|
class="nav-item mobile tabs-more-btn d-md-none"
|
|
|
|
v-if="myActiveSchema?.tabs?.length > 2"
|
|
|
|
>
|
|
|
|
<div class="dropdown">
|
|
|
|
<button
|
|
|
|
class="btn"
|
|
|
|
type="button"
|
|
|
|
id="dropdownMenuButton"
|
|
|
|
data-bs-toggle="dropdown"
|
|
|
|
aria-haspopup="true"
|
|
|
|
aria-expanded="false"
|
|
|
|
>
|
|
|
|
<svg class="icon icon-Component-81--1">
|
|
|
|
<use xlink:href="#icon-Component-81--1"></use>
|
|
|
|
</svg>
|
|
|
|
</button>
|
|
|
|
<div
|
|
|
|
class="dropdown-menu"
|
|
|
|
aria-labelledby="dropdownMenuButton"
|
|
|
|
>
|
|
|
|
<a
|
|
|
|
class="dropdown-item"
|
|
|
|
@click.prevent="updateCategoryList(navItem, index)"
|
|
|
|
v-for="(navItem, index) in myActiveSchema?.tabs"
|
|
|
|
:key="index"
|
|
|
|
:class="{ active: activeTab?.key == navItem.key }"
|
|
|
|
>
|
|
|
|
{{ navItem.title }}</a
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-12 pt-3">
|
|
|
|
<component
|
|
|
|
:is="contentComponentName(activeTab?.key)"
|
|
|
|
:listAnswer="listAnswerForTerm"
|
|
|
|
:pagination="pagination"
|
|
|
|
@changePage="changePaging"
|
|
|
|
@researchModalHandler="researchModalHandler"
|
|
|
|
></component>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<base-modal-v2
|
|
|
|
v-if="showModal"
|
|
|
|
@close="closeBaseModal"
|
|
|
|
:showHeaderCloseButton="true"
|
|
|
|
:hasFooter="false"
|
|
|
|
:modalTitle="modalTitle"
|
|
|
|
minHeight="17em"
|
|
|
|
overflow="hidden"
|
|
|
|
:showSaveButton="true"
|
|
|
|
:showCloseButton="true"
|
|
|
|
:showDeleteButton="false"
|
|
|
|
>
|
|
|
|
<slot> {{ modalTitle }}</slot>
|
|
|
|
|
|
|
|
<slot name="body">
|
|
|
|
<component
|
|
|
|
:is="slotComponentName"
|
|
|
|
:valueModal="valueModalResearch"
|
|
|
|
@closeAfterSaving="closeAfterSaving"
|
|
|
|
></component>
|
|
|
|
</slot>
|
|
|
|
</base-modal-v2>
|
|
|
|
</div>
|
|
|
|
</section>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import { mapState, mapActions } from "pinia";
|
|
|
|
import researchApi from "~/apis/researchApi";
|
|
|
|
|
2025-02-11 07:09:24 +00:00
|
|
|
import { useResearchStore } from "../stores/researchStore";
|
2025-02-04 12:40:58 +00:00
|
|
|
|
|
|
|
export default {
|
|
|
|
beforeMount() {
|
|
|
|
this.httpService = new HttpService(import.meta.env.VITE_BASE_URL);
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
if (this.myActiveSchema) {
|
|
|
|
this.researchActiveSchemaSetter(this.myActiveSchema);
|
|
|
|
|
|
|
|
this.getMultiSelect(this.myActiveSchema.lists.url_GET);
|
|
|
|
this.activeTab = this.myActiveTabs;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
beforeDestroy() {},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
projects: [],
|
|
|
|
showModal: false,
|
|
|
|
modalTitle: null,
|
|
|
|
slotComponentName: null,
|
|
|
|
valueModalResearch: {},
|
|
|
|
newProjects: "",
|
|
|
|
listAnswerForTerm: [],
|
|
|
|
treeItems: [],
|
|
|
|
childrenList: [],
|
|
|
|
parentList: {},
|
|
|
|
httpService: undefined,
|
|
|
|
activeTab: null,
|
|
|
|
listTypeId: 0,
|
|
|
|
firstChoiceOfTree: "",
|
|
|
|
isRightPanel: true,
|
|
|
|
pagination: {
|
|
|
|
page: 1,
|
|
|
|
pages: 0,
|
|
|
|
total: 0,
|
|
|
|
offset: 0, // page * per_page
|
|
|
|
limit: 10, //per_page
|
|
|
|
},
|
|
|
|
};
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
...mapState(useResearchStore, ["researchSchemaGetter", "researchTermsGetter"]),
|
|
|
|
|
|
|
|
repoUrl() {
|
|
|
|
return import.meta.env.VITE_REPO + "/";
|
|
|
|
},
|
|
|
|
myActiveSchema() {
|
|
|
|
return this.researchSchemaGetter.find((item) => {
|
|
|
|
return item.key == "term";
|
|
|
|
});
|
|
|
|
},
|
|
|
|
myActiveTabs() {
|
|
|
|
return this.myActiveSchema.tabs.find((item) => {
|
|
|
|
return item.key == "fish";
|
|
|
|
});
|
|
|
|
},
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
...mapActions(useResearchStore, [
|
|
|
|
"researchTermsSetter",
|
|
|
|
"researchActiveSchemaSetter",
|
|
|
|
]),
|
|
|
|
closeAfterSaving() {
|
|
|
|
this.closeBaseModal();
|
|
|
|
setTimeout(() => {
|
|
|
|
this.getItemsForResearch(this.firstChoiceOfTree.id);
|
|
|
|
}, 1000);
|
|
|
|
},
|
|
|
|
// #region function all
|
|
|
|
researchModalHandler(event) {
|
|
|
|
this.openBaseModal("ResearchFishModal", event.itemSchema.title);
|
|
|
|
this.valueModalResearch = event;
|
|
|
|
},
|
|
|
|
openBaseModal(componentName, title) {
|
|
|
|
this.showModal = true;
|
|
|
|
this.slotComponentName = componentName;
|
|
|
|
this.modalTitle = title;
|
|
|
|
},
|
|
|
|
closeBaseModal() {
|
|
|
|
this.showModal = false;
|
|
|
|
},
|
|
|
|
updateCategoryList(navItem, index) {
|
|
|
|
this.activeTab = navItem;
|
|
|
|
},
|
|
|
|
contentComponentName(key) {
|
|
|
|
if (key == "fish") return "ResearchContent";
|
|
|
|
else if (key == "wiki") return "WikiPage";
|
|
|
|
else if (key == "change") return "ProcessologyPage";
|
|
|
|
else if (key == "treechart") return "Tree";
|
|
|
|
|
|
|
|
return "ResearchContent";
|
|
|
|
},
|
|
|
|
selectProject(item) {
|
|
|
|
this.researchTermsSetter(item);
|
|
|
|
this.newProjects = item;
|
|
|
|
this.getListTree();
|
|
|
|
},
|
|
|
|
// #endregion
|
|
|
|
// #region function for tree and MultiSelect
|
|
|
|
getMultiSelect(url) {
|
|
|
|
this.httpService.getRequest(url).then((res) => {
|
|
|
|
this.researchTermsSetter(res.data[0]);
|
|
|
|
|
|
|
|
this.projects = res.data;
|
|
|
|
this.newProjects = res.data[0];
|
|
|
|
this.getListTree();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
getListTree(parent = 0, ischildren = false, parentItem = {}) {
|
|
|
|
const payload = {
|
|
|
|
projectid: this.newProjects?.id,
|
|
|
|
parent: parent,
|
|
|
|
sortby: "id",
|
|
|
|
offset: 0,
|
|
|
|
limit: 100,
|
|
|
|
listtype: this.listTypeId,
|
|
|
|
};
|
|
|
|
let url = researchApi.subject.list;
|
|
|
|
|
|
|
|
this.httpService.formDataRequest(url, payload).then((res) => {
|
|
|
|
if (!ischildren) {
|
|
|
|
this.treeItems = res.data;
|
|
|
|
this.firstChoiceOfTree = res.data[0];
|
|
|
|
this.getItemsForResearch(res.data[0].id);
|
|
|
|
} else {
|
|
|
|
this.childrenList = res.data;
|
|
|
|
this.parentList = parentItem;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
clickOnTreeItem(item) {
|
|
|
|
this.firstChoiceOfTree = item;
|
|
|
|
this.resetPagination();
|
|
|
|
this.getItemsForResearch(item.id);
|
|
|
|
},
|
|
|
|
// #endregion
|
|
|
|
// #region function for component
|
|
|
|
getItemsForResearch(id) {
|
|
|
|
let url = this.activeTab?.url_GET;
|
|
|
|
url = url.replace("{{offset}}", this.pagination.offset);
|
|
|
|
url = url.replace("{{limit}}", this.pagination.limit);
|
|
|
|
let filter = "";
|
|
|
|
if (id == 0)
|
|
|
|
filter = `&f_rt=${this.myActiveSchema.label}`; // برای نمایش همه
|
|
|
|
else filter = `&f_rt=${this.myActiveSchema.label}&f_sb=${id}`;
|
|
|
|
url = url.replace("{{filter}}", filter);
|
|
|
|
|
|
|
|
this.httpService.getRequest(url).then((res) => {
|
|
|
|
this.listAnswerForTerm = res.hits.hits;
|
|
|
|
const total = res.hits.total.value;
|
|
|
|
|
|
|
|
const pages = Math.ceil(total / this.pagination.limit);
|
|
|
|
const pagination = {
|
|
|
|
total: total,
|
|
|
|
pages: pages == 0 ? 1 : pages,
|
|
|
|
};
|
|
|
|
this.pagination = { ...this.pagination, ...pagination };
|
|
|
|
});
|
|
|
|
},
|
|
|
|
changePaging(item) {
|
|
|
|
this.pagination = item;
|
|
|
|
this.getItemsForResearch(this.firstChoiceOfTree.id);
|
|
|
|
},
|
|
|
|
resetPagination() {
|
|
|
|
this.pagination = {
|
|
|
|
page: 1,
|
|
|
|
pages: 0,
|
|
|
|
total: 0,
|
|
|
|
offset: 0, // page * per_page
|
|
|
|
limit: 10, //per_page
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
// #endregion
|
|
|
|
},
|
|
|
|
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
|
|
.v-popper--theme-dropdown {
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
.v-popper__inner {
|
|
|
|
.my-tooltip-content {
|
|
|
|
color: white;
|
|
|
|
background-color: black;
|
|
|
|
padding: 1em;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.btn-right-panel {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
@media screen and (max-width: 61.998em) {
|
|
|
|
.right-panel {
|
|
|
|
padding-top: 0.5em;
|
|
|
|
position: fixed;
|
|
|
|
z-index: 9;
|
|
|
|
width: 24em;
|
|
|
|
top: 0;
|
|
|
|
bottom: 0;
|
|
|
|
right: 0;
|
|
|
|
margin-right: var(--sidebar-collapsed-width);
|
|
|
|
background: #fff;
|
|
|
|
justify-content: center;
|
|
|
|
// box-shadow: -1px 0px 7px 1px #eee;
|
|
|
|
}
|
|
|
|
.btn-right-panel {
|
|
|
|
display: block;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@media screen and (max-width: 47.938em) {
|
|
|
|
.nav {
|
|
|
|
li {
|
|
|
|
.nav-link {
|
|
|
|
font-size: 0.8rem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
li.desktop:nth-child(n + 3) {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
.dropdown-menu {
|
|
|
|
a.dropdown-item:nth-child(-n + 2) {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// .combo-list {
|
|
|
|
// margin-top: 1em;
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
.right-panel {
|
|
|
|
margin-right: 0;
|
|
|
|
width: 18em;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|