base struktur update
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
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
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
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
|
||||
},
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user