🚸 (sheets) Better Get data settings UI
This commit is contained in:
@@ -78,7 +78,7 @@ export const TableList = <T,>({
|
||||
const handleMouseLeave = () => setShowDeleteIndex(null)
|
||||
|
||||
return (
|
||||
<Stack spacing={0} pt="2">
|
||||
<Stack spacing={0}>
|
||||
{items.map((item, itemIndex) => (
|
||||
<Box key={item.id}>
|
||||
{itemIndex !== 0 && ComponentBetweenItems && (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AlertInfo } from '@/components/AlertInfo'
|
||||
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
|
||||
import { useI18n, useScopedI18n } from '@/locales'
|
||||
import { useI18n } from '@/locales'
|
||||
import {
|
||||
Modal,
|
||||
ModalBody,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useI18n, useScopedI18n } from '@/locales'
|
||||
import { Tag, TagProps, ThemeTypings } from '@chakra-ui/react'
|
||||
import { Plan } from '@typebot.io/prisma'
|
||||
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
import { Divider, Stack, Text, useDisclosure } from '@chakra-ui/react'
|
||||
import {
|
||||
Accordion,
|
||||
AccordionButton,
|
||||
AccordionIcon,
|
||||
AccordionItem,
|
||||
AccordionPanel,
|
||||
Stack,
|
||||
Text,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react'
|
||||
import { DropdownList } from '@/components/DropdownList'
|
||||
import { useTypebot } from '@/features/editor/providers/TypebotProvider'
|
||||
import {
|
||||
@@ -97,7 +106,7 @@ export const GoogleSheetsSettings = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Stack spacing={4}>
|
||||
{workspace && (
|
||||
<CredentialsDropdown
|
||||
type="google sheets"
|
||||
@@ -130,15 +139,12 @@ export const GoogleSheetsSettings = ({
|
||||
{options?.spreadsheetId &&
|
||||
options.credentialsId &&
|
||||
isDefined(options.sheetId) && (
|
||||
<>
|
||||
<Divider />
|
||||
<DropdownList
|
||||
currentItem={'action' in options ? options.action : undefined}
|
||||
onItemSelect={handleActionChange}
|
||||
items={Object.values(GoogleSheetsAction)}
|
||||
placeholder="Select an operation"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{options.action && (
|
||||
<ActionOptions
|
||||
@@ -175,9 +181,8 @@ const ActionOptions = ({
|
||||
const handleExtractingCellsChange = (cellsToExtract: ExtractingCell[]) =>
|
||||
onOptionsChange({ ...options, cellsToExtract } as GoogleSheetsOptions)
|
||||
|
||||
const handleFilterChange = (
|
||||
filter: NonNullable<GoogleSheetsGetOptions['filter']>
|
||||
) => onOptionsChange({ ...options, filter } as GoogleSheetsOptions)
|
||||
const handleFilterChange = (filter: GoogleSheetsGetOptions['filter']) =>
|
||||
onOptionsChange({ ...options, filter } as GoogleSheetsOptions)
|
||||
|
||||
const UpdatingCellItem = useMemo(
|
||||
() =>
|
||||
@@ -227,36 +232,61 @@ const ActionOptions = ({
|
||||
)
|
||||
case GoogleSheetsAction.GET:
|
||||
return (
|
||||
<Stack>
|
||||
<Accordion allowMultiple>
|
||||
{options.referenceCell && (
|
||||
<>
|
||||
<Text>Row to select</Text>
|
||||
<AccordionItem>
|
||||
<AccordionButton>
|
||||
<Text w="full" textAlign="left">
|
||||
Rows to select
|
||||
</Text>
|
||||
<AccordionIcon />
|
||||
</AccordionButton>
|
||||
|
||||
<AccordionPanel pt="4">
|
||||
<CellWithValueStack
|
||||
columns={sheet?.columns ?? []}
|
||||
item={options.referenceCell ?? { id: 'reference' }}
|
||||
onItemChange={handleReferenceCellChange}
|
||||
/>
|
||||
</>
|
||||
</AccordionPanel>
|
||||
</AccordionItem>
|
||||
)}
|
||||
{options.filter && (
|
||||
<>
|
||||
<Text>Filter</Text>
|
||||
{!options.referenceCell && (
|
||||
<AccordionItem>
|
||||
<AccordionButton>
|
||||
<Text w="full" textAlign="left">
|
||||
Rows to filter
|
||||
</Text>
|
||||
<AccordionIcon />
|
||||
</AccordionButton>
|
||||
|
||||
<AccordionPanel pt="4">
|
||||
<RowsFilterTableList
|
||||
columns={sheet?.columns ?? []}
|
||||
filter={options.filter ?? {}}
|
||||
filter={options.filter}
|
||||
onFilterChange={handleFilterChange}
|
||||
/>
|
||||
</>
|
||||
</AccordionPanel>
|
||||
</AccordionItem>
|
||||
)}
|
||||
<AccordionItem>
|
||||
<AccordionButton>
|
||||
<Text w="full" textAlign="left">
|
||||
Columns to extract
|
||||
</Text>
|
||||
<AccordionIcon />
|
||||
</AccordionButton>
|
||||
|
||||
<Text>Cells to extract</Text>
|
||||
<AccordionPanel pt="4">
|
||||
<TableList<ExtractingCell>
|
||||
initialItems={options.cellsToExtract}
|
||||
onItemsChange={handleExtractingCellsChange}
|
||||
Item={ExtractingCellItem}
|
||||
addLabel="Add a value"
|
||||
/>
|
||||
</Stack>
|
||||
</AccordionPanel>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
)
|
||||
default:
|
||||
return <></>
|
||||
|
||||
@@ -10,11 +10,9 @@ import React, { useCallback } from 'react'
|
||||
import { RowsFilterComparisonItem } from './RowsFilterComparisonItem'
|
||||
|
||||
type Props = {
|
||||
filter: NonNullable<GoogleSheetsGetOptions['filter']>
|
||||
filter: GoogleSheetsGetOptions['filter']
|
||||
columns: string[]
|
||||
onFilterChange: (
|
||||
filter: NonNullable<GoogleSheetsGetOptions['filter']>
|
||||
) => void
|
||||
onFilterChange: (filter: GoogleSheetsGetOptions['filter']) => void
|
||||
}
|
||||
|
||||
export const RowsFilterTableList = ({
|
||||
@@ -22,11 +20,15 @@ export const RowsFilterTableList = ({
|
||||
columns,
|
||||
onFilterChange,
|
||||
}: Props) => {
|
||||
const handleComparisonsChange = (comparisons: RowsFilterComparison[]) =>
|
||||
onFilterChange({ ...filter, comparisons })
|
||||
const updateComparisons = (comparisons: RowsFilterComparison[]) =>
|
||||
onFilterChange({
|
||||
...filter,
|
||||
logicalOperator: filter?.logicalOperator ?? LogicalOperator.AND,
|
||||
comparisons,
|
||||
})
|
||||
|
||||
const handleLogicalOperatorChange = (logicalOperator: LogicalOperator) =>
|
||||
onFilterChange({ ...filter, logicalOperator })
|
||||
const updateLogicalOperator = (logicalOperator: LogicalOperator) =>
|
||||
filter && onFilterChange({ ...filter, logicalOperator })
|
||||
|
||||
const createRowsFilterComparisonItem = useCallback(
|
||||
(props: TableListItemProps<RowsFilterComparison>) => (
|
||||
@@ -37,14 +39,14 @@ export const RowsFilterTableList = ({
|
||||
|
||||
return (
|
||||
<TableList<RowsFilterComparison>
|
||||
initialItems={filter?.comparisons}
|
||||
onItemsChange={handleComparisonsChange}
|
||||
initialItems={filter?.comparisons ?? []}
|
||||
onItemsChange={updateComparisons}
|
||||
Item={createRowsFilterComparisonItem}
|
||||
ComponentBetweenItems={() => (
|
||||
<Flex justify="center">
|
||||
<DropdownList
|
||||
currentItem={filter?.logicalOperator}
|
||||
onItemSelect={handleLogicalOperatorChange}
|
||||
onItemSelect={updateLogicalOperator}
|
||||
items={Object.values(LogicalOperator)}
|
||||
/>
|
||||
</Flex>
|
||||
|
||||
@@ -99,6 +99,8 @@ test.describe.parallel('Google sheets integration', () => {
|
||||
await page.click('text=Select an operation')
|
||||
await page.click('text=Get data from sheet')
|
||||
|
||||
await page.getByRole('button', { name: 'Rows to filter' }).click()
|
||||
await page.getByRole('button', { name: 'Add filter rule' }).click()
|
||||
await page.click('text=Select a column')
|
||||
await page.click('button >> text="Email"')
|
||||
await page.getByRole('button', { name: 'Select an operator' }).click()
|
||||
@@ -110,6 +112,7 @@ test.describe.parallel('Google sheets integration', () => {
|
||||
await page.getByRole('button', { name: 'AND', exact: true }).click()
|
||||
await page.getByRole('menuitem', { name: 'OR' }).click()
|
||||
|
||||
await page.getByRole('button', { name: 'Columns to extract' }).click()
|
||||
await page.click('text=Select a column')
|
||||
await page.getByRole('menuitem', { name: 'Email' }).click()
|
||||
await page.getByRole('button', { name: 'Select an operator' }).click()
|
||||
|
||||
@@ -26,6 +26,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
}).files.list({
|
||||
q: "mimeType='application/vnd.google-apps.spreadsheet'",
|
||||
fields: 'nextPageToken, files(id, name)',
|
||||
pageSize: 300,
|
||||
})
|
||||
return res.send(response.data)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
- Paste the following Custom CSS:
|
||||
|
||||
```css
|
||||
body {
|
||||
.typebot-container {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
@@ -13,15 +13,9 @@ body {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.typebot-guest-bubble {
|
||||
margin-right: 0;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.bubble1,
|
||||
.bubble2 {
|
||||
margin-right: 0;
|
||||
margin-left: 0.25rem;
|
||||
.guest-container {
|
||||
margin-left: 0;
|
||||
margin-right: 50px;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -518,6 +518,18 @@
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"clickLink": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"alt": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
||||
@@ -179,6 +179,18 @@
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"clickLink": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"alt": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
@@ -2923,6 +2935,18 @@
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"clickLink": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"alt": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { ComponentProps } from 'react'
|
||||
import { ComponentProps } from 'react'
|
||||
import {
|
||||
Mjml,
|
||||
MjmlBody,
|
||||
@@ -17,14 +17,6 @@ type ReachedChatsLimitEmailProps = {
|
||||
url: string
|
||||
}
|
||||
|
||||
const now = new Date()
|
||||
const firstDayOfNextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1)
|
||||
const readableResetDate = firstDayOfNextMonth
|
||||
.toDateString()
|
||||
.split(' ')
|
||||
.slice(1, 4)
|
||||
.join(' ')
|
||||
|
||||
export const ReachedChatsLimitEmail = ({
|
||||
chatsLimit,
|
||||
url,
|
||||
|
||||
@@ -9,7 +9,7 @@ type Props = {
|
||||
|
||||
export const GuestBubble = (props: Props) => (
|
||||
<div
|
||||
class="flex justify-end mb-2 items-end animate-fade-in"
|
||||
class="flex justify-end mb-2 items-end animate-fade-in guest-container"
|
||||
style={{ 'margin-left': '50px' }}
|
||||
>
|
||||
<span
|
||||
|
||||
@@ -104,14 +104,6 @@ export const defaultGoogleSheetsGetOptions = (
|
||||
id: createId(),
|
||||
},
|
||||
],
|
||||
filter: {
|
||||
comparisons: [
|
||||
{
|
||||
id: createId(),
|
||||
},
|
||||
],
|
||||
logicalOperator: LogicalOperator.AND,
|
||||
},
|
||||
})
|
||||
|
||||
export const defaultGoogleSheetsInsertOptions = (
|
||||
|
||||
Reference in New Issue
Block a user