/** * Session-cached read of the UI-restriction flags on the logged-in org's * linked C_BPartner (via /api/admin/organizations/ui-flags): * - isHideQty → useHideQty().showStockQty gates stock-quantity UI * - isDisallowExport → useDisallowExport().allowExport gates export buttons * * Both composables share one state + one fetch. Until the flags resolve, * limited customers ('c' menu) default to RESTRICTED (nothing flashes in) * while staff default to unrestricted (no flicker, nothing blocks on the * fetch); a failing endpoint keeps that role-based default in force. * * State lives here rather than in states.ts because it is owned entirely by * this composable (same convention as the chat composables / useLookup). */ // Client-only dedupe: several components (e.g. multiple expanded master-detail // rows, page + grid) may call load() in the same tick. let inflight: Promise | null = null const useBpartnerFlagsState = () => useState('bpartnerUiFlags', () => ({ orgId: '', hideQty: false, disallowExport: false, loaded: false })) const loadBpartnerFlags = async () => { if (import.meta.server) return const state = useBpartnerFlagsState() const orgCookie = useCookie('logship_organization_id') const orgKey = String(orgCookie.value ?? '') if (state.value.loaded && state.value.orgId === orgKey) return if (inflight) return inflight inflight = (async () => { try { const res: any = await $fetch('/api/admin/organizations/ui-flags', { headers: useRequestHeaders(['cookie']) }) state.value.hideQty = res?.hideQty === true state.value.disallowExport = res?.disallowExport === true // resolved:false = the server-side check itself failed → stay unloaded // so the consumers keep the role-based default. state.value.loaded = res?.resolved !== false } catch (e) { state.value.hideQty = false state.value.disallowExport = false state.value.loaded = false } state.value.orgId = orgKey inflight = null })() return inflight } export const useHideQty = () => { const state = useBpartnerFlagsState() const { getMenuType } = useRoleMenu() const hideQty = computed(() => state.value.hideQty) const showStockQty = computed(() => state.value.loaded ? !state.value.hideQty : getMenuType() !== 'c' ) return { hideQty, showStockQty, loaded: computed(() => state.value.loaded), load: loadBpartnerFlags } } export const useDisallowExport = () => { const state = useBpartnerFlagsState() const { getMenuType } = useRoleMenu() const disallowExport = computed(() => state.value.disallowExport) const allowExport = computed(() => state.value.loaded ? !state.value.disallowExport : getMenuType() !== 'c' ) return { disallowExport, allowExport, loaded: computed(() => state.value.loaded), load: loadBpartnerFlags } }