129 lines
3.5 KiB
JavaScript
129 lines
3.5 KiB
JavaScript
import { writable, get } from "svelte/store"
|
|
import { views } from "./"
|
|
import { cloneDeep } from "lodash/fp"
|
|
import api from "builderStore/api"
|
|
|
|
export function createTablesStore() {
|
|
const store = writable({})
|
|
const { subscribe, update, set } = store
|
|
|
|
async function fetch() {
|
|
const tablesResponse = await api.get(`/api/tables`)
|
|
const tables = await tablesResponse.json()
|
|
update(state => ({ ...state, list: tables }))
|
|
}
|
|
|
|
async function select(table) {
|
|
if (!table) {
|
|
update(state => ({
|
|
...state,
|
|
selected: {},
|
|
}))
|
|
} else {
|
|
update(state => ({
|
|
...state,
|
|
selected: table,
|
|
draft: cloneDeep(table),
|
|
}))
|
|
views.select({ name: `all_${table._id}` })
|
|
}
|
|
}
|
|
|
|
async function save(table) {
|
|
const updatedTable = cloneDeep(table)
|
|
const oldTable = get(store).list.filter(t => t._id === table._id)[0]
|
|
|
|
const fieldNames = []
|
|
// update any renamed schema keys to reflect their names
|
|
for (let key of Object.keys(updatedTable.schema)) {
|
|
// if field name has been seen before remove it
|
|
if (fieldNames.indexOf(key.toLowerCase()) !== -1) {
|
|
delete updatedTable.schema[key]
|
|
continue
|
|
}
|
|
const field = updatedTable.schema[key]
|
|
const oldField = oldTable?.schema[key]
|
|
// if the type has changed then revert back to the old field
|
|
if (oldField != null && oldField?.type !== field.type) {
|
|
updatedTable.schema[key] = oldField
|
|
}
|
|
// field has been renamed
|
|
if (field.name && field.name !== key) {
|
|
updatedTable.schema[field.name] = field
|
|
updatedTable._rename = { old: key, updated: field.name }
|
|
delete updatedTable.schema[key]
|
|
}
|
|
// finally record this field has been used
|
|
fieldNames.push(key.toLowerCase())
|
|
}
|
|
|
|
const response = await api.post(`/api/tables`, updatedTable)
|
|
const savedTable = await response.json()
|
|
await fetch()
|
|
await select(savedTable)
|
|
return savedTable
|
|
}
|
|
|
|
return {
|
|
subscribe,
|
|
fetch,
|
|
select,
|
|
save,
|
|
init: async () => {
|
|
const response = await api.get("/api/tables")
|
|
const json = await response.json()
|
|
set({
|
|
list: json,
|
|
selected: {},
|
|
draft: {},
|
|
})
|
|
},
|
|
delete: async table => {
|
|
await api.delete(`/api/tables/${table._id}/${table._rev}`)
|
|
update(state => ({
|
|
...state,
|
|
list: state.list.filter(existing => existing._id !== table._id),
|
|
selected: {},
|
|
}))
|
|
},
|
|
saveField: ({ originalName, field, primaryDisplay = false, indexes }) => {
|
|
update(state => {
|
|
// delete the original if renaming
|
|
// need to handle if the column had no name, empty string
|
|
if (originalName || originalName === "") {
|
|
delete state.draft.schema[originalName]
|
|
state.draft._rename = {
|
|
old: originalName,
|
|
updated: field.name,
|
|
}
|
|
}
|
|
|
|
// Optionally set display column
|
|
if (primaryDisplay) {
|
|
state.draft.primaryDisplay = field.name
|
|
}
|
|
|
|
if (indexes) {
|
|
state.draft.indexes = indexes
|
|
}
|
|
|
|
state.draft.schema = {
|
|
...state.draft.schema,
|
|
[field.name]: cloneDeep(field),
|
|
}
|
|
save(state.draft)
|
|
return state
|
|
})
|
|
},
|
|
deleteField: field => {
|
|
update(state => {
|
|
delete state.draft.schema[field.name]
|
|
save(state.draft)
|
|
return state
|
|
})
|
|
},
|
|
}
|
|
}
|
|
|
|
export const tables = createTablesStore()
|