src/stores/dashboardApps.ts
Rama main · réplica de lectura del repositorio original.
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import { useConsole } from '~/services/console'
import { readAllConsoleRows } from '~/services/consoleRows'
import { useDisplayStore } from '~/stores/display'
import { useOrganizationStore } from './organization'
export const useDashboardAppsStore = defineStore('dashboardApps', () => {
const apps = ref<{ app_id: string, name: string | null }[]>([])
const isLoading = ref(false)
const isLoaded = ref(false)
const currentOrgId = ref<string | null>(null)
let loadPromise: Promise<void> | null = null
let loadGeneration = 0
const appNames = computed(() => {
const names: { [appId: string]: string } = {}
apps.value.forEach((app) => {
names[app.app_id] = app.name || app.app_id
})
return names
})
const appIds = computed(() => apps.value.map(app => app.app_id))
async function fetchApps(force = false) {
const organizationStore = useOrganizationStore()
const targetOrgId = organizationStore.currentOrganization?.gid
// Quick check: if already loaded for the SAME org and not forcing, return immediately
if (!force && isLoaded.value && currentOrgId.value === targetOrgId) {
return
}
try {
await organizationStore.dedupFetchOrganizations()
}
catch (error) {
console.error('Error preparing organization data for apps fetch:', error)
return
}
const orgId = organizationStore.currentOrganization?.gid
if (!orgId) {
reset()
isLoaded.value = true
return
}
if (currentOrgId.value === orgId && loadPromise)
return loadPromise
if (!force && isLoaded.value && currentOrgId.value === orgId)
return
// Reset if organization changed
if (currentOrgId.value !== orgId) {
reset()
currentOrgId.value = orgId
}
isLoading.value = true
const capgo = useConsole()
const generation = loadGeneration
const isCurrent = () => generation === loadGeneration && organizationStore.currentOrganization?.gid === orgId
const request = (async () => {
try {
const { data, error } = await readAllConsoleRows<{ app_id: string, name: string | null }>((from, to) => {
if (!isCurrent())
return Promise.resolve({ data: [], error: null })
return capgo
.from('apps')
.select('app_id, name')
.eq('owner_org', orgId)
.order('app_id')
.range(from, to)
})
if (!isCurrent())
return
if (error)
throw error
apps.value = data || []
isLoaded.value = true
const display = useDisplayStore()
display.setAppNameResolver(appId => appNames.value[appId])
}
catch (error) {
if (!isCurrent())
return
console.error('Error fetching apps:', error)
}
})()
loadPromise = request
try {
await request
}
finally {
if (loadPromise === request) {
isLoading.value = false
loadPromise = null
}
}
}
function upsertApp(app: { app_id: string, name: string | null, ownerOrgId?: string | null }) {
const organizationStore = useOrganizationStore()
const ownerOrgId = app.ownerOrgId ?? organizationStore.currentOrganization?.gid ?? null
if (ownerOrgId && currentOrgId.value && ownerOrgId !== currentOrgId.value)
return
if (ownerOrgId && !currentOrgId.value)
currentOrgId.value = ownerOrgId
const nextApp = { app_id: app.app_id, name: app.name }
const existingIndex = apps.value.findIndex(item => item.app_id === nextApp.app_id)
if (existingIndex >= 0) {
apps.value[existingIndex] = { ...apps.value[existingIndex], ...nextApp }
return
}
apps.value = [...apps.value, nextApp]
}
function reset() {
loadGeneration += 1
loadPromise = null
apps.value = []
isLoaded.value = false
isLoading.value = false
currentOrgId.value = null
}
return {
// State
apps,
isLoading,
isLoaded,
currentOrgId,
// Getters
appNames,
appIds,
// Actions
fetchApps,
upsertApp,
reset,
}
})