task_ui/pages/TaskTeams.vue
2025-04-21 11:49:42 +03:30

599 lines
17 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>