DONE: layout letter with letterhead and footer, notification for newly...

This commit is contained in:
ISMAIL MASSERAN
2026-06-28 02:16:49 +00:00
parent 94ecbe5887
commit 034ecf947f
400 changed files with 29802 additions and 5446 deletions
+14
View File
@@ -0,0 +1,14 @@
import { computed, type ComputedRef } from 'vue'
import type { MenuList } from '@/core/utils/filterMenuByPermission'
import { filterMenuByPermission } from '@/core/utils/filterMenuByPermission'
import { usePermissions } from './usePermissions'
export function useFilteredMenu(menu: MenuList): ComputedRef<MenuList> {
const { activeRolePermissions, hasPermission } = usePermissions()
return computed(() => {
void activeRolePermissions.value
return filterMenuByPermission(menu, hasPermission)
})
}
+45
View File
@@ -0,0 +1,45 @@
import { computed } from 'vue'
import {
getActiveRolePermissions,
hasActiveRolePermission,
hasAnyActiveRolePermission,
} from '@/core/utils/activeRolePermission'
import { useAuthStore } from '@/stores/auth'
import type { AuthPermission } from '@/modules/auth/types/auth.types'
const DEVELOPER_ROLE = 'DEVELOPER'
export function usePermissions() {
const authStore = useAuthStore()
const activeRolePermissions = computed<AuthPermission[]>(() =>
getActiveRolePermissions(authStore.user, authStore.activeRole),
)
const isDeveloper = computed(
() => authStore.activeRole?.name === DEVELOPER_ROLE,
)
function hasPermission(permission: string): boolean {
return hasActiveRolePermission(
authStore.user,
authStore.activeRole,
permission,
)
}
function hasAnyPermission(permissions: string[]): boolean {
return hasAnyActiveRolePermission(
authStore.user,
authStore.activeRole,
permissions,
)
}
return {
activeRolePermissions,
hasPermission,
hasAnyPermission,
isDeveloper,
}
}
+4 -23
View File
@@ -59,28 +59,9 @@ export function useRoleSwitcher() {
return
}
const nextRoleLabel = availableRoles.value.find((r) => r.id === nextRoleId)?.name
const currentRoleLabel = authStore.activeRole?.name
const result = await Swal.fire({
title: 'Tukar peranan?',
text: `Anda akan bertukar daripada "${currentRoleLabel}" kepada "${nextRoleLabel}".`,
icon: 'question',
showCancelButton: true,
confirmButtonText: 'Ya, bertukar',
cancelButtonText: 'Batal',
reverseButtons: true,
})
if (!result.isConfirmed) {
roleComboValue.value = authStore.activeRole?.id ? [authStore.activeRole.id] : ['']
selectedRoleId.value = authStore.activeRole?.id ?? ''
return
}
roleComboValue.value = [nextRoleId]
selectedRoleId.value = nextRoleId
await onSwitchRole()
await onSwitchRole(nextRoleId)
}
const onRoleInputValueChange = ({ inputValue }: { inputValue: string }) => {
@@ -94,12 +75,12 @@ export function useRoleSwitcher() {
roleOptions.value = filtered.length > 0 ? filtered : all
}
const onSwitchRole = async () => {
if (!selectedRoleId.value || selectedRoleId.value === authStore.activeRole?.id) return
const onSwitchRole = async (roleId: string) => {
if (!roleId || roleId === authStore.activeRole?.id) return
switchingRole.value = true
try {
const res = await authStore.switchRole(selectedRoleId.value)
const res = await authStore.switchRole(roleId)
await Swal.fire({
toast: true,