2025-02-01 09:34:55 +00:00
|
|
|
|
<template>
|
2025-02-20 06:22:41 +00:00
|
|
|
|
<NuxtLayout name="default" :menu="adminMenu">
|
|
|
|
|
<div class="pages role-page px-3 pb-0 pt-2">
|
|
|
|
|
<sub-header-with-select
|
|
|
|
|
canCreate="roles_new"
|
|
|
|
|
@open-form="toggleRolesPanel"
|
|
|
|
|
:showProjectSelect="$attrs.showProjectSelect"
|
|
|
|
|
title="نقش ها"
|
|
|
|
|
></sub-header-with-select>
|
2025-02-01 09:34:55 +00:00
|
|
|
|
|
2025-02-20 06:22:41 +00:00
|
|
|
|
<div class="pages-content pb-0 pt-2">
|
|
|
|
|
<template v-if="canView">
|
|
|
|
|
<my-table
|
|
|
|
|
:tableActions="tableActions"
|
|
|
|
|
height="auto"
|
|
|
|
|
maxHeight="calc(100vh - 9em)"
|
|
|
|
|
class="my-table"
|
|
|
|
|
ref="rolesTable"
|
|
|
|
|
:hasSearch="false"
|
|
|
|
|
:paginationInfo="pagination"
|
|
|
|
|
:sortingInfo="sorting"
|
|
|
|
|
:items="roles"
|
|
|
|
|
:fetchingData="fetchingData"
|
|
|
|
|
:tableColumns="tableColumns"
|
|
|
|
|
:totalPages="pagination.pages"
|
|
|
|
|
@delete-table-item="deleteItem"
|
|
|
|
|
@edit-table-item="toggleRolesPanel"
|
|
|
|
|
@page-changed="pageChanged"
|
|
|
|
|
@page-limit-changed="pageLimitChanged"
|
|
|
|
|
@sort-changed="sortChanged"
|
|
|
|
|
></my-table>
|
|
|
|
|
</template>
|
|
|
|
|
<NoData v-else>
|
|
|
|
|
<the-content-loading v-if="fetchingData"></the-content-loading>
|
2025-02-01 09:34:55 +00:00
|
|
|
|
|
2025-02-20 06:22:41 +00:00
|
|
|
|
<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>
|
|
|
|
|
عدم دسترسی
|
2025-02-01 09:34:55 +00:00
|
|
|
|
</div>
|
2025-02-20 06:22:41 +00:00
|
|
|
|
</div>
|
|
|
|
|
</NoData>
|
|
|
|
|
<div class="side-panel" v-if="showPanel">
|
|
|
|
|
<div class="side-panel-header">
|
|
|
|
|
<h6 class="">مدیریت نقش ها</h6>
|
|
|
|
|
</div>
|
2025-02-01 09:34:55 +00:00
|
|
|
|
|
2025-02-20 06:22:41 +00:00
|
|
|
|
<div class="side-panel-content">
|
|
|
|
|
<form class="section-form" role="section" @submit.prevent="save()">
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
<label for="title">عنوان نقش</label>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
class="form-control"
|
|
|
|
|
id="title"
|
|
|
|
|
name="title"
|
|
|
|
|
v-model="selectedItemClone.title"
|
|
|
|
|
/>
|
2025-02-01 09:34:55 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
2025-02-20 06:22:41 +00:00
|
|
|
|
<div class="side-panel-footer mt-4">
|
|
|
|
|
<div>
|
|
|
|
|
<button
|
|
|
|
|
type="submit"
|
|
|
|
|
class="btn btn-outline-primary"
|
|
|
|
|
:disabled="loading"
|
|
|
|
|
@click.prevent="save()"
|
|
|
|
|
>
|
|
|
|
|
<the-button-loading
|
|
|
|
|
v-if="loading"
|
|
|
|
|
:style="{ transform: 'scale(0.5)' }"
|
|
|
|
|
></the-button-loading>
|
|
|
|
|
ثبت
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
:disabled="loading"
|
|
|
|
|
@click.prevent="showPanel = false"
|
|
|
|
|
type="button"
|
|
|
|
|
class="btn btn-default"
|
|
|
|
|
data-dismiss="modal"
|
|
|
|
|
>
|
|
|
|
|
لغو
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<button
|
|
|
|
|
v-if="selectedItemClone.id"
|
|
|
|
|
@click="deleteItemHandler(selectedItemClone.id)"
|
|
|
|
|
title="حذف"
|
|
|
|
|
class="btn delete-btn btn-outline-danger"
|
|
|
|
|
type="button"
|
|
|
|
|
>
|
|
|
|
|
<svg class="icon icon-Component-295--1">
|
|
|
|
|
<use xlink:href="#icon-Component-295--1"></use>
|
|
|
|
|
</svg>
|
|
|
|
|
حذف
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
2025-02-01 09:34:55 +00:00
|
|
|
|
</div>
|
2025-02-20 06:22:41 +00:00
|
|
|
|
</form>
|
|
|
|
|
</div>
|
2025-02-01 09:34:55 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-02-20 06:22:41 +00:00
|
|
|
|
</NuxtLayout>
|
2025-02-01 09:34:55 +00:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import apis from "~/apis/permitApi";
|
|
|
|
|
import adminMenu from "~/json/admin/json/menu.json";
|
2025-02-20 06:22:41 +00:00
|
|
|
|
|
2025-02-01 09:34:55 +00:00
|
|
|
|
import { defineAsyncComponent } from "vue";
|
|
|
|
|
import { mapActions, mapState } from "pinia";
|
|
|
|
|
import { useCommonStore } from "~/stores/commonStore";
|
|
|
|
|
import { usePermitStore } from "~/stores/permitStore";
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: "Roles",
|
|
|
|
|
setup() {
|
|
|
|
|
definePageMeta({
|
|
|
|
|
name: "Roles",
|
|
|
|
|
layout: false,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
mounted() {
|
|
|
|
|
this.checkPermisionBeforGetList();
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.httpService = useNuxtApp()["$http"];
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
projectGetter() {
|
|
|
|
|
this.showPanel = false;
|
|
|
|
|
this.checkPermisionBeforGetList();
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
2025-02-20 06:22:41 +00:00
|
|
|
|
adminMenu: adminMenu,
|
2025-02-01 09:34:55 +00:00
|
|
|
|
httpService: {},
|
|
|
|
|
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",
|
|
|
|
|
can: "item-info_edit",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
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",
|
|
|
|
|
can: "item-list_delete",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
canView: false,
|
|
|
|
|
fetchingData: false,
|
|
|
|
|
tableColumns: [
|
|
|
|
|
{
|
|
|
|
|
isLink: true,
|
|
|
|
|
key: "title",
|
|
|
|
|
title: "عنوان",
|
|
|
|
|
width: "2",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
pagination: {
|
|
|
|
|
page: 1,
|
|
|
|
|
pages: 0,
|
|
|
|
|
total: 0,
|
|
|
|
|
offset: 0, // page * per_page
|
|
|
|
|
limit: 10, //per_page
|
|
|
|
|
},
|
|
|
|
|
sorting: {
|
|
|
|
|
sortby: "id",
|
|
|
|
|
sortorder: "asc", // asc | desc | none
|
|
|
|
|
},
|
|
|
|
|
roles: [],
|
|
|
|
|
loading: false,
|
|
|
|
|
showPanel: false,
|
|
|
|
|
selectedItemClone: {
|
|
|
|
|
title: "",
|
|
|
|
|
id: undefined,
|
|
|
|
|
// project_id: undefined,
|
|
|
|
|
},
|
|
|
|
|
prevSelectedItemIndex: undefined,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
// ...mapGetters("permit", ["projectGetter"]),
|
|
|
|
|
...mapState(usePermitStore, ["projectGetter"]),
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
// ...mapActions(["checkPermissions"]),
|
|
|
|
|
// ...mapMutations("permit", ["SET_PROJECT"]),
|
|
|
|
|
...mapActions(useCommonStore, ["checkPermissions"]),
|
|
|
|
|
...mapActions(usePermitStore, ["SET_PROJECT"]),
|
|
|
|
|
|
|
|
|
|
async getRoles() {
|
|
|
|
|
this.fetchingData = true;
|
|
|
|
|
const payload = {
|
|
|
|
|
// project_id: this.projectGetter?.id,
|
|
|
|
|
isown: 3,
|
|
|
|
|
...this.sorting,
|
|
|
|
|
...this.pagination,
|
|
|
|
|
};
|
2025-02-20 06:22:41 +00:00
|
|
|
|
return await this.httpService
|
|
|
|
|
.postRequest(permitUrl() + apis.roles.list, payload)
|
2025-02-01 09:34:55 +00:00
|
|
|
|
.then((res) => {
|
2025-02-20 06:22:41 +00:00
|
|
|
|
this.roles = res.data;
|
|
|
|
|
this.pagination = { ...this.pagination, ...res.pagination };
|
2025-02-01 09:34:55 +00:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
.finally(() => {
|
|
|
|
|
this.fetchingData = false;
|
|
|
|
|
this.changeDetectionCounter++;
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
save() {
|
2025-02-20 06:22:41 +00:00
|
|
|
|
const url = this.selectedItemClone.id ? apis.roles.edit : apis.roles.add;
|
2025-02-01 09:34:55 +00:00
|
|
|
|
|
2025-02-20 06:22:41 +00:00
|
|
|
|
this.httpService
|
|
|
|
|
.postRequest(permitUrl() + url, this.selectedItemClone)
|
|
|
|
|
.then((res) => {
|
|
|
|
|
this.getRoles();
|
2025-02-01 09:34:55 +00:00
|
|
|
|
|
2025-02-20 06:22:41 +00:00
|
|
|
|
mySwalToast({
|
|
|
|
|
title: "تبریک",
|
|
|
|
|
html: res.data.message,
|
|
|
|
|
icon: "success",
|
|
|
|
|
});
|
2025-02-01 09:34:55 +00:00
|
|
|
|
|
2025-02-20 06:22:41 +00:00
|
|
|
|
this.showPanel = false;
|
|
|
|
|
this.resetForm();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
deleteItemHandler(id) {
|
|
|
|
|
// const foundObject = this.roles.find(obj => obj.id === id);
|
|
|
|
|
const index = this.roles.findIndex((obj) => obj.id === id);
|
|
|
|
|
this.deleteItem(index);
|
2025-02-01 09:34:55 +00:00
|
|
|
|
},
|
|
|
|
|
deleteItem(index) {
|
2025-02-20 06:22:41 +00:00
|
|
|
|
|
|
|
|
|
// debugger
|
2025-02-01 09:34:55 +00:00
|
|
|
|
let sectionId = this.roles[index].id;
|
|
|
|
|
const data = {
|
|
|
|
|
// project_id: this.projectGetter?.id,
|
|
|
|
|
id: sectionId,
|
|
|
|
|
};
|
2025-02-20 06:22:41 +00:00
|
|
|
|
|
2025-02-01 09:34:55 +00:00
|
|
|
|
|
2025-02-20 06:22:41 +00:00
|
|
|
|
mySwalConfirm({
|
2025-02-01 09:34:55 +00:00
|
|
|
|
title: "هشدار",
|
|
|
|
|
html: "از حذف این بخش مطمئن هستید؟",
|
|
|
|
|
icon: "warning",
|
|
|
|
|
}).then((result) => {
|
|
|
|
|
if (result.isConfirmed) {
|
2025-02-20 06:22:41 +00:00
|
|
|
|
this.httpService
|
|
|
|
|
.postRequest(permitUrl() + apis.roles.delete, data)
|
|
|
|
|
.then((res) => {
|
|
|
|
|
this.getRoles();
|
2025-02-01 09:34:55 +00:00
|
|
|
|
|
2025-02-20 06:22:41 +00:00
|
|
|
|
mySwalToast({
|
|
|
|
|
title: "تبریک",
|
|
|
|
|
html: res.data.message,
|
|
|
|
|
icon: "success",
|
|
|
|
|
});
|
2025-02-01 09:34:55 +00:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
updateList() {
|
|
|
|
|
this.resetPagination();
|
|
|
|
|
this.getRoles();
|
|
|
|
|
},
|
|
|
|
|
resetPagination() {
|
|
|
|
|
this.pagination = {
|
|
|
|
|
pages: 0,
|
|
|
|
|
total: 0,
|
|
|
|
|
page: 1,
|
|
|
|
|
offset: 0,
|
|
|
|
|
limit: 10,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
pageLimitChanged(paging) {
|
|
|
|
|
this.resetPagination();
|
|
|
|
|
this.pagination.limit = paging.limit;
|
|
|
|
|
|
|
|
|
|
this.getRoles();
|
|
|
|
|
},
|
|
|
|
|
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.getRoles();
|
|
|
|
|
},
|
|
|
|
|
sortChanged(sorting) {
|
|
|
|
|
// keep limit status.
|
|
|
|
|
// reset page and offset values.
|
|
|
|
|
|
|
|
|
|
this.pagination.page = this.pagination.offset = 0;
|
|
|
|
|
this.sorting = sorting;
|
|
|
|
|
|
|
|
|
|
this.getRoles();
|
|
|
|
|
},
|
|
|
|
|
toggleRolesPanel(index = undefined) {
|
2025-02-20 06:22:41 +00:00
|
|
|
|
|
2025-02-01 09:34:55 +00:00
|
|
|
|
if (index !== undefined) {
|
|
|
|
|
if (this.prevSelectedItemIndex !== undefined)
|
|
|
|
|
this.roles[this.prevSelectedItemIndex].active = false;
|
|
|
|
|
|
|
|
|
|
this.prevSelectedItemIndex = index;
|
|
|
|
|
this.roles[index].active = true;
|
|
|
|
|
|
2025-02-20 06:22:41 +00:00
|
|
|
|
this.selectedItemClone = this.roles[index];
|
2025-02-01 09:34:55 +00:00
|
|
|
|
} else this.resetForm();
|
|
|
|
|
|
|
|
|
|
this.showPanel = true;
|
|
|
|
|
},
|
|
|
|
|
resetForm() {
|
|
|
|
|
this.selectedItemClone = {
|
|
|
|
|
title: "",
|
|
|
|
|
id: undefined,
|
|
|
|
|
// project_id: this.projectGetter?.id,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
checkPermisionBeforGetList() {
|
|
|
|
|
if (this.fetchingData) return;
|
|
|
|
|
this.fetchingData = true;
|
|
|
|
|
|
|
|
|
|
this.checkPermissions({ permission: "roles_view", _this: this })
|
|
|
|
|
.then(() => {
|
|
|
|
|
if (this.projectGetter) {
|
|
|
|
|
this.getRoles()
|
|
|
|
|
.then(() => {
|
|
|
|
|
this.canView = true;
|
|
|
|
|
this.fetchingData = false;
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
this.canView = false;
|
|
|
|
|
this.fetchingData = false;
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.getProjects().then(() => {
|
|
|
|
|
this.getRoles()
|
|
|
|
|
.then(() => {
|
|
|
|
|
this.canView = true;
|
|
|
|
|
this.fetchingData = false;
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
this.canView = false;
|
|
|
|
|
this.fetchingData = false;
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
this.canView = false;
|
|
|
|
|
this.fetchingData = false;
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
async getProjects() {
|
2025-02-20 06:22:41 +00:00
|
|
|
|
return await this.httpService
|
|
|
|
|
.postRequest(permitUrl() + apis.projects.list)
|
|
|
|
|
.then((res) => {
|
|
|
|
|
console.log(
|
|
|
|
|
"🚀 ~ returnawaitthis.httpService.postRequest ~ res:",
|
|
|
|
|
res
|
|
|
|
|
);
|
|
|
|
|
this.SET_PROJECT(res.data[0]);
|
|
|
|
|
});
|
2025-02-01 09:34:55 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
components: {
|
|
|
|
|
// SubHeaderWithSelect: defineAsyncComponent(() =>
|
|
|
|
|
// import("@/components/global/SubHeaderWithSelect.vue")
|
|
|
|
|
// ),
|
|
|
|
|
// TheContentLoading: defineAsyncComponent(() =>
|
|
|
|
|
// import("@/components/global/TheContentLoading.vue")
|
|
|
|
|
// ),
|
|
|
|
|
// MyTable: defineAsyncComponent(() =>
|
|
|
|
|
// import("@/components/global/MyTable.vue")
|
|
|
|
|
// ),
|
|
|
|
|
// NoData: defineAsyncComponent(() =>
|
|
|
|
|
// import("@/components/global/NoData.vue")
|
|
|
|
|
// ),
|
|
|
|
|
// TheButtonLoading: defineAsyncComponent(() =>
|
|
|
|
|
// import("@/components/global/TheButtonLoading.vue")
|
|
|
|
|
// ),
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
<style scoped lang="scss"></style>
|