From d80cca9a111d4092b4098e6ffa83f08448a9d1c3 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 3 Jul 2023 11:14:07 +0100 Subject: [PATCH 01/20] Allow all users into the design section, enable multi dev collab on screens, improve routing --- .../src/builderStore/store/frontend.js | 29 ++++++++++++++ .../builder/src/builderStore/websocket.js | 11 ++++-- packages/builder/src/helpers/urlStateSync.js | 20 +++++----- .../builder/app/[application]/_layout.svelte | 38 +++++++------------ .../[application]/automation/_layout.svelte | 9 ----- .../app/[application]/design/_layout.svelte | 12 ------ packages/server/src/api/controllers/screen.ts | 10 ++++- packages/server/src/websockets/builder.ts | 22 ++++++++++- packages/shared-core/src/constants.ts | 2 + 9 files changed, 89 insertions(+), 64 deletions(-) diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index 5de58f02e7..4af3be4673 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -353,6 +353,35 @@ export const getFrontendStore = () => { } return await sequentialScreenPatch(patchFn, screenId) }, + replace: async (screenId, screen) => { + if (!screenId) { + return + } + + // Handle deletion + if (!screen) { + store.update(state => ({ + ...state, + screens: state.screens.filter(x => x._id !== screenId), + })) + return + } + + // Add new datasource + const index = get(store).screens.findIndex(x => x._id === screen._id) + if (index === -1) { + store.update(state => ({ + ...state, + screens: [...state.screens, screen], + })) + } + + // Update existing datasource + store.update(state => { + state.screens[index] = screen + return state + }) + }, delete: async screens => { const screensToDelete = Array.isArray(screens) ? screens : [screens] diff --git a/packages/builder/src/builderStore/websocket.js b/packages/builder/src/builderStore/websocket.js index af6d58ee7f..8562c8024c 100644 --- a/packages/builder/src/builderStore/websocket.js +++ b/packages/builder/src/builderStore/websocket.js @@ -31,7 +31,7 @@ export const createBuilderWebsocket = appId => { }) socket.onOther(BuilderSocketEvent.LockTransfer, ({ userId }) => { if (userId === get(auth)?.user?._id) { - notifications.success("You can now edit screens and automations") + notifications.success("You can now edit automations") store.update(state => ({ ...state, hasLock: true, @@ -39,15 +39,18 @@ export const createBuilderWebsocket = appId => { } }) - // Table events + // Data section events socket.onOther(BuilderSocketEvent.TableChange, ({ id, table }) => { tables.replaceTable(id, table) }) - - // Datasource events socket.onOther(BuilderSocketEvent.DatasourceChange, ({ id, datasource }) => { datasources.replaceDatasource(id, datasource) }) + // Design section events + socket.onOther(BuilderSocketEvent.ScreenChange, ({ id, screen }) => { + store.actions.screens.replace(id, screen) + }) + return socket } diff --git a/packages/builder/src/helpers/urlStateSync.js b/packages/builder/src/helpers/urlStateSync.js index 47f3438468..c4c48fb3fb 100644 --- a/packages/builder/src/helpers/urlStateSync.js +++ b/packages/builder/src/helpers/urlStateSync.js @@ -114,26 +114,24 @@ export const syncURLToState = options => { // Updates the URL with new state values const mapStateToUrl = state => { - let needsUpdate = false const urlValue = cachedParams?.[urlParam] const stateValue = state?.[stateKey] - if (stateValue !== urlValue) { - needsUpdate = true - log(`url.${urlParam} (${urlValue}) <= state.${stateKey} (${stateValue})`) - if (validate && fallbackUrl) { - if (!validate(stateValue)) { - log("Invalid state param!", stateValue) - redirectUrl(fallbackUrl) - return - } + + // As the store updated, validate that the current state value is valid + if (validate && fallbackUrl) { + if (!validate(stateValue)) { + log("Invalid state param!", stateValue) + redirectUrl(fallbackUrl) + return } } // Avoid updating the URL if not necessary to prevent a wasted render // cycle - if (!needsUpdate) { + if (stateValue === urlValue) { return } + log(`url.${urlParam} (${urlValue}) <= state.${stateKey} (${stateValue})`) // Navigate to the new URL if (!get(isChangingPage)) { diff --git a/packages/builder/src/pages/builder/app/[application]/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/_layout.svelte index 0d5942c39e..3703279044 100644 --- a/packages/builder/src/pages/builder/app/[application]/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/_layout.svelte @@ -151,31 +151,19 @@ on:click={() => $goto("../../portal/apps")} /> - {#if $store.hasLock} - - {#each $layout.children as { path, title }} - - - - {/each} - - {:else} -
- -
- Another user is currently editing your screens and automations -
-
- {/if} + + {#each $layout.children as { path, title }} + + + + {/each} +
{$store.name} diff --git a/packages/builder/src/pages/builder/app/[application]/automation/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/automation/_layout.svelte index 79ca5df168..74dfe671ab 100644 --- a/packages/builder/src/pages/builder/app/[application]/automation/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/automation/_layout.svelte @@ -8,15 +8,6 @@ import { onDestroy, onMount } from "svelte" import { syncURLToState } from "helpers/urlStateSync" import * as routify from "@roxi/routify" - import { store } from "builderStore" - import { redirect } from "@roxi/routify" - - // Prevent access for other users than the lock holder - $: { - if (!$store.hasLock) { - $redirect("../data") - } - } // Keep URL and state in sync for selected screen ID const stopSyncing = syncURLToState({ diff --git a/packages/builder/src/pages/builder/app/[application]/design/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/design/_layout.svelte index d23514ae6d..ec21d909aa 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/_layout.svelte @@ -1,14 +1,2 @@ - - diff --git a/packages/server/src/api/controllers/screen.ts b/packages/server/src/api/controllers/screen.ts index 9cbd019d6e..ddfec91c0c 100644 --- a/packages/server/src/api/controllers/screen.ts +++ b/packages/server/src/api/controllers/screen.ts @@ -8,6 +8,7 @@ import { } from "@budibase/backend-core" import { updateAppPackage } from "./application" import { Plugin, ScreenProps, BBContext } from "@budibase/types" +import { builderSocket } from "../../websockets" export async function fetch(ctx: BBContext) { const db = context.getAppDB() @@ -87,13 +88,17 @@ export async function save(ctx: BBContext) { if (eventFn) { await eventFn(screen) } - ctx.message = `Screen ${screen.name} saved.` - ctx.body = { + const savedScreen = { ...screen, _id: response.id, _rev: response.rev, + } + ctx.message = `Screen ${screen.name} saved.` + ctx.body = { + ...savedScreen, pluginAdded, } + builderSocket?.emitScreenUpdate(ctx, savedScreen) } export async function destroy(ctx: BBContext) { @@ -108,6 +113,7 @@ export async function destroy(ctx: BBContext) { message: "Screen deleted successfully", } ctx.status = 200 + builderSocket?.emitScreenDeletion(ctx, id) } function findPlugins(component: ScreenProps, foundPlugins: string[]) { diff --git a/packages/server/src/websockets/builder.ts b/packages/server/src/websockets/builder.ts index 2524d9608b..839f8732b7 100644 --- a/packages/server/src/websockets/builder.ts +++ b/packages/server/src/websockets/builder.ts @@ -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, + Screen, +} from "@budibase/types" import { gridSocket } from "./index" import { clearLock, updateLock } from "../utilities/redis" import { Socket } from "socket.io" @@ -101,4 +107,18 @@ export default class BuilderSocket extends BaseSocket { datasource: null, }) } + + emitScreenUpdate(ctx: any, screen: Screen) { + this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.ScreenChange, { + id: screen._id, + screen, + }) + } + + emitScreenDeletion(ctx: any, id: string) { + this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.ScreenChange, { + id, + screen: null, + }) + } } diff --git a/packages/shared-core/src/constants.ts b/packages/shared-core/src/constants.ts index 307285012b..e3784ac354 100644 --- a/packages/shared-core/src/constants.ts +++ b/packages/shared-core/src/constants.ts @@ -86,6 +86,8 @@ export enum BuilderSocketEvent { TableChange = "TableChange", DatasourceChange = "DatasourceChange", LockTransfer = "LockTransfer", + ScreenChange = "ScreenChange", + AppMetadataChange = "AppMetadataChange", } export const SocketSessionTTL = 60 From 4725faf8b53192d06f135d06525cd592fd9b3062 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 3 Jul 2023 11:23:08 +0100 Subject: [PATCH 02/20] Update websocket user metadata structures --- packages/frontend-core/src/components/grid/stores/users.js | 5 +++-- packages/server/src/websockets/builder.ts | 7 +++++++ packages/server/src/websockets/grid.ts | 7 +++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/frontend-core/src/components/grid/stores/users.js b/packages/frontend-core/src/components/grid/stores/users.js index b6e74ef276..5a39f3769a 100644 --- a/packages/frontend-core/src/components/grid/stores/users.js +++ b/packages/frontend-core/src/components/grid/stores/users.js @@ -30,8 +30,9 @@ export const deriveStores = context => { ([$users, $focusedCellId]) => { let map = {} $users.forEach(user => { - if (user.focusedCellId && user.focusedCellId !== $focusedCellId) { - map[user.focusedCellId] = user + const cellId = user.gridMetadata?.focusedCellId + if (cellId && cellId !== $focusedCellId) { + map[cellId] = user } }) return map diff --git a/packages/server/src/websockets/builder.ts b/packages/server/src/websockets/builder.ts index 839f8732b7..d7a4701b06 100644 --- a/packages/server/src/websockets/builder.ts +++ b/packages/server/src/websockets/builder.ts @@ -78,6 +78,13 @@ export default class BuilderSocket extends BaseSocket { } } + async updateUser(socket: Socket, patch: Object) { + await super.updateUser(socket, { + ...socket.data.builderMetadata, + ...patch, + }) + } + emitTableUpdate(ctx: any, table: Table) { this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.TableChange, { id: table._id, diff --git a/packages/server/src/websockets/grid.ts b/packages/server/src/websockets/grid.ts index ffe26828bc..d9e454608b 100644 --- a/packages/server/src/websockets/grid.ts +++ b/packages/server/src/websockets/grid.ts @@ -69,6 +69,13 @@ export default class GridSocket extends BaseSocket { }) } + async updateUser(socket: Socket, patch: Object) { + await super.updateUser(socket, { + ...socket.data.gridMetadata, + ...patch, + }) + } + emitRowUpdate(ctx: any, row: Row) { const tableId = getTableId(ctx) const room = `${ctx.appId}-${tableId}` From 7be2d6896e564c73be857bd7c910349e62b9b523 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 4 Jul 2023 08:58:14 +0100 Subject: [PATCH 03/20] Add indicators to show selected state in data section --- packages/builder/src/builderStore/index.js | 13 +++++ .../src/builderStore/store/frontend.js | 8 +++ .../DatasourceNavigator.svelte | 4 ++ .../TableNavigator/TableNavigator.svelte | 3 + .../src/components/common/NavItem.svelte | 57 ++++++++++++++++++- .../app/[application]/data/_layout.svelte | 6 ++ .../datasource/[datasourceId]/_layout.svelte | 4 ++ .../data/datasource/bb_internal/index.svelte | 2 + .../index.svelte | 3 + .../data/query/[queryId]/_layout.svelte | 4 ++ .../data/table/[tableId]/_layout.svelte | 4 ++ .../data/view/[viewName]/_layout.svelte | 4 ++ packages/server/src/websockets/builder.ts | 7 ++- packages/shared-core/src/constants.ts | 1 + 14 files changed, 117 insertions(+), 3 deletions(-) diff --git a/packages/builder/src/builderStore/index.js b/packages/builder/src/builderStore/index.js index 9dca6a64e6..1022f917d0 100644 --- a/packages/builder/src/builderStore/index.js +++ b/packages/builder/src/builderStore/index.js @@ -118,3 +118,16 @@ export const selectedAutomation = derived(automationStore, $automationStore => { x => x._id === $automationStore.selectedAutomationId ) }) + +// Derive map of resource IDs to other users. +// We only ever care about a single user in each resource, so if multiple users +// share the same datasource we can just overwrite them. +export const userSelectedResourceMap = derived(userStore, $userStore => { + let map = {} + $userStore.forEach(user => { + if (user.selectedResourceId) { + map[user.selectedResourceId] = user + } + }) + return map +}) diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index 4af3be4673..a3e499e336 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -38,6 +38,7 @@ import { import { makePropSafe as safe } from "@budibase/string-templates" import { getComponentFieldOptions } from "helpers/formFields" import { createBuilderWebsocket } from "builderStore/websocket" +import { BuilderSocketEvent } from "@budibase/shared-core" const INITIAL_FRONTEND_STATE = { initialised: false, @@ -1394,6 +1395,13 @@ export const getFrontendStore = () => { }) }, }, + websocket: { + selectResource: id => { + websocket.emit(BuilderSocketEvent.SelectResource, { + resourceId: id, + }) + }, + }, } return store diff --git a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte index e2dd1b4cc3..c34afce783 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte @@ -13,6 +13,7 @@ } from "helpers/data/utils" import IntegrationIcon from "./IntegrationIcon.svelte" import { TableNames } from "constants" + import { userSelectedResourceMap } from "builderStore" let openDataSources = [] @@ -166,6 +167,7 @@ selected={$isActive("./table/:tableId") && $tables.selected?._id === TableNames.USERS} on:click={() => selectTable(TableNames.USERS)} + selectedBy={$userSelectedResourceMap[TableNames.USERS]} /> {#each enrichedDataSources as datasource, idx} selectDatasource(datasource)} on:iconClick={() => toggleNode(datasource)} + selectedBy={$userSelectedResourceMap[datasource._id]} >
$goto(`./query/${query._id}`)} + selectedBy={$userSelectedResourceMap[query._id]} > diff --git a/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte b/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte index a7e5764865..d9def682dc 100644 --- a/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte +++ b/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte @@ -5,6 +5,7 @@ import EditViewPopover from "./popovers/EditViewPopover.svelte" import NavItem from "components/common/NavItem.svelte" import { goto, isActive } from "@roxi/routify" + import { userSelectedResourceMap } from "builderStore" const alphabetical = (a, b) => a.name?.toLowerCase() > b.name?.toLowerCase() ? 1 : -1 @@ -30,6 +31,7 @@ selected={$isActive("./table/:tableId") && $tables.selected?._id === table._id} on:click={() => selectTable(table._id)} + selectedBy={$userSelectedResourceMap[table._id]} > {#if table._id !== TableNames.USERS} @@ -42,6 +44,7 @@ text={viewName} selected={$isActive("./view") && $views.selected?.name === viewName} on:click={() => $goto(`./view/${encodeURIComponent(viewName)}`)} + selectedBy={$userSelectedResourceMap[viewName]} > import { Icon } from "@budibase/bbui" import { createEventDispatcher, getContext } from "svelte" + import { helpers } from "@budibase/shared-core" + import { UserAvatar } from "@budibase/frontend-core" export let icon export let withArrow = false @@ -18,12 +20,15 @@ export let rightAlignIcon = false export let id export let showTooltip = false + export let selectedBy = null const scrollApi = getContext("scroll") const dispatch = createEventDispatcher() let contentRef + $: selected && contentRef && scrollToView() + $: style = getStyle(indentLevel, selectedBy) const onClick = () => { scrollToView() @@ -42,6 +47,14 @@ const bounds = contentRef.getBoundingClientRect() scrollApi.scrollTo(bounds) } + + const getStyle = (indentLevel, selectedBy) => { + let style = `padding-left:calc(${indentLevel * 14}px);` + if (selectedBy) { + style += `--selected-by-color:${helpers.getUserColor(selectedBy)};` + } + return style + }
{/if}
+ {#if selectedBy} +
{helpers.getUserLabel(selectedBy)}
+ {/if} + + + + +
diff --git a/packages/builder/src/components/deploy/DeploymentHistory.svelte b/packages/builder/src/components/deploy/DeploymentHistory.svelte deleted file mode 100644 index e025abf1c7..0000000000 --- a/packages/builder/src/components/deploy/DeploymentHistory.svelte +++ /dev/null @@ -1,236 +0,0 @@ - - -{#if deployments.length > 0} -
-
- Deployment History -
- {#if deployments.some(deployment => deployment.status === DeploymentStatus.SUCCESS)} - View Your Deployed App → - - {/if} -
-
-
- {#each deployments as deployment} -
-
- - {formatDate(deployment.updatedAt, "fullDate")} - - - {formatDate(deployment.updatedAt, "timeOnly")} - -
-
- {#if deployment.status.toLowerCase() === "pending"} - - {/if} -
showErrorReasonModal(deployment.err)} - class={`deployment-status ${deployment.status}`} - > - - {deployment.status} - {#if deployment.status === DeploymentStatus.FAILURE} - - {/if} - -
-
-
- {/each} -
-
-{/if} - - - - - - {errorReason} - - - - diff --git a/packages/builder/src/components/deploy/utils.js b/packages/builder/src/components/deploy/utils.js deleted file mode 100644 index cb254f0dbf..0000000000 --- a/packages/builder/src/components/deploy/utils.js +++ /dev/null @@ -1,25 +0,0 @@ -export const DeploymentStatus = { - SUCCESS: "SUCCESS", - PENDING: "PENDING", - FAILURE: "FAILURE", -} - -// Required to check any updated deployment statuses between polls -export function checkIncomingDeploymentStatus(current, incoming) { - return incoming.reduce((acc, incomingDeployment) => { - if (incomingDeployment.status === DeploymentStatus.FAILURE) { - const currentDeployment = current.find( - deployment => deployment._id === incomingDeployment._id - ) - - //We have just been notified of an ongoing deployments failure - if ( - !currentDeployment || - currentDeployment.status === DeploymentStatus.PENDING - ) { - acc.push(incomingDeployment) - } - } - return acc - }, []) -} diff --git a/packages/builder/src/pages/builder/app/[application]/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/_layout.svelte index 3703279044..8581200578 100644 --- a/packages/builder/src/pages/builder/app/[application]/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/_layout.svelte @@ -1,7 +1,12 @@ -{#if url} - - {text || ""} - -{:else} - - - {text || ""} - -{/if} +
+ {#if url} + + {text || ""} + + {:else} + +
+ {text || ""} +
+ {/if} + {#if tooltip} +
+ +
+ {/if} +
diff --git a/packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte index 225e3977c3..de65333f6f 100644 --- a/packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte @@ -3,6 +3,7 @@ import { Page, Layout } from "@budibase/bbui" import { url, isActive } from "@roxi/routify" import DeleteModal from "components/deploy/DeleteModal.svelte" + import { isOnlyUser } from "builderStore" let deleteModal @@ -49,6 +50,10 @@ on:click={() => { deleteModal.show() }} + disabled={!$isOnlyUser} + tooltip={$isOnlyUser + ? null + : "Unavailable - another user is editing this app"} />
@@ -61,7 +66,7 @@ diff --git a/packages/bbui/src/Popover/Popover.svelte b/packages/bbui/src/Popover/Popover.svelte index 9f951a6a7e..20207a85da 100644 --- a/packages/bbui/src/Popover/Popover.svelte +++ b/packages/bbui/src/Popover/Popover.svelte @@ -90,6 +90,6 @@ .spectrum-Popover { min-width: var(--spectrum-global-dimension-size-2000); border-color: var(--spectrum-global-color-gray-300); - overflow: auto; + overflow: visible; } diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index aa3ae3a90b..af421f8aa8 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -1404,7 +1404,6 @@ export const getFrontendStore = () => { }, metadata: { replace: metadata => { - console.log("NEW METADATA", metadata) store.update(state => ({ ...state, ...metadata, diff --git a/packages/builder/src/components/deploy/AppActions.svelte b/packages/builder/src/components/deploy/AppActions.svelte index c93f792870..7fc545ce44 100644 --- a/packages/builder/src/components/deploy/AppActions.svelte +++ b/packages/builder/src/components/deploy/AppActions.svelte @@ -253,7 +253,15 @@ Unpublish - Revert + + Revert + {:else} Not published From aedd04b98aae442750b2616a083b147044239011 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 5 Jul 2023 09:02:10 +0100 Subject: [PATCH 12/20] Fix issue with location of socket metadata --- packages/builder/src/builderStore/index.js | 4 ++-- packages/server/src/websockets/builder.ts | 6 ++++-- packages/server/src/websockets/grid.ts | 6 ++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/builder/src/builderStore/index.js b/packages/builder/src/builderStore/index.js index 8dbee49327..e8fba9a0ee 100644 --- a/packages/builder/src/builderStore/index.js +++ b/packages/builder/src/builderStore/index.js @@ -127,8 +127,8 @@ export const selectedAutomation = derived(automationStore, $automationStore => { export const userSelectedResourceMap = derived(userStore, $userStore => { let map = {} $userStore.forEach(user => { - if (user.selectedResourceId) { - map[user.selectedResourceId] = user + if (user.builderMetadata?.selectedResourceId) { + map[user.builderMetadata?.selectedResourceId] = user } }) return map diff --git a/packages/server/src/websockets/builder.ts b/packages/server/src/websockets/builder.ts index 8b40115702..cff42ce178 100644 --- a/packages/server/src/websockets/builder.ts +++ b/packages/server/src/websockets/builder.ts @@ -86,8 +86,10 @@ export default class BuilderSocket extends BaseSocket { async updateUser(socket: Socket, patch: Object) { await super.updateUser(socket, { - ...socket.data.builderMetadata, - ...patch, + builderMetadata: { + ...socket.data.builderMetadata, + ...patch, + }, }) } diff --git a/packages/server/src/websockets/grid.ts b/packages/server/src/websockets/grid.ts index d9e454608b..f95137ee08 100644 --- a/packages/server/src/websockets/grid.ts +++ b/packages/server/src/websockets/grid.ts @@ -71,8 +71,10 @@ export default class GridSocket extends BaseSocket { async updateUser(socket: Socket, patch: Object) { await super.updateUser(socket, { - ...socket.data.gridMetadata, - ...patch, + gridMetadata: { + ...socket.data.gridMetadata, + ...patch, + }, }) } From 57242840b7235bd33516f0587f5a5c997aeabb13 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 5 Jul 2023 09:10:03 +0100 Subject: [PATCH 13/20] Update tooltips to transition and to use friendly names when possible --- packages/bbui/src/Button/Button.svelte | 26 ++----------------- .../src/components/UserAvatar.svelte | 8 +++--- 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/packages/bbui/src/Button/Button.svelte b/packages/bbui/src/Button/Button.svelte index 816c4900b2..0aa9a12ee2 100644 --- a/packages/bbui/src/Button/Button.svelte +++ b/packages/bbui/src/Button/Button.svelte @@ -16,8 +16,6 @@ export let tooltip = undefined export let newStyles = true export let id - - let showTooltip = false