feat(google-sheets): create spreadsheet row
This commit is contained in:
@@ -0,0 +1,145 @@
|
|||||||
|
import defineAction from '../../../../helpers/define-action';
|
||||||
|
|
||||||
|
type TSheetsResponse = {
|
||||||
|
sheets: {
|
||||||
|
properties: {
|
||||||
|
sheetId: string;
|
||||||
|
title: string;
|
||||||
|
};
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default defineAction({
|
||||||
|
name: 'Create Spreadsheet Row',
|
||||||
|
key: 'createSpreadsheetRow',
|
||||||
|
description: 'Creates a new row in a specific spreadsheet.',
|
||||||
|
arguments: [
|
||||||
|
{
|
||||||
|
label: 'Drive',
|
||||||
|
key: 'driveId',
|
||||||
|
type: 'dropdown' as const,
|
||||||
|
required: false,
|
||||||
|
description:
|
||||||
|
'The Google Drive where your spreadsheet resides. If nothing is selected, then your personal Google Drive will be used.',
|
||||||
|
variables: false,
|
||||||
|
source: {
|
||||||
|
type: 'query',
|
||||||
|
name: 'getDynamicData',
|
||||||
|
arguments: [
|
||||||
|
{
|
||||||
|
name: 'key',
|
||||||
|
value: 'listDrives',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Spreadsheet',
|
||||||
|
key: 'spreadsheetId',
|
||||||
|
type: 'dropdown' as const,
|
||||||
|
required: true,
|
||||||
|
dependsOn: ['parameters.driveId'],
|
||||||
|
description: 'The spreadsheets in your Google Drive.',
|
||||||
|
variables: false,
|
||||||
|
source: {
|
||||||
|
type: 'query',
|
||||||
|
name: 'getDynamicData',
|
||||||
|
arguments: [
|
||||||
|
{
|
||||||
|
name: 'key',
|
||||||
|
value: 'listSpreadsheets',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'parameters.driveId',
|
||||||
|
value: '{parameters.driveId}',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Worksheet',
|
||||||
|
key: 'worksheetId',
|
||||||
|
type: 'dropdown' as const,
|
||||||
|
required: true,
|
||||||
|
dependsOn: ['parameters.spreadsheetId'],
|
||||||
|
description: 'The worksheets in your selected spreadsheet.',
|
||||||
|
variables: false,
|
||||||
|
source: {
|
||||||
|
type: 'query',
|
||||||
|
name: 'getDynamicData',
|
||||||
|
arguments: [
|
||||||
|
{
|
||||||
|
name: 'key',
|
||||||
|
value: 'listWorksheets',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'parameters.spreadsheetId',
|
||||||
|
value: '{parameters.spreadsheetId}',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
additionalFields: {
|
||||||
|
type: 'query',
|
||||||
|
name: 'getDynamicFields',
|
||||||
|
arguments: [
|
||||||
|
{
|
||||||
|
name: 'key',
|
||||||
|
value: 'listSheetHeaders',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'parameters.worksheetId',
|
||||||
|
value: '{parameters.worksheetId}',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'parameters.spreadsheetId',
|
||||||
|
value: '{parameters.spreadsheetId}',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
async run($) {
|
||||||
|
const {
|
||||||
|
data: { sheets },
|
||||||
|
} = await $.http.get<TSheetsResponse>(
|
||||||
|
`/v4/spreadsheets/${$.step.parameters.spreadsheetId}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const selectedSheet = sheets.find(
|
||||||
|
(sheet) => sheet.properties.sheetId === $.step.parameters.worksheetId
|
||||||
|
);
|
||||||
|
|
||||||
|
const sheetName = selectedSheet.properties.title;
|
||||||
|
|
||||||
|
const range = sheetName;
|
||||||
|
|
||||||
|
const dataValues = Object.entries($.step.parameters)
|
||||||
|
.filter((entry: [string, string]) => entry[0].startsWith('header-'))
|
||||||
|
.map((value) => value[1]);
|
||||||
|
|
||||||
|
const values = [dataValues];
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
valueInputOption: 'USER_ENTERED',
|
||||||
|
insertDataOption: 'INSERT_ROWS',
|
||||||
|
includeValuesInResponse: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
majorDimension: 'ROWS',
|
||||||
|
range,
|
||||||
|
values,
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data } = await $.http.post(
|
||||||
|
`/v4/spreadsheets/${$.step.parameters.spreadsheetId}/values/${range}:append`,
|
||||||
|
body,
|
||||||
|
{ params }
|
||||||
|
);
|
||||||
|
|
||||||
|
$.setActionItem({
|
||||||
|
raw: data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
3
packages/backend/src/apps/google-sheets/actions/index.ts
Normal file
3
packages/backend/src/apps/google-sheets/actions/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import createSpreadsheetRow from './create-spreadsheet-row';
|
||||||
|
|
||||||
|
export default [createSpreadsheetRow];
|
@@ -1,4 +1,5 @@
|
|||||||
import listDrives from './list-drives';
|
import listDrives from './list-drives';
|
||||||
import listSpreadsheets from './list-spreadsheets';
|
import listSpreadsheets from './list-spreadsheets';
|
||||||
|
import listWorksheets from './list-worksheets';
|
||||||
|
|
||||||
export default [listDrives, listSpreadsheets];
|
export default [listDrives, listSpreadsheets, listWorksheets];
|
||||||
|
@@ -0,0 +1,42 @@
|
|||||||
|
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'List worksheets',
|
||||||
|
key: 'listWorksheets',
|
||||||
|
|
||||||
|
async run($: IGlobalVariable) {
|
||||||
|
const spreadsheetId = $.step.parameters.spreadsheetId as string;
|
||||||
|
|
||||||
|
const worksheets: {
|
||||||
|
data: IJSONObject[];
|
||||||
|
} = {
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!spreadsheetId) {
|
||||||
|
return worksheets;
|
||||||
|
}
|
||||||
|
|
||||||
|
const params: Record<string, unknown> = {
|
||||||
|
pageToken: undefined as unknown as string,
|
||||||
|
};
|
||||||
|
|
||||||
|
do {
|
||||||
|
const { data } = await $.http.get(`/v4/spreadsheets/${spreadsheetId}`, {
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
params.pageToken = data.nextPageToken;
|
||||||
|
|
||||||
|
if (data.sheets?.length) {
|
||||||
|
for (const sheet of data.sheets) {
|
||||||
|
worksheets.data.push({
|
||||||
|
value: sheet.properties.sheetId,
|
||||||
|
name: sheet.properties.title,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (params.pageToken);
|
||||||
|
|
||||||
|
return worksheets;
|
||||||
|
},
|
||||||
|
};
|
@@ -0,0 +1,3 @@
|
|||||||
|
import listSheetHeaders from './list-sheet-headers';
|
||||||
|
|
||||||
|
export default [listSheetHeaders];
|
@@ -0,0 +1,67 @@
|
|||||||
|
import { IGlobalVariable } from '@automatisch/types';
|
||||||
|
|
||||||
|
type TSheetsResponse = {
|
||||||
|
sheets: {
|
||||||
|
properties: {
|
||||||
|
sheetId: string;
|
||||||
|
title: string;
|
||||||
|
};
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
|
||||||
|
type TSheetsValueResponse = {
|
||||||
|
majorDimension: string;
|
||||||
|
range: string;
|
||||||
|
values: string[][];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'List Sheet Headers',
|
||||||
|
key: 'listSheetHeaders',
|
||||||
|
|
||||||
|
async run($: IGlobalVariable) {
|
||||||
|
if (!$.step.parameters.spreadsheetId || !$.step.parameters.worksheetId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: { sheets },
|
||||||
|
} = await $.http.get<TSheetsResponse>(
|
||||||
|
`/v4/spreadsheets/${$.step.parameters.spreadsheetId}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const selectedSheet = sheets.find(
|
||||||
|
(sheet) => sheet.properties.sheetId === $.step.parameters.worksheetId
|
||||||
|
);
|
||||||
|
|
||||||
|
const sheetName = selectedSheet.properties.title;
|
||||||
|
|
||||||
|
const range = `${sheetName}!1:1`;
|
||||||
|
|
||||||
|
const params: Record<string, unknown> = {
|
||||||
|
majorDimension: 'ROWS',
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data } = await $.http.get<TSheetsValueResponse>(
|
||||||
|
`/v4/spreadsheets/${$.step.parameters.spreadsheetId}/values/${range}`,
|
||||||
|
{
|
||||||
|
params,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!data.values) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = data.values[0].map((item: string, index: number) => ({
|
||||||
|
label: item,
|
||||||
|
key: `header-${index}`,
|
||||||
|
type: 'string' as const,
|
||||||
|
required: false,
|
||||||
|
value: item,
|
||||||
|
variables: true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
};
|
@@ -2,7 +2,9 @@ import defineApp from '../../helpers/define-app';
|
|||||||
import addAuthHeader from './common/add-auth-header';
|
import addAuthHeader from './common/add-auth-header';
|
||||||
import auth from './auth';
|
import auth from './auth';
|
||||||
import triggers from './triggers';
|
import triggers from './triggers';
|
||||||
|
import actions from './actions';
|
||||||
import dynamicData from './dynamic-data';
|
import dynamicData from './dynamic-data';
|
||||||
|
import dynamicFields from './dynamic-fields';
|
||||||
|
|
||||||
export default defineApp({
|
export default defineApp({
|
||||||
name: 'Google Sheets',
|
name: 'Google Sheets',
|
||||||
@@ -16,5 +18,7 @@ export default defineApp({
|
|||||||
beforeRequest: [addAuthHeader],
|
beforeRequest: [addAuthHeader],
|
||||||
auth,
|
auth,
|
||||||
triggers,
|
triggers,
|
||||||
|
actions,
|
||||||
dynamicData,
|
dynamicData,
|
||||||
|
dynamicFields,
|
||||||
});
|
});
|
||||||
|
@@ -120,6 +120,7 @@ export default defineConfig({
|
|||||||
collapsed: true,
|
collapsed: true,
|
||||||
items: [
|
items: [
|
||||||
{ text: 'Triggers', link: '/apps/google-sheets/triggers' },
|
{ text: 'Triggers', link: '/apps/google-sheets/triggers' },
|
||||||
|
{ text: 'Actions', link: '/apps/google-sheets/actions' },
|
||||||
{ text: 'Connection', link: '/apps/google-sheets/connection' },
|
{ text: 'Connection', link: '/apps/google-sheets/connection' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
12
packages/docs/pages/apps/google-sheets/actions.md
Normal file
12
packages/docs/pages/apps/google-sheets/actions.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
favicon: /favicons/google-sheets.svg
|
||||||
|
items:
|
||||||
|
- name: Create Spreadsheet Row
|
||||||
|
desc: Creates a new row in a specific spreadsheet
|
||||||
|
---
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import CustomListing from '../../components/CustomListing.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<CustomListing />
|
@@ -4,7 +4,6 @@ import { useFormContext } from 'react-hook-form';
|
|||||||
import set from 'lodash/set';
|
import set from 'lodash/set';
|
||||||
import type { UseFormReturn } from 'react-hook-form';
|
import type { UseFormReturn } from 'react-hook-form';
|
||||||
import isEqual from 'lodash/isEqual';
|
import isEqual from 'lodash/isEqual';
|
||||||
import omit from 'lodash/omit';
|
|
||||||
import type {
|
import type {
|
||||||
IField,
|
IField,
|
||||||
IFieldDropdownSource,
|
IFieldDropdownSource,
|
||||||
@@ -13,7 +12,7 @@ import type {
|
|||||||
|
|
||||||
import { GET_DYNAMIC_DATA } from 'graphql/queries/get-dynamic-data';
|
import { GET_DYNAMIC_DATA } from 'graphql/queries/get-dynamic-data';
|
||||||
|
|
||||||
const variableRegExp = /({.*?})/g;
|
const variableRegExp = /({.*?})/;
|
||||||
|
|
||||||
function computeArguments(
|
function computeArguments(
|
||||||
args: IFieldDropdownSource['arguments'],
|
args: IFieldDropdownSource['arguments'],
|
||||||
|
@@ -12,7 +12,7 @@ import type {
|
|||||||
|
|
||||||
import { GET_DYNAMIC_FIELDS } from 'graphql/queries/get-dynamic-fields';
|
import { GET_DYNAMIC_FIELDS } from 'graphql/queries/get-dynamic-fields';
|
||||||
|
|
||||||
const variableRegExp = /({.*?})/g;
|
const variableRegExp = /({.*?})/;
|
||||||
|
|
||||||
// TODO: extract this function to a separate file
|
// TODO: extract this function to a separate file
|
||||||
function computeArguments(
|
function computeArguments(
|
||||||
@@ -64,7 +64,10 @@ function useDynamicFields(stepId: string | undefined, schema: IField) {
|
|||||||
const computedVariables = React.useMemo(() => {
|
const computedVariables = React.useMemo(() => {
|
||||||
if (schema.type === 'dropdown' && schema.additionalFields) {
|
if (schema.type === 'dropdown' && schema.additionalFields) {
|
||||||
try {
|
try {
|
||||||
const variables = computeArguments(schema.additionalFields.arguments, getValues);
|
const variables = computeArguments(
|
||||||
|
schema.additionalFields.arguments,
|
||||||
|
getValues
|
||||||
|
);
|
||||||
|
|
||||||
// if computed variables are the same, return the last computed variables.
|
// if computed variables are the same, return the last computed variables.
|
||||||
if (isEqual(variables, lastComputedVariables.current)) {
|
if (isEqual(variables, lastComputedVariables.current)) {
|
||||||
|
Reference in New Issue
Block a user