mirror of
https://github.com/supabase/supabase.git
synced 2026-10-08 19:05:06 +03:00
150 lines
4.9 KiB
TypeScript
150 lines
4.9 KiB
TypeScript
import { cloneDeep } from 'lodash'
|
|
import { values } from 'mobx'
|
|
import { Organization, Project } from 'types'
|
|
|
|
import { API_URL, PROJECT_STATUS } from 'lib/constants'
|
|
import { getWithTimeout } from 'lib/common/fetch'
|
|
import { IRootStore } from '../RootStore'
|
|
import DatabaseStore, { IDatabaseStore } from './DatabaseStore'
|
|
import OrganizationStore from './OrganizationStore'
|
|
import ProjectStore, { IProjectStore } from './ProjectStore'
|
|
|
|
export interface IAppStore {
|
|
projects: IProjectStore
|
|
organizations: OrganizationStore
|
|
database: IDatabaseStore
|
|
onProjectCreated: (project: Project) => void
|
|
onProjectUpdated: (project: Project) => void
|
|
onProjectDeleted: (project: Project) => void
|
|
onProjectPaused: (projectId: number) => void
|
|
onProjectStatusUpdated: (projectId: number, value: string) => void
|
|
onProjectPostgrestStatusUpdated: (projectId: number, value: 'OFFLINE' | 'ONLINE') => void
|
|
onOrgAdded: (org: any) => void
|
|
onOrgUpdated: (org: any) => void
|
|
onOrgDeleted: (org: any) => void
|
|
}
|
|
export default class AppStore implements IAppStore {
|
|
rootStore: IRootStore
|
|
projects: ProjectStore
|
|
organizations: OrganizationStore
|
|
database: DatabaseStore
|
|
|
|
baseUrl: string
|
|
|
|
constructor(rootStore: IRootStore) {
|
|
this.rootStore = rootStore
|
|
this.baseUrl = API_URL || '/api'
|
|
|
|
const headers: any = {}
|
|
|
|
this.projects = new ProjectStore(rootStore, `${this.baseUrl}/projects`, headers)
|
|
this.organizations = new OrganizationStore(rootStore, `${this.baseUrl}/organizations`, headers)
|
|
this.database = new DatabaseStore(rootStore, `${this.baseUrl}/database`, headers)
|
|
}
|
|
|
|
onProjectCreated(project: any) {
|
|
if (project && project.id) {
|
|
const temp: Project = {
|
|
id: project.id,
|
|
ref: project.ref,
|
|
name: project.name,
|
|
status: project.status,
|
|
organization_id: project.organization_id,
|
|
cloud_provider: project.cloud_provider,
|
|
region: project.region,
|
|
inserted_at: project.inserted_at,
|
|
subscription_id: project.subscription_id,
|
|
}
|
|
this.projects.data[project.id] = temp
|
|
}
|
|
}
|
|
|
|
onProjectUpdated(project: any) {
|
|
if (project && project.id) {
|
|
const clone = cloneDeep(this.projects.data[project.id])
|
|
// only update available param
|
|
if (project.name) clone.name = project.name
|
|
if (project.status) clone.status = project.status
|
|
this.projects.data[project.id] = clone
|
|
}
|
|
}
|
|
|
|
onProjectDeleted(project: any) {
|
|
if (project && project.id) {
|
|
// cleanup project saved queries
|
|
localStorage.removeItem(`supabase-queries-state-${project.ref}`)
|
|
localStorage.removeItem(`supabase_${project.ref}`)
|
|
delete this.projects.data[project.id]
|
|
}
|
|
}
|
|
|
|
// At global store level so that it can continue checking while the user
|
|
// is doing something else outside of the project page
|
|
async onProjectPaused(projectId: number) {
|
|
const checkProjectInactive = async () => {
|
|
const projectRef = this.projects.data[projectId]?.ref
|
|
const projectStatus = await getWithTimeout(`${API_URL}/projects/${projectRef}/status`, {
|
|
timeout: 2000,
|
|
})
|
|
if (projectStatus.status === PROJECT_STATUS.INACTIVE) {
|
|
this.onProjectStatusUpdated(projectId, PROJECT_STATUS.INACTIVE)
|
|
} else {
|
|
setTimeout(() => checkProjectInactive(), 5000)
|
|
}
|
|
}
|
|
|
|
setTimeout(() => checkProjectInactive(), 5000)
|
|
}
|
|
|
|
onProjectStatusUpdated(projectId: number, value: string) {
|
|
const clone = cloneDeep(this.projects.data[projectId])
|
|
clone.status = value
|
|
this.projects.data[projectId] = clone
|
|
}
|
|
|
|
onProjectPostgrestStatusUpdated(projectId: number, value: 'OFFLINE' | 'ONLINE') {
|
|
const clone = cloneDeep(this.projects.data[projectId])
|
|
clone.postgrestStatus = value
|
|
this.projects.data[projectId] = clone
|
|
}
|
|
|
|
onOrgUpdated(updatedOrg: Organization) {
|
|
if (updatedOrg && updatedOrg.id) {
|
|
const originalOrg = this.organizations.data[updatedOrg.id]
|
|
this.organizations.data[updatedOrg.id] = {
|
|
...originalOrg,
|
|
...updatedOrg,
|
|
}
|
|
}
|
|
}
|
|
|
|
onOrgAdded(org: Organization) {
|
|
if (org && org.id) {
|
|
this.organizations.data[org.id] = org
|
|
}
|
|
}
|
|
|
|
onOrgDeleted(org: Organization) {
|
|
if (org && org.id) {
|
|
const projects = values(this.projects.data)
|
|
// cleanup projects saved queries
|
|
const removedprojects = projects.filter(
|
|
(project: Project) => project.organization_id === org.id
|
|
)
|
|
removedprojects.forEach((project: Project) => {
|
|
localStorage.removeItem(`supabase-queries-state-${project.ref}`)
|
|
localStorage.removeItem(`supabase_${project.ref}`)
|
|
})
|
|
// remove projects belong to removed org
|
|
const updatedProjects = projects.filter(
|
|
(project: Project) => project.organization_id != org.id
|
|
)
|
|
this.projects.data = updatedProjects.reduce((map: any, x: any) => {
|
|
map[x.id] = { ...x }
|
|
return map
|
|
}, {})
|
|
delete (this.organizations.data as any)[org.id]
|
|
}
|
|
}
|
|
}
|