Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support view RBAC with forms and cache view definitions #14899

Merged
merged 5 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions packages/client/src/components/app/forms/Form.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

const context = getContext("context")
const component = getContext("component")
const { API, fetchDatasourceSchema } = getContext("sdk")
const { fetchDatasourceSchema, fetchDatasourceDefinition } = getContext("sdk")

const getInitialFormStep = () => {
const parsedFormStep = parseInt(initialFormStep)
Expand All @@ -32,9 +32,9 @@
return parsedFormStep
}

let loaded = false
let definition
let schema
let table
let loaded = false
let currentStep = getContext("current-step") || writable(getInitialFormStep())

$: fetchSchema(dataSource)
Expand Down Expand Up @@ -84,12 +84,10 @@

// Fetches the form schema from this form's dataSource
const fetchSchema = async dataSource => {
if (dataSource?.tableId && !dataSource?.type?.startsWith("query")) {
try {
table = await API.fetchTableDefinition(dataSource.tableId)
} catch (error) {
table = null
}
try {
definition = await fetchDatasourceDefinition(dataSource)
} catch (error) {
definition = null
}
const res = await fetchDatasourceSchema(dataSource)
schema = res || {}
Expand Down Expand Up @@ -121,7 +119,7 @@
{readonly}
{actionType}
{schema}
{table}
{definition}
{initialValues}
{disableSchemaValidation}
{editAutoColumns}
Expand Down
6 changes: 3 additions & 3 deletions packages/client/src/components/app/forms/InnerForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
export let initialValues
export let size
export let schema
export let table
export let definition
export let disableSchemaValidation = false
export let editAutoColumns = false

Expand Down Expand Up @@ -164,7 +164,7 @@
schemaConstraints,
validationRules,
field,
table
definition
)

// Sanitise the default value to ensure it doesn't contain invalid data
Expand Down Expand Up @@ -338,7 +338,7 @@
schemaConstraints,
validationRules,
field,
table
definition
)

// Update validator
Expand Down
8 changes: 4 additions & 4 deletions packages/client/src/components/app/forms/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@ import { Helpers } from "@budibase/bbui"
/**
* Creates a validation function from a combination of schema-level constraints
* and custom validation rules
* @param schemaConstraints any schema level constraints from the table
* @param schemaConstraints any schema level constraints from the datasource
* @param customRules any custom validation rules
* @param field the field name we are evaluating
* @param table the definition of the table we are evaluating
* @param definition the definition of the datasource we are evaluating
* @returns {function} a validator function which accepts test values
*/
export const createValidatorFromConstraints = (
schemaConstraints,
customRules,
field,
table
definition
) => {
let rules = []

// Convert schema constraints into validation rules
if (schemaConstraints) {
// Required constraint
if (
field === table?.primaryDisplay ||
field === definition?.primaryDisplay ||
schemaConstraints.presence?.allowEmpty === false ||
schemaConstraints.presence === true
) {
Expand Down
6 changes: 5 additions & 1 deletion packages/client/src/sdk.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ import Provider from "components/context/Provider.svelte"
import Block from "components/Block.svelte"
import BlockComponent from "components/BlockComponent.svelte"
import { ActionTypes } from "./constants"
import { fetchDatasourceSchema } from "./utils/schema.js"
import {
fetchDatasourceSchema,
fetchDatasourceDefinition,
} from "./utils/schema.js"
import { getAPIKey } from "./utils/api.js"
import { enrichButtonActions } from "./utils/buttonActions.js"
import { processStringSync, makePropSafe } from "@budibase/string-templates"
Expand Down Expand Up @@ -66,6 +69,7 @@ export default {
linkable,
getAction,
fetchDatasourceSchema,
fetchDatasourceDefinition,
fetchData,
QueryUtils,
ContextScopes: Constants.ContextScopes,
Expand Down
39 changes: 29 additions & 10 deletions packages/client/src/utils/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,13 @@ import ViewV2Fetch from "@budibase/frontend-core/src/fetch/ViewV2Fetch.js"
import QueryArrayFetch from "@budibase/frontend-core/src/fetch/QueryArrayFetch"

/**
* Fetches the schema of any kind of datasource.
* Constructs a fetch instance for a given datasource.
* All datasource fetch classes implement their own functionality to get the
* schema of a datasource of their respective types.
* @param datasource the datasource to fetch the schema for
* @param options options for enriching the schema
* @param datasource the datasource
* @returns
*/
export const fetchDatasourceSchema = async (
datasource,
options = { enrichRelationships: false, formSchema: false }
) => {
const getDatasourceFetchInstance = datasource => {
const handler = {
table: TableFetch,
view: ViewFetch,
Expand All @@ -34,10 +31,23 @@ export const fetchDatasourceSchema = async (
if (!handler) {
return null
}
const instance = new handler({ API })
return new handler({ API })
}

// Get the datasource definition and then schema
const definition = await instance.getDefinition(datasource)
/**
* Fetches the schema of any kind of datasource.
* @param datasource the datasource to fetch the schema for
* @param options options for enriching the schema
*/
export const fetchDatasourceSchema = async (
datasource,
options = { enrichRelationships: false, formSchema: false }
) => {
const instance = getDatasourceFetchInstance(datasource)
const definition = await instance?.getDefinition(datasource)
if (!definition) {
return null
}

// Get the normal schema as long as we aren't wanting a form schema
let schema
Expand Down Expand Up @@ -75,6 +85,15 @@ export const fetchDatasourceSchema = async (
return instance.enrichSchema(schema)
}

/**
* Fetches the definition of any kind of datasource.
* @param datasource the datasource to fetch the schema for
*/
export const fetchDatasourceDefinition = async datasource => {
const instance = getDatasourceFetchInstance(datasource)
return await instance?.getDefinition(datasource)
}

/**
* Fetches the schema of relationship fields for a SQL table schema
* @param schema the schema to enrich
Expand Down
1 change: 1 addition & 0 deletions packages/frontend-core/src/api/viewsV2.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const buildViewV2Endpoints = API => ({
fetchDefinition: async viewId => {
return await API.get({
url: `/api/v2/views/${encodeURIComponent(viewId)}`,
cache: true,
})
},
/**
Expand Down
Loading