Skip to content

Commit

Permalink
feat(airtable): add create record action
Browse files Browse the repository at this point in the history
  • Loading branch information
ridvanakca committed May 15, 2024
1 parent c413ab0 commit 3916a40
Show file tree
Hide file tree
Showing 11 changed files with 274 additions and 1 deletion.
92 changes: 92 additions & 0 deletions packages/backend/src/apps/airtable/actions/create-record/index.js
Original file line number Diff line number Diff line change
@@ -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 {
result[key] = value;
}
return result;
}, {});

const body = {
typecast: true,
fields,
};

const { data } = await $.http.post(`/v0/${baseId}/${tableId}`, body);

$.setActionItem({
raw: data,
});
},
});
3 changes: 3 additions & 0 deletions packages/backend/src/apps/airtable/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import createRecord from './create-record/index.js';

export default [createRecord];
4 changes: 4 additions & 0 deletions packages/backend/src/apps/airtable/dynamic-data/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import listBases from './list-bases/index.js';
import listTables from './list-tables/index.js';

export default [listBases, listTables];
Original file line number Diff line number Diff line change
@@ -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;
},
};
Original file line number Diff line number Diff line change
@@ -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;
},
};
3 changes: 3 additions & 0 deletions packages/backend/src/apps/airtable/dynamic-fields/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import listFields from './list-fields/index.js';

export default [listFields];
Original file line number Diff line number Diff line change
@@ -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;
},
};
6 changes: 6 additions & 0 deletions packages/backend/src/apps/airtable/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import defineApp from '../../helpers/define-app.js';
import addAuthHeader from './common/add-auth-header.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({
name: 'Airtable',
Expand All @@ -13,4 +16,7 @@ export default defineApp({
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,
actions,
dynamicData,
dynamicFields,
});
5 changes: 4 additions & 1 deletion packages/docs/pages/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ export default defineConfig({
text: 'Airtable',
collapsible: 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',
Expand Down
12 changes: 12 additions & 0 deletions packages/docs/pages/apps/airtable/actions.md
Original file line number Diff line number Diff line change
@@ -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 />
1 change: 1 addition & 0 deletions packages/docs/pages/guide/available-apps.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

The following integrations are currently supported by Automatisch.

- [Airtable](/apps/airtable/actions)
- [Carbone](/apps/carbone/actions)
- [DeepL](/apps/deepl/actions)
- [Delay](/apps/delay/actions)
Expand Down

0 comments on commit 3916a40

Please sign in to comment.