Initial typings

This commit is contained in:
Adria Navarro 2025-01-20 20:26:37 +01:00
parent 0c12217b14
commit 8160914bb3
2 changed files with 53 additions and 47 deletions

View File

@ -57,7 +57,7 @@ interface ComponentSetting {
interface ComponentState { interface ComponentState {
components: Record<string, ComponentDefinition> components: Record<string, ComponentDefinition>
customComponents: string[] customComponents: string[]
selectedComponentId: string | null selectedComponentId: string | null | undefined
componentToPaste?: Component | null componentToPaste?: Component | null
settingsCache: Record<string, ComponentSetting[]> settingsCache: Record<string, ComponentSetting[]>
selectedScreenId?: string | null selectedScreenId?: string | null
@ -478,10 +478,11 @@ export class ComponentStore extends BudiStore<ComponentState> {
extras._children = [] extras._children = []
} }
const $selectedScreen = get(selectedScreen)
// Add step name to form steps // Add step name to form steps
if (componentName.endsWith("/formstep")) { if (componentName.endsWith("/formstep") && $selectedScreen) {
const parentForm = findClosestMatchingComponent( const parentForm = findClosestMatchingComponent(
get(selectedScreen).props, $selectedScreen.props,
get(selectedComponent)._id, get(selectedComponent)._id,
(component: Component) => component._component.endsWith("/form") (component: Component) => component._component.endsWith("/form")
) )
@ -608,7 +609,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
async patch( async patch(
patchFn: (component: Component, screen: Screen) => any, patchFn: (component: Component, screen: Screen) => any,
componentId?: string, componentId?: string,
screenId?: string screenId?: string | null
) { ) {
// Use selected component by default // Use selected component by default
if (!componentId || !screenId) { if (!componentId || !screenId) {
@ -840,7 +841,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
getPrevious() { getPrevious() {
const state = get(this.store) const state = get(this.store)
const componentId = state.selectedComponentId const componentId = state.selectedComponentId
const screen = get(selectedScreen) const screen = get(selectedScreen)!
const parent = findComponentParent(screen.props, componentId) const parent = findComponentParent(screen.props, componentId)
const index = parent?._children.findIndex( const index = parent?._children.findIndex(
(x: Component) => x._id === componentId (x: Component) => x._id === componentId
@ -889,7 +890,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
const state = get(this.store) const state = get(this.store)
const component = get(selectedComponent) const component = get(selectedComponent)
const componentId = component?._id const componentId = component?._id
const screen = get(selectedScreen) const screen = get(selectedScreen)!
const parent = findComponentParent(screen.props, componentId) const parent = findComponentParent(screen.props, componentId)
const index = parent?._children.findIndex( const index = parent?._children.findIndex(
(x: Component) => x._id === componentId (x: Component) => x._id === componentId

View File

@ -13,11 +13,11 @@ import {
import { createHistoryStore } from "@/stores/builder/history" import { createHistoryStore } from "@/stores/builder/history"
import { API } from "@/api" import { API } from "@/api"
import { BudiStore } from "../BudiStore" import { BudiStore } from "../BudiStore"
import { Screen } from "@budibase/types" import { Component, Screen } from "@budibase/types"
interface ScreenState { interface ScreenState {
screens: Screen[] screens: Screen[]
selectedScreenId: string | null selectedScreenId: string | null | undefined
} }
export const INITIAL_SCREENS_STATE: ScreenState = { export const INITIAL_SCREENS_STATE: ScreenState = {
@ -43,7 +43,7 @@ export class ScreenStore extends BudiStore<ScreenState> {
this.sequentialScreenPatch = this.sequentialScreenPatch.bind(this) this.sequentialScreenPatch = this.sequentialScreenPatch.bind(this)
this.removeCustomLayout = this.removeCustomLayout.bind(this) this.removeCustomLayout = this.removeCustomLayout.bind(this)
this.history = createHistoryStore({ const history = createHistoryStore({
getDoc: id => get(this.store).screens?.find(screen => screen._id === id), getDoc: id => get(this.store).screens?.find(screen => screen._id === id),
selectDoc: this.select, selectDoc: this.select,
afterAction: () => { afterAction: () => {
@ -57,8 +57,8 @@ export class ScreenStore extends BudiStore<ScreenState> {
}, },
}) })
this.delete = this.history.wrapDeleteDoc(this.deleteScreen) this.delete = history.wrapDeleteDoc(this.deleteScreen)
this.save = this.history.wrapSaveDoc(this.saveScreen) this.save = history.wrapSaveDoc(this.saveScreen)
} }
/** /**
@ -72,7 +72,7 @@ export class ScreenStore extends BudiStore<ScreenState> {
* Replace ALL store screens with application package screens * Replace ALL store screens with application package screens
* @param {object} pkg * @param {object} pkg
*/ */
syncAppScreens(pkg) { syncAppScreens(pkg: { screens: Screen[] }) {
this.update(state => ({ this.update(state => ({
...state, ...state,
screens: [...pkg.screens], screens: [...pkg.screens],
@ -85,7 +85,7 @@ export class ScreenStore extends BudiStore<ScreenState> {
* @param {string} screenId * @param {string} screenId
* @returns * @returns
*/ */
select(screenId) { select(screenId: string) {
// Check this screen exists // Check this screen exists
const state = get(this.store) const state = get(this.store)
const screen = state.screens.find(screen => screen._id === screenId) const screen = state.screens.find(screen => screen._id === screenId)
@ -113,12 +113,12 @@ export class ScreenStore extends BudiStore<ScreenState> {
* @throws Will throw an error containing the name of the component causing * @throws Will throw an error containing the name of the component causing
* the invalid screen state * the invalid screen state
*/ */
validate(screen) { validate(screen: Screen) {
// Recursive function to find any illegal children in component trees // Recursive function to find any illegal children in component trees
const findIllegalChild = ( const findIllegalChild = (
component, component: Component,
illegalChildren = [], illegalChildren: string[] = [],
legalDirectChildren = [] legalDirectChildren: string[] = []
) => { ) => {
const type = component._component const type = component._component
@ -178,7 +178,7 @@ export class ScreenStore extends BudiStore<ScreenState> {
const illegalChild = findIllegalChild(screen.props) const illegalChild = findIllegalChild(screen.props)
if (illegalChild) { if (illegalChild) {
const def = componentStore.getDefinition(illegalChild) const def = componentStore.getDefinition(illegalChild)
throw `You can't place a ${def.name} here` throw `You can't place a ${def?.name} here`
} }
} }
@ -189,7 +189,7 @@ export class ScreenStore extends BudiStore<ScreenState> {
* @param {object} screen * @param {object} screen
* @returns {object} * @returns {object}
*/ */
async saveScreen(screen) { async saveScreen(screen: Screen): Promise<Screen> {
const appState = get(appStore) const appState = get(appStore)
// Validate screen structure if the app supports it // Validate screen structure if the app supports it
@ -236,7 +236,7 @@ export class ScreenStore extends BudiStore<ScreenState> {
* After saving a screen, sync plugins and routes to the appStore * After saving a screen, sync plugins and routes to the appStore
* @param {object} savedScreen * @param {object} savedScreen
*/ */
async syncScreenData(savedScreen) { async syncScreenData(savedScreen: Screen) {
const appState = get(appStore) const appState = get(appStore)
// If plugins changed we need to fetch the latest app metadata // If plugins changed we need to fetch the latest app metadata
let usedPlugins = appState.usedPlugins let usedPlugins = appState.usedPlugins
@ -262,7 +262,8 @@ export class ScreenStore extends BudiStore<ScreenState> {
* This is slightly better than just a traditional "patch" endpoint and this * This is slightly better than just a traditional "patch" endpoint and this
* supports deeply mutating the current doc rather than just appending data. * supports deeply mutating the current doc rather than just appending data.
*/ */
sequentialScreenPatch = Utils.sequential(async (patchFn, screenId) => { sequentialScreenPatch = Utils.sequential(
async (patchFn: (screen: Screen) => any, screenId: string) => {
const state = get(this.store) const state = get(this.store)
const screen = state.screens.find(screen => screen._id === screenId) const screen = state.screens.find(screen => screen._id === screenId)
if (!screen) { if (!screen) {
@ -276,7 +277,8 @@ export class ScreenStore extends BudiStore<ScreenState> {
return return
} }
return this.save(clone) return this.save(clone)
}) }
)
/** /**
* @param {function} patchFn * @param {function} patchFn
@ -304,7 +306,7 @@ export class ScreenStore extends BudiStore<ScreenState> {
* @param {object} screen * @param {object} screen
* @returns * @returns
*/ */
async replace(screenId, screen) { async replace(screenId: string, screen: Screen) {
if (!screenId) { if (!screenId) {
return return
} }
@ -343,14 +345,14 @@ export class ScreenStore extends BudiStore<ScreenState> {
* @param {object | array} screens * @param {object | array} screens
* @returns * @returns
*/ */
async deleteScreen(screens) { async deleteScreen(screens: Screen[]) {
const screensToDelete = Array.isArray(screens) ? screens : [screens] const screensToDelete = Array.isArray(screens) ? screens : [screens]
// Build array of promises to speed up bulk deletions // Build array of promises to speed up bulk deletions
let promises = [] let promises: Promise<any>[] = []
let deleteUrls = [] let deleteUrls: string[] = []
screensToDelete.forEach(screen => { screensToDelete.forEach(screen => {
// Delete the screen // Delete the screen
promises.push(API.deleteScreen(screen._id, screen._rev)) promises.push(API.deleteScreen(screen._id!, screen._rev!))
// Remove links to this screen // Remove links to this screen
deleteUrls.push(screen.routing.route) deleteUrls.push(screen.routing.route)
}) })
@ -365,7 +367,10 @@ export class ScreenStore extends BudiStore<ScreenState> {
}) })
// Deselect the current screen if it was deleted // Deselect the current screen if it was deleted
if (deletedIds.includes(state.selectedScreenId)) { if (
state.selectedScreenId &&
deletedIds.includes(state.selectedScreenId)
) {
state.selectedScreenId = null state.selectedScreenId = null
componentStore.update(state => ({ componentStore.update(state => ({
...state, ...state,
@ -395,13 +400,13 @@ export class ScreenStore extends BudiStore<ScreenState> {
* @param {any} value * @param {any} value
* @returns * @returns
*/ */
async updateSetting(screen, name, value) { async updateSetting(screen: Screen, name: string, value: string) {
if (!screen || !name) { if (!screen || !name) {
return return
} }
// Apply setting update // Apply setting update
const patchFn = screen => { const patchFn = (screen: Screen) => {
if (!screen) { if (!screen) {
return false return false
} }
@ -428,7 +433,7 @@ export class ScreenStore extends BudiStore<ScreenState> {
) )
}) })
if (otherHomeScreens.length && updatedScreen.routing.homeScreen) { if (otherHomeScreens.length && updatedScreen.routing.homeScreen) {
const patchFn = screen => { const patchFn = (screen: Screen) => {
screen.routing.homeScreen = false screen.routing.homeScreen = false
} }
for (let otherHomeScreen of otherHomeScreens) { for (let otherHomeScreen of otherHomeScreens) {
@ -438,11 +443,11 @@ export class ScreenStore extends BudiStore<ScreenState> {
} }
// Move to layouts store // Move to layouts store
async removeCustomLayout(screen) { async removeCustomLayout(screen: Screen) {
// Pull relevant settings from old layout, if required // Pull relevant settings from old layout, if required
const layout = get(layoutStore).layouts.find(x => x._id === screen.layoutId) const layout = get(layoutStore).layouts.find(x => x._id === screen.layoutId)
const patchFn = screen => { const patchFn = (screen: Screen) => {
screen.layoutId = null delete screen.layoutId
screen.showNavigation = layout?.props.navigation !== "None" screen.showNavigation = layout?.props.navigation !== "None"
screen.width = layout?.props.width || "Large" screen.width = layout?.props.width || "Large"
} }
@ -454,9 +459,9 @@ export class ScreenStore extends BudiStore<ScreenState> {
* and up-to-date. Ensures stability after a product update. * and up-to-date. Ensures stability after a product update.
* @param {object} screen * @param {object} screen
*/ */
async enrichEmptySettings(screen) { async enrichEmptySettings(screen: Screen) {
// Flatten the recursive component tree // Flatten the recursive component tree
const components = findAllMatchingComponents(screen.props, x => x) const components = findAllMatchingComponents(screen.props, (x: string) => x)
// Iterate over all components and run checks // Iterate over all components and run checks
components.forEach(component => { components.forEach(component => {