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"
|
||||
|
||||
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 connectToDatasource = datasource => {
|
||||
|
@ -51,13 +51,16 @@ export const createGridWebsocket = context => {
|
|||
})
|
||||
|
||||
// Table events
|
||||
socket.onOther(GridSocketEvent.TableChange, ({ table: newTable }) => {
|
||||
// Only update table if one exists. If the table was deleted then we don't
|
||||
// want to know - let the builder navigate away
|
||||
if (newTable) {
|
||||
table.set(newTable)
|
||||
socket.onOther(
|
||||
GridSocketEvent.DatasourceChange,
|
||||
({ datasource: newDatasource }) => {
|
||||
// Only update definition if one exists. If the datasource was deleted
|
||||
// then we don't want to know - let the builder navigate away
|
||||
if (newDatasource) {
|
||||
definition.set(newDatasource)
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
// Change websocket connection when table changes
|
||||
datasource.subscribe(connectToDatasource)
|
||||
|
|
|
@ -159,7 +159,7 @@ async function deleteRows(ctx: UserCtx<DeleteRowRequest>) {
|
|||
|
||||
for (let row of rows) {
|
||||
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, row)
|
||||
gridSocket?.emitRowDeletion(ctx, row._id!)
|
||||
gridSocket?.emitRowDeletion(ctx, row)
|
||||
}
|
||||
|
||||
return rows
|
||||
|
@ -175,7 +175,7 @@ async function deleteRow(ctx: UserCtx<DeleteRowRequest>) {
|
|||
await quotas.removeRow()
|
||||
|
||||
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, resp.row)
|
||||
gridSocket?.emitRowDeletion(ctx, resp.row._id!)
|
||||
gridSocket?.emitRowDeletion(ctx, resp.row)
|
||||
|
||||
return resp
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ export async function destroy(ctx: UserCtx) {
|
|||
ctx.status = 200
|
||||
ctx.table = deletedTable
|
||||
ctx.body = { message: `Table ${tableId} deleted.` }
|
||||
builderSocket?.emitTableDeletion(ctx, tableId)
|
||||
builderSocket?.emitTableDeletion(ctx, deletedTable)
|
||||
}
|
||||
|
||||
export async function bulkImport(ctx: UserCtx) {
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
ViewResponse,
|
||||
ViewV2,
|
||||
} from "@budibase/types"
|
||||
import { builderSocket } from "../../../websockets"
|
||||
import { builderSocket, gridSocket } from "../../../websockets"
|
||||
|
||||
async function parseSchema(view: CreateViewRequest) {
|
||||
if (!view.schema) {
|
||||
|
@ -41,7 +41,7 @@ async function parseSchema(view: CreateViewRequest) {
|
|||
|
||||
export async function get(ctx: Ctx<void, ViewResponse>) {
|
||||
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)
|
||||
builderSocket?.emitTableUpdate(ctx, table)
|
||||
gridSocket?.emitViewUpdate(ctx, result)
|
||||
}
|
||||
|
||||
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)
|
||||
builderSocket?.emitTableUpdate(ctx, table)
|
||||
gridSocket?.emitViewUpdate(ctx, result)
|
||||
}
|
||||
|
||||
export async function remove(ctx: Ctx) {
|
||||
|
@ -111,4 +113,5 @@ export async function remove(ctx: Ctx) {
|
|||
|
||||
const table = await sdk.tables.getTable(view.tableId)
|
||||
builderSocket?.emitTableUpdate(ctx, table)
|
||||
gridSocket?.emitViewDeletion(ctx, view)
|
||||
}
|
||||
|
|
|
@ -108,12 +108,12 @@ export default class BuilderSocket extends BaseSocket {
|
|||
gridSocket?.emitTableUpdate(ctx, table)
|
||||
}
|
||||
|
||||
emitTableDeletion(ctx: any, id: string) {
|
||||
emitTableDeletion(ctx: any, table: Table) {
|
||||
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.TableChange, {
|
||||
id,
|
||||
id: table._id,
|
||||
table: null,
|
||||
})
|
||||
gridSocket?.emitTableDeletion(ctx, id)
|
||||
gridSocket?.emitTableDeletion(ctx, table)
|
||||
}
|
||||
|
||||
emitDatasourceUpdate(ctx: any, datasource: Datasource) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import { auth, permissions } from "@budibase/backend-core"
|
|||
import http from "http"
|
||||
import Koa from "koa"
|
||||
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 { GridSocketEvent } from "@budibase/shared-core"
|
||||
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 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) {
|
||||
const room = `${ctx.appId}-${table._id}`
|
||||
this.emitToRoom(ctx, room, GridSocketEvent.TableChange, {
|
||||
this.emitToRoom(ctx, room, GridSocketEvent.DatasourceChange, {
|
||||
id: table._id,
|
||||
table,
|
||||
datasource: table,
|
||||
})
|
||||
}
|
||||
|
||||
emitTableDeletion(ctx: any, id: string) {
|
||||
const room = `${ctx.appId}-${id}`
|
||||
this.emitToRoom(ctx, room, GridSocketEvent.TableChange, { id, table: null })
|
||||
emitTableDeletion(ctx: any, table: Table) {
|
||||
const room = `${ctx.appId}-${table._id}`
|
||||
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
|
||||
// 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, {
|
||||
...payload,
|
||||
apiSessionId: ctx.headers?.[Header.SESSION_ID],
|
||||
|
|
|
@ -76,7 +76,7 @@ export enum SocketEvent {
|
|||
|
||||
export enum GridSocketEvent {
|
||||
RowChange = "RowChange",
|
||||
TableChange = "TableChange",
|
||||
DatasourceChange = "DatasourceChange",
|
||||
SelectDatasource = "SelectDatasource",
|
||||
SelectCell = "SelectCell",
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue