Skip to content

Commit

Permalink
Merge branch 'master' into type-portal-oidc-store
Browse files Browse the repository at this point in the history
  • Loading branch information
aptkingston authored Jan 9, 2025
2 parents 833cb84 + b50e2c7 commit 4d0a1b0
Show file tree
Hide file tree
Showing 40 changed files with 688 additions and 379 deletions.
3 changes: 3 additions & 0 deletions packages/bbui/src/helpers.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module "./helpers" {
export const cloneDeep: <T>(obj: T) => T
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
export let showDataProviders = true
const dispatch = createEventDispatcher()
const arrayTypes = ["attachment", "array"]
let anchorRight, dropdownRight
let drawer
Expand Down Expand Up @@ -116,8 +115,11 @@
}
})
$: fields = bindings
.filter(x => arrayTypes.includes(x.fieldSchema?.type))
.filter(x => x.fieldSchema?.tableId != null)
.filter(
x =>
x.fieldSchema?.type === "attachment" ||
(x.fieldSchema?.type === "array" && x.tableId)
)
.map(binding => {
const { providerId, readableBinding, runtimeBinding } = binding
const { name, type, tableId } = binding.fieldSchema
Expand Down
16 changes: 8 additions & 8 deletions packages/client/src/utils/schema.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { API } from "api"
import TableFetch from "@budibase/frontend-core/src/fetch/TableFetch.js"
import ViewFetch from "@budibase/frontend-core/src/fetch/ViewFetch.js"
import QueryFetch from "@budibase/frontend-core/src/fetch/QueryFetch.js"
import RelationshipFetch from "@budibase/frontend-core/src/fetch/RelationshipFetch.js"
import NestedProviderFetch from "@budibase/frontend-core/src/fetch/NestedProviderFetch.js"
import FieldFetch from "@budibase/frontend-core/src/fetch/FieldFetch.js"
import JSONArrayFetch from "@budibase/frontend-core/src/fetch/JSONArrayFetch.js"
import ViewV2Fetch from "@budibase/frontend-core/src/fetch/ViewV2Fetch.js"
import TableFetch from "@budibase/frontend-core/src/fetch/TableFetch"
import ViewFetch from "@budibase/frontend-core/src/fetch/ViewFetch"
import QueryFetch from "@budibase/frontend-core/src/fetch/QueryFetch"
import RelationshipFetch from "@budibase/frontend-core/src/fetch/RelationshipFetch"
import NestedProviderFetch from "@budibase/frontend-core/src/fetch/NestedProviderFetch"
import FieldFetch from "@budibase/frontend-core/src/fetch/FieldFetch"
import JSONArrayFetch from "@budibase/frontend-core/src/fetch/JSONArrayFetch"
import ViewV2Fetch from "@budibase/frontend-core/src/fetch/ViewV2Fetch"
import QueryArrayFetch from "@budibase/frontend-core/src/fetch/QueryArrayFetch"

/**
Expand Down
14 changes: 12 additions & 2 deletions packages/frontend-core/src/api/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ import { BaseAPIClient } from "./types"

export interface ViewEndpoints {
// Missing request or response types
fetchViewData: (name: string, opts: any) => Promise<Row[]>
fetchViewData: (
name: string,
opts: {
calculation?: string
field?: string
groupBy?: string
tableId: string
}
) => Promise<Row[]>
exportView: (name: string, format: string) => Promise<any>
saveView: (view: any) => Promise<any>
deleteView: (name: string) => Promise<any>
Expand All @@ -20,7 +28,9 @@ export const buildViewEndpoints = (API: BaseAPIClient): ViewEndpoints => ({
fetchViewData: async (name, { field, groupBy, calculation }) => {
const params = new URLSearchParams()
if (calculation) {
params.set("field", field)
if (field) {
params.set("field", field)
}
params.set("calculation", calculation)
}
if (groupBy) {
Expand Down
13 changes: 9 additions & 4 deletions packages/frontend-core/src/api/viewsV2.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
CreateViewRequest,
CreateViewResponse,
PaginatedSearchRowResponse,
SearchRowResponse,
SearchViewRowRequest,
UpdateViewRequest,
Expand All @@ -13,10 +14,14 @@ export interface ViewV2Endpoints {
fetchDefinition: (viewId: string) => Promise<ViewResponseEnriched>
create: (view: CreateViewRequest) => Promise<CreateViewResponse>
update: (view: UpdateViewRequest) => Promise<UpdateViewResponse>
fetch: (
fetch: <T extends SearchViewRowRequest>(
viewId: string,
opts: SearchViewRowRequest
) => Promise<SearchRowResponse>
opts: T
) => Promise<
T extends { paginate: true }
? PaginatedSearchRowResponse
: SearchRowResponse
>
delete: (viewId: string) => Promise<void>
}

Expand Down Expand Up @@ -59,7 +64,7 @@ export const buildViewV2Endpoints = (API: BaseAPIClient): ViewV2Endpoints => ({
* @param viewId the id of the view
* @param opts the search options
*/
fetch: async (viewId, opts) => {
fetch: async (viewId, opts: SearchViewRowRequest) => {
return await API.post({
url: `/api/v2/views/${encodeURIComponent(viewId)}/search`,
body: opts,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const deriveStores = (context: StoreContext): ConfigDerivedStore => {
}

// Disable features for non DS+
if (!["table", "viewV2"].includes(type)) {
if (type && !["table", "viewV2"].includes(type)) {
config.canAddRows = false
config.canEditRows = false
config.canDeleteRows = false
Expand Down
22 changes: 12 additions & 10 deletions packages/frontend-core/src/components/grid/stores/datasource.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// TODO: datasource and defitions are unions of the different implementations. At this point, the datasource does not know what type is being used, and the assignations will cause TS exceptions. Casting it "as any" for now. This should be fixed improving the type usages.

import { derived, get, Readable, Writable } from "svelte/store"
import { getDatasourceDefinition, getDatasourceSchema } from "../../../fetch"
import { enrichSchemaWithRelColumns, memo } from "../../../utils"
Expand Down Expand Up @@ -71,18 +73,18 @@ export const deriveStores = (context: StoreContext): DerivedDatasourceStore => {
} = context

const schema = derived(definition, $definition => {
let schema: Record<string, UIFieldSchema> = getDatasourceSchema({
const schema: Record<string, any> | undefined = getDatasourceSchema({
API,
datasource: get(datasource),
definition: $definition,
datasource: get(datasource) as any, // TODO: see line 1
definition: $definition ?? undefined,
})
if (!schema) {
return null
}

// Ensure schema is configured as objects.
// Certain datasources like queries use primitives.
Object.keys(schema || {}).forEach(key => {
Object.keys(schema).forEach(key => {
if (typeof schema[key] !== "object") {
schema[key] = { name: key, type: schema[key] }
}
Expand Down Expand Up @@ -130,13 +132,13 @@ export const deriveStores = (context: StoreContext): DerivedDatasourceStore => {
([$datasource, $definition]) => {
let type = $datasource?.type
if (type === "provider") {
type = ($datasource as any).value?.datasource?.type
type = ($datasource as any).value?.datasource?.type // TODO: see line 1
}
// Handle calculation views
if (type === "viewV2" && $definition?.type === ViewV2Type.CALCULATION) {
return false
}
return ["table", "viewV2", "link"].includes(type)
return !!type && ["table", "viewV2", "link"].includes(type)
}
)

Expand Down Expand Up @@ -184,9 +186,9 @@ export const createActions = (context: StoreContext): ActionDatasourceStore => {
const refreshDefinition = async () => {
const def = await getDatasourceDefinition({
API,
datasource: get(datasource),
datasource: get(datasource) as any, // TODO: see line 1
})
definition.set(def)
definition.set(def as any) // TODO: see line 1
}

// Saves the datasource definition
Expand Down Expand Up @@ -231,7 +233,7 @@ export const createActions = (context: StoreContext): ActionDatasourceStore => {
if ("default" in newDefinition.schema[column]) {
delete newDefinition.schema[column].default
}
return await saveDefinition(newDefinition as any)
return await saveDefinition(newDefinition as any) // TODO: see line 1
}

// Adds a schema mutation for a single field
Expand Down Expand Up @@ -307,7 +309,7 @@ export const createActions = (context: StoreContext): ActionDatasourceStore => {
await saveDefinition({
...$definition,
schema: newSchema,
} as any)
} as any) // TODO: see line 1
resetSchemaMutations()
}

Expand Down
9 changes: 5 additions & 4 deletions packages/frontend-core/src/components/grid/stores/rows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ import {
import { tick } from "svelte"
import { Helpers } from "@budibase/bbui"
import { sleep } from "../../../utils/utils"
import { FieldType, Row, UIFetchAPI, UIRow } from "@budibase/types"
import { FieldType, Row, UIRow } from "@budibase/types"
import { getRelatedTableValues } from "../../../utils"
import { Store as StoreContext } from "."
import DataFetch from "../../../fetch/DataFetch"

interface IndexedUIRow extends UIRow {
__idx: number
}

interface RowStore {
rows: Writable<UIRow[]>
fetch: Writable<UIFetchAPI | null>
fetch: Writable<DataFetch<any, any, any> | null> // TODO: type this properly, having a union of all the possible options
loaded: Writable<boolean>
refreshing: Writable<boolean>
loading: Writable<boolean>
Expand Down Expand Up @@ -225,7 +226,7 @@ export const createActions = (context: StoreContext): RowActionStore => {
})

// Subscribe to changes of this fetch model
unsubscribe = newFetch.subscribe(async ($fetch: UIFetchAPI) => {
unsubscribe = newFetch.subscribe(async $fetch => {
if ($fetch.error) {
// Present a helpful error to the user
let message = "An unknown error occurred"
Expand Down Expand Up @@ -253,7 +254,7 @@ export const createActions = (context: StoreContext): RowActionStore => {

// Reset state properties when dataset changes
if (!$instanceLoaded || resetRows) {
definition.set($fetch.definition)
definition.set($fetch.definition as any) // TODO: datasource and defitions are unions of the different implementations. At this point, the datasource does not know what type is being used, and the assignations will cause TS exceptions. Casting it "as any" for now. This should be fixed improving the type usages.
}

// Reset scroll state when data changes
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend-core/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export const Cookies = {
}

// Table names
export const TableNames = {
USERS: "ta_users",
export const enum TableNames {
USERS = "ta_users",
}

export const BudibaseRoles = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import DataFetch from "./DataFetch.js"
import DataFetch from "./DataFetch"

export default class CustomFetch extends DataFetch {
interface CustomDatasource {
data: any
}

type CustomDefinition = Record<string, any>

export default class CustomFetch extends DataFetch<
CustomDatasource,
CustomDefinition
> {
// Gets the correct Budibase type for a JS value
getType(value) {
getType(value: any) {
if (value == null) {
return "string"
}
Expand All @@ -22,7 +31,7 @@ export default class CustomFetch extends DataFetch {
}

// Parses the custom data into an array format
parseCustomData(data) {
parseCustomData(data: any) {
if (!data) {
return []
}
Expand Down Expand Up @@ -55,7 +64,7 @@ export default class CustomFetch extends DataFetch {
}

// Enriches the custom data to ensure the structure and format is usable
enrichCustomData(data) {
enrichCustomData(data: (string | any)[]) {
if (!data?.length) {
return []
}
Expand All @@ -72,7 +81,7 @@ export default class CustomFetch extends DataFetch {
// Try parsing strings
if (typeof value === "string") {
const split = value.split(",").map(x => x.trim())
let obj = {}
const obj: Record<string, string> = {}
for (let i = 0; i < split.length; i++) {
const suffix = i === 0 ? "" : ` ${i + 1}`
const key = `Value${suffix}`
Expand All @@ -87,27 +96,29 @@ export default class CustomFetch extends DataFetch {
}

// Extracts and parses the custom data from the datasource definition
getCustomData(datasource) {
getCustomData(datasource: CustomDatasource) {
return this.enrichCustomData(this.parseCustomData(datasource?.data))
}

async getDefinition(datasource) {
async getDefinition() {
const { datasource } = this.options

// Try and work out the schema from the array provided
let schema = {}
const schema: CustomDefinition = {}
const data = this.getCustomData(datasource)
if (!data?.length) {
return { schema }
}

// Go through every object and extract all valid keys
for (let datum of data) {
for (let key of Object.keys(datum)) {
for (const datum of data) {
for (const key of Object.keys(datum)) {
if (key === "_id") {
continue
}
if (!schema[key]) {
let type = this.getType(datum[key])
let constraints = {}
const constraints: any = {}

// Determine whether we should render text columns as options instead
if (type === "string") {
Expand Down
Loading

0 comments on commit 4d0a1b0

Please sign in to comment.