Merge branch 'master' into typing/stores-grid-users
This commit is contained in:
commit
184815ac7d
|
@ -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,
|
|
@ -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,
|
||||
}))
|
||||
}
|
||||
}
|
|
@ -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()
|
|
@ -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()
|
|
@ -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) {
|
|
@ -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 => {
|
||||
|
|
Loading…
Reference in New Issue