Update server and builder to properly sync changes with tables and views across all users
This commit is contained in:
parent
733a638a99
commit
b5546f8d9b
|
@ -3,7 +3,7 @@ import { createWebsocket } from "../../../utils"
|
||||||
import { SocketEvent, GridSocketEvent } from "@budibase/shared-core"
|
import { SocketEvent, GridSocketEvent } from "@budibase/shared-core"
|
||||||
|
|
||||||
export const createGridWebsocket = context => {
|
export const createGridWebsocket = context => {
|
||||||
const { rows, datasource, users, focusedCellId, table, API } = context
|
const { rows, datasource, users, focusedCellId, definition, API } = context
|
||||||
const socket = createWebsocket("/socket/grid")
|
const socket = createWebsocket("/socket/grid")
|
||||||
|
|
||||||
const connectToDatasource = datasource => {
|
const connectToDatasource = datasource => {
|
||||||
|
@ -51,13 +51,16 @@ export const createGridWebsocket = context => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Table events
|
// Table events
|
||||||
socket.onOther(GridSocketEvent.TableChange, ({ table: newTable }) => {
|
socket.onOther(
|
||||||
// Only update table if one exists. If the table was deleted then we don't
|
GridSocketEvent.DatasourceChange,
|
||||||
// want to know - let the builder navigate away
|
({ datasource: newDatasource }) => {
|
||||||
if (newTable) {
|
// Only update definition if one exists. If the datasource was deleted
|
||||||
table.set(newTable)
|
// then we don't want to know - let the builder navigate away
|
||||||
|
if (newDatasource) {
|
||||||
|
definition.set(newDatasource)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Change websocket connection when table changes
|
// Change websocket connection when table changes
|
||||||
datasource.subscribe(connectToDatasource)
|
datasource.subscribe(connectToDatasource)
|
||||||
|
|
|
@ -159,7 +159,7 @@ async function deleteRows(ctx: UserCtx<DeleteRowRequest>) {
|
||||||
|
|
||||||
for (let row of rows) {
|
for (let row of rows) {
|
||||||
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, row)
|
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, row)
|
||||||
gridSocket?.emitRowDeletion(ctx, row._id!)
|
gridSocket?.emitRowDeletion(ctx, row)
|
||||||
}
|
}
|
||||||
|
|
||||||
return rows
|
return rows
|
||||||
|
@ -175,7 +175,7 @@ async function deleteRow(ctx: UserCtx<DeleteRowRequest>) {
|
||||||
await quotas.removeRow()
|
await quotas.removeRow()
|
||||||
|
|
||||||
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, resp.row)
|
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, resp.row)
|
||||||
gridSocket?.emitRowDeletion(ctx, resp.row._id!)
|
gridSocket?.emitRowDeletion(ctx, resp.row)
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ export async function destroy(ctx: UserCtx) {
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
ctx.table = deletedTable
|
ctx.table = deletedTable
|
||||||
ctx.body = { message: `Table ${tableId} deleted.` }
|
ctx.body = { message: `Table ${tableId} deleted.` }
|
||||||
builderSocket?.emitTableDeletion(ctx, tableId)
|
builderSocket?.emitTableDeletion(ctx, deletedTable)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function bulkImport(ctx: UserCtx) {
|
export async function bulkImport(ctx: UserCtx) {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
ViewResponse,
|
ViewResponse,
|
||||||
ViewV2,
|
ViewV2,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { builderSocket } from "../../../websockets"
|
import { builderSocket, gridSocket } from "../../../websockets"
|
||||||
|
|
||||||
async function parseSchema(view: CreateViewRequest) {
|
async function parseSchema(view: CreateViewRequest) {
|
||||||
if (!view.schema) {
|
if (!view.schema) {
|
||||||
|
@ -41,7 +41,7 @@ async function parseSchema(view: CreateViewRequest) {
|
||||||
|
|
||||||
export async function get(ctx: Ctx<void, ViewResponse>) {
|
export async function get(ctx: Ctx<void, ViewResponse>) {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
data: await sdk.views.get(ctx.params.viewId, { enriched: true })
|
data: await sdk.views.get(ctx.params.viewId, { enriched: true }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ export async function create(ctx: Ctx<CreateViewRequest, ViewResponse>) {
|
||||||
|
|
||||||
const table = await sdk.tables.getTable(tableId)
|
const table = await sdk.tables.getTable(tableId)
|
||||||
builderSocket?.emitTableUpdate(ctx, table)
|
builderSocket?.emitTableUpdate(ctx, table)
|
||||||
|
gridSocket?.emitViewUpdate(ctx, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update(ctx: Ctx<UpdateViewRequest, ViewResponse>) {
|
export async function update(ctx: Ctx<UpdateViewRequest, ViewResponse>) {
|
||||||
|
@ -101,6 +102,7 @@ export async function update(ctx: Ctx<UpdateViewRequest, ViewResponse>) {
|
||||||
|
|
||||||
const table = await sdk.tables.getTable(tableId)
|
const table = await sdk.tables.getTable(tableId)
|
||||||
builderSocket?.emitTableUpdate(ctx, table)
|
builderSocket?.emitTableUpdate(ctx, table)
|
||||||
|
gridSocket?.emitViewUpdate(ctx, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function remove(ctx: Ctx) {
|
export async function remove(ctx: Ctx) {
|
||||||
|
@ -111,4 +113,5 @@ export async function remove(ctx: Ctx) {
|
||||||
|
|
||||||
const table = await sdk.tables.getTable(view.tableId)
|
const table = await sdk.tables.getTable(view.tableId)
|
||||||
builderSocket?.emitTableUpdate(ctx, table)
|
builderSocket?.emitTableUpdate(ctx, table)
|
||||||
|
gridSocket?.emitViewDeletion(ctx, view)
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,12 +108,12 @@ export default class BuilderSocket extends BaseSocket {
|
||||||
gridSocket?.emitTableUpdate(ctx, table)
|
gridSocket?.emitTableUpdate(ctx, table)
|
||||||
}
|
}
|
||||||
|
|
||||||
emitTableDeletion(ctx: any, id: string) {
|
emitTableDeletion(ctx: any, table: Table) {
|
||||||
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.TableChange, {
|
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.TableChange, {
|
||||||
id,
|
id: table._id,
|
||||||
table: null,
|
table: null,
|
||||||
})
|
})
|
||||||
gridSocket?.emitTableDeletion(ctx, id)
|
gridSocket?.emitTableDeletion(ctx, table)
|
||||||
}
|
}
|
||||||
|
|
||||||
emitDatasourceUpdate(ctx: any, datasource: Datasource) {
|
emitDatasourceUpdate(ctx: any, datasource: Datasource) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { auth, permissions } from "@budibase/backend-core"
|
||||||
import http from "http"
|
import http from "http"
|
||||||
import Koa from "koa"
|
import Koa from "koa"
|
||||||
import { getTableId } from "../api/controllers/row/utils"
|
import { getTableId } from "../api/controllers/row/utils"
|
||||||
import { Row, Table } from "@budibase/types"
|
import { Row, Table, View, ViewV2 } from "@budibase/types"
|
||||||
import { Socket } from "socket.io"
|
import { Socket } from "socket.io"
|
||||||
import { GridSocketEvent } from "@budibase/shared-core"
|
import { GridSocketEvent } from "@budibase/shared-core"
|
||||||
import { userAgent } from "koa-useragent"
|
import { userAgent } from "koa-useragent"
|
||||||
|
@ -88,22 +88,52 @@ export default class GridSocket extends BaseSocket {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
emitRowDeletion(ctx: any, id: string) {
|
emitRowDeletion(ctx: any, row: Row) {
|
||||||
const resourceId = ctx.params?.viewId || getTableId(ctx)
|
const resourceId = ctx.params?.viewId || getTableId(ctx)
|
||||||
const room = `${ctx.appId}-${resourceId}`
|
const room = `${ctx.appId}-${resourceId}`
|
||||||
this.emitToRoom(ctx, room, GridSocketEvent.RowChange, { id, row: null })
|
this.emitToRoom(ctx, room, GridSocketEvent.RowChange, {
|
||||||
|
id: row._id,
|
||||||
|
row: null,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
emitTableUpdate(ctx: any, table: Table) {
|
emitTableUpdate(ctx: any, table: Table) {
|
||||||
const room = `${ctx.appId}-${table._id}`
|
const room = `${ctx.appId}-${table._id}`
|
||||||
this.emitToRoom(ctx, room, GridSocketEvent.TableChange, {
|
this.emitToRoom(ctx, room, GridSocketEvent.DatasourceChange, {
|
||||||
id: table._id,
|
id: table._id,
|
||||||
table,
|
datasource: table,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
emitTableDeletion(ctx: any, id: string) {
|
emitTableDeletion(ctx: any, table: Table) {
|
||||||
const room = `${ctx.appId}-${id}`
|
const room = `${ctx.appId}-${table._id}`
|
||||||
this.emitToRoom(ctx, room, GridSocketEvent.TableChange, { id, table: null })
|
this.emitToRoom(ctx, room, GridSocketEvent.DatasourceChange, {
|
||||||
|
id: table._id,
|
||||||
|
datasource: null,
|
||||||
|
})
|
||||||
|
|
||||||
|
// When the table is deleted we need to notify all views that they have
|
||||||
|
// also been deleted
|
||||||
|
Object.values(table.views || {})
|
||||||
|
.filter((view: View | ViewV2) => (view as ViewV2).version === 2)
|
||||||
|
.forEach((view: View | ViewV2) => {
|
||||||
|
this.emitViewDeletion(ctx, view as ViewV2)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
emitViewUpdate(ctx: any, view: ViewV2) {
|
||||||
|
const room = `${ctx.appId}-${view.id}`
|
||||||
|
this.emitToRoom(ctx, room, GridSocketEvent.DatasourceChange, {
|
||||||
|
id: view.id,
|
||||||
|
datasource: view,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
emitViewDeletion(ctx: any, view: ViewV2) {
|
||||||
|
const room = `${ctx.appId}-${view.id}`
|
||||||
|
this.emitToRoom(ctx, room, GridSocketEvent.DatasourceChange, {
|
||||||
|
id: view.id,
|
||||||
|
datasource: null,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,7 +270,7 @@ export class BaseSocket {
|
||||||
|
|
||||||
// Emit an event to everyone in a room, including metadata of whom
|
// Emit an event to everyone in a room, including metadata of whom
|
||||||
// the originator of the request was
|
// the originator of the request was
|
||||||
emitToRoom(ctx: any, room: string, event: string, payload: any) {
|
emitToRoom(ctx: any, room: string | string[], event: string, payload: any) {
|
||||||
this.io.in(room).emit(event, {
|
this.io.in(room).emit(event, {
|
||||||
...payload,
|
...payload,
|
||||||
apiSessionId: ctx.headers?.[Header.SESSION_ID],
|
apiSessionId: ctx.headers?.[Header.SESSION_ID],
|
||||||
|
|
|
@ -76,7 +76,7 @@ export enum SocketEvent {
|
||||||
|
|
||||||
export enum GridSocketEvent {
|
export enum GridSocketEvent {
|
||||||
RowChange = "RowChange",
|
RowChange = "RowChange",
|
||||||
TableChange = "TableChange",
|
DatasourceChange = "DatasourceChange",
|
||||||
SelectDatasource = "SelectDatasource",
|
SelectDatasource = "SelectDatasource",
|
||||||
SelectCell = "SelectCell",
|
SelectCell = "SelectCell",
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue