Add multi user sync for roles

This commit is contained in:
Andrew Kingston 2024-09-16 09:40:52 +01:00
parent bf10b4cd9d
commit a120a9c97a
No known key found for this signature in database
5 changed files with 56 additions and 2 deletions

View File

@ -55,6 +55,34 @@ export function createRolesStore() {
_id: savedRole._id.replace("role_", ""), _id: savedRole._id.replace("role_", ""),
} }
}, },
replace: (roleId, role) => {
console.log("replace", roleId, role)
// Handles external updates of roles
if (!roleId) {
return
}
// Handle deletion
if (!role) {
store.update(state => state.filter(x => x._id !== roleId))
return
}
// Add new role
const index = get(store).findIndex(x => x._id === role._id)
if (index === -1) {
store.update(state => [...state, role])
}
// Update existing role
else if (role) {
store.update(state => {
state[index] = role
return [...state]
})
}
},
} }
return { return {

View File

@ -9,6 +9,7 @@ import {
snippets, snippets,
datasources, datasources,
tables, tables,
roles,
} from "stores/builder" } from "stores/builder"
import { get } from "svelte/store" import { get } from "svelte/store"
import { auth, appsStore } from "stores/portal" import { auth, appsStore } from "stores/portal"
@ -56,12 +57,18 @@ export const createBuilderWebsocket = appId => {
datasources.replaceDatasource(id, datasource) datasources.replaceDatasource(id, datasource)
}) })
// Role events
socket.onOther(BuilderSocketEvent.RoleChange, ({ id, role }) => {
roles.replaceRole(id, role)
})
// Design section events // Design section events
socket.onOther(BuilderSocketEvent.ScreenChange, ({ id, screen }) => { socket.onOther(BuilderSocketEvent.ScreenChange, ({ id, screen }) => {
screenStore.replace(id, screen) screenStore.replace(id, screen)
}) })
// App events
socket.onOther(BuilderSocketEvent.AppMetadataChange, ({ metadata }) => { socket.onOther(BuilderSocketEvent.AppMetadataChange, ({ metadata }) => {
//Sync app metadata across the stores
appStore.syncMetadata(metadata) appStore.syncMetadata(metadata)
themeStore.syncMetadata(metadata) themeStore.syncMetadata(metadata)
navigationStore.syncMetadata(metadata) navigationStore.syncMetadata(metadata)
@ -79,7 +86,7 @@ export const createBuilderWebsocket = appId => {
} }
) )
// Automations // Automation events
socket.onOther(BuilderSocketEvent.AutomationChange, ({ id, automation }) => { socket.onOther(BuilderSocketEvent.AutomationChange, ({ id, automation }) => {
automationStore.actions.replace(id, automation) automationStore.actions.replace(id, automation)
}) })

View File

@ -21,6 +21,7 @@ import {
} from "@budibase/types" } from "@budibase/types"
import { RoleColor, sdk as sharedSdk } from "@budibase/shared-core" import { RoleColor, sdk as sharedSdk } from "@budibase/shared-core"
import sdk from "../../sdk" import sdk from "../../sdk"
import { builderSocket } from "src/websockets"
const UpdateRolesOptions = { const UpdateRolesOptions = {
CREATED: "created", CREATED: "created",
@ -130,6 +131,7 @@ export async function save(ctx: UserCtx<SaveRoleRequest, SaveRoleResponse>) {
}, },
}) })
} }
builderSocket?.emitRoleUpdate(ctx, role)
} }
export async function destroy(ctx: UserCtx<void, DestroyRoleResponse>) { export async function destroy(ctx: UserCtx<void, DestroyRoleResponse>) {
@ -165,6 +167,7 @@ export async function destroy(ctx: UserCtx<void, DestroyRoleResponse>) {
) )
ctx.message = `Role ${ctx.params.roleId} deleted successfully` ctx.message = `Role ${ctx.params.roleId} deleted successfully`
ctx.status = 200 ctx.status = 200
builderSocket?.emitRoleDeletion(ctx, role)
} }
export async function accessible(ctx: UserCtx<void, AccessibleRolesResponse>) { export async function accessible(ctx: UserCtx<void, AccessibleRolesResponse>) {

View File

@ -11,6 +11,7 @@ import {
Screen, Screen,
App, App,
Automation, Automation,
Role,
} from "@budibase/types" } from "@budibase/types"
import { gridSocket } from "./index" import { gridSocket } from "./index"
import { clearLock, updateLock } from "../utilities/redis" import { clearLock, updateLock } from "../utilities/redis"
@ -100,6 +101,20 @@ export default class BuilderSocket extends BaseSocket {
}) })
} }
emitRoleUpdate(ctx: any, role: Role) {
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.RoleChange, {
id: role._id,
role,
})
}
emitRoleDeletion(ctx: any, role: Role) {
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.RoleChange, {
id: role._id,
role: null,
})
}
emitTableUpdate(ctx: any, table: Table, options?: EmitOptions) { emitTableUpdate(ctx: any, table: Table, options?: EmitOptions) {
if (table.sourceId == null || table.sourceId === "") { if (table.sourceId == null || table.sourceId === "") {
throw new Error("Table sourceId is not set") throw new Error("Table sourceId is not set")

View File

@ -96,6 +96,7 @@ export enum BuilderSocketEvent {
SelectResource = "SelectResource", SelectResource = "SelectResource",
AppPublishChange = "AppPublishChange", AppPublishChange = "AppPublishChange",
AutomationChange = "AutomationChange", AutomationChange = "AutomationChange",
RoleChange = "RoleChange",
} }
export const SocketSessionTTL = 60 export const SocketSessionTTL = 60