✨ Add NocoDB block (#1365)
#970 #997 Fully integrate NocoDB. Added all API Functions: - List Table Records - Create Table Records - Update Table Records - Delete Table Records - Read Table Record - Count Table Records - List Linked Records - Link Records - Unlink Records Optional Todo: - Save responses of non-get requests in a variable (error validation try-catch is added and logged so i do not think so it is much needed) You are free to implement any extra validation/function :D --------- Co-authored-by: Baptiste Arnaud <baptiste.arnaud95@gmail.com>
This commit is contained in:
committed by
GitHub
parent
3e4e7531f6
commit
a17781dfa6
@@ -6,12 +6,14 @@ import { ZodObjectLayout } from './zodLayouts/ZodObjectLayout'
|
||||
import { ZodActionDiscriminatedUnion } from './zodLayouts/ZodActionDiscriminatedUnion'
|
||||
import { useForgedBlock } from '../hooks/useForgedBlock'
|
||||
import { ForgedBlock } from '@typebot.io/forge-repository/types'
|
||||
import { useState } from 'react'
|
||||
|
||||
type Props = {
|
||||
block: ForgedBlock
|
||||
onOptionsChange: (options: BlockOptions) => void
|
||||
}
|
||||
export const ForgedBlockSettings = ({ block, onOptionsChange }: Props) => {
|
||||
const [keySuffix, setKeySuffix] = useState<number>(0)
|
||||
const { blockDef, blockSchema, actionDef } = useForgedBlock(
|
||||
block.type,
|
||||
block.options?.action
|
||||
@@ -32,7 +34,10 @@ export const ForgedBlockSettings = ({ block, onOptionsChange }: Props) => {
|
||||
const actionOptions = actionOptionsKeys.reduce(
|
||||
(acc, key) => ({
|
||||
...acc,
|
||||
[key]: undefined,
|
||||
[key]:
|
||||
block.options[key] && typeof block.options[key] !== 'object'
|
||||
? block.options[key]
|
||||
: undefined,
|
||||
}),
|
||||
{}
|
||||
)
|
||||
@@ -40,6 +45,7 @@ export const ForgedBlockSettings = ({ block, onOptionsChange }: Props) => {
|
||||
...updates,
|
||||
...actionOptions,
|
||||
})
|
||||
setKeySuffix((prev) => prev + 1)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -85,6 +91,7 @@ export const ForgedBlockSettings = ({ block, onOptionsChange }: Props) => {
|
||||
/>
|
||||
)}
|
||||
<ZodActionDiscriminatedUnion
|
||||
key={block.id + keySuffix}
|
||||
schema={blockSchema.shape.options}
|
||||
blockDef={blockDef}
|
||||
blockOptions={block.options}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { NumberInput, TextInput, Textarea } from '@/components/inputs'
|
||||
import { z } from '@typebot.io/forge/zod'
|
||||
import { ZodLayoutMetadata } from '@typebot.io/forge/zod'
|
||||
import { evaluateIsHidden } from '@typebot.io/forge/zod/helpers/evaluateIsHidden'
|
||||
import Markdown, { Components } from 'react-markdown'
|
||||
import { ZodTypeAny } from 'zod'
|
||||
import { ForgeSelectInput } from '../ForgeSelectInput'
|
||||
@@ -64,7 +65,7 @@ export const ZodFieldLayout = ({
|
||||
const innerSchema = getZodInnerSchema(schema)
|
||||
const layout = innerSchema._def.layout
|
||||
|
||||
if (layout?.isHidden) return null
|
||||
if (evaluateIsHidden(layout?.isHidden, blockOptions)) return null
|
||||
|
||||
switch (innerSchema._def.typeName) {
|
||||
case 'ZodObject':
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
ForgedBlock,
|
||||
} from '@typebot.io/forge-repository/types'
|
||||
import { getZodInnerSchema } from '../../helpers/getZodInnerSchema'
|
||||
import { evaluateIsHidden } from '@typebot.io/forge/zod/helpers/evaluateIsHidden'
|
||||
|
||||
export const ZodObjectLayout = ({
|
||||
schema,
|
||||
@@ -37,20 +38,23 @@ export const ZodObjectLayout = ({
|
||||
blockOptions?: ForgedBlock['options']
|
||||
onDataChange: (value: any) => void
|
||||
}): ReactNode[] => {
|
||||
const layout = getZodInnerSchema(schema)._def.layout
|
||||
if (layout?.isHidden) return []
|
||||
return Object.keys(schema.shape).reduce<{
|
||||
const innerSchema = getZodInnerSchema(schema)
|
||||
const shape =
|
||||
'shape' in innerSchema ? innerSchema.shape : innerSchema._def.shape()
|
||||
const layout = innerSchema._def.layout
|
||||
if (evaluateIsHidden(layout?.isHidden, blockOptions)) return []
|
||||
return Object.keys(shape).reduce<{
|
||||
nodes: ReactNode[]
|
||||
accordionsCreated: string[]
|
||||
}>(
|
||||
(nodes, key, index) => {
|
||||
if (ignoreKeys?.includes(key)) return nodes
|
||||
const keySchema = getZodInnerSchema(schema.shape[key])
|
||||
const keySchema = getZodInnerSchema(shape[key])
|
||||
const layout = keySchema._def.layout as
|
||||
| ZodLayoutMetadata<ZodTypeAny>
|
||||
| undefined
|
||||
|
||||
if (layout?.isHidden) return nodes
|
||||
if (evaluateIsHidden(layout?.isHidden, blockOptions)) return nodes
|
||||
if (
|
||||
layout &&
|
||||
layout.accordion &&
|
||||
@@ -60,7 +64,7 @@ export const ZodObjectLayout = ({
|
||||
if (nodes.accordionsCreated.includes(layout.accordion)) return nodes
|
||||
const accordionKeys = getObjectKeysWithSameAccordionAttr(
|
||||
layout.accordion,
|
||||
schema
|
||||
shape
|
||||
)
|
||||
return {
|
||||
nodes: [
|
||||
@@ -77,7 +81,7 @@ export const ZodObjectLayout = ({
|
||||
{accordionKeys.map((accordionKey, idx) => (
|
||||
<ZodFieldLayout
|
||||
key={accordionKey + idx}
|
||||
schema={schema.shape[accordionKey]}
|
||||
schema={shape[accordionKey]}
|
||||
data={data?.[accordionKey]}
|
||||
onDataChange={(val) =>
|
||||
onDataChange({ ...data, [accordionKey]: val })
|
||||
@@ -118,12 +122,9 @@ export const ZodObjectLayout = ({
|
||||
).nodes
|
||||
}
|
||||
|
||||
const getObjectKeysWithSameAccordionAttr = (
|
||||
accordion: string,
|
||||
schema: z.ZodObject<any>
|
||||
) =>
|
||||
Object.keys(schema.shape).reduce<string[]>((keys, currentKey) => {
|
||||
const l = schema.shape[currentKey]._def.layout as
|
||||
const getObjectKeysWithSameAccordionAttr = (accordion: string, shape: any) =>
|
||||
Object.keys(shape).reduce<string[]>((keys, currentKey) => {
|
||||
const l = shape[currentKey]._def.layout as
|
||||
| ZodLayoutMetadata<ZodTypeAny>
|
||||
| undefined
|
||||
return !l?.accordion || l.accordion !== accordion
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
title: Anthropic
|
||||
---
|
||||
|
||||
<Warning>
|
||||
There is an ongoing issue with Anthropic block streaming capabilities. We are
|
||||
working on a fix and will update this page once the issue is resolved.
|
||||
</Warning>
|
||||
|
||||
## Create Message
|
||||
|
||||
With the Anthropic block, you can create chat messages based on your user queries and display the answer back to your typebot using Claude AI.
|
||||
|
||||
31
apps/docs/editor/blocks/integrations/nocodb.mdx
Normal file
31
apps/docs/editor/blocks/integrations/nocodb.mdx
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: NocoDB
|
||||
---
|
||||
|
||||
With the NocoDB block, you can create, update or get data from your NocoDB tables.
|
||||
|
||||
## How to find my `Table ID`?
|
||||
|
||||
To find your `Table ID`, you need to go to your NocoDB dashboard and click on the 3 dots button next to your table name.
|
||||
|
||||
<Frame>
|
||||
<img
|
||||
src="/images/blocks/integrations/nocodb-table-id.jpg"
|
||||
alt="NocoDB table ID"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
## Search Records
|
||||
|
||||
This action allows you to search for existing records in a table. It requires your `Table ID` and can optionally take a `View ID` to search in a specific view.
|
||||
|
||||
<Frame>
|
||||
<img
|
||||
src="/images/blocks/integrations/nocodb.jpg"
|
||||
alt="NocoDB block example"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
You can configure the filter to return `All`, `First`, `Last` or `Random` found records.
|
||||
|
||||
Then all you need to do is to map the found fields to variables that you can re-use on your bot.
|
||||
BIN
apps/docs/images/blocks/integrations/nocodb-table-id.jpg
Normal file
BIN
apps/docs/images/blocks/integrations/nocodb-table-id.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
BIN
apps/docs/images/blocks/integrations/nocodb.jpg
Normal file
BIN
apps/docs/images/blocks/integrations/nocodb.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 110 KiB |
@@ -126,7 +126,8 @@
|
||||
"editor/blocks/integrations/mistral",
|
||||
"editor/blocks/integrations/elevenlabs",
|
||||
"editor/blocks/integrations/anthropic",
|
||||
"editor/blocks/integrations/dify-ai"
|
||||
"editor/blocks/integrations/dify-ai",
|
||||
"editor/blocks/integrations/nocodb"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -20532,6 +20532,242 @@
|
||||
"id",
|
||||
"type"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"outgoingEdgeId": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"nocodb"
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"credentialsId": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"credentialsId": {
|
||||
"type": "string"
|
||||
},
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Search Records"
|
||||
]
|
||||
},
|
||||
"tableId": {
|
||||
"type": "string"
|
||||
},
|
||||
"viewId": {
|
||||
"type": "string"
|
||||
},
|
||||
"returnType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"All",
|
||||
"First",
|
||||
"Last",
|
||||
"Random"
|
||||
]
|
||||
},
|
||||
"filter": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"comparisons": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Equal to",
|
||||
"Not equal",
|
||||
"Contains",
|
||||
"Greater than",
|
||||
"Less than",
|
||||
"Is set",
|
||||
"Is empty",
|
||||
"Starts with",
|
||||
"Ends with"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"joiner": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"AND",
|
||||
"OR"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"comparisons"
|
||||
]
|
||||
},
|
||||
"responseMapping": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fieldName": {
|
||||
"type": "string"
|
||||
},
|
||||
"variableId": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"credentialsId": {
|
||||
"type": "string"
|
||||
},
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Create Record"
|
||||
]
|
||||
},
|
||||
"tableId": {
|
||||
"type": "string"
|
||||
},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"credentialsId": {
|
||||
"type": "string"
|
||||
},
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Update Existing Record"
|
||||
]
|
||||
},
|
||||
"tableId": {
|
||||
"type": "string"
|
||||
},
|
||||
"viewId": {
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"comparisons": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Equal to",
|
||||
"Not equal",
|
||||
"Contains",
|
||||
"Greater than",
|
||||
"Less than",
|
||||
"Is set",
|
||||
"Is empty",
|
||||
"Starts with",
|
||||
"Ends with"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"joiner": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"AND",
|
||||
"OR"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"comparisons"
|
||||
]
|
||||
},
|
||||
"updates": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fieldName": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"type"
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "Block"
|
||||
|
||||
@@ -11513,6 +11513,242 @@
|
||||
"id",
|
||||
"type"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"outgoingEdgeId": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"nocodb"
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"credentialsId": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"credentialsId": {
|
||||
"type": "string"
|
||||
},
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Search Records"
|
||||
]
|
||||
},
|
||||
"tableId": {
|
||||
"type": "string"
|
||||
},
|
||||
"viewId": {
|
||||
"type": "string"
|
||||
},
|
||||
"returnType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"All",
|
||||
"First",
|
||||
"Last",
|
||||
"Random"
|
||||
]
|
||||
},
|
||||
"filter": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"comparisons": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Equal to",
|
||||
"Not equal",
|
||||
"Contains",
|
||||
"Greater than",
|
||||
"Less than",
|
||||
"Is set",
|
||||
"Is empty",
|
||||
"Starts with",
|
||||
"Ends with"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"joiner": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"AND",
|
||||
"OR"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"comparisons"
|
||||
]
|
||||
},
|
||||
"responseMapping": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fieldName": {
|
||||
"type": "string"
|
||||
},
|
||||
"variableId": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"credentialsId": {
|
||||
"type": "string"
|
||||
},
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Create Record"
|
||||
]
|
||||
},
|
||||
"tableId": {
|
||||
"type": "string"
|
||||
},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"credentialsId": {
|
||||
"type": "string"
|
||||
},
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Update Existing Record"
|
||||
]
|
||||
},
|
||||
"tableId": {
|
||||
"type": "string"
|
||||
},
|
||||
"viewId": {
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"comparisons": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Equal to",
|
||||
"Not equal",
|
||||
"Contains",
|
||||
"Greater than",
|
||||
"Less than",
|
||||
"Is set",
|
||||
"Is empty",
|
||||
"Starts with",
|
||||
"Ends with"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"joiner": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"AND",
|
||||
"OR"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"comparisons"
|
||||
]
|
||||
},
|
||||
"updates": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fieldName": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"type"
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "Block"
|
||||
|
||||
Reference in New Issue
Block a user