⚡ (sheets) Add option to select single row when matching multiple
Closes #501
This commit is contained in:
@ -21,6 +21,7 @@ import {
|
||||
GoogleSheetsInsertRowOptions,
|
||||
GoogleSheetsOptions,
|
||||
GoogleSheetsUpdateRowOptions,
|
||||
totalRowsToExtractOptions,
|
||||
} from '@typebot.io/schemas'
|
||||
import React, { useMemo } from 'react'
|
||||
import { isDefined } from '@typebot.io/lib'
|
||||
@ -184,6 +185,11 @@ const ActionOptions = ({
|
||||
const handleFilterChange = (filter: GoogleSheetsGetOptions['filter']) =>
|
||||
onOptionsChange({ ...options, filter } as GoogleSheetsOptions)
|
||||
|
||||
const updateTotalRowsToExtract = (
|
||||
totalRowsToExtract: GoogleSheetsGetOptions['totalRowsToExtract']
|
||||
) =>
|
||||
onOptionsChange({ ...options, totalRowsToExtract } as GoogleSheetsOptions)
|
||||
|
||||
const UpdatingCellItem = useMemo(
|
||||
() =>
|
||||
function Component(props: TableListItemProps<Cell>) {
|
||||
@ -273,59 +279,69 @@ const ActionOptions = ({
|
||||
case GoogleSheetsAction.GET:
|
||||
return (
|
||||
<Accordion allowMultiple>
|
||||
{options.referenceCell && (
|
||||
<Stack>
|
||||
{options.referenceCell && (
|
||||
<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.referenceCell && (
|
||||
<>
|
||||
<AccordionItem>
|
||||
<AccordionButton>
|
||||
<Text w="full" textAlign="left">
|
||||
Rows to filter
|
||||
</Text>
|
||||
<AccordionIcon />
|
||||
</AccordionButton>
|
||||
|
||||
<AccordionPanel pt="4">
|
||||
<RowsFilterTableList
|
||||
columns={sheet?.columns ?? []}
|
||||
filter={options.filter}
|
||||
onFilterChange={handleFilterChange}
|
||||
/>
|
||||
</AccordionPanel>
|
||||
</AccordionItem>
|
||||
<DropdownList
|
||||
items={totalRowsToExtractOptions}
|
||||
currentItem={options.totalRowsToExtract ?? 'All'}
|
||||
onItemSelect={updateTotalRowsToExtract}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<AccordionItem>
|
||||
<AccordionButton>
|
||||
<Text w="full" textAlign="left">
|
||||
Rows to select
|
||||
Columns to extract
|
||||
</Text>
|
||||
<AccordionIcon />
|
||||
</AccordionButton>
|
||||
|
||||
<AccordionPanel pt="4">
|
||||
<CellWithValueStack
|
||||
columns={sheet?.columns ?? []}
|
||||
item={options.referenceCell ?? { id: 'reference' }}
|
||||
onItemChange={handleReferenceCellChange}
|
||||
<TableList<ExtractingCell>
|
||||
initialItems={options.cellsToExtract}
|
||||
onItemsChange={handleExtractingCellsChange}
|
||||
Item={ExtractingCellItem}
|
||||
addLabel="Add a value"
|
||||
/>
|
||||
</AccordionPanel>
|
||||
</AccordionItem>
|
||||
)}
|
||||
{!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}
|
||||
onFilterChange={handleFilterChange}
|
||||
/>
|
||||
</AccordionPanel>
|
||||
</AccordionItem>
|
||||
)}
|
||||
<AccordionItem>
|
||||
<AccordionButton>
|
||||
<Text w="full" textAlign="left">
|
||||
Columns to extract
|
||||
</Text>
|
||||
<AccordionIcon />
|
||||
</AccordionButton>
|
||||
|
||||
<AccordionPanel pt="4">
|
||||
<TableList<ExtractingCell>
|
||||
initialItems={options.cellsToExtract}
|
||||
onItemsChange={handleExtractingCellsChange}
|
||||
Item={ExtractingCellItem}
|
||||
addLabel="Add a value"
|
||||
/>
|
||||
</AccordionPanel>
|
||||
</AccordionItem>
|
||||
</Stack>
|
||||
</Accordion>
|
||||
)
|
||||
default:
|
||||
|
@ -38,10 +38,13 @@ export const getRow = async (
|
||||
await doc.loadInfo()
|
||||
const sheet = doc.sheetsById[sheetId]
|
||||
const rows = await sheet.getRows()
|
||||
const filteredRows = rows.filter((row) =>
|
||||
referenceCell
|
||||
? row[referenceCell.column as string] === referenceCell.value
|
||||
: matchFilter(row, filter as NonNullable<typeof filter>)
|
||||
const filteredRows = getTotalRows(
|
||||
options.totalRowsToExtract,
|
||||
rows.filter((row) =>
|
||||
referenceCell
|
||||
? row[referenceCell.column as string] === referenceCell.value
|
||||
: matchFilter(row, filter as NonNullable<typeof filter>)
|
||||
)
|
||||
)
|
||||
if (filteredRows.length === 0) {
|
||||
log = {
|
||||
@ -99,3 +102,20 @@ export const getRow = async (
|
||||
}
|
||||
return { outgoingEdgeId, logs: log ? [log] : undefined }
|
||||
}
|
||||
|
||||
const getTotalRows = <T>(
|
||||
totalRowsToExtract: GoogleSheetsGetOptions['totalRowsToExtract'],
|
||||
rows: T[]
|
||||
): T[] => {
|
||||
switch (totalRowsToExtract) {
|
||||
case 'All':
|
||||
case undefined:
|
||||
return rows
|
||||
case 'First':
|
||||
return rows.slice(0, 1)
|
||||
case 'Last':
|
||||
return rows.slice(-1)
|
||||
case 'Random':
|
||||
return [rows[Math.floor(Math.random() * rows.length)]]
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,13 @@ const initialGoogleSheetsOptionsSchema = googleSheetsOptionsBaseSchema.merge(
|
||||
})
|
||||
)
|
||||
|
||||
export const totalRowsToExtractOptions = [
|
||||
'All',
|
||||
'First',
|
||||
'Last',
|
||||
'Random',
|
||||
] as const
|
||||
|
||||
const googleSheetsGetOptionsSchema = googleSheetsOptionsBaseSchema.merge(
|
||||
z.object({
|
||||
action: z.enum([GoogleSheetsAction.GET]),
|
||||
@ -48,6 +55,7 @@ const googleSheetsGetOptionsSchema = googleSheetsOptionsBaseSchema.merge(
|
||||
})
|
||||
.optional(),
|
||||
cellsToExtract: z.array(extractingCellSchema),
|
||||
totalRowsToExtract: z.enum(totalRowsToExtractOptions).optional(),
|
||||
})
|
||||
)
|
||||
|
||||
|
Reference in New Issue
Block a user