Files
supabase/studio/stores/project/ProjectFunctionsStore.ts
2022-06-09 15:23:35 +08:00

203 lines
4.8 KiB
TypeScript

import { makeAutoObservable, toJS } from 'mobx'
import { keyBy } from 'lodash'
import { get, post, patch, delete_ } from 'lib/common/fetch'
import { UserContent, UserContentMap } from 'types'
import { IRootStore } from '../RootStore'
export interface IProjectFunctionsStore {
isLoading: boolean
isInitialized: boolean
isLoaded: boolean
error: any
baseUrl: string
projectRef: string
load: () => void
list: (filter?: any) => any[]
byId: (id?: any) => any
reports: (filter?: any) => any[]
sqlSnippets: (filter?: any) => any[]
setProjectRef: (ref?: string) => void
}
export default class ProjectFunctionsStore implements IProjectFunctionsStore {
rootStore: IRootStore
STATES = {
INITIAL: 'initial',
LOADING: 'loading',
ERROR: 'error',
LOADED: 'loaded',
}
baseUrl: string
projectRef: string
// @ts-ignore
data: UserContentMap = []
state = this.STATES.INITIAL
error = null
constructor(rootStore: IRootStore, options: { projectRef: string }) {
const { projectRef } = options
this.projectRef = projectRef
this.rootStore = rootStore
this.baseUrl = ``
makeAutoObservable(this)
}
get isLoading() {
return this.state === this.STATES.INITIAL || this.state === this.STATES.LOADING
}
get isInitialized() {
return this.state !== this.STATES.INITIAL
}
get isLoaded() {
return this.state === this.STATES.LOADED
}
async fetchData() {
const headers = {
'Content-Type': 'application/json',
}
const response = await get(this.baseUrl, { headers })
if (response.error) {
throw response.error
}
this.data = keyBy(response, 'id')
return response
}
async load() {
let { LOADING, ERROR, LOADED } = this.STATES
try {
this.error = null
this.state = LOADING
await this.fetchData()
this.state = LOADED
return this.data
} catch (e: any) {
console.error('Failed to load project content', e.message)
this.error = e
this.state = ERROR
}
}
async loadPersistentData() {}
async loadRemotePersistentData(userId: any) {
const sqlSnippets = this.sqlSnippets((x: any) => x.owner_id === userId)
}
list(filter?: any) {
const arr = Object.values(this.data)
if (!!filter) {
return arr.filter(filter).sort((a, b) => a.name.localeCompare(b.name))
} else {
return arr.sort((a, b) => a.name.localeCompare(b.name))
}
}
byId(id: any) {
return toJS(this.data)[id]
}
reports(filter?: any) {
let arr = Object.values(this.data)
if (!!filter) {
return arr
.filter((x) => x.type == 'report')
.filter(filter)
.sort((a, b) => a.name.localeCompare(b.name))
} else {
return arr.filter((x) => x.type == 'report').sort((a, b) => a.name.localeCompare(b.name))
}
}
sqlSnippets(filter?: any) {
let arr = Object.values(this.data)
if (!!filter) {
const arr_filtered = arr
.filter((x) => x.type == 'sql')
.filter(filter)
.sort((a, b) => a.name.localeCompare(b.name))
return arr_filtered
} else {
const arr_filtered = arr
.filter((x) => x.type == 'sql')
.sort((a, b) => a.name.localeCompare(b.name))
return arr_filtered
}
}
async create(payload: any) {
try {
const headers = {
'Content-Type': 'application/json',
}
const created = await post(this.baseUrl, payload, { headers })
if (created.error) throw created.error
this.data[created['id']] = created
return { data: created, error: null }
} catch (error) {
return { data: null, error }
}
}
async update(id: any, updates: any, type: UserContent['type']) {
try {
const headers = {
'Content-Type': 'application/json',
}
let payload = {
...updates,
type,
id,
}
const url = `${this.baseUrl}?id=${id}`
const updated = await patch(url, payload, { headers })
if (updated.error) throw updated.error
this.data[id] = updated
return { data: updated, error: null }
} catch (error) {
return { data: null, error }
}
}
async updateSql(id: any, updates: any) {
return this.update(id, updates, 'sql')
}
async updateReport(id: any, updates: any) {
return this.update(id, updates, 'report')
}
async del(id: any) {
try {
const headers = {
'Content-Type': 'application/json',
}
const url = `${this.baseUrl}?id=${id}`
const deleted = await delete_(url, {}, { headers })
if (deleted.error) throw deleted.error
delete this.data[id]
return { data: true, error: null }
} catch (error) {
return { data: false, error }
}
}
setProjectRef(ref?: string) {
if (ref) {
this.projectRef = ref
this.baseUrl = `${process.env.NEXT_PUBLIC_API_ADMIN_URL}/projects/${ref}/functions`
}
}
}