455 lines
14 KiB
Vue
455 lines
14 KiB
Vue
![]() |
<template>
|
|||
|
<div class="research p-0 container-fluid">
|
|||
|
<div class="row px-3 border-bottom">
|
|||
|
<div class="col mb-4">
|
|||
|
<div class="d-flex align-items-center">
|
|||
|
<label for="repositories-desktop" class="float-labels no-wrap ms-2">
|
|||
|
<svg class="icon icon-filter">
|
|||
|
<use xlink:href="#icon-filter"></use>
|
|||
|
</svg>
|
|||
|
</label>
|
|||
|
|
|||
|
<USelectMenu
|
|||
|
option-attribute="title"
|
|||
|
:popper="{ placement: 'left-end' }"
|
|||
|
searchable
|
|||
|
searchable-placeholder="Search a person..."
|
|||
|
v-model="multiSelectValue"
|
|||
|
:options="multiSelectOptions"
|
|||
|
placeholder="انتخاب فیلتر "
|
|||
|
@update:model-value="onSelectNavigation"
|
|||
|
>
|
|||
|
</USelectMenu>
|
|||
|
|
|||
|
<!-- <multiselect
|
|||
|
:allow-empty="false"
|
|||
|
:searchable="true"
|
|||
|
:close-on-select="true"
|
|||
|
:show-labels="false"
|
|||
|
label="title"
|
|||
|
track-by="key"
|
|||
|
placeholder="انتخاب فیلتر "
|
|||
|
:value="multiSelectValue"
|
|||
|
:options="multiSelectOptions"
|
|||
|
@select="fetchResearchItems"
|
|||
|
:hide-selected="false"
|
|||
|
:max-height="200"
|
|||
|
:width="50"
|
|||
|
openDirection="rtl"
|
|||
|
id="repositories-desktop"
|
|||
|
class="multiselect mt-1"
|
|||
|
>
|
|||
|
</multiselect> -->
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<!-- #region لیست تمام تحقیقات -->
|
|||
|
<div class="row mx-0">
|
|||
|
<the-content-loading
|
|||
|
v-if="loading"
|
|||
|
:loadingTitle="'در حال دریافت اطلاعات'"
|
|||
|
class="table-loading"
|
|||
|
></the-content-loading>
|
|||
|
|
|||
|
<template v-else>
|
|||
|
<template v-if="listResearch?.length">
|
|||
|
<template v-for="(item, index) in listResearch">
|
|||
|
<div class="col">
|
|||
|
<div class="card_fish mt-4 mb-1">
|
|||
|
<div class="card_fish_header">
|
|||
|
<div class="img">
|
|||
|
<div class="d-flex">
|
|||
|
<img
|
|||
|
:alt="userFullname(item._source.user)"
|
|||
|
class="rounded img-fluid user-avatar"
|
|||
|
:src="userAvatar(item._source.user)"
|
|||
|
/>
|
|||
|
<div class="d-flex flex-column">
|
|||
|
<P class="me-3 mb-0"
|
|||
|
>{{ item._source.research_type }}
|
|||
|
<span class="me-3 text-date">
|
|||
|
{{ dateTofarsi(item._source.date_create) }}
|
|||
|
</span>
|
|||
|
</P>
|
|||
|
<div v-if="item._source.text_subject" class="me-3">
|
|||
|
{{ item._source?.text_subject }}
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
<context-menu
|
|||
|
:contextMenu="tableActions"
|
|||
|
@edit-item="showResearch(item)"
|
|||
|
@remove-item="removeItemHandler(item)"
|
|||
|
style="position: relative"
|
|||
|
></context-menu>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div
|
|||
|
role="button"
|
|||
|
class="card_fish_main"
|
|||
|
@click.prevent="showResearch(item, true)"
|
|||
|
>
|
|||
|
<div class="text_fish">
|
|||
|
<p>
|
|||
|
{{ itemTextMain(item._source) }}
|
|||
|
</p>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</template>
|
|||
|
</template>
|
|||
|
<no-data v-else>
|
|||
|
<div 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>
|
|||
|
</template>
|
|||
|
</div>
|
|||
|
|
|||
|
<!-- #endregion -->
|
|||
|
</div>
|
|||
|
</template>
|
|||
|
<script>
|
|||
|
import entityApi from "~/apis/entityApi.js";
|
|||
|
import { mapActions, mapState } from "pinia";
|
|||
|
|
|||
|
import { useEntityStore } from "~/stores/entityStore";
|
|||
|
import { useSearchStore } from "~/stores/searchStore";
|
|||
|
import { useCommonStore } from "~/stores/commonStore";
|
|||
|
|
|||
|
import { cloneDeep } from "lodash";
|
|||
|
|
|||
|
/**
|
|||
|
* @vue-data {undefined} httpService - سرویس HTTP برای درخواستها.
|
|||
|
* @vue-data {Array} listResearch - لیست تحقیقات
|
|||
|
* @vue-data {Array} tableActions - لیست اقدامات context-menu
|
|||
|
*/
|
|||
|
|
|||
|
export default {
|
|||
|
props: {
|
|||
|
activeSchema: {
|
|||
|
default() {
|
|||
|
return [];
|
|||
|
},
|
|||
|
},
|
|||
|
},
|
|||
|
data() {
|
|||
|
return {
|
|||
|
loading: false,
|
|||
|
httpService: undefined,
|
|||
|
multiSelectValue: undefined,
|
|||
|
|
|||
|
listResearch: [],
|
|||
|
tableActions: [
|
|||
|
{
|
|||
|
showOutside: false,
|
|||
|
show: true,
|
|||
|
icon: "Component-108--1",
|
|||
|
title: "ویرایش",
|
|||
|
to: { name: "undefined" },
|
|||
|
selected: false,
|
|||
|
disabled: false,
|
|||
|
howToOpen: "",
|
|||
|
href: "",
|
|||
|
class: "edit-btn",
|
|||
|
action: "edit-item",
|
|||
|
can: "item-info_edit",
|
|||
|
},
|
|||
|
{
|
|||
|
showOutside: false,
|
|||
|
show: true,
|
|||
|
icon: "Component-295--1",
|
|||
|
title: "حذف",
|
|||
|
to: { name: "undefined" },
|
|||
|
selected: false,
|
|||
|
disabled: false,
|
|||
|
howToOpen: "",
|
|||
|
href: "",
|
|||
|
class: "delete-btn",
|
|||
|
action: "remove",
|
|||
|
can: "item-list_delete",
|
|||
|
},
|
|||
|
{
|
|||
|
showOutside: false,
|
|||
|
show: true,
|
|||
|
icon: "Component-145--1",
|
|||
|
title: "موضوع",
|
|||
|
to: { name: "undefined" },
|
|||
|
selected: false,
|
|||
|
disabled: false,
|
|||
|
howToOpen: "",
|
|||
|
href: "",
|
|||
|
class: "",
|
|||
|
action: "showSubjectForm",
|
|||
|
can: "list-item-subject_new",
|
|||
|
},
|
|||
|
],
|
|||
|
multiSelectOptions: [],
|
|||
|
};
|
|||
|
},
|
|||
|
beforeMount() {
|
|||
|
this.httpService = useNuxtApp()["$http"];
|
|||
|
},
|
|||
|
mounted() {
|
|||
|
setTimeout(() => {
|
|||
|
this.handleMultiSelect(this.activeEntityViewSchemaGetter?.researchs);
|
|||
|
}, 1000);
|
|||
|
|
|||
|
if (this.$route.query.research_type) {
|
|||
|
let id = this.$route.query.research_id;
|
|||
|
|
|||
|
this.getResearchById(id).then((res) => {
|
|||
|
if (res) {
|
|||
|
this.showResearch(res);
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
},
|
|||
|
methods: {
|
|||
|
...mapActions(useEntityStore, ["activeResearchTypeSetter"]),
|
|||
|
async handleMultiSelect(options) {
|
|||
|
let listOptions = options;
|
|||
|
this.multiSelectOptions = listOptions;
|
|||
|
// if (this.activeResearchTypeGetter == undefined) {
|
|||
|
// listOptions.forEach((element) => {
|
|||
|
// if (element.key == "all") {
|
|||
|
// this.activeResearchTypeSetter(element);
|
|||
|
// }
|
|||
|
// });
|
|||
|
// }
|
|||
|
let schema = "";
|
|||
|
if (this.$route.query.research_type) {
|
|||
|
schema = options.find(
|
|||
|
(itemKey) => itemKey.title === this.$route.query.research_type
|
|||
|
);
|
|||
|
this.fetchResearchItems(schema);
|
|||
|
} else {
|
|||
|
listOptions.forEach((element) => {
|
|||
|
if (element.key == "all") {
|
|||
|
this.activeResearchTypeSetter(element);
|
|||
|
this.fetchResearchItems(element);
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
},
|
|||
|
async getResearchById(id, isReadonly = false) {
|
|||
|
let url = repoUrl() + entityApi.fish.get_byids;
|
|||
|
url = url.replace("{{index_key}}", "research");
|
|||
|
url = url.replace("{{id}}", id);
|
|||
|
|
|||
|
return await this.httpService
|
|||
|
.getRequest(url)
|
|||
|
.then((res) => {
|
|||
|
if (res.status == 0) return res;
|
|||
|
else return undefined;
|
|||
|
})
|
|||
|
.catch((error) => {
|
|||
|
console.error("خطا :", error);
|
|||
|
return undefined;
|
|||
|
});
|
|||
|
},
|
|||
|
showResearch(item, isReadonly = false) {
|
|||
|
let schema = this.activeEntityViewSchemaGetter?.researchs.find(
|
|||
|
(itemKey) => itemKey.key === item._source?.research_key
|
|||
|
);
|
|||
|
|
|||
|
this.$emit("fishHandlerInResearch", {
|
|||
|
action: "edit",
|
|||
|
itemEdit: item,
|
|||
|
itemSchema: schema,
|
|||
|
isReadonly: isReadonly,
|
|||
|
});
|
|||
|
},
|
|||
|
/**
|
|||
|
* تبدیل تاریخ به فرمت فارسی
|
|||
|
* @param {Number} item - تاریخ به صورت timestamp
|
|||
|
* @returns {String} تاریخ به فرمت فارسی
|
|||
|
* @example
|
|||
|
* // استفاده:
|
|||
|
* dateTofarsi(1609459200); // returns "1399/10/11"
|
|||
|
*/
|
|||
|
dateTofarsi(item) {
|
|||
|
const m = item * 1000;
|
|||
|
const d = new Date(m).toLocaleDateString("fa-IR");
|
|||
|
return d;
|
|||
|
},
|
|||
|
/**
|
|||
|
* گرداننده حذف آیتم
|
|||
|
* @param {Object} item - آیتمی که باید حذف شود
|
|||
|
*/
|
|||
|
removeItemHandler(item) {
|
|||
|
this.mySwalConfirm({
|
|||
|
title: "هشدار!!!",
|
|||
|
html: `از حذف <b>${item._source.research_type}</b> اطمینان دارید؟ `,
|
|||
|
icon: "warning",
|
|||
|
}).then((result) => {
|
|||
|
if (result.isConfirmed) {
|
|||
|
let url = repoUrl() + entityApi.research.deleteItem;
|
|||
|
// let key = "";
|
|||
|
// if (this.$route.params?.key) key = this.$route.params.key;
|
|||
|
url = url.replace("{{index_key}}", this.multiSelectValue?.index_key);
|
|||
|
url = url.replace("{{id}}", item._id);
|
|||
|
this.httpService.postRequest(url).then((res) => {
|
|||
|
this.mySwalToast({
|
|||
|
html: res.message,
|
|||
|
});
|
|||
|
setTimeout(() => {
|
|||
|
this.fetchResearchItems(this.activeResearchTypeGetter);
|
|||
|
}, 500);
|
|||
|
});
|
|||
|
}
|
|||
|
});
|
|||
|
},
|
|||
|
/**
|
|||
|
* گرفتن متن اصلی آیتم
|
|||
|
* @param {Object} item - آیتمی که متن اصلی آن باید گرفته شود
|
|||
|
* @returns {String} متن اصلی آیتم
|
|||
|
*/
|
|||
|
itemTextMain(item) {
|
|||
|
return item.text_main;
|
|||
|
},
|
|||
|
/**
|
|||
|
* گرفتن لیست آیتمهای تحقیق.
|
|||
|
* @description این متد لیست آیتمهای تحقیق را از سرور دریافت کرده و مقدار `listResearch` را بهروز میکند.
|
|||
|
* اگر فیلتر انتخاب شده دارای کلید "all" باشد، تمام آیتمها را دریافت میکند و در غیر این صورت، آیتمها را بر اساس نوع تحقیق فیلتر میکند.
|
|||
|
* @param {Object} selectedItem - فیلتر انتخاب شده.
|
|||
|
* @param {String} selectedItem.key - کلید فیلتر انتخاب شده.
|
|||
|
* @param {String} selectedItem.title - عنوان فیلتر انتخاب شده.
|
|||
|
* @example
|
|||
|
* this.fetchResearchItems({ key: 'all', title: 'All Research' });
|
|||
|
*/
|
|||
|
async fetchResearchItems(selectedItem) {
|
|||
|
if (this.loading) return;
|
|||
|
this.loading = true;
|
|||
|
|
|||
|
this.multiSelectValue = selectedItem;
|
|||
|
this.activeResearchTypeSetter(selectedItem);
|
|||
|
|
|||
|
// معنی نداره چک این !!!!
|
|||
|
// if (!this.selectedItemEntityGetter) return;
|
|||
|
if (!selectedItem) return;
|
|||
|
|
|||
|
let url = "";
|
|||
|
if (selectedItem.key == "all") {
|
|||
|
url = repoUrl() + entityApi.research.listByEntityId;
|
|||
|
} else {
|
|||
|
url = repoUrl() + entityApi.research.listByEntityIdByFilter;
|
|||
|
url = url.replace("{{filter}}", "research_type=" + selectedItem.title);
|
|||
|
}
|
|||
|
url = url.replace("{{entity_id}}", this.$route.params.id);
|
|||
|
return await this.httpService
|
|||
|
.getRequest(url)
|
|||
|
.then((res) => {
|
|||
|
this.listResearch = res?.hits.hits;
|
|||
|
})
|
|||
|
.catch((error) => {
|
|||
|
console.error("خطای شبکه:", error);
|
|||
|
this.loading = false;
|
|||
|
})
|
|||
|
.finally(() => {
|
|||
|
this.loading = false;
|
|||
|
});
|
|||
|
},
|
|||
|
/**
|
|||
|
* پر کردن مقدار `multiSelectOptions`.
|
|||
|
* @description این متد در قدم اول تغییراتی در `listSchema` ایجاد کرده و مقدار "all" را اضافه میکند.
|
|||
|
* سپس `multiSelectOptions` را بهروز کرده و برای هر آیتم در `multiSelectOptions`، اگر کلید آن "all" باشد، آیتمهای تحقیق را دریافت میکند.
|
|||
|
* @param {Array} listSchema - ساختار سایت.
|
|||
|
* @example
|
|||
|
* this.updateMultiSelectOptions([{ key: 'link', title: 'Link' }, { key: 'type', title: 'Type' }]);
|
|||
|
* @deprecated "بصورت مستقیم درخواست زدیم و دیگه نیازی به این متد نبود."
|
|||
|
*/
|
|||
|
// updateMultiSelectOptions(listSchema) {
|
|||
|
// listSchema.forEach((item) => {
|
|||
|
// if (item.key == "link") {
|
|||
|
// item.key = "all";
|
|||
|
// item.title = "همه";
|
|||
|
// this.fetchResearchItems(item);
|
|||
|
// }
|
|||
|
// });
|
|||
|
// this.multiSelectOptions = listSchema;
|
|||
|
// const index = listSchema.findIndex((item) => item.key === "link");
|
|||
|
// if (index !== -1) {
|
|||
|
// listSchema.splice(index, 1);
|
|||
|
// }
|
|||
|
// listSchema.push({
|
|||
|
// key: "all",
|
|||
|
// title: "همه",
|
|||
|
// });
|
|||
|
// this.multiSelectOptions = listSchema;
|
|||
|
// this.multiSelectOptions.forEach((item) => {
|
|||
|
// if (item.key == "all") {
|
|||
|
// this.fetchResearchItems(item);
|
|||
|
// }
|
|||
|
// });
|
|||
|
// },
|
|||
|
},
|
|||
|
|
|||
|
computed: {
|
|||
|
...mapState(useEntityStore, [
|
|||
|
"selectedItemEntityGetter",
|
|||
|
"activeEntityViewSchemaGetter",
|
|||
|
"activeResearchTypeGetter",
|
|||
|
]),
|
|||
|
},
|
|||
|
};
|
|||
|
</script>
|
|||
|
<style scoped lang="scss">
|
|||
|
.research {
|
|||
|
overflow-y: auto;
|
|||
|
overflow-x: hidden;
|
|||
|
height: 90dvh;
|
|||
|
width: 19em;
|
|||
|
}
|
|||
|
.card_fish {
|
|||
|
width: 17em;
|
|||
|
height: 150px;
|
|||
|
display: grid;
|
|||
|
grid-template-rows: 1fr 2fr 1fr;
|
|||
|
justify-self: center;
|
|||
|
background-color: #f2f2f2;
|
|||
|
border-radius: 10px;
|
|||
|
// box-shadow: 0px 3px 7px;
|
|||
|
box-shadow: 0px 1px 3px;
|
|||
|
|
|||
|
.img {
|
|||
|
display: flex;
|
|||
|
justify-content: space-between;
|
|||
|
margin: 6px 10px;
|
|||
|
.text-date {
|
|||
|
font-size: 0.875em;
|
|||
|
color: #a7a098;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.card_fish_main {
|
|||
|
&:hover {
|
|||
|
.text_fish {
|
|||
|
p {
|
|||
|
color: var(--primary-color);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
.text_fish {
|
|||
|
margin: 0px 12px;
|
|||
|
|
|||
|
height: 73px;
|
|||
|
overflow: hidden;
|
|||
|
|
|||
|
p {
|
|||
|
font-size: 12px;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|