Added Permission Check Function
This commit is contained in:
parent
660f994036
commit
f0185dc7d5
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -34,3 +34,4 @@ coverage
|
|||
|
||||
# Vitest
|
||||
__screenshots__/
|
||||
config.json
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"ENVIRONMENT": "PRODUCTION || DEVELOPMENT",
|
||||
"PAGE_TITLE": "Dolphin",
|
||||
"PAGE_TITLE_LOGO": "http://localhost:3000/img/Dolphin/dolphinfav.ico",
|
||||
"PAGE_TITLE_LOGO": "/img/Dolphin/dolphinfav.ico",
|
||||
"CLIENT_NAME": "Mavorion Systems",
|
||||
"CLIENT_LOGO": "",
|
||||
"CLIENT_LOCATION": "LAZIMPAT",
|
||||
"API_BASE_URL": "http://localhost:8000/api/"
|
||||
"CLIENT_LOGO": "",
|
||||
"API_BASE_URL": "http://localhost:8000/api/v1/"
|
||||
}
|
||||
|
|
|
|||
124
src/core/app/sidebarItems.ts
Normal file
124
src/core/app/sidebarItems.ts
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
import type { SidebarItem } from "../types/app/sidebar.type";
|
||||
|
||||
const sidebarItems = (): SidebarItem[] => {
|
||||
return [
|
||||
{
|
||||
label: "Dashboard",
|
||||
},
|
||||
{
|
||||
label: "Dashboard",
|
||||
icon: "Home",
|
||||
to: "/",
|
||||
},
|
||||
{
|
||||
label: "Stock Verification",
|
||||
icon: "Blocks",
|
||||
children: [
|
||||
{
|
||||
label: "Opening Stock",
|
||||
to: "/stock-verification/opening-stock/",
|
||||
},
|
||||
{
|
||||
label: "Closing Stock",
|
||||
to: "/stock-verification/closing-stock/",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Components",
|
||||
},
|
||||
{
|
||||
label: "Content Layout",
|
||||
icon: "Package",
|
||||
to: "/component/content-layout",
|
||||
},
|
||||
{
|
||||
label: "Modal",
|
||||
icon: "MessageSquareCode",
|
||||
to: "/component/modal",
|
||||
},
|
||||
{
|
||||
label: "Switch",
|
||||
icon: "ToggleLeft",
|
||||
to: "/component/switch",
|
||||
},
|
||||
{
|
||||
label: "Toggle",
|
||||
icon: "ToggleRight",
|
||||
to: "/component/toggle",
|
||||
},
|
||||
{
|
||||
label: "Tabulator",
|
||||
icon: "Table",
|
||||
to: "/component/tabulator",
|
||||
},
|
||||
{
|
||||
label: "Towser",
|
||||
icon: "Blinds",
|
||||
to: "/component/towser",
|
||||
},
|
||||
{
|
||||
label: "Date Range",
|
||||
icon: "CalendarRange",
|
||||
to: "/component/date-range",
|
||||
},
|
||||
{
|
||||
label: "Date Selector",
|
||||
icon: "Calendar",
|
||||
to: "/component/date-selector",
|
||||
},
|
||||
{
|
||||
label: "Wizard Stepper",
|
||||
icon: "WandSparkles",
|
||||
to: "/component/wizard",
|
||||
},
|
||||
{
|
||||
label: "Loader",
|
||||
icon: "Loader",
|
||||
to: "/component/loader",
|
||||
},
|
||||
{
|
||||
label: "Directives",
|
||||
},
|
||||
{
|
||||
label: "Input Error",
|
||||
icon: "TriangleAlert",
|
||||
to: "/directives/input-error",
|
||||
},
|
||||
{
|
||||
label: "Input Currency",
|
||||
icon: "CircleDollarSign",
|
||||
to: "/directives/input-currency",
|
||||
},
|
||||
{
|
||||
label: "Input Select",
|
||||
icon: "TextCursorInput",
|
||||
to: "/directives/input-select",
|
||||
},
|
||||
{
|
||||
label: "Tooltip",
|
||||
icon: "BookOpenText",
|
||||
to: "/directives/tooltip",
|
||||
},
|
||||
{
|
||||
label: "CSS",
|
||||
},
|
||||
{
|
||||
label: "Buttons",
|
||||
icon: "SquareArrowLeft",
|
||||
to: "/css/button",
|
||||
},
|
||||
{
|
||||
label: "Input",
|
||||
icon: "TextCursor",
|
||||
to: "/css/input",
|
||||
},
|
||||
{
|
||||
label: "Font",
|
||||
icon: "CaseSensitive",
|
||||
to: "/css/font",
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export default sidebarItems;
|
||||
|
|
@ -4,8 +4,10 @@ export type SidebarItem = {
|
|||
label: string;
|
||||
to?: RouteLocationRaw;
|
||||
icon?: string;
|
||||
isVisible?: boolean;
|
||||
children?: {
|
||||
label: string;
|
||||
to: RouteLocationRaw;
|
||||
isVisible?: boolean;
|
||||
}[];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,5 +11,7 @@ export interface UserDetails {
|
|||
email: string;
|
||||
phone: number | null;
|
||||
department: string | null;
|
||||
isSuperUser: boolean;
|
||||
roles: [];
|
||||
permissions: string[];
|
||||
}
|
||||
|
|
|
|||
39
src/core/utils/permission.util.ts
Normal file
39
src/core/utils/permission.util.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { useAuth } from "@/stores/Auth/auth.store";
|
||||
import { storeToRefs } from "pinia";
|
||||
|
||||
export const hasPermission = (
|
||||
permission: string | undefined | null | Array<string>,
|
||||
requireAll: boolean = true,
|
||||
allowSuperUser: boolean = true
|
||||
) => {
|
||||
const authStore = useAuth();
|
||||
const { user } = storeToRefs(authStore);
|
||||
|
||||
if (user.value && user.value.isSuperUser && allowSuperUser) {
|
||||
return true;
|
||||
}
|
||||
const p = new Set(user.value.permissions);
|
||||
|
||||
if (!p) return false;
|
||||
if (!permission) return true;
|
||||
if (Array.isArray(permission)) {
|
||||
if (requireAll) {
|
||||
return permission.every((perm) => p.has(perm));
|
||||
} else {
|
||||
return permission.some((perm) => p.has(perm));
|
||||
}
|
||||
}
|
||||
|
||||
return p?.has(permission);
|
||||
};
|
||||
|
||||
export const isSuperUser = () => {
|
||||
const authStore = useAuth();
|
||||
const { user } = storeToRefs(authStore);
|
||||
|
||||
if (user.value && user.value.isSuperUser) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
<div class="app-container" :class="coreStore.isSidebarOpen ? 'sidebar-open' : 'sidebar-close'">
|
||||
<Header></Header>
|
||||
<div class="body-container">
|
||||
<Sidebar :sidebarItems="sidebarItems"></Sidebar>
|
||||
<Sidebar></Sidebar>
|
||||
<div class="main-container">
|
||||
<div class="relative">
|
||||
<RouterView />
|
||||
|
|
@ -19,130 +19,4 @@ import Header from "./components/Header.vue";
|
|||
import { useCore } from "@/stores/App/core.store";
|
||||
|
||||
const coreStore = useCore();
|
||||
|
||||
import type { SidebarItem } from "@/core/types/app/sidebar.type";
|
||||
|
||||
const sidebarItems: SidebarItem[] = [
|
||||
{
|
||||
label: "Dashboard",
|
||||
},
|
||||
{
|
||||
label: "Dashboard",
|
||||
icon: "Home",
|
||||
to: "/",
|
||||
},
|
||||
{
|
||||
label: "Stock Verification",
|
||||
icon: "Blocks",
|
||||
children: [
|
||||
{
|
||||
label: "Opening Stock",
|
||||
to: "/stock-verification/opening-stock/",
|
||||
},
|
||||
{
|
||||
label: "Closing Stock",
|
||||
to: "/stock-verification/closing-stock/",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Components",
|
||||
},
|
||||
{
|
||||
label: "Content Layout",
|
||||
icon: "Package",
|
||||
to: "/component/content-layout",
|
||||
},
|
||||
{
|
||||
label: "Modal",
|
||||
icon: "MessageSquareCode",
|
||||
to: "/component/modal",
|
||||
},
|
||||
{
|
||||
label: "Switch",
|
||||
icon: "ToggleLeft",
|
||||
to: "/component/switch",
|
||||
},
|
||||
{
|
||||
label: "Toggle",
|
||||
icon: "ToggleRight",
|
||||
to: "/component/toggle",
|
||||
},
|
||||
{
|
||||
label: "Tabulator",
|
||||
icon: "Table",
|
||||
to: "/component/tabulator",
|
||||
},
|
||||
{
|
||||
label: "Towser",
|
||||
icon: "Blinds",
|
||||
to: "/component/towser",
|
||||
},
|
||||
{
|
||||
label: "Date Range",
|
||||
icon: "CalendarRange",
|
||||
to: "/component/date-range",
|
||||
},
|
||||
{
|
||||
label: "Date Selector",
|
||||
icon: "Calendar",
|
||||
to: "/component/date-selector",
|
||||
},
|
||||
{
|
||||
label: "Wizard Stepper",
|
||||
icon: "WandSparkles",
|
||||
to: "/component/wizard",
|
||||
},
|
||||
{
|
||||
label: "Loader",
|
||||
icon: "Loader",
|
||||
to: "/component/loader",
|
||||
},
|
||||
// {
|
||||
// label: "ImageCropper Upload",
|
||||
// icon: "Crop",
|
||||
// to: "/component/image-cropper",
|
||||
// },
|
||||
{
|
||||
label: "Directives",
|
||||
},
|
||||
{
|
||||
label: "Input Error",
|
||||
icon: "TriangleAlert",
|
||||
to: "/directives/input-error",
|
||||
},
|
||||
{
|
||||
label: "Input Currency",
|
||||
icon: "CircleDollarSign",
|
||||
to: "/directives/input-currency",
|
||||
},
|
||||
{
|
||||
label: "Input Select",
|
||||
icon: "TextCursorInput",
|
||||
to: "/directives/input-select",
|
||||
},
|
||||
{
|
||||
label: "Tooltip",
|
||||
icon: "BookOpenText",
|
||||
to: "/directives/tooltip",
|
||||
},
|
||||
{
|
||||
label: "CSS",
|
||||
},
|
||||
{
|
||||
label: "Buttons",
|
||||
icon: "SquareArrowLeft",
|
||||
to: "/css/button",
|
||||
},
|
||||
{
|
||||
label: "Input",
|
||||
icon: "TextCursor",
|
||||
to: "/css/input",
|
||||
},
|
||||
{
|
||||
label: "Font",
|
||||
icon: "CaseSensitive",
|
||||
to: "/css/font",
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
class="w-[42px] h-[42px] object-cover rounded-full"
|
||||
/>
|
||||
</span>
|
||||
<span v-else class="h-[38px] my-auto text-[28px]">
|
||||
<span v-else class="h-[38px] my-auto text-[24px]">
|
||||
{{ getNameInitials(user.full_name ? user.full_name : user.username) }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getNameInitials } from "@/core/utils/Common";
|
||||
import { getNameInitials } from "@/core/utils/common.util";
|
||||
import { useAuth } from "@/stores/Auth/auth.store";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
|
|
|
|||
|
|
@ -7,13 +7,16 @@
|
|||
<Icons name="TextAlignJustify" size="30" />
|
||||
</button>
|
||||
<div class="sidebar-items">
|
||||
<div v-for="(item, index) in sidebarItems">
|
||||
<div class="sidebar-header" v-if="!item.to && !item.children">
|
||||
<div v-for="(item, index) in SidebarItems">
|
||||
<div
|
||||
class="sidebar-header"
|
||||
v-if="!item.to && !item.children && (item.isVisible != undefined ? item.isVisible : true)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<RouterLink
|
||||
:to="item.to"
|
||||
v-if="item.to && !item.children"
|
||||
v-if="item.to && !item.children && (item.isVisible != undefined ? item.isVisible : true)"
|
||||
class="sidebar-default"
|
||||
:class="isActive(item) ? 'sidebar-item-active' : ''"
|
||||
@click="isActive(item) ? toggleDropdown(-1) : null"
|
||||
|
|
@ -24,7 +27,7 @@
|
|||
<span>{{ item.label }}</span>
|
||||
</RouterLink>
|
||||
<div
|
||||
v-if="item.children && !item.to"
|
||||
v-if="item.children && !item.to && (item.isVisible != undefined ? item.isVisible : true)"
|
||||
class="sidebar-dropdown"
|
||||
:class="activeDropdown == index ? 'sidebar-item-open' : ''"
|
||||
>
|
||||
|
|
@ -40,8 +43,11 @@
|
|||
|
||||
<div class="sidebar-dropdown-items" v-animate-dropdown>
|
||||
<div class="sidebar-dropdown-item" v-for="childitem in item.children">
|
||||
<!-- v-if="childitem.permission ? hasPermission(childitem.permission) : true" -->
|
||||
<RouterLink :to="childitem.to" :class="isActive(childitem) ? 'sidebar-item-active' : ''">
|
||||
<RouterLink
|
||||
:to="childitem.to"
|
||||
:class="isActive(childitem) ? 'sidebar-item-active' : ''"
|
||||
v-if="childitem.isVisible != undefined ? childitem.isVisible : true"
|
||||
>
|
||||
<span>{{ childitem.label }}</span>
|
||||
</RouterLink>
|
||||
</div>
|
||||
|
|
@ -53,20 +59,16 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, type PropType, ref } from "vue";
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import type { SidebarItem } from "@/core/types/app/sidebar.type";
|
||||
import { useCore } from "@/stores/App/core.store";
|
||||
import sidebarItems from "@/core/app/sidebarItems";
|
||||
|
||||
const router = useRouter();
|
||||
const coreStore = useCore();
|
||||
|
||||
const props = defineProps({
|
||||
sidebarItems: {
|
||||
type: Array as PropType<SidebarItem[]>,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
const SidebarItems = computed(() => sidebarItems());
|
||||
|
||||
const activeDropdown = ref(-1);
|
||||
|
||||
|
|
@ -89,12 +91,12 @@ onMounted(() => {
|
|||
});
|
||||
|
||||
const checkDropDown = () => {
|
||||
if (props.sidebarItems) {
|
||||
props.sidebarItems.forEach((item) => {
|
||||
if (SidebarItems.value) {
|
||||
SidebarItems.value.forEach((item) => {
|
||||
if (item.children && !item.to) {
|
||||
item.children.forEach((child) => {
|
||||
if (child.to == router.currentRoute.value.path) {
|
||||
toggleDropdown(props.sidebarItems.indexOf(item));
|
||||
toggleDropdown(SidebarItems.value.indexOf(item));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user