Merge branch 'master' of github.com:Budibase/budibase into feature/frontend-js-performance
This commit is contained in:
commit
65f9c26666
|
@ -293,7 +293,7 @@
|
||||||
type: RowSelector,
|
type: RowSelector,
|
||||||
props: {
|
props: {
|
||||||
row: inputData["oldRow"] || {
|
row: inputData["oldRow"] || {
|
||||||
tableId: inputData["row"].tableId,
|
tableId: inputData["row"]?.tableId,
|
||||||
},
|
},
|
||||||
meta: {
|
meta: {
|
||||||
fields: inputData["meta"]?.oldFields || {},
|
fields: inputData["meta"]?.oldFields || {},
|
||||||
|
|
|
@ -9,3 +9,4 @@ export {
|
||||||
lowercase,
|
lowercase,
|
||||||
isBuilderInputFocused,
|
isBuilderInputFocused,
|
||||||
} from "./helpers"
|
} from "./helpers"
|
||||||
|
export * as featureFlag from "./featureFlags"
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
import { Component, Screen, ScreenProps } from "@budibase/types"
|
import { Component, Screen, ScreenProps } from "@budibase/types"
|
||||||
import clientManifest from "@budibase/client/manifest.json"
|
import clientManifest from "@budibase/client/manifest.json"
|
||||||
|
|
||||||
export function findComponentsBySettingsType(screen: Screen, type: string) {
|
export function findComponentsBySettingsType(
|
||||||
|
screen: Screen,
|
||||||
|
type: string | string[]
|
||||||
|
) {
|
||||||
|
const typesArray = Array.isArray(type) ? type : [type]
|
||||||
|
|
||||||
const result: {
|
const result: {
|
||||||
component: Component
|
component: Component
|
||||||
setting: {
|
setting: {
|
||||||
|
@ -9,10 +14,7 @@ export function findComponentsBySettingsType(screen: Screen, type: string) {
|
||||||
key: string
|
key: string
|
||||||
}
|
}
|
||||||
}[] = []
|
}[] = []
|
||||||
function recurseFieldComponentsInChildren(
|
function recurseFieldComponentsInChildren(component: ScreenProps) {
|
||||||
component: ScreenProps,
|
|
||||||
type: string
|
|
||||||
) {
|
|
||||||
if (!component) {
|
if (!component) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -20,7 +22,7 @@ export function findComponentsBySettingsType(screen: Screen, type: string) {
|
||||||
const definition = getManifestDefinition(component)
|
const definition = getManifestDefinition(component)
|
||||||
const setting =
|
const setting =
|
||||||
"settings" in definition &&
|
"settings" in definition &&
|
||||||
definition.settings.find((s: any) => s.type === type)
|
definition.settings.find((s: any) => typesArray.includes(s.type))
|
||||||
if (setting && "type" in setting) {
|
if (setting && "type" in setting) {
|
||||||
result.push({
|
result.push({
|
||||||
component,
|
component,
|
||||||
|
@ -28,11 +30,11 @@ export function findComponentsBySettingsType(screen: Screen, type: string) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
component._children?.forEach(child => {
|
component._children?.forEach(child => {
|
||||||
recurseFieldComponentsInChildren(child, type)
|
recurseFieldComponentsInChildren(child)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
recurseFieldComponentsInChildren(screen?.props, type)
|
recurseFieldComponentsInChildren(screen?.props)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,51 +3,67 @@ import { tables } from "./tables"
|
||||||
import { selectedScreen } from "./screens"
|
import { selectedScreen } from "./screens"
|
||||||
import { viewsV2 } from "./viewsV2"
|
import { viewsV2 } from "./viewsV2"
|
||||||
import { findComponentsBySettingsType } from "@/helpers/screen"
|
import { findComponentsBySettingsType } from "@/helpers/screen"
|
||||||
import { Screen, Table, ViewV2 } from "@budibase/types"
|
import { UIDatasourceType, Screen } from "@budibase/types"
|
||||||
|
import { queries } from "./queries"
|
||||||
|
import { views } from "./views"
|
||||||
|
import { featureFlag } from "@/helpers"
|
||||||
|
|
||||||
|
function reduceBy<TItem extends {}, TKey extends keyof TItem>(
|
||||||
|
key: TKey,
|
||||||
|
list: TItem[]
|
||||||
|
) {
|
||||||
|
return list.reduce(
|
||||||
|
(result, item) => ({
|
||||||
|
...result,
|
||||||
|
[item[key] as string]: item,
|
||||||
|
}),
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const friendlyNameByType: Partial<Record<UIDatasourceType, string>> = {
|
||||||
|
viewV2: "view",
|
||||||
|
}
|
||||||
|
|
||||||
|
const validationKeyByType: Record<UIDatasourceType, string | null> = {
|
||||||
|
table: "tableId",
|
||||||
|
view: "name",
|
||||||
|
viewV2: "id",
|
||||||
|
query: "_id",
|
||||||
|
custom: null,
|
||||||
|
}
|
||||||
|
|
||||||
export const screenComponentErrors = derived(
|
export const screenComponentErrors = derived(
|
||||||
[selectedScreen, tables, viewsV2],
|
[selectedScreen, tables, views, viewsV2, queries],
|
||||||
([$selectedScreen, $tables, $viewsV2]): Record<string, string[]> => {
|
([$selectedScreen, $tables, $views, $viewsV2, $queries]): Record<
|
||||||
function flattenTablesAndViews(tables: Table[], views: ViewV2[]) {
|
string,
|
||||||
return {
|
string[]
|
||||||
...tables.reduce(
|
> => {
|
||||||
(list, table) => ({
|
if (!featureFlag.isEnabled("CHECK_SCREEN_COMPONENT_SETTINGS_ERRORS")) {
|
||||||
...list,
|
return {}
|
||||||
[table._id!]: table,
|
|
||||||
}),
|
|
||||||
{}
|
|
||||||
),
|
|
||||||
...views.reduce(
|
|
||||||
(list, view) => ({
|
|
||||||
...list,
|
|
||||||
[view.id]: view,
|
|
||||||
}),
|
|
||||||
{}
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInvalidDatasources(
|
function getInvalidDatasources(
|
||||||
screen: Screen,
|
screen: Screen,
|
||||||
datasources: Record<string, any>
|
datasources: Record<string, any>
|
||||||
) {
|
) {
|
||||||
const friendlyNameByType = {
|
|
||||||
table: "table",
|
|
||||||
view: "view",
|
|
||||||
viewV2: "view",
|
|
||||||
}
|
|
||||||
|
|
||||||
const result: Record<string, string[]> = {}
|
const result: Record<string, string[]> = {}
|
||||||
for (const { component, setting } of findComponentsBySettingsType(
|
for (const { component, setting } of findComponentsBySettingsType(
|
||||||
screen,
|
screen,
|
||||||
"table"
|
["table", "dataSource"]
|
||||||
)) {
|
)) {
|
||||||
const { resourceId, type, label } = component[setting.key]
|
const componentSettings = component[setting.key]
|
||||||
|
const { label } = componentSettings
|
||||||
|
const type = componentSettings.type as UIDatasourceType
|
||||||
|
|
||||||
|
const validationKey = validationKeyByType[type]
|
||||||
|
if (!validationKey) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const resourceId = componentSettings[validationKey]
|
||||||
if (!datasources[resourceId]) {
|
if (!datasources[resourceId]) {
|
||||||
const friendlyTypeName =
|
const friendlyTypeName = friendlyNameByType[type] ?? type
|
||||||
friendlyNameByType[type as keyof typeof friendlyNameByType]
|
|
||||||
result[component._id!] = [
|
result[component._id!] = [
|
||||||
`The ${friendlyTypeName} named "${label}" does not exist`,
|
`The ${friendlyTypeName} named "${label}" could not be found`,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +71,13 @@ export const screenComponentErrors = derived(
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const datasources = flattenTablesAndViews($tables.list, $viewsV2.list)
|
const datasources = {
|
||||||
|
...reduceBy("_id", $tables.list),
|
||||||
|
...reduceBy("name", $views.list),
|
||||||
|
...reduceBy("id", $viewsV2.list),
|
||||||
|
...reduceBy("_id", $queries.list),
|
||||||
|
}
|
||||||
|
|
||||||
return getInvalidDatasources($selectedScreen, datasources)
|
return getInvalidDatasources($selectedScreen, datasources)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
.component-placeholder {
|
.component-placeholder {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: flex-start;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: var(--spectrum-global-color-gray-600);
|
color: var(--spectrum-global-color-gray-600);
|
||||||
font-size: var(--font-size-s);
|
font-size: var(--font-size-s);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
export enum FeatureFlag {
|
export enum FeatureFlag {
|
||||||
USE_ZOD_VALIDATOR = "USE_ZOD_VALIDATOR",
|
USE_ZOD_VALIDATOR = "USE_ZOD_VALIDATOR",
|
||||||
|
CHECK_SCREEN_COMPONENT_SETTINGS_ERRORS = "CHECK_SCREEN_COMPONENT_SETTINGS_ERRORS",
|
||||||
|
|
||||||
// Account-portal
|
// Account-portal
|
||||||
DIRECT_LOGIN_TO_ACCOUNT_PORTAL = "DIRECT_LOGIN_TO_ACCOUNT_PORTAL",
|
DIRECT_LOGIN_TO_ACCOUNT_PORTAL = "DIRECT_LOGIN_TO_ACCOUNT_PORTAL",
|
||||||
|
@ -7,6 +8,7 @@ export enum FeatureFlag {
|
||||||
|
|
||||||
export const FeatureFlagDefaults = {
|
export const FeatureFlagDefaults = {
|
||||||
[FeatureFlag.USE_ZOD_VALIDATOR]: false,
|
[FeatureFlag.USE_ZOD_VALIDATOR]: false,
|
||||||
|
[FeatureFlag.CHECK_SCREEN_COMPONENT_SETTINGS_ERRORS]: false,
|
||||||
|
|
||||||
// Account-portal
|
// Account-portal
|
||||||
[FeatureFlag.DIRECT_LOGIN_TO_ACCOUNT_PORTAL]: false,
|
[FeatureFlag.DIRECT_LOGIN_TO_ACCOUNT_PORTAL]: false,
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
export type UIDatasourceType = "table" | "view" | "viewV2" | "query" | "custom"
|
|
@ -2,3 +2,4 @@ export * from "./stores"
|
||||||
export * from "./bindings"
|
export * from "./bindings"
|
||||||
export * from "./components"
|
export * from "./components"
|
||||||
export * from "./dataFetch"
|
export * from "./dataFetch"
|
||||||
|
export * from "./datasource"
|
||||||
|
|
Loading…
Reference in New Issue