Merge pull request #15262 from Budibase/feat/ts-store-conversions-pc

Builder store typescript conversions
This commit is contained in:
Peter Clement 2024-12-30 13:33:21 +00:00 committed by GitHub
commit e32784e5aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 154 additions and 65 deletions

View File

@ -1,7 +1,54 @@
import { API } from "api"
import { BudiStore } from "../BudiStore"
import {
App,
AppFeatures,
AppIcon,
AutomationSettings,
Plugin,
} from "@budibase/types"
export const INITIAL_APP_META_STATE = {
interface ClientFeatures {
spectrumThemes: boolean
intelligentLoading: boolean
deviceAwareness: boolean
state: boolean
rowSelection: boolean
customThemes: boolean
devicePreview: boolean
messagePassing: boolean
continueIfAction: boolean
showNotificationAction: boolean
sidePanel: boolean
}
interface TypeSupportPresets {
[key: string]: any
}
interface AppMetaState {
appId: string
name: string
url: string
libraries: string[]
clientFeatures: ClientFeatures
typeSupportPresets: TypeSupportPresets
features: AppFeatures
clientLibPath: string
hasLock: boolean
appInstance: { _id: string } | null
initialised: boolean
hasAppPackage: boolean
usedPlugins: Plugin[] | null
automations: AutomationSettings
routes: { [key: string]: any }
version?: string
revertableVersion?: string
upgradableVersion?: string
icon?: AppIcon
}
export const INITIAL_APP_META_STATE: AppMetaState = {
appId: "",
name: "",
url: "",
@ -34,23 +81,27 @@ export const INITIAL_APP_META_STATE = {
routes: {},
}
export class AppMetaStore extends BudiStore {
export class AppMetaStore extends BudiStore<AppMetaState> {
constructor() {
super(INITIAL_APP_META_STATE)
}
reset() {
reset(): void {
this.store.set({ ...INITIAL_APP_META_STATE })
}
syncAppPackage(pkg) {
syncAppPackage(pkg: {
application: App
clientLibPath: string
hasLock: boolean
}): void {
const { application: app, clientLibPath, hasLock } = pkg
this.update(state => ({
...state,
name: app.name,
appId: app.appId,
url: app.url,
url: app.url || "",
hasLock,
clientLibPath,
libraries: app.componentLibraries,
@ -58,8 +109,8 @@ export class AppMetaStore extends BudiStore {
appInstance: app.instance,
revertableVersion: app.revertableVersion,
upgradableVersion: app.upgradableVersion,
usedPlugins: app.usedPlugins,
icon: app.icon || {},
usedPlugins: app.usedPlugins || null,
icon: app.icon,
features: {
...INITIAL_APP_META_STATE.features,
...app.features,
@ -70,7 +121,7 @@ export class AppMetaStore extends BudiStore {
}))
}
syncClientFeatures(features) {
syncClientFeatures(features: Partial<ClientFeatures>): void {
this.update(state => ({
...state,
clientFeatures: {
@ -80,14 +131,14 @@ export class AppMetaStore extends BudiStore {
}))
}
syncClientTypeSupportPresets(typeSupportPresets) {
syncClientTypeSupportPresets(typeSupportPresets: TypeSupportPresets): void {
this.update(state => ({
...state,
typeSupportPresets,
}))
}
async syncAppRoutes() {
async syncAppRoutes(): Promise<void> {
const resp = await API.fetchAppRoutes()
this.update(state => ({
...state,
@ -96,7 +147,7 @@ export class AppMetaStore extends BudiStore {
}
// Returned from socket
syncMetadata(metadata) {
syncMetadata(metadata: { name: string; url: string; icon?: AppIcon }): void {
const { name, url, icon } = metadata
this.update(state => ({
...state,

View File

@ -1,10 +1,28 @@
import { get } from "svelte/store"
import { createBuilderWebsocket } from "./websocket.js"
import { Socket } from "socket.io-client"
import { BuilderSocketEvent } from "@budibase/shared-core"
import { BudiStore } from "../BudiStore.js"
import { TOUR_KEYS } from "components/portal/onboarding/tours.js"
import { App } from "@budibase/types"
export const INITIAL_BUILDER_STATE = {
interface BuilderState {
previousTopNavPath: Record<string, string>
highlightedSetting: {
key: string
type: "info" | string
} | null
propertyFocus: string | null
builderSidePanel: boolean
onboarding: boolean
tourNodes: Record<string, HTMLElement> | null
tourKey: string | null
tourStepKey: string | null
hoveredComponentId: string | null
websocket?: Socket
}
export const INITIAL_BUILDER_STATE: BuilderState = {
previousTopNavPath: {},
highlightedSetting: null,
propertyFocus: null,
@ -16,7 +34,9 @@ export const INITIAL_BUILDER_STATE = {
hoveredComponentId: null,
}
export class BuilderStore extends BudiStore {
export class BuilderStore extends BudiStore<BuilderState> {
websocket?: Socket
constructor() {
super({ ...INITIAL_BUILDER_STATE })
@ -32,11 +52,9 @@ export class BuilderStore extends BudiStore {
this.registerTourNode = this.registerTourNode.bind(this)
this.destroyTourNode = this.destroyTourNode.bind(this)
this.startBuilderOnboarding = this.startBuilderOnboarding.bind(this)
this.websocket
}
init(app) {
init(app: App): void {
if (!app?.appId) {
console.error("BuilderStore: No appId supplied for websocket")
return
@ -46,45 +64,46 @@ export class BuilderStore extends BudiStore {
}
}
refresh() {
this.store.set(this.store.get())
refresh(): void {
const currentState = get(this.store)
this.store.set(currentState)
}
reset() {
reset(): void {
this.store.set({ ...INITIAL_BUILDER_STATE })
this.websocket?.disconnect()
this.websocket = null
this.websocket = undefined
}
highlightSetting(key, type) {
highlightSetting(key?: string, type?: string): void {
this.update(state => ({
...state,
highlightedSetting: key ? { key, type: type || "info" } : null,
}))
}
propertyFocus(key) {
propertyFocus(key: string | null): void {
this.update(state => ({
...state,
propertyFocus: key,
}))
}
showBuilderSidePanel() {
showBuilderSidePanel(): void {
this.update(state => ({
...state,
builderSidePanel: true,
}))
}
hideBuilderSidePanel() {
hideBuilderSidePanel(): void {
this.update(state => ({
...state,
builderSidePanel: false,
}))
}
setPreviousTopNavPath(route, url) {
setPreviousTopNavPath(route: string, url: string): void {
this.update(state => ({
...state,
previousTopNavPath: {
@ -94,13 +113,13 @@ export class BuilderStore extends BudiStore {
}))
}
selectResource(id) {
this.websocket.emit(BuilderSocketEvent.SelectResource, {
selectResource(id: string): void {
this.websocket?.emit(BuilderSocketEvent.SelectResource, {
resourceId: id,
})
}
registerTourNode(tourStepKey, node) {
registerTourNode(tourStepKey: string, node: HTMLElement): void {
this.update(state => {
const update = {
...state,
@ -113,7 +132,7 @@ export class BuilderStore extends BudiStore {
})
}
destroyTourNode(tourStepKey) {
destroyTourNode(tourStepKey: string): void {
const store = get(this.store)
if (store.tourNodes?.[tourStepKey]) {
const nodes = { ...store.tourNodes }
@ -125,7 +144,7 @@ export class BuilderStore extends BudiStore {
}
}
startBuilderOnboarding() {
startBuilderOnboarding(): void {
this.update(state => ({
...state,
onboarding: true,
@ -133,19 +152,19 @@ export class BuilderStore extends BudiStore {
}))
}
endBuilderOnboarding() {
endBuilderOnboarding(): void {
this.update(state => ({
...state,
onboarding: false,
}))
}
setTour(tourKey) {
setTour(tourKey?: string | null): void {
this.update(state => ({
...state,
tourStepKey: null,
tourNodes: null,
tourKey: tourKey,
tourKey: tourKey || null,
}))
}
}

View File

@ -1,28 +0,0 @@
import { writable } from "svelte/store"
export const INITIAL_CONTEXT_MENU_STATE = {
id: null,
items: [],
position: { x: 0, y: 0 },
visible: false,
}
export function createViewsStore() {
const store = writable({ ...INITIAL_CONTEXT_MENU_STATE })
const open = (id, items, position) => {
store.set({ id, items, position, visible: true })
}
const close = () => {
store.set({ ...INITIAL_CONTEXT_MENU_STATE })
}
return {
subscribe: store.subscribe,
open,
close,
}
}
export const contextMenuStore = createViewsStore()

View File

@ -0,0 +1,46 @@
import { writable } from "svelte/store"
interface Position {
x: number
y: number
}
interface MenuItem {
label: string
icon?: string
action: () => void
}
interface ContextMenuState {
id: string | null
items: MenuItem[]
position: Position
visible: boolean
}
export const INITIAL_CONTEXT_MENU_STATE: ContextMenuState = {
id: null,
items: [],
position: { x: 0, y: 0 },
visible: false,
}
export function createViewsStore() {
const store = writable<ContextMenuState>({ ...INITIAL_CONTEXT_MENU_STATE })
const open = (id: string, items: MenuItem[], position: Position): void => {
store.set({ id, items, position, visible: true })
}
const close = (): void => {
store.set({ ...INITIAL_CONTEXT_MENU_STATE })
}
return {
subscribe: store.subscribe,
open,
close,
}
}
export const contextMenuStore = createViewsStore()

View File

@ -1,11 +1,12 @@
import { writable } from "svelte/store"
import { writable, type Writable } from "svelte/store"
import { API } from "api"
import { notifications } from "@budibase/bbui"
import { DeploymentProgressResponse } from "@budibase/types"
export const createDeploymentStore = () => {
let store = writable([])
let store: Writable<DeploymentProgressResponse[]> = writable([])
const load = async () => {
const load = async (): Promise<void> => {
try {
store.set(await API.getAppDeployments())
} catch (err) {

View File

@ -65,7 +65,7 @@ describe("Builder store", () => {
ctx.test.builderStore.reset()
expect(disconnected).toBe(true)
expect(ctx.test.store).toStrictEqual(INITIAL_BUILDER_STATE)
expect(ctx.test.builderStore.websocket).toBeNull()
expect(ctx.test.builderStore.websocket).toBeUndefined()
})
it("Attempt to emit a resource select event to the websocket on select", ctx => {