feat(airtable): add create record action
This commit is contained in:
@@ -0,0 +1,92 @@
|
|||||||
|
import defineAction from '../../../../helpers/define-action.js';
|
||||||
|
|
||||||
|
export default defineAction({
|
||||||
|
name: 'Create record',
|
||||||
|
key: 'createRecord',
|
||||||
|
description: 'Creates a new record with fields that automatically populate.',
|
||||||
|
arguments: [
|
||||||
|
{
|
||||||
|
label: 'Base',
|
||||||
|
key: 'baseId',
|
||||||
|
type: 'dropdown',
|
||||||
|
required: true,
|
||||||
|
description: 'Base in which to create the record.',
|
||||||
|
variables: true,
|
||||||
|
source: {
|
||||||
|
type: 'query',
|
||||||
|
name: 'getDynamicData',
|
||||||
|
arguments: [
|
||||||
|
{
|
||||||
|
name: 'key',
|
||||||
|
value: 'listBases',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Table',
|
||||||
|
key: 'tableId',
|
||||||
|
type: 'dropdown',
|
||||||
|
required: true,
|
||||||
|
dependsOn: ['parameters.baseId'],
|
||||||
|
description: '',
|
||||||
|
variables: true,
|
||||||
|
source: {
|
||||||
|
type: 'query',
|
||||||
|
name: 'getDynamicData',
|
||||||
|
arguments: [
|
||||||
|
{
|
||||||
|
name: 'key',
|
||||||
|
value: 'listTables',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'parameters.baseId',
|
||||||
|
value: '{parameters.baseId}',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
additionalFields: {
|
||||||
|
type: 'query',
|
||||||
|
name: 'getDynamicFields',
|
||||||
|
arguments: [
|
||||||
|
{
|
||||||
|
name: 'key',
|
||||||
|
value: 'listFields',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'parameters.baseId',
|
||||||
|
value: '{parameters.baseId}',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'parameters.tableId',
|
||||||
|
value: '{parameters.tableId}',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
async run($) {
|
||||||
|
const { baseId, tableId, ...rest } = $.step.parameters;
|
||||||
|
|
||||||
|
const fields = Object.entries(rest).reduce((result, [key, value]) => {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
result[key] = value.map((item) => item.value);
|
||||||
|
} else if (value !== '') {
|
||||||
|
result[key] = value;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
typecast: true,
|
||||||
|
fields,
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data } = await $.http.post(`/v0/${baseId}/${tableId}`, body);
|
||||||
|
|
||||||
|
$.setActionItem({
|
||||||
|
raw: data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
3
packages/backend/src/apps/airtable/actions/index.js
Normal file
3
packages/backend/src/apps/airtable/actions/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import createRecord from './create-record/index.js';
|
||||||
|
|
||||||
|
export default [createRecord];
|
4
packages/backend/src/apps/airtable/dynamic-data/index.js
Normal file
4
packages/backend/src/apps/airtable/dynamic-data/index.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import listBases from './list-bases/index.js';
|
||||||
|
import listTables from './list-tables/index.js';
|
||||||
|
|
||||||
|
export default [listBases, listTables];
|
@@ -0,0 +1,28 @@
|
|||||||
|
export default {
|
||||||
|
name: 'List bases',
|
||||||
|
key: 'listBases',
|
||||||
|
|
||||||
|
async run($) {
|
||||||
|
const bases = {
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const params = {};
|
||||||
|
|
||||||
|
do {
|
||||||
|
const { data } = await $.http.get('/v0/meta/bases', { params });
|
||||||
|
params.offset = data.offset;
|
||||||
|
|
||||||
|
if (data?.bases) {
|
||||||
|
for (const base of data.bases) {
|
||||||
|
bases.data.push({
|
||||||
|
value: base.id,
|
||||||
|
name: base.name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (params.offset);
|
||||||
|
|
||||||
|
return bases;
|
||||||
|
},
|
||||||
|
};
|
@@ -0,0 +1,35 @@
|
|||||||
|
export default {
|
||||||
|
name: 'List tables',
|
||||||
|
key: 'listTables',
|
||||||
|
|
||||||
|
async run($) {
|
||||||
|
const tables = {
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
const baseId = $.step.parameters.baseId;
|
||||||
|
|
||||||
|
if (!baseId) {
|
||||||
|
return tables;
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = {};
|
||||||
|
|
||||||
|
do {
|
||||||
|
const { data } = await $.http.get(`/v0/meta/bases/${baseId}/tables`, {
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
params.offset = data.offset;
|
||||||
|
|
||||||
|
if (data?.tables) {
|
||||||
|
for (const table of data.tables) {
|
||||||
|
tables.data.push({
|
||||||
|
value: table.id,
|
||||||
|
name: table.name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (params.offset);
|
||||||
|
|
||||||
|
return tables;
|
||||||
|
},
|
||||||
|
};
|
@@ -0,0 +1,3 @@
|
|||||||
|
import listFields from './list-fields/index.js';
|
||||||
|
|
||||||
|
export default [listFields];
|
@@ -0,0 +1,86 @@
|
|||||||
|
const hasValue = (value) => value !== null && value !== undefined;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'List fields',
|
||||||
|
key: 'listFields',
|
||||||
|
|
||||||
|
async run($) {
|
||||||
|
const options = [];
|
||||||
|
const { baseId, tableId } = $.step.parameters;
|
||||||
|
|
||||||
|
if (!hasValue(baseId) || !hasValue(tableId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data } = await $.http.get(`/v0/meta/bases/${baseId}/tables`);
|
||||||
|
|
||||||
|
const selectedTable = data.tables.find((table) => table.id === tableId);
|
||||||
|
|
||||||
|
if (!selectedTable) return;
|
||||||
|
|
||||||
|
selectedTable.fields.forEach((field) => {
|
||||||
|
if (field.type === 'singleSelect') {
|
||||||
|
options.push({
|
||||||
|
label: field.name,
|
||||||
|
key: field.name,
|
||||||
|
type: 'dropdown',
|
||||||
|
required: false,
|
||||||
|
variables: true,
|
||||||
|
options: field.options.choices.map((choice) => ({
|
||||||
|
label: choice.name,
|
||||||
|
value: choice.id,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
} else if (field.type === 'multipleSelects') {
|
||||||
|
options.push({
|
||||||
|
label: field.name,
|
||||||
|
key: field.name,
|
||||||
|
type: 'dynamic',
|
||||||
|
required: false,
|
||||||
|
variables: true,
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
label: 'Value',
|
||||||
|
key: 'value',
|
||||||
|
type: 'dropdown',
|
||||||
|
required: false,
|
||||||
|
variables: true,
|
||||||
|
options: field.options.choices.map((choice) => ({
|
||||||
|
label: choice.name,
|
||||||
|
value: choice.id,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
} else if (field.type === 'checkbox') {
|
||||||
|
options.push({
|
||||||
|
label: field.name,
|
||||||
|
key: field.name,
|
||||||
|
type: 'dropdown',
|
||||||
|
required: false,
|
||||||
|
variables: true,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'Yes',
|
||||||
|
value: 'true',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'No',
|
||||||
|
value: 'false',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
options.push({
|
||||||
|
label: field.name,
|
||||||
|
key: field.name,
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
variables: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
};
|
@@ -1,6 +1,9 @@
|
|||||||
import defineApp from '../../helpers/define-app.js';
|
import defineApp from '../../helpers/define-app.js';
|
||||||
import addAuthHeader from './common/add-auth-header.js';
|
import addAuthHeader from './common/add-auth-header.js';
|
||||||
import auth from './auth/index.js';
|
import auth from './auth/index.js';
|
||||||
|
import actions from './actions/index.js';
|
||||||
|
import dynamicData from './dynamic-data/index.js';
|
||||||
|
import dynamicFields from './dynamic-fields/index.js';
|
||||||
|
|
||||||
export default defineApp({
|
export default defineApp({
|
||||||
name: 'Airtable',
|
name: 'Airtable',
|
||||||
@@ -13,4 +16,7 @@ export default defineApp({
|
|||||||
supportsConnections: true,
|
supportsConnections: true,
|
||||||
beforeRequest: [addAuthHeader],
|
beforeRequest: [addAuthHeader],
|
||||||
auth,
|
auth,
|
||||||
|
actions,
|
||||||
|
dynamicData,
|
||||||
|
dynamicFields,
|
||||||
});
|
});
|
||||||
|
@@ -36,7 +36,10 @@ export default defineConfig({
|
|||||||
text: 'Airtable',
|
text: 'Airtable',
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
collapsed: true,
|
collapsed: true,
|
||||||
items: [{ text: 'Connection', link: '/apps/airtable/connection' }],
|
items: [
|
||||||
|
{ text: 'Actions', link: '/apps/airtable/actions' },
|
||||||
|
{ text: 'Connection', link: '/apps/airtable/connection' },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: 'Carbone',
|
text: 'Carbone',
|
||||||
|
12
packages/docs/pages/apps/airtable/actions.md
Normal file
12
packages/docs/pages/apps/airtable/actions.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
favicon: /favicons/airtable.svg
|
||||||
|
items:
|
||||||
|
- name: Create record
|
||||||
|
desc: Creates a new record with fields that automatically populate.
|
||||||
|
---
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import CustomListing from '../../components/CustomListing.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<CustomListing />
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
The following integrations are currently supported by Automatisch.
|
The following integrations are currently supported by Automatisch.
|
||||||
|
|
||||||
|
- [Airtable](/apps/airtable/actions)
|
||||||
- [Carbone](/apps/carbone/actions)
|
- [Carbone](/apps/carbone/actions)
|
||||||
- [DeepL](/apps/deepl/actions)
|
- [DeepL](/apps/deepl/actions)
|
||||||
- [Delay](/apps/delay/actions)
|
- [Delay](/apps/delay/actions)
|
||||||
|
Reference in New Issue
Block a user