<template> <div class=" container-fluid"> <div class="all-selects justify-content-between col-12"> <div class="selects col-md-4 justify-content-start align-items-center"> <div> <label class="teams-label"> ماه: </label> <select id="month-select" class="form-control ms-1" v-model="selectedMonth" @change="getMainList" > <option v-for="month in months" :key="month" :value="month"> {{ getPersianMonthName(month) }} </option> </select> </div> <div class="me-3 ms-3"> <label class="teams-label"> سال: </label> <select id="year-select" class="form-select form-control" v-model="selectedYear" @change="getMainList" > <option v-for="year in years" :key="year" :value="year"> {{ year }} </option> </select> </div> <div> <label class="teams-label">تیم ها:</label> <select v-model="group_id" @change="getMainList" class="form-select form-control"> <option selected value="">همه</option> <option v-for="item in groups" :value="item.id"> {{ item.title }} </option> </select> </div> <!-- <div> <button title="شروع" type="button" class="btn btn-primary btn-start" @click.prevent="setActiveTab(navItem)" > شروع </button> </div> --> </div> <div class="d-flex align-items-center grouping col-md-8 justify-content-end" > <div class="select-teams"> <label class="teams-label-Grouping"> گروه بندی:</label> <select v-model="groupType" @change="getsorting()" class="form-control" > <option selected value="nogroup">بدون گروه بندی</option> <option value="day">روز</option> <option value="category">دسته</option> <option value="title">عنوان</option> <option value="organ">سازمان</option> </select> </div> <div class="switch-component"> <switch-component name="switch-view-mode" @change-mode="showchart($event)" class="task-admin-switch" texts1="Normal" texts2="Chartical" ></switch-component> </div> </div> </div> <main class="pages-content-container" :class="{ expanded: !isSidebarCollapsed }" > <div class="pages-content pt-3"> <div class="" :class="{ 'd-flex': showPanel || showPanelTeams }"> <template v-if="canView"> <my-table class="p-0 ms-3 col-4" :tableActions="tableActions" height="calc(100vh + -14em)" minHeight="25em" maxHeight="calc(100dvh + -13em)" :paginationInfo="pagination" :sortingInfo="sorting" :items="mainList" :fetchingData="fetchingData" :tableColumns="tableColumns" :totalPages="pagination.pages" :showActions="false" @search="searchUsers" @reset-form="searchUsers" @edit-table-item="toggleUsersPanel" @page-changed="pageChanged" @page-limit-changed="pageLimitChanged" @sort-changed="sortChanged" > </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="col-md-8 form-sorting_group"> <component v-if="showcomponent" :is="changeSorting()" :listItem="listItem" :columns="columnGroup" :workList="workList" :userId="userId" ></component> <pie-donut class="mt-5" v-if="showChart" :dataPie="dataPie" :PieOptions="PieOptions" width="90%" height="300px" ></pie-donut> </div> </div> </div> </main> </div> </template> <script> import { mapGetters, mapActions } from "vuex"; import HttpService from "@services/httpService"; import menu from "@task/json/menu.json"; import adminApi from "@apis/adminApi"; import taskApi from "@apis/taskApi"; import { p2e } from "@plugins/persianNumber"; export default { beforeMount() { this.httpService = new HttpService( this.taskMicroServiceName ); }, mounted() { this.checkPermisionBeforGetList(); var d = new Date().toLocaleDateString("fa-IR"); let items = d.split("/"); this.selectedYear = p2e(items[0]); this.selectedMonth = p2e(items[1]); this.getWorkingHoursInformation(); this.getTaskGroups(); }, data() { return { PieOptions: { radius: ["40%", "70%"], selectedMode: "single", }, showChart: false, showcomponent: true, listItem: [], group_id: "", groupType: "nogroup", userId: "", tasks: [{ category: "", title: "", duration: "" }], groups: [], months: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"], years: ["1400", "1401", "1402", "1403", "1404", "1405"], selectedYear: "", selectedMonth: "", mainList: [], 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: "firstName", title: "نام", width: "2", }, { isLink: true, key: "lastname", title: "نام خانوادگی", width: "2", }, { isLink: true, key: "team", title: "تیم", width: "2", }, { isLink: true, key: "useTime", title: "خالص ماهانه", width: "2", }, ], sorting: { sortby: "", sortorder: "", // asc | desc | none }, selectedItem: {}, selectedItemClone: {}, cloneItems: [], prevSelectedItemIndex: undefined, users: [], loading: false, showPanel: true, showPanelTeams: false, workList: [], rotated: false, dataPie: [], allUserId: "", }; }, computed: { columnGroup() { if (this.groupType == "category") return [ { label: "دسته", key: "category", class: "col-6" }, { label: "تعداد روز", key: "day_count", class: "col-2" }, { label: "تعداد فرآیند", key: "task_count", class: "col-2" }, { label: "مدت", key: "duration", class: "col-2" }, ]; else if (this.groupType == "organ") return [ { label: "سازمان", key: "organ", class: "col-6" }, { label: "تعداد روز", key: "day_count", class: "col-2" }, { label: "تعداد فرآیند", key: "task_count", class: "col-2" }, { label: "مدت", key: "duration", class: "col-2" }, ]; else if (this.groupType == "title") return [ { label: "عنوان", key: "title", class: "col-6" }, { label: "تعداد روز", key: "day_count", class: "col-2" }, { label: "تعداد فرآیند", key: "category_count", class: "col-2" }, { label: "مدت", key: "duration", class: "col-2" }, ]; else return [ { label: "تاریخ", key: "normalDate", class: "col-2" }, { label: "دسته", key: "category", class: "col-3" }, { label: "عنوان", key: "title", class: "col-6" }, { label: "مدت", key: "duration", class: "col-1" }, ]; }, buildName() { return process.env.VUE_APP_BUILD_NAME + "-sidebar"; }, }, methods: { ...mapGetters(["isSidebarCollapsed"]), ...mapActions(["checkPermissions"]), checkPermisionBeforGetList() { if (this.fetchingData) return; this.fetchingData = true; this.checkPermissions({ _this: this, permission: "admin_list" }) .then(() => { this.getMainList() .then(() => { this.canView = true; this.fetchingData = false; }) .catch(() => { this.canView = false; this.fetchingData = false; }); }) .catch(() => { this.canView = false; this.fetchingData = false; }); }, async getMainList() { let url = taskApi.taskReport.getList; let payload = { group_id: this.group_id, year: this.selectedYear, month: this.selectedMonth, ...this.sorting, ...this.pagination, }; return await this.httpService .postRequest(url, payload) .then((res) => { // console.log("mainList", res.data); this.mainList = res.data; this.allUserId = this.mainList.map((item) => item.user_id).join(","); this.pagination = { ...this.pagination, ...res.pagination }; // this.onLinkedTitleClick({ // rowItem: this.markActive(0), // tableColumn: {}, // index: 0, // }); }) .catch((err) => { console.info(err); }) .finally(() => { this.getsorting(); if (this.showChart) { this.getvalueChartDonut(); } }); }, markActive(index) { if (this.prevSelectedItemIndex !== undefined) { this.$set(this.mainList[this.prevSelectedItemIndex], "active", false); } this.prevSelectedItemIndex = index; this.$set(this.mainList[index], "active", true); this.selectedItemClone = structuredClone(this.mainList[index]); return this.selectedItemClone; }, // onLinkedTitleClick({ rowItem, tableColumn, index }) { // // console.log(this.group_id) // this.userId = rowItem.user_id; // let payload = { // user_id: this.userId, // year: this.selectedYear, // month: this.selectedMonth, // }; // const url = taskApi.workingHours.load; // this.httpService // .postRequest(url, payload) // .then((res) => { // this.workList = res.data; // this.showPanel = true; // this.markActive(index); // }) // .finally(() => { // if (this.showChart) { // this.getvalueChartDonut(); // } // this.getsorting(); // }); // }, getWorkingHoursInformation() { // console.log(this.currentUser); const payload = { user_id: this.currentUser.user_id, // offset: 0, // limit: 50, sortby: "taskDate", sortorder: "desc", year: this.selectedYear, month: this.selectedMonth, }; const url = taskApi.workingHours.load; this.httpService .postRequest(url, payload) .then((res) => { this.workList = res.data; }) .finally(() => { this.getsorting(); if (this.showChart) { this.getvalueChartDonut(); } }); }, datefa(item) { let m = item * 1000; let d = new Date(m).toLocaleDateString("fa-IR"); return d; }, selectDate(items) { if (items.oldDate) { let item = items.oldDate.split("-"); let date = {}; date.day = item[2]; date.month = item[1]; date.year = item[0]; this.$emit("select-day", date); } }, 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; }, searchUsers(query = "") { this.resetPagination(); this[groupType](query); // this.getGroupsWithoutAdmin(query); }, toggleUsersPanel(index = undefined) { if (index !== undefined) { if (this.prevSelectedItemIndex !== undefined) this.mainList[this.prevSelectedItemIndex].active = false; this.prevSelectedItemIndex = index; this.$set(this.mainList[index], "active", true); this.selectedItemClone = structuredClone(this.mainList[index]); this.showPanel = true; this.showPanelTeams = false; } else { this.resetForm(); } }, resetForm() { this.selectedItemClone = undefined; this.users = []; this.showPanel = 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.getMainList(); // this[this.searchType](); }, 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.getMainList(); // this[this.searchType](); }, sortChanged(sorting) { this.pagination.page = this.pagination.offset = 0; this.sorting = sorting; this.getMainList(); // this[this.searchType](); }, updateList() { this.resetPagination(); this.getMainList(); }, openCreatePanel() { if (this.showPanelTeams) { this.showPanelTeams = false; } else { this.showPanelTeams = true; this.showPanel = false; } }, closeShowPanelTeams() { this.showPanelTeams = false; }, save(formData = undefined) { if (this.loading) return; this.loading = true; const url = formData.id ? apis.users.update : apis.users.create; formData; this.httpService .postRequest(url, formData) .then((res) => { this.getUsers().then(() => { this.loading = false; }); this.mySwalToast({ html: res.message, }); this.showPanel = false; this.resetForm(); }) .finally(() => { this.loading = false; }); }, getPersianMonthName(month) { const monthNames = [ "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", ]; return monthNames[parseInt(month) - 1]; }, getTaskGroups() { const payload = { organ: "", sortby: "title", sortorder: "asc", }; const url = taskApi.taskReport.groupList; this.httpService .postRequest(url, payload) .then((res) => { this.groups = res.data; }); }, changeSorting() { if (this.groupType == "day") { return "SortingByDayTasksAdmin"; } else { return "SortingTasksAdmin"; } }, getsorting() { let payload = { users_id: this.allUserId, year: this.selectedYear, month: this.selectedMonth, group: this.groupType, }; const url = taskApi.taskReport.sortgroup; this.httpService .postRequest(url, payload) .then((res) => { this.listItem = res.data; // console.log("listItem:", res.data); }) .finally(() => { return "SortingTasksAdmin"; }); }, showchart(value) { if (!value) { this.showChart = true; this.showcomponent = false; this.getvalueChartDonut(); return "PieDonut"; } else { this.showChart = false; this.showcomponent = true; } }, getvalueChartDonut() { let payload = { users_id: this.allUserId, year: this.selectedYear, month: this.selectedMonth, }; let url = taskApi.taskChart.donut; var vm = this; this.httpService.postRequest(url, payload).then((res) => { // console.log("chart", res.data); vm.dataPie = []; res.data.forEach((element) => { vm.dataPie.push({ y: element.Percent, name: element.category, // color: colors[5], drilldown: { categories: [element.category], data: [element.Total], }, }); }); }); }, }, components: { UsersSearch: () => import( "@admin/components/UsersSearch" ), TeamForm: () => import( "@task/components/TeamForm"), SortingTasksAdmin: () => import( "@task/components/SortingTasksAdmin" ), SortingByDayTasksAdmin: () => import( "@task/components/SortingByDayTasksAdmin" ), PieDonut: () => import("@components/charts/PieDonut.vue"), SwitchComponent: () => import("@components/SwitchComponent.vue"), }, }; </script> <style lang="scss"> .task-system { .table-container { .table-responsive { height: calc(100vh + -15em) !important; .table { font-size: 1rem; } } } } </style> <style scoped lang="scss"> .form-control { border-radius: 0.5em; height: 2.5em; text-align: end; } // .side-panel { // padding: 1em; // width: 30em; // max-width: 100%; // background-color: #fafafa; // border-right: 1px solid #eee; // } // .pages-content-container { // margin-right: 6em; // } .selects { display: flex; // margin-right: 4em; } .all-selects { display: flex; width: 96%; } .select-teams { display: flex; align-items: center; // width: 13em; margin-top: 1em; } .teams-label { // min-width: 3em; margin-top: 0.5em; position: relative; top: 1.4em; font-size: 0.8em; right: 1em; background-color: white; z-index: 99; } .teams-label-Grouping { // min-width: 5em; width: 47%; margin-top: 0.5em; position: relative; bottom: 1.3em; font-size: 0.8em; right: 6em; background-color: white; z-index: 99; } .card-header, .card { border-radius: 0.25em !important; } .card-body { border-bottom: 1px rgb(223 223 223) solid; font-size: 0.9rem; } .component { padding-left: 5em !important; z-index: 99; } .btn-start { margin-top: 2em; margin-right: 1em; } .form-control{ width: 6em; } </style>