599 lines
17 KiB
Vue
599 lines
17 KiB
Vue
<template>
|
||
<div>
|
||
<div class=" container-fluid">
|
||
<header>
|
||
<the-navbar></the-navbar>
|
||
</header>
|
||
<the-sidebar2 :menu="menu" :showUserAvatar="true"></the-sidebar2>
|
||
<main
|
||
class="pages-content-container main-page__content"
|
||
:class="{ expanded: !isSidebarCollapsed }"
|
||
>
|
||
<div class="pages-content mt-4 mt-lg-0 col-12">
|
||
<div class="" :class="{ 'd-flex': showPanel || showPanelTeams }">
|
||
<template v-if="canView">
|
||
<my-table
|
||
:tableActions="tableActions"
|
||
height="auto"
|
||
:hasSearch="true"
|
||
minHeight="25em"
|
||
maxHeight="calc(100dvh - 5em)"
|
||
:paginationInfo="pagination"
|
||
:sortingInfo="sorting"
|
||
:items="groupLists"
|
||
:fetchingData="fetchingData"
|
||
:tableColumns="tableColumns"
|
||
:totalPages="pagination.pages"
|
||
@search="searchGroups"
|
||
@reset-form="searchGroups"
|
||
@delete-table-item="deleteItem"
|
||
@edit-table-item="toggleUsersPanel"
|
||
@page-changed="pageChanged"
|
||
@page-limit-changed="pageLimitChanged"
|
||
@sort-changed="sortChanged"
|
||
@on-linked-title-click="onLinkedTitleClick"
|
||
>
|
||
<template v-slot:tableHeaderActions>
|
||
<div class="d-flex">
|
||
<!-- <div class="dropdown">
|
||
<button
|
||
class="btn dropdown-toggle"
|
||
type="button"
|
||
data-bs-toggle="dropdown"
|
||
aria-expanded="false"
|
||
>
|
||
{{ groupsTranslation[searchType] }}
|
||
</button>
|
||
<div class="dropdown-menu text-end">
|
||
<button
|
||
class="dropdown-item"
|
||
type="button"
|
||
@click.prevent="setSearchType('getGroupsWithoutAdmin')"
|
||
:class="{
|
||
active: searchType == 'getGroupsWithoutAdmin',
|
||
}"
|
||
value="getGroupsWithoutAdmin"
|
||
>
|
||
{{ groupsTranslation["getGroupsWithoutAdmin"] }}
|
||
</button>
|
||
<button
|
||
class="dropdown-item"
|
||
type="button"
|
||
@click.prevent="setSearchType('getGroupsWithAdmin')"
|
||
:class="{ active: searchType == 'getGroupsWithAdmin' }"
|
||
value="getGroupsWithAdmin"
|
||
>
|
||
{{ groupsTranslation["getGroupsWithAdmin"] }}
|
||
</button>
|
||
</div>
|
||
</div> -->
|
||
<button
|
||
v-if="createPanel"
|
||
@click.prevent="openCreatePanel()"
|
||
class="btn btn-primary"
|
||
type="button"
|
||
>
|
||
افزودن تیم
|
||
</button>
|
||
</div>
|
||
</template>
|
||
</my-table>
|
||
</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 class="side-panel" v-if="showPanel">
|
||
<div
|
||
class="side-panel-header d-flex mb-3 pb-3 border-bottom align-items-center"
|
||
>
|
||
<!-- <h5 class="m-0">اعضای تیم</h5> -->
|
||
<button
|
||
@click.prevent="addMember()"
|
||
class="btn btn-primary"
|
||
type="button"
|
||
>
|
||
افزودن عضو جدید
|
||
</button>
|
||
<button
|
||
@click.prevent="toggleUsersPanel()"
|
||
class="btn me-auto"
|
||
type="button"
|
||
>
|
||
<svg class="icon icon-Component-294--1">
|
||
<use xlink:href="#icon-Component-294--1"></use>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="side-panel-content">
|
||
<MembersSearch
|
||
v-if="showPanel"
|
||
:listMember="listMember"
|
||
:searchResults="users"
|
||
@on-send="searchUsers"
|
||
@delete-member="deleteMembers"
|
||
@edit-member="editMembers"
|
||
></MembersSearch>
|
||
</div>
|
||
</div>
|
||
<div class="side-panel" v-if="showPanelTeams">
|
||
<div
|
||
class="side-panel-header d-flex mb-3 pb-3 border-bottom align-items-center"
|
||
>
|
||
<h6 class="m-0">مدیریت تیم ها</h6>
|
||
|
||
<button
|
||
@click.prevent="closeShowPanelTeams()"
|
||
class="btn btn-outline-primary me-auto"
|
||
type="button"
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
|
||
<div class="side-panel-content">
|
||
<TeamForm
|
||
v-if="showPanelTeams"
|
||
@on-pass-by-emit="save"
|
||
@close-form="closeShowPanelTeams()"
|
||
:teamData="selectedItemClone"
|
||
></TeamForm>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<AddMemberToTeamModal
|
||
@update-member="updateMembers"
|
||
:item="[]"
|
||
v-if="showAddMember"
|
||
class="add-member"
|
||
></AddMemberToTeamModal>
|
||
</main>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { mapGetters, mapActions } from "vuex";
|
||
import HttpService from "@services/httpService";
|
||
import menu from "@task/json/menu.json";
|
||
import permitApis from "@apis/permitApi";
|
||
import taskApi from "@apis/taskApi";
|
||
|
||
export default {
|
||
beforeMount() {
|
||
this.httpService = new HttpService(this.taskMicroServiceName);
|
||
},
|
||
mounted() {
|
||
this.checkPermisionBeforGetList();
|
||
},
|
||
data() {
|
||
return {
|
||
groupsId: "",
|
||
showAddMember: false,
|
||
listMember: [],
|
||
users: [],
|
||
createPanel: true,
|
||
searchType: "getGroupsWithoutAdmin",
|
||
groupLists: [],
|
||
menu: menu,
|
||
firstTimeSearching: false,
|
||
httpService: undefined,
|
||
tableActions: [
|
||
{
|
||
showOutside: true,
|
||
show: true,
|
||
icon: "Component-242--1",
|
||
title: "تعیین مدیر",
|
||
to: {
|
||
name: "undefined",
|
||
},
|
||
selected: false,
|
||
disabled: false,
|
||
howToOpen: "",
|
||
href: "",
|
||
class: "edit-btn",
|
||
action: "edit-table-item",
|
||
},
|
||
{
|
||
showOutside: true,
|
||
show: true,
|
||
icon: "Component-295--1",
|
||
title: "حذف",
|
||
to: {
|
||
name: "undefined",
|
||
},
|
||
selected: false,
|
||
disabled: false,
|
||
howToOpen: "",
|
||
href: "",
|
||
class: "delete-btn",
|
||
action: "delete-table-item",
|
||
},
|
||
],
|
||
canView: false,
|
||
fetchingData: false,
|
||
tableColumns: [
|
||
{
|
||
isLink: true,
|
||
key: "title",
|
||
title: "عنوان",
|
||
width: "4",
|
||
},
|
||
{
|
||
isLink: true,
|
||
key: "organ",
|
||
title: "سازمان",
|
||
width: "4",
|
||
},
|
||
],
|
||
pagination: {
|
||
page: 1,
|
||
pages: 0,
|
||
total: 0,
|
||
offset: 0,
|
||
limit: 10,
|
||
},
|
||
sorting: {
|
||
sortby: "title",
|
||
sortorder: "asc", // asc | desc | none
|
||
},
|
||
// users: [],
|
||
loading: false,
|
||
showPanel: false,
|
||
showPanelTeams: false,
|
||
selectedItemClone: undefined,
|
||
|
||
prevSelectedItemIndex: undefined,
|
||
};
|
||
},
|
||
computed: {
|
||
...mapGetters(["isSidebarCollapsed"]),
|
||
|
||
...mapGetters("permit", ["projectGetter"]),
|
||
},
|
||
methods: {
|
||
...mapActions(["checkPermissions"]),
|
||
|
||
async getGroups() {
|
||
let url = taskApi.taskTeams.getList;
|
||
let payload = {
|
||
organ: "",
|
||
...this.sorting,
|
||
...this.pagination,
|
||
};
|
||
return await this.httpService.postRequest(url, payload).then((res) => {
|
||
this.groupLists = res.data;
|
||
// this.pagination.pages = res.pagination.pages;
|
||
this.pagination = { ...this.pagination, ...res.pagination };
|
||
});
|
||
},
|
||
checkPermisionBeforGetList() {
|
||
if (this.fetchingData) return;
|
||
this.fetchingData = true;
|
||
|
||
this.checkPermissions({ _this: this, permission: "teams_list" })
|
||
.then(() => {
|
||
this.getGroups()
|
||
.then(() => {
|
||
this.canView = true;
|
||
this.fetchingData = false;
|
||
})
|
||
.catch(() => {
|
||
this.canView = false;
|
||
this.fetchingData = false;
|
||
});
|
||
})
|
||
.catch(() => {
|
||
this.canView = false;
|
||
this.fetchingData = false;
|
||
});
|
||
},
|
||
updateUrl(url, query = "") {
|
||
url = url.replace("@offset", this.pagination.offset);
|
||
url = url.replace("@limit", this.pagination.limit);
|
||
url = url.replace("@sortby", this.sorting.sortby);
|
||
url = url.replace("@sortorder", this.sorting.sortorder);
|
||
|
||
// for searching groups.
|
||
if (query?.length) url = url.replace("@query", query);
|
||
else url = url.replace("/@query", query);
|
||
return url;
|
||
},
|
||
save(formData = undefined) {
|
||
if (this.loading) return;
|
||
this.loading = true;
|
||
|
||
const url = formData.id ? taskApi.taskTeams.edit : taskApi.taskTeams.add;
|
||
|
||
this.httpService
|
||
.postRequest(url, formData)
|
||
.then((res) => {
|
||
this.getGroups().then(() => {
|
||
this.loading = false;
|
||
});
|
||
|
||
this.mySwalToast({
|
||
html: res.message,
|
||
});
|
||
|
||
this.showPanel = false;
|
||
this.showPanelTeams = false;
|
||
this.createPanel = true;
|
||
|
||
this.resetForm();
|
||
})
|
||
.finally(() => {
|
||
this.loading = false;
|
||
});
|
||
},
|
||
deleteItem(index) {
|
||
// if (this.loading) return;
|
||
this.loading = true;
|
||
let groupId = this.groupLists[index].id;
|
||
const payload = {
|
||
id: groupId,
|
||
};
|
||
let url = taskApi.taskTeams.delete;
|
||
|
||
this.mySwalConfirm({
|
||
title: "هشدار",
|
||
html: "از حذف این مورد مطمئن هستید؟",
|
||
icon: "warning",
|
||
}).then((result) => {
|
||
if (result.isConfirmed) {
|
||
this.httpService.postRequest(url, payload).then((res) => {
|
||
this.getGroups().then(() => {
|
||
this.loading = false;
|
||
// this.showPanel = false;
|
||
});
|
||
|
||
this.mySwalToast({
|
||
html: res.message,
|
||
});
|
||
});
|
||
}
|
||
});
|
||
},
|
||
openCreatePanel() {
|
||
this.selectedItemClone = undefined;
|
||
|
||
if (this.showPanelTeams) {
|
||
this.showPanelTeams = false;
|
||
} else {
|
||
this.showPanelTeams = true;
|
||
this.showPanel = false;
|
||
this.createPanel = false;
|
||
}
|
||
},
|
||
toggleUsersPanel(index = undefined) {
|
||
if (index !== undefined) {
|
||
if (this.prevSelectedItemIndex !== undefined)
|
||
this.groupLists[this.prevSelectedItemIndex].active = false;
|
||
|
||
this.prevSelectedItemIndex = index;
|
||
this.$set(this.groupLists[index], "active", true);
|
||
|
||
this.selectedItemClone = structuredClone(this.groupLists[index]);
|
||
|
||
this.showPanel = false;
|
||
this.showPanelTeams = true;
|
||
this.createPanel = false;
|
||
} else {
|
||
this.resetForm();
|
||
}
|
||
},
|
||
closeShowPanelTeams() {
|
||
this.showPanelTeams = false;
|
||
this.createPanel = true;
|
||
},
|
||
resetForm() {
|
||
this.selectedItemClone = undefined;
|
||
this.showPanel = false;
|
||
this.showPanelTeams = false;
|
||
},
|
||
// pagination and sorting
|
||
resetPagination() {
|
||
this.pagination = {
|
||
pages: 0,
|
||
total: 0,
|
||
page: 1,
|
||
offset: 0,
|
||
limit: 10,
|
||
};
|
||
},
|
||
pageLimitChanged(paging) {
|
||
this.resetPagination();
|
||
this.pagination.limit = paging.limit;
|
||
|
||
this.getGroups();
|
||
},
|
||
pageChanged(paging) {
|
||
let page = paging.pageNumber;
|
||
page -= 1;
|
||
this.pagination.offset = page * paging.limit;
|
||
this.pagination.limit = paging.limit;
|
||
this.pagination.page = paging.pageNumber;
|
||
|
||
this.getGroups();
|
||
},
|
||
sortChanged(sorting) {
|
||
this.pagination.page = this.pagination.offset = 0;
|
||
this.sorting = sorting;
|
||
|
||
this.getGroups();
|
||
},
|
||
searchGroups(query) {
|
||
this.resetPagination();
|
||
this[this.searchType](query);
|
||
},
|
||
async searchUsers(query = "") {
|
||
// this.resetPagination();
|
||
|
||
let url = this.loginMicroServiceName + permitApis.users.search;
|
||
url = url.replace("{{offset}}", 0);
|
||
url = url.replace("{{limit}}", 50);
|
||
url = url.replace("{{sortby}}", "username");
|
||
url = url.replace("{{sortorder}}", "desc");
|
||
|
||
// removing '/' before query if query is empty.
|
||
if (query) url = url.replace("{{query}}", query);
|
||
else url = url.replace("/{{query}}", query);
|
||
|
||
return await this.httpService.getRequest(url).then((res) => {
|
||
this.users = res.data;
|
||
// this.pagination = { ...this.pagination, ...res.pagination };
|
||
});
|
||
},
|
||
onLinkedTitleClick(index) {
|
||
this.showPanelTeams = false;
|
||
this.showPanel = true;
|
||
this.groupsId = index.index;
|
||
this.getMembers();
|
||
// if (this.showPanel) {
|
||
// this.showPanel = false;
|
||
// } else {
|
||
// this.showPanelTeams = false;
|
||
// this.showPanel = true;
|
||
// }
|
||
},
|
||
getMembers() {
|
||
let payload = {
|
||
group_id: this.groupsId + 1,
|
||
offset: 0,
|
||
limit: 50,
|
||
sortby: "id",
|
||
sortorder: "asc",
|
||
};
|
||
const url = taskApi.taskTeams.members;
|
||
this.httpService.postRequest(url, payload).then((res) => {
|
||
this.listMember = res.data;
|
||
});
|
||
},
|
||
addMember() {
|
||
this.showAddMember = true;
|
||
setTimeout(() => {
|
||
$("#share-modal").modal("show");
|
||
}, 500);
|
||
},
|
||
updateMembers(payload) {
|
||
const formData = {
|
||
...payload,
|
||
...{ group_id: this.groupsId + 1 },
|
||
};
|
||
const url = taskApi.taskTeams.addMembers;
|
||
this.httpService
|
||
.postRequest(url, formData)
|
||
.then((response) => {
|
||
this.getMembers();
|
||
this.mySwalToast({
|
||
title: "تبریک",
|
||
html: response.message,
|
||
icon: "success",
|
||
});
|
||
})
|
||
.catch((err) => {
|
||
this.mySwalToast({
|
||
title: "خطا",
|
||
html: err.response.message ?? err.message,
|
||
icon: "error",
|
||
});
|
||
})
|
||
.finally(() => {
|
||
$("#share-modal").modal("hide");
|
||
setTimeout(() => {
|
||
this.showModal = true;
|
||
}, 500);
|
||
|
||
this.loading = false;
|
||
});
|
||
},
|
||
deleteMembers(list) {
|
||
let payload = {
|
||
id: list.id,
|
||
};
|
||
const url = taskApi.taskTeams.deleteMembers;
|
||
this.httpService.postRequest(url, payload);
|
||
this.mySwalConfirm({
|
||
title: "هشدار!!!",
|
||
html: "از حذف این مورد مطمئن هستید؟",
|
||
}).then((result) => {
|
||
if (result.isConfirmed) {
|
||
this.getMembers();
|
||
this.mySwalToast({
|
||
title: "تبریک",
|
||
html: "مورد با موفقیت حذف شد",
|
||
icon: "success",
|
||
});
|
||
}
|
||
});
|
||
},
|
||
editMembers(payload) {
|
||
// console.log(this.listMember.id)
|
||
const formData = {
|
||
...payload,
|
||
...{ project_id: this.projectId },
|
||
};
|
||
const url = taskApi.taskTeams.editMembers;
|
||
this.httpService
|
||
.postRequest(url, formData)
|
||
.then((response) => {
|
||
this.getMembers();
|
||
this.mySwalToast({
|
||
title: "تبریک",
|
||
html: response.message,
|
||
icon: "success",
|
||
});
|
||
})
|
||
.catch((err) => {
|
||
this.mySwalToast({
|
||
title: "خطا",
|
||
html: err.response.message ?? err.message,
|
||
icon: "error",
|
||
});
|
||
})
|
||
.finally(() => {
|
||
$("#share-modal").modal("hide");
|
||
setTimeout(() => {
|
||
this.showModal = true;
|
||
}, 500);
|
||
|
||
this.loading = false;
|
||
});
|
||
},
|
||
},
|
||
components: {
|
||
MembersSearch: () => import("@task/components/MembersSearch"),
|
||
TeamForm: () => import("@task/components/TeamForm"),
|
||
AddMemberToTeamModal: () => import("@task/components/AddMemberToTeamModal"),
|
||
},
|
||
};
|
||
</script>
|
||
<style scoped lang="scss">
|
||
.side-panel {
|
||
padding: 1em;
|
||
width: 30em;
|
||
max-width: 100%;
|
||
background-color: #fafafa;
|
||
border-right: 1px solid #eee;
|
||
}
|
||
// .pages-content-container {
|
||
// margin-right: 8em;
|
||
// margin-left: 2em;
|
||
// }
|
||
</style>
|