Broadcast datasource change via websocket when making changes to tables
This commit is contained in:
parent
4ea5b69ed3
commit
5e5dc902d1
|
@ -1,5 +1,4 @@
|
|||
import { get, writable, derived } from "svelte/store"
|
||||
import { datasources } from "./"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
import { API } from "api"
|
||||
import { SWITCHABLE_TYPES } from "constants/backend"
|
||||
|
@ -63,7 +62,6 @@ export function createTablesStore() {
|
|||
|
||||
const savedTable = await API.saveTable(updatedTable)
|
||||
replaceTable(savedTable._id, savedTable)
|
||||
await datasources.fetch()
|
||||
select(savedTable._id)
|
||||
return savedTable
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
RelationshipTypes,
|
||||
} from "@budibase/types"
|
||||
import sdk from "../../../sdk"
|
||||
import { builderSocket } from "../../../websockets"
|
||||
const { cloneDeep } = require("lodash/fp")
|
||||
|
||||
async function makeTableRequest(
|
||||
|
@ -318,6 +319,13 @@ export async function save(ctx: UserCtx) {
|
|||
datasource.entities[tableToSave.name] = tableToSave
|
||||
await db.put(datasource)
|
||||
|
||||
// Since tables are stored inside datasources, we need to notify clients
|
||||
// that the datasource definition changed
|
||||
const updatedDatasource = await db.get(datasource._id)
|
||||
builderSocket?.emitDatasourceUpdate(ctx, updatedDatasource, {
|
||||
includeOriginator: true,
|
||||
})
|
||||
|
||||
return tableToSave
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,13 @@ import { BaseSocket } from "./websocket"
|
|||
import { permissions, events } from "@budibase/backend-core"
|
||||
import http from "http"
|
||||
import Koa from "koa"
|
||||
import { Datasource, Table, SocketSession, ContextUser } from "@budibase/types"
|
||||
import {
|
||||
Datasource,
|
||||
Table,
|
||||
SocketSession,
|
||||
ContextUser,
|
||||
SocketMessageOptions,
|
||||
} from "@budibase/types"
|
||||
import { gridSocket } from "./index"
|
||||
import { clearLock, updateLock } from "../utilities/redis"
|
||||
import { Socket } from "socket.io"
|
||||
|
@ -66,33 +72,61 @@ export default class BuilderSocket extends BaseSocket {
|
|||
}
|
||||
}
|
||||
|
||||
emitTableUpdate(ctx: any, table: Table) {
|
||||
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.TableChange, {
|
||||
emitTableUpdate(ctx: any, table: Table, options?: SocketMessageOptions) {
|
||||
this.emitToRoom(
|
||||
ctx,
|
||||
ctx.appId,
|
||||
BuilderSocketEvent.TableChange,
|
||||
{
|
||||
id: table._id,
|
||||
table,
|
||||
})
|
||||
gridSocket?.emitTableUpdate(ctx, table)
|
||||
},
|
||||
options
|
||||
)
|
||||
gridSocket?.emitTableUpdate(ctx, table, options)
|
||||
}
|
||||
|
||||
emitTableDeletion(ctx: any, id: string) {
|
||||
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.TableChange, {
|
||||
emitTableDeletion(ctx: any, id: string, options?: SocketMessageOptions) {
|
||||
this.emitToRoom(
|
||||
ctx,
|
||||
ctx.appId,
|
||||
BuilderSocketEvent.TableChange,
|
||||
{
|
||||
id,
|
||||
table: null,
|
||||
})
|
||||
gridSocket?.emitTableDeletion(ctx, id)
|
||||
},
|
||||
options
|
||||
)
|
||||
gridSocket?.emitTableDeletion(ctx, id, options)
|
||||
}
|
||||
|
||||
emitDatasourceUpdate(ctx: any, datasource: Datasource) {
|
||||
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.DatasourceChange, {
|
||||
emitDatasourceUpdate(
|
||||
ctx: any,
|
||||
datasource: Datasource,
|
||||
options?: SocketMessageOptions
|
||||
) {
|
||||
this.emitToRoom(
|
||||
ctx,
|
||||
ctx.appId,
|
||||
BuilderSocketEvent.DatasourceChange,
|
||||
{
|
||||
id: datasource._id,
|
||||
datasource,
|
||||
})
|
||||
},
|
||||
options
|
||||
)
|
||||
}
|
||||
|
||||
emitDatasourceDeletion(ctx: any, id: string) {
|
||||
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.DatasourceChange, {
|
||||
emitDatasourceDeletion(ctx: any, id: string, options?: SocketMessageOptions) {
|
||||
this.emitToRoom(
|
||||
ctx,
|
||||
ctx.appId,
|
||||
BuilderSocketEvent.DatasourceChange,
|
||||
{
|
||||
id,
|
||||
datasource: null,
|
||||
})
|
||||
},
|
||||
options
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { 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, SocketMessageOptions, Table } from "@budibase/types"
|
||||
import { Socket } from "socket.io"
|
||||
import { GridSocketEvent } from "@budibase/shared-core"
|
||||
|
||||
|
@ -29,27 +29,51 @@ export default class GridSocket extends BaseSocket {
|
|||
})
|
||||
}
|
||||
|
||||
emitRowUpdate(ctx: any, row: Row) {
|
||||
emitRowUpdate(ctx: any, row: Row, options?: SocketMessageOptions) {
|
||||
const tableId = getTableId(ctx)
|
||||
this.emitToRoom(ctx, tableId, GridSocketEvent.RowChange, {
|
||||
this.emitToRoom(
|
||||
ctx,
|
||||
tableId,
|
||||
GridSocketEvent.RowChange,
|
||||
{
|
||||
id: row._id,
|
||||
row,
|
||||
})
|
||||
},
|
||||
options
|
||||
)
|
||||
}
|
||||
|
||||
emitRowDeletion(ctx: any, id: string) {
|
||||
emitRowDeletion(ctx: any, id: string, options?: SocketMessageOptions) {
|
||||
const tableId = getTableId(ctx)
|
||||
this.emitToRoom(ctx, tableId, GridSocketEvent.RowChange, { id, row: null })
|
||||
this.emitToRoom(
|
||||
ctx,
|
||||
tableId,
|
||||
GridSocketEvent.RowChange,
|
||||
{ id, row: null },
|
||||
options
|
||||
)
|
||||
}
|
||||
|
||||
emitTableUpdate(ctx: any, table: Table) {
|
||||
this.emitToRoom(ctx, table._id!, GridSocketEvent.TableChange, {
|
||||
emitTableUpdate(ctx: any, table: Table, options?: SocketMessageOptions) {
|
||||
this.emitToRoom(
|
||||
ctx,
|
||||
table._id!,
|
||||
GridSocketEvent.TableChange,
|
||||
{
|
||||
id: table._id,
|
||||
table,
|
||||
})
|
||||
},
|
||||
options
|
||||
)
|
||||
}
|
||||
|
||||
emitTableDeletion(ctx: any, id: string) {
|
||||
this.emitToRoom(ctx, id, GridSocketEvent.TableChange, { id, table: null })
|
||||
emitTableDeletion(ctx: any, id: string, options?: SocketMessageOptions) {
|
||||
this.emitToRoom(
|
||||
ctx,
|
||||
id,
|
||||
GridSocketEvent.TableChange,
|
||||
{ id, table: null },
|
||||
options
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import { createAdapter } from "@socket.io/redis-adapter"
|
|||
import { Socket } from "socket.io"
|
||||
import { getSocketPubSubClients } from "../utilities/redis"
|
||||
import { SocketEvent, SocketSessionTTL } from "@budibase/shared-core"
|
||||
import { SocketSession } from "@budibase/types"
|
||||
import { SocketSession, SocketMessageOptions } from "@budibase/types"
|
||||
|
||||
export class BaseSocket {
|
||||
io: Server
|
||||
|
@ -276,12 +276,24 @@ export class BaseSocket {
|
|||
this.io.sockets.emit(event, payload)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// Emit an event to everyone in a room
|
||||
emitToRoom(
|
||||
ctx: any,
|
||||
room: string,
|
||||
event: string,
|
||||
payload: any,
|
||||
options?: SocketMessageOptions
|
||||
) {
|
||||
// By default, we include the session API of the originator so that they can ignore
|
||||
// this event. If we want to include the originator then we leave it unset to that all
|
||||
// clients will react to it.
|
||||
let apiSessionId = null
|
||||
if (!options?.includeOriginator) {
|
||||
apiSessionId = ctx.headers?.[Header.SESSION_ID]
|
||||
}
|
||||
this.io.in(room).emit(event, {
|
||||
...payload,
|
||||
apiSessionId: ctx.headers?.[Header.SESSION_ID],
|
||||
apiSessionId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,3 +7,7 @@ export interface SocketSession {
|
|||
room?: string
|
||||
connectedAt: number
|
||||
}
|
||||
|
||||
export interface SocketMessageOptions {
|
||||
includeOriginator?: boolean
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue