refactor: replace hardcoded sidebar menu items with a dynamic configuration array and automated rendering logic
This commit is contained in:
parent
869866beaf
commit
bd38bbb74e
@ -1,7 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Link, usePage } from '@inertiajs/vue3';
|
import { Link, usePage } from '@inertiajs/vue3';
|
||||||
import { Banknote, CalendarDays, Clock, FolderTree, History, Layers, LayoutDashboard, Package, Receipt, Scissors, Settings2, ShoppingBag, ShoppingCart, User, UserCheck, Users, Wallet, WalletCards } from '@lucide/vue';
|
import { Banknote, CalendarDays, Clock, FolderTree, History, Layers, LayoutDashboard, Package, Receipt, Scissors, Settings2, ShoppingBag, ShoppingCart, User, UserCheck, Users, Wallet, WalletCards } from '@lucide/vue';
|
||||||
import { computed } from 'vue';
|
|
||||||
import {
|
import {
|
||||||
Sidebar,
|
Sidebar,
|
||||||
SidebarContent,
|
SidebarContent,
|
||||||
@ -19,34 +18,68 @@ import { useCan } from '@/composables/useCan';
|
|||||||
const page = usePage();
|
const page = usePage();
|
||||||
const { can } = useCan();
|
const { can } = useCan();
|
||||||
|
|
||||||
const isDashboardActive = computed(() => page.url.startsWith('/admin/dashboard'));
|
interface MenuItem {
|
||||||
const isEmployeesActive = computed(() => page.url.startsWith('/admin/hr/employees'));
|
title: string;
|
||||||
const isAttendancesActive = computed(() => page.url.startsWith('/admin/hr/attendances'));
|
href: string;
|
||||||
const isLeaveRequestsActive = computed(() => page.url.startsWith('/admin/hr/leave-requests'));
|
icon: any;
|
||||||
const showHrMenu = computed(() => can('employees.view') || can('attendances.view') || can('leave-requests.view'));
|
permission?: string;
|
||||||
const isCategoriesActive = computed(() => page.url.startsWith('/admin/master/categories'));
|
}
|
||||||
const isProductsActive = computed(() => page.url.startsWith('/admin/master/products'));
|
|
||||||
const isRawMaterialsActive = computed(() => page.url.startsWith('/admin/master/raw-materials'));
|
interface MenuGroup {
|
||||||
const isSuppliersActive = computed(() => page.url.startsWith('/admin/master/suppliers'));
|
label: string;
|
||||||
const isCustomersActive = computed(() => page.url.startsWith('/admin/master/customers'));
|
items: MenuItem[];
|
||||||
const isPurchasesActive = computed(() => page.url.startsWith('/admin/manage/purchases'));
|
}
|
||||||
const isOrdersActive = computed(() => page.url.startsWith('/admin/manage/orders'));
|
|
||||||
const isCuttingsActive = computed(() => page.url.startsWith('/admin/manage/cuttings'));
|
const menuGroups: MenuGroup[] = [
|
||||||
const showManageMenu = computed(() => can('purchases.view') || can('orders.view') || can('cuttings.view'));
|
{
|
||||||
const isCashActive = computed(() => page.url.startsWith('/admin/finance/cash'));
|
label: 'Menu',
|
||||||
const isExpensesActive = computed(() => page.url.startsWith('/admin/finance/expenses'));
|
items: [
|
||||||
const isEmployeeAdvancesActive = computed(() => page.url.startsWith('/admin/finance/employee-advances'));
|
{ title: 'Dashboard', href: '/admin/dashboard', icon: LayoutDashboard },
|
||||||
const isPayrollActive = computed(() => page.url.startsWith('/admin/finance/payroll'));
|
],
|
||||||
const showFinanceMenu = computed(() => (
|
},
|
||||||
can('cash.view') || can('expenses.view') || can('employee-advances.view') || can('payroll.view')
|
{
|
||||||
));
|
label: 'Master',
|
||||||
const showMasterMenu = computed(() => (
|
items: [
|
||||||
can('categories.view') || can('products.view') || can('raw-materials.view')
|
{ title: 'Kategori', href: '/admin/master/categories', icon: FolderTree, permission: 'categories.view' },
|
||||||
|| can('suppliers.view') || can('customers.view')
|
{ title: 'Produk', href: '/admin/master/products', icon: Package, permission: 'products.view' },
|
||||||
));
|
{ title: 'Bahan Baku', href: '/admin/master/raw-materials', icon: Layers, permission: 'raw-materials.view' },
|
||||||
const isSettingActive = computed(() => page.url.startsWith('/admin/system/setting'));
|
{ title: 'Supplier', href: '/admin/master/suppliers', icon: User, permission: 'suppliers.view' },
|
||||||
const isActivityLogsActive = computed(() => page.url.startsWith('/admin/system/activity-logs'));
|
{ title: 'Customer', href: '/admin/master/customers', icon: UserCheck, permission: 'customers.view' },
|
||||||
const showSystemMenu = computed(() => can('settings.view') || can('activity-logs.view'));
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Kelola',
|
||||||
|
items: [
|
||||||
|
{ title: 'Belanja', href: '/admin/manage/purchases', icon: ShoppingBag, permission: 'purchases.view' },
|
||||||
|
{ title: 'Cutting', href: '/admin/manage/cuttings', icon: Scissors, permission: 'cuttings.view' },
|
||||||
|
{ title: 'Pesanan', href: '/admin/manage/orders', icon: ShoppingCart, permission: 'orders.view' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Keuangan',
|
||||||
|
items: [
|
||||||
|
{ title: 'Kas Toko', href: '/admin/finance/cash', icon: Wallet, permission: 'cash.view' },
|
||||||
|
{ title: 'Pengeluaran', href: '/admin/finance/expenses', icon: Receipt, permission: 'expenses.view' },
|
||||||
|
{ title: 'Kasbon', href: '/admin/finance/employee-advances', icon: Banknote, permission: 'employee-advances.view' },
|
||||||
|
{ title: 'Gaji', href: '/admin/finance/payroll', icon: WalletCards, permission: 'payroll.view' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'HR',
|
||||||
|
items: [
|
||||||
|
{ title: 'Pegawai', href: '/admin/hr/employees', icon: Users, permission: 'employees.view' },
|
||||||
|
{ title: 'Presensi', href: '/admin/hr/attendances', icon: Clock, permission: 'attendances.view' },
|
||||||
|
{ title: 'Cuti', href: '/admin/hr/leave-requests', icon: CalendarDays, permission: 'leave-requests.view' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Sistem',
|
||||||
|
items: [
|
||||||
|
{ title: 'Pengaturan', href: '/admin/system/setting', icon: Settings2, permission: 'settings.view' },
|
||||||
|
{ title: 'Log Aktivitas', href: '/admin/system/activity-logs', icon: History, permission: 'activity-logs.view' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -65,193 +98,31 @@ const showSystemMenu = computed(() => can('settings.view') || can('activity-logs
|
|||||||
</SidebarMenu>
|
</SidebarMenu>
|
||||||
</SidebarHeader>
|
</SidebarHeader>
|
||||||
<SidebarContent>
|
<SidebarContent>
|
||||||
<SidebarGroup>
|
<template v-for="group in menuGroups" :key="group.label">
|
||||||
<SidebarGroupLabel>Menu</SidebarGroupLabel>
|
<SidebarGroup v-if="group.items.some(item => !item.permission || can(item.permission))">
|
||||||
<SidebarGroupContent>
|
<SidebarGroupLabel>{{ group.label }}</SidebarGroupLabel>
|
||||||
<SidebarMenu>
|
<SidebarGroupContent>
|
||||||
<SidebarMenuItem>
|
<SidebarMenu>
|
||||||
<SidebarMenuButton as-child tooltip="Dashboard" :is-active="isDashboardActive">
|
<template v-for="item in group.items" :key="item.href">
|
||||||
<Link href="/admin/dashboard">
|
<SidebarMenuItem v-if="!item.permission || can(item.permission)">
|
||||||
<LayoutDashboard />
|
<SidebarMenuButton
|
||||||
<span>Dashboard</span>
|
as-child
|
||||||
</Link>
|
:tooltip="item.title"
|
||||||
</SidebarMenuButton>
|
:is-active="page.url.startsWith(item.href)"
|
||||||
</SidebarMenuItem>
|
>
|
||||||
</SidebarMenu>
|
<Link :href="item.href">
|
||||||
</SidebarGroupContent>
|
<component :is="item.icon" />
|
||||||
</SidebarGroup>
|
<span>{{ item.title }}</span>
|
||||||
<SidebarGroup v-if="showMasterMenu">
|
</Link>
|
||||||
<SidebarGroupLabel>Master</SidebarGroupLabel>
|
</SidebarMenuButton>
|
||||||
<SidebarGroupContent>
|
</SidebarMenuItem>
|
||||||
<SidebarMenu>
|
</template>
|
||||||
<SidebarMenuItem v-if="can('categories.view')">
|
</SidebarMenu>
|
||||||
<SidebarMenuButton as-child tooltip="Kategori" :is-active="isCategoriesActive">
|
</SidebarGroupContent>
|
||||||
<Link href="/admin/master/categories">
|
</SidebarGroup>
|
||||||
<FolderTree />
|
</template>
|
||||||
<span>Kategori</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
<SidebarMenuItem v-if="can('products.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Produk" :is-active="isProductsActive">
|
|
||||||
<Link href="/admin/master/products">
|
|
||||||
<Package />
|
|
||||||
<span>Produk</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
<SidebarMenuItem v-if="can('raw-materials.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Bahan Baku" :is-active="isRawMaterialsActive">
|
|
||||||
<Link href="/admin/master/raw-materials">
|
|
||||||
<Layers />
|
|
||||||
<span>Bahan Baku</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
<SidebarMenuItem v-if="can('suppliers.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Supplier" :is-active="isSuppliersActive">
|
|
||||||
<Link href="/admin/master/suppliers">
|
|
||||||
<User />
|
|
||||||
<span>Supplier</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
<SidebarMenuItem v-if="can('customers.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Customer" :is-active="isCustomersActive">
|
|
||||||
<Link href="/admin/master/customers">
|
|
||||||
<UserCheck />
|
|
||||||
<span>Customer</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
</SidebarMenu>
|
|
||||||
</SidebarGroupContent>
|
|
||||||
</SidebarGroup>
|
|
||||||
<SidebarGroup v-if="showManageMenu">
|
|
||||||
<SidebarGroupLabel>Kelola</SidebarGroupLabel>
|
|
||||||
<SidebarGroupContent>
|
|
||||||
<SidebarMenu>
|
|
||||||
<SidebarMenuItem v-if="can('purchases.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Belanja" :is-active="isPurchasesActive">
|
|
||||||
<Link href="/admin/manage/purchases">
|
|
||||||
<ShoppingBag />
|
|
||||||
<span>Belanja</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
<SidebarMenuItem v-if="can('orders.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Pesanan" :is-active="isOrdersActive">
|
|
||||||
<Link href="/admin/manage/orders">
|
|
||||||
<ShoppingCart />
|
|
||||||
<span>Pesanan</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
<SidebarMenuItem v-if="can('cuttings.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Cutting" :is-active="isCuttingsActive">
|
|
||||||
<Link href="/admin/manage/cuttings">
|
|
||||||
<Scissors />
|
|
||||||
<span>Cutting</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
</SidebarMenu>
|
|
||||||
</SidebarGroupContent>
|
|
||||||
</SidebarGroup>
|
|
||||||
<SidebarGroup v-if="showFinanceMenu">
|
|
||||||
<SidebarGroupLabel>Keuangan</SidebarGroupLabel>
|
|
||||||
<SidebarGroupContent>
|
|
||||||
<SidebarMenu>
|
|
||||||
<SidebarMenuItem v-if="can('cash.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Kas Toko" :is-active="isCashActive">
|
|
||||||
<Link href="/admin/finance/cash">
|
|
||||||
<Wallet />
|
|
||||||
<span>Kas Toko</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
<SidebarMenuItem v-if="can('expenses.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Pengeluaran" :is-active="isExpensesActive">
|
|
||||||
<Link href="/admin/finance/expenses">
|
|
||||||
<Receipt />
|
|
||||||
<span>Pengeluaran</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
<SidebarMenuItem v-if="can('employee-advances.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Kasbon" :is-active="isEmployeeAdvancesActive">
|
|
||||||
<Link href="/admin/finance/employee-advances">
|
|
||||||
<Banknote />
|
|
||||||
<span>Kasbon</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
<SidebarMenuItem v-if="can('payroll.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Gaji" :is-active="isPayrollActive">
|
|
||||||
<Link href="/admin/finance/payroll">
|
|
||||||
<WalletCards />
|
|
||||||
<span>Gaji</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
</SidebarMenu>
|
|
||||||
</SidebarGroupContent>
|
|
||||||
</SidebarGroup>
|
|
||||||
<SidebarGroup v-if="showHrMenu">
|
|
||||||
<SidebarGroupLabel>HR</SidebarGroupLabel>
|
|
||||||
<SidebarGroupContent>
|
|
||||||
<SidebarMenu>
|
|
||||||
<SidebarMenuItem v-if="can('employees.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Pegawai" :is-active="isEmployeesActive">
|
|
||||||
<Link href="/admin/hr/employees">
|
|
||||||
<Users />
|
|
||||||
<span>Pegawai</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
<SidebarMenuItem v-if="can('attendances.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Presensi" :is-active="isAttendancesActive">
|
|
||||||
<Link href="/admin/hr/attendances">
|
|
||||||
<Clock />
|
|
||||||
<span>Presensi</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
<SidebarMenuItem v-if="can('leave-requests.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Cuti" :is-active="isLeaveRequestsActive">
|
|
||||||
<Link href="/admin/hr/leave-requests">
|
|
||||||
<CalendarDays />
|
|
||||||
<span>Cuti</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
</SidebarMenu>
|
|
||||||
</SidebarGroupContent>
|
|
||||||
</SidebarGroup>
|
|
||||||
<SidebarGroup v-if="showSystemMenu">
|
|
||||||
<SidebarGroupLabel>Sistem</SidebarGroupLabel>
|
|
||||||
<SidebarGroupContent>
|
|
||||||
<SidebarMenu>
|
|
||||||
<SidebarMenuItem v-if="can('settings.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Pengaturan" :is-active="isSettingActive">
|
|
||||||
<Link href="/admin/system/setting">
|
|
||||||
<Settings2 />
|
|
||||||
<span>Pengaturan</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
<SidebarMenuItem v-if="can('activity-logs.view')">
|
|
||||||
<SidebarMenuButton as-child tooltip="Log Aktivitas" :is-active="isActivityLogsActive">
|
|
||||||
<Link href="/admin/system/activity-logs">
|
|
||||||
<History />
|
|
||||||
<span>Log Aktivitas</span>
|
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
</SidebarMenu>
|
|
||||||
</SidebarGroupContent>
|
|
||||||
</SidebarGroup>
|
|
||||||
</SidebarContent>
|
</SidebarContent>
|
||||||
<SidebarRail />
|
<SidebarRail />
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user