73a32380e7
NPM Installation / build (16.x, ubuntu-latest) (push) Has been cancelled
NPM Installation / build (16.x, windows-latest) (push) Has been cancelled
NPM Installation / build (17.x, ubuntu-latest) (push) Has been cancelled
NPM Installation / build (17.x, windows-latest) (push) Has been cancelled
NPM Installation / build (18.x, ubuntu-latest) (push) Has been cancelled
NPM Installation / build (18.x, windows-latest) (push) Has been cancelled
101 lines
2.3 KiB
JavaScript
101 lines
2.3 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import { getMyMenus } from '@/services/menuService'
|
|
|
|
let pendingMenuRequest = null
|
|
|
|
function extractErrorMessage(error) {
|
|
const fallback = 'Gagal memuat menu.'
|
|
const data = error?.response?.data
|
|
|
|
if (!data) return error?.message || fallback
|
|
if (typeof data?.message === 'string') return data.message
|
|
|
|
return fallback
|
|
}
|
|
|
|
function mapMenuItem(item, isChild = false) {
|
|
const hasChildren = Array.isArray(item?.children) && item.children.filter(Boolean).length > 0
|
|
const name = item?.name || 'Untitled'
|
|
const to = item?.url || '#'
|
|
|
|
if (hasChildren) {
|
|
return {
|
|
component: 'CNavGroup',
|
|
name,
|
|
to,
|
|
...(isChild ? {} : { icon: item?.icon || 'cil-menu' }),
|
|
items: item.children.filter(Boolean).map((child) => mapMenuItem(child, true)),
|
|
}
|
|
}
|
|
|
|
return {
|
|
component: 'CNavItem',
|
|
name,
|
|
to,
|
|
...(isChild ? {} : { icon: item?.icon || 'cil-menu' }),
|
|
}
|
|
}
|
|
|
|
export const useMenuStore = defineStore('menu', {
|
|
state: () => ({
|
|
isMaster: false,
|
|
dynamicMenus: [],
|
|
loading: false,
|
|
error: null,
|
|
initialized: false,
|
|
}),
|
|
|
|
getters: {
|
|
mappedMenus(state) {
|
|
return state.dynamicMenus.map((item) => mapMenuItem(item))
|
|
},
|
|
},
|
|
|
|
actions: {
|
|
async fetchMenus({ force = false } = {}) {
|
|
if (this.initialized && !force) {
|
|
return this.dynamicMenus
|
|
}
|
|
|
|
if (pendingMenuRequest) {
|
|
return pendingMenuRequest
|
|
}
|
|
|
|
this.loading = true
|
|
this.error = null
|
|
|
|
pendingMenuRequest = (async () => {
|
|
try {
|
|
const response = await getMyMenus()
|
|
const payload = response?.data || {}
|
|
|
|
this.isMaster = !!payload?.is_master
|
|
this.dynamicMenus = Array.isArray(payload?.menus) ? payload.menus : []
|
|
this.initialized = true
|
|
|
|
return this.dynamicMenus
|
|
} catch (error) {
|
|
this.error = extractErrorMessage(error)
|
|
this.initialized = false
|
|
this.dynamicMenus = []
|
|
throw error
|
|
} finally {
|
|
this.loading = false
|
|
pendingMenuRequest = null
|
|
}
|
|
})()
|
|
|
|
return pendingMenuRequest
|
|
},
|
|
|
|
reset() {
|
|
this.isMaster = false
|
|
this.dynamicMenus = []
|
|
this.loading = false
|
|
this.error = null
|
|
this.initialized = false
|
|
pendingMenuRequest = null
|
|
},
|
|
},
|
|
})
|