Merge pull request #15384 from Budibase/BUDI-8986/ground-work

Typing some components and returning 404 for views not found
This commit is contained in:
Adria Navarro 2025-01-20 15:20:39 +01:00 committed by GitHub
commit 7cededcd76
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 89 additions and 60 deletions

View File

@ -1,23 +1,23 @@
<script>
<script lang="ts">
import {
default as AbsTooltip,
TooltipPosition,
TooltipType,
} from "../Tooltip/AbsTooltip.svelte"
export let name = "Add"
export let hidden = false
export let name: string = "Add"
export let hidden: boolean = false
export let size = "M"
export let hoverable = false
export let disabled = false
export let color = undefined
export let hoverColor = undefined
export let tooltip = undefined
export let hoverable: boolean = false
export let disabled: boolean = false
export let color: string | undefined = undefined
export let hoverColor: string | undefined = undefined
export let tooltip: string | undefined = undefined
export let tooltipPosition = TooltipPosition.Bottom
export let tooltipType = TooltipType.Default
export let tooltipColor = undefined
export let tooltipWrap = true
export let newStyles = false
export let tooltipColor: string | undefined = undefined
export let tooltipWrap: boolean = true
export let newStyles: boolean = false
</script>
<AbsTooltip

View File

@ -23,7 +23,7 @@
export let type = TooltipType.Default
export let text = ""
export let fixed = false
export let color = null
export let color = ""
export let noWrap = false
let wrapper

View File

@ -14,7 +14,6 @@
GroupUserDatasource,
DataFetchOptions,
} from "@budibase/types"
import { SDK, Component } from "../../index"
type ProviderDatasource = Exclude<
DataFetchDatasource,
@ -29,8 +28,8 @@
export let paginate: boolean
export let autoRefresh: number
const { styleable, Provider, ActionTypes, API } = getContext<SDK>("sdk")
const component = getContext<Component>("component")
const { styleable, Provider, ActionTypes, API } = getContext("sdk")
const component = getContext("component")
let interval: ReturnType<typeof setInterval>
let queryExtensions: Record<string, any> = {}

View File

@ -1,37 +1,43 @@
<script>
<script lang="ts">
import { getContext } from "svelte"
import InnerFormBlock from "./InnerFormBlock.svelte"
import { Utils } from "@budibase/frontend-core"
import FormBlockWrapper from "./FormBlockWrapper.svelte"
import { get } from "svelte/store"
import { TableSchema, UIDatasource } from "@budibase/types"
export let actionType
export let dataSource
export let size
export let disabled
export let fields
export let buttons
export let buttonPosition
export let title
export let description
export let rowId
export let actionUrl
export let noRowsMessage
export let notificationOverride
export let buttonsCollapsed
export let buttonsCollapsedText
type Field = { name: string; active: boolean }
export let actionType: string
export let dataSource: UIDatasource
export let size: string
export let disabled: boolean
export let fields: (Field | string)[]
export let buttons: {
"##eventHandlerType": string
parameters: Record<string, string>
}[]
export let buttonPosition: "top" | "bottom"
export let title: string
export let description: string
export let rowId: string
export let actionUrl: string
export let noRowsMessage: string
export let notificationOverride: boolean
export let buttonsCollapsed: boolean
export let buttonsCollapsedText: string
// Legacy
export let showDeleteButton
export let showSaveButton
export let saveButtonLabel
export let deleteButtonLabel
export let showDeleteButton: boolean
export let showSaveButton: boolean
export let saveButtonLabel: boolean
export let deleteButtonLabel: boolean
const { fetchDatasourceSchema, generateGoldenSample } = getContext("sdk")
const component = getContext("component")
const context = getContext("context")
let schema
let schema: TableSchema
$: fetchSchema(dataSource)
$: id = $component.id
@ -61,7 +67,7 @@
}
}
const convertOldFieldFormat = fields => {
const convertOldFieldFormat = (fields: (Field | string)[]): Field[] => {
if (!fields) {
return []
}
@ -82,11 +88,11 @@
})
}
const getDefaultFields = (fields, schema) => {
const getDefaultFields = (fields: Field[], schema: TableSchema) => {
if (!schema) {
return []
}
let defaultFields = []
let defaultFields: Field[] = []
if (!fields || fields.length === 0) {
Object.values(schema)
@ -101,15 +107,14 @@
return [...fields, ...defaultFields].filter(field => field.active)
}
const fetchSchema = async () => {
schema = (await fetchDatasourceSchema(dataSource)) || {}
const fetchSchema = async (datasource: UIDatasource) => {
schema = (await fetchDatasourceSchema(datasource)) || {}
}
</script>
<FormBlockWrapper {actionType} {dataSource} {rowId} {noRowsMessage}>
<InnerFormBlock
{dataSource}
{actionUrl}
{actionType}
{size}
{disabled}
@ -117,7 +122,6 @@
{title}
{description}
{schema}
{notificationOverride}
buttons={buttonsOrDefault}
buttonPosition={buttons ? buttonPosition : "top"}
{buttonsCollapsed}

View File

@ -1,11 +1,13 @@
<script>
<script lang="ts">
import { getContext } from "svelte"
import { Icon } from "@budibase/bbui"
import MissingRequiredSetting from "./MissingRequiredSetting.svelte"
import MissingRequiredAncestor from "./MissingRequiredAncestor.svelte"
export let missingRequiredSettings
export let missingRequiredAncestors
export let missingRequiredSettings:
| { key: string; label: string }[]
| undefined
export let missingRequiredAncestors: string[] | undefined
const component = getContext("component")
const { styleable, builderStore } = getContext("sdk")

7
packages/client/src/context.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
import { Component, Context, SDK } from "."
declare module "svelte" {
export function getContext(key: "sdk"): SDK
export function getContext(key: "component"): Component
export function getContext(key: "context"): Context
}

View File

@ -7,9 +7,17 @@ export interface SDK {
styleable: any
Provider: any
ActionTypes: typeof ActionTypes
fetchDatasourceSchema: any
generateGoldenSample: any
builderStore: Readable<{
inBuilder: boolean
}>
}
export type Component = Readable<{
id: string
styles: any
errorState: boolean
}>
export type Context = Readable<{}>

View File

@ -1,5 +1,6 @@
import { API } from "api"
import { DataFetchMap, DataFetchType } from "@budibase/frontend-core"
import { FieldType, TableSchema } from "@budibase/types"
/**
* Constructs a fetch instance for a given datasource.
@ -42,14 +43,14 @@ export const fetchDatasourceSchema = async <
}
// Get the normal schema as long as we aren't wanting a form schema
let schema: any
let schema: TableSchema | undefined
if (datasource?.type !== "query" || !options?.formSchema) {
schema = instance.getSchema(definition as any)
schema = instance.getSchema(definition as any) as TableSchema
} else if ("parameters" in definition && definition.parameters?.length) {
schema = {}
definition.parameters.forEach(param => {
schema[param.name] = { ...param, type: "string" }
})
for (const param of definition.parameters) {
schema[param.name] = { ...param, type: FieldType.STRING }
}
}
if (!schema) {
return null
@ -57,11 +58,11 @@ export const fetchDatasourceSchema = async <
// Strip hidden fields from views
if (datasource.type === "viewV2") {
Object.keys(schema).forEach(field => {
for (const field of Object.keys(schema)) {
if (!schema[field].visible) {
delete schema[field]
}
})
}
}
// Enrich schema with relationships if required

View File

@ -123,9 +123,11 @@ async function parseSchema(view: CreateViewRequest) {
}
export async function get(ctx: Ctx<void, ViewResponseEnriched>) {
ctx.body = {
data: await sdk.views.getEnriched(ctx.params.viewId),
const view = await sdk.views.getEnriched(ctx.params.viewId)
if (!view) {
ctx.throw(404)
}
ctx.body = { data: view }
}
export async function fetch(ctx: Ctx<void, ViewFetchResponseEnriched>) {

View File

@ -22,7 +22,9 @@ export async function get(viewId: string): Promise<ViewV2> {
return ensureQueryUISet(found)
}
export async function getEnriched(viewId: string): Promise<ViewV2Enriched> {
export async function getEnriched(
viewId: string
): Promise<ViewV2Enriched | undefined> {
const { tableId } = utils.extractViewInfoFromID(viewId)
const { datasourceId, tableName } = breakExternalTableId(tableId)
@ -32,7 +34,7 @@ export async function getEnriched(viewId: string): Promise<ViewV2Enriched> {
const views = Object.values(table.views!).filter(isV2)
const found = views.find(v => v.id === viewId)
if (!found) {
throw new Error("No view found")
return
}
return await enrichSchema(ensureQueryUISet(found), table.schema)
}

View File

@ -40,7 +40,9 @@ export async function get(viewId: string): Promise<ViewV2> {
return pickApi(tableId).get(viewId)
}
export async function getEnriched(viewId: string): Promise<ViewV2Enriched> {
export async function getEnriched(
viewId: string
): Promise<ViewV2Enriched | undefined> {
const { tableId } = utils.extractViewInfoFromID(viewId)
return pickApi(tableId).getEnriched(viewId)
}

View File

@ -17,13 +17,15 @@ export async function get(viewId: string): Promise<ViewV2> {
return ensureQueryUISet(found)
}
export async function getEnriched(viewId: string): Promise<ViewV2Enriched> {
export async function getEnriched(
viewId: string
): Promise<ViewV2Enriched | undefined> {
const { tableId } = utils.extractViewInfoFromID(viewId)
const table = await sdk.tables.getTable(tableId)
const views = Object.values(table.views!).filter(isV2)
const found = views.find(v => v.id === viewId)
if (!found) {
throw new Error("No view found")
return
}
return await enrichSchema(ensureQueryUISet(found), table.schema)
}