diff --git a/packages/backend/src/apps/asana/actions/create-task/index.js b/packages/backend/src/apps/asana/actions/create-task/index.js
new file mode 100644
index 00000000..c4de2d8c
--- /dev/null
+++ b/packages/backend/src/apps/asana/actions/create-task/index.js
@@ -0,0 +1,312 @@
+import defineAction from '../../../../helpers/define-action.js';
+import omitBy from 'lodash/omitBy.js';
+import isEmpty from 'lodash/isEmpty.js';
+
+export default defineAction({
+ name: 'Create task',
+ key: 'createTask',
+ description: 'Creates a new task.',
+ arguments: [
+ {
+ label: 'Workspace',
+ key: 'workspaceId',
+ type: 'dropdown',
+ required: true,
+ description: '',
+ variables: true,
+ source: {
+ type: 'query',
+ name: 'getDynamicData',
+ arguments: [
+ {
+ name: 'key',
+ value: 'listWorkspaces',
+ },
+ ],
+ },
+ },
+ {
+ label: 'Project',
+ key: 'projectId',
+ type: 'dropdown',
+ required: false,
+ description: '',
+ variables: true,
+ source: {
+ type: 'query',
+ name: 'getDynamicData',
+ arguments: [
+ {
+ name: 'key',
+ value: 'listProjects',
+ },
+ {
+ name: 'parameters.workspaceId',
+ value: '{parameters.workspaceId}',
+ },
+ ],
+ },
+ },
+ {
+ label: 'Section',
+ key: 'sectionId',
+ type: 'dropdown',
+ required: false,
+ description: '',
+ variables: true,
+ source: {
+ type: 'query',
+ name: 'getDynamicData',
+ arguments: [
+ {
+ name: 'key',
+ value: 'listSections',
+ },
+ {
+ name: 'parameters.projectId',
+ value: '{parameters.projectId}',
+ },
+ ],
+ },
+ },
+ {
+ label: 'Due date type',
+ key: 'dueDateType',
+ type: 'dropdown',
+ required: false,
+ description: "If not filled in, 'Date & time' will be assumed.",
+ options: [
+ {
+ label: 'Date & time',
+ value: 'at',
+ },
+ {
+ label: 'Date only',
+ value: 'on',
+ },
+ ],
+ },
+ {
+ label: 'Due date (date & time)',
+ key: 'dueDate',
+ type: 'string',
+ required: false,
+ description:
+ 'Example due at: 2019-09-15T02:06:58.147Z, example due on: 2019-09-15',
+ variables: true,
+ },
+ {
+ label: 'Name',
+ key: 'name',
+ type: 'string',
+ required: false,
+ description: '',
+ variables: true,
+ },
+ {
+ label: 'Description',
+ key: 'description',
+ type: 'string',
+ required: false,
+ description: 'You can format the description using html.',
+ variables: true,
+ },
+ {
+ label: 'Is the description rich text?',
+ key: 'richText',
+ type: 'dropdown',
+ required: false,
+ description: '',
+ variables: true,
+ options: [
+ {
+ label: 'No',
+ value: 'false',
+ },
+ {
+ label: 'Yes',
+ value: 'true',
+ },
+ ],
+ },
+ {
+ label: 'Mark Task as complete?',
+ key: 'taskCompleted',
+ type: 'dropdown',
+ required: false,
+ description: '',
+ variables: true,
+ options: [
+ {
+ label: 'No',
+ value: 'false',
+ },
+ {
+ label: 'Yes',
+ value: 'true',
+ },
+ ],
+ },
+ {
+ label: 'Mark Task as liked?',
+ key: 'taskLiked',
+ type: 'dropdown',
+ required: false,
+ description: '',
+ variables: true,
+ options: [
+ {
+ label: 'No',
+ value: 'false',
+ },
+ {
+ label: 'Yes',
+ value: 'true',
+ },
+ ],
+ },
+ {
+ label: 'Assignee',
+ key: 'assigneeId',
+ type: 'dropdown',
+ required: false,
+ dependsOn: ['parameters.workspaceId'],
+ description: '',
+ variables: true,
+ source: {
+ type: 'query',
+ name: 'getDynamicData',
+ arguments: [
+ {
+ name: 'key',
+ value: 'listUsers',
+ },
+ {
+ name: 'parameters.workspaceId',
+ value: '{parameters.workspaceId}',
+ },
+ ],
+ },
+ },
+ {
+ label: 'Followers',
+ key: 'followerIds',
+ type: 'dynamic',
+ required: false,
+ description: '',
+ fields: [
+ {
+ label: 'Follower',
+ key: 'followerId',
+ type: 'dropdown',
+ required: false,
+ dependsOn: ['parameters.workspaceId'],
+ description: '',
+ variables: true,
+ source: {
+ type: 'query',
+ name: 'getDynamicData',
+ arguments: [
+ {
+ name: 'key',
+ value: 'listUsers',
+ },
+ {
+ name: 'parameters.workspaceId',
+ value: '{parameters.workspaceId}',
+ },
+ ],
+ },
+ },
+ ],
+ },
+ {
+ label: 'Tags',
+ key: 'tagIds',
+ type: 'dynamic',
+ required: false,
+ description: '',
+ fields: [
+ {
+ label: 'Tag',
+ key: 'tagId',
+ type: 'dropdown',
+ required: false,
+ dependsOn: ['parameters.workspaceId'],
+ description: '',
+ variables: true,
+ source: {
+ type: 'query',
+ name: 'getDynamicData',
+ arguments: [
+ {
+ name: 'key',
+ value: 'listTags',
+ },
+ {
+ name: 'parameters.workspaceId',
+ value: '{parameters.workspaceId}',
+ },
+ ],
+ },
+ },
+ ],
+ },
+ ],
+
+ async run($) {
+ const {
+ workspaceId,
+ projectId,
+ sectionId,
+ dueDateType,
+ dueDate,
+ name,
+ description,
+ richText,
+ taskCompleted,
+ taskLiked,
+ assigneeId,
+ followerIds,
+ tagIds,
+ } = $.step.parameters;
+
+ const allFollowers = followerIds
+ .map((followerId) => followerId.followerId)
+ .filter(Boolean);
+
+ const allTags = tagIds.map((tagId) => tagId.tagId).filter(Boolean);
+
+ const data = {
+ name,
+ completed: taskCompleted,
+ liked: taskLiked,
+ assignee: assigneeId,
+ assignee_section: sectionId,
+ followers: allFollowers,
+ projects: projectId,
+ tags: allTags,
+ workspace: workspaceId,
+ };
+
+ if (richText === 'true') {
+ data.html_notes = description;
+ } else {
+ data.notes = description;
+ }
+
+ if (dueDateType === 'on') {
+ data.due_on = dueDate;
+ } else {
+ data.due_at = dueDate;
+ }
+
+ const filteredData = omitBy(data, isEmpty);
+
+ const response = await $.http.post('/1.0/tasks', { data: filteredData });
+
+ $.setActionItem({
+ raw: response.data,
+ });
+ },
+});
diff --git a/packages/backend/src/apps/asana/actions/index.js b/packages/backend/src/apps/asana/actions/index.js
new file mode 100644
index 00000000..dc3e333a
--- /dev/null
+++ b/packages/backend/src/apps/asana/actions/index.js
@@ -0,0 +1,3 @@
+import createTask from './create-task/index.js';
+
+export default [createTask];
diff --git a/packages/backend/src/apps/asana/dynamic-data/index.js b/packages/backend/src/apps/asana/dynamic-data/index.js
index 749767f2..d804f360 100644
--- a/packages/backend/src/apps/asana/dynamic-data/index.js
+++ b/packages/backend/src/apps/asana/dynamic-data/index.js
@@ -1,3 +1,15 @@
+import listProjects from './list-projects/index.js';
+import listSections from './list-sections/index.js';
+import listTags from './list-tags/index.js';
+import listTeams from './list-teams/index.js';
+import listUsers from './list-users/index.js';
import listWorkspaces from './list-workspaces/index.js';
-export default [listWorkspaces];
+export default [
+ listProjects,
+ listSections,
+ listTags,
+ listTeams,
+ listUsers,
+ listWorkspaces,
+];
diff --git a/packages/backend/src/apps/asana/dynamic-data/list-projects/index.js b/packages/backend/src/apps/asana/dynamic-data/list-projects/index.js
new file mode 100644
index 00000000..2e4a88da
--- /dev/null
+++ b/packages/backend/src/apps/asana/dynamic-data/list-projects/index.js
@@ -0,0 +1,42 @@
+export default {
+ name: 'List projects',
+ key: 'listProjects',
+
+ async run($) {
+ const projects = {
+ data: [],
+ };
+ const workspaceId = $.step.parameters.workspaceId;
+
+ if (!workspaceId) {
+ return projects;
+ }
+
+ const params = {
+ limit: 100,
+ offset: undefined,
+ workspace: workspaceId,
+ };
+
+ do {
+ const {
+ data: { data, next_page },
+ } = await $.http.get('/1.0/projects', {
+ params,
+ });
+
+ params.offset = next_page?.offset;
+
+ if (data) {
+ for (const project of data) {
+ projects.data.push({
+ value: project.gid,
+ name: project.name,
+ });
+ }
+ }
+ } while (params.offset);
+
+ return projects;
+ },
+};
diff --git a/packages/backend/src/apps/asana/dynamic-data/list-sections/index.js b/packages/backend/src/apps/asana/dynamic-data/list-sections/index.js
new file mode 100644
index 00000000..5ad9aa16
--- /dev/null
+++ b/packages/backend/src/apps/asana/dynamic-data/list-sections/index.js
@@ -0,0 +1,41 @@
+export default {
+ name: 'List sections',
+ key: 'listSections',
+
+ async run($) {
+ const sections = {
+ data: [],
+ };
+ const projectId = $.step.parameters.projectId;
+
+ if (!projectId) {
+ return sections;
+ }
+
+ const params = {
+ limit: 100,
+ offset: undefined,
+ };
+
+ do {
+ const {
+ data: { data, next_page },
+ } = await $.http.get(`/1.0/projects/${projectId}/sections`, {
+ params,
+ });
+
+ params.offset = next_page?.offset;
+
+ if (data) {
+ for (const section of data) {
+ sections.data.push({
+ value: section.gid,
+ name: section.name,
+ });
+ }
+ }
+ } while (params.offset);
+
+ return sections;
+ },
+};
diff --git a/packages/backend/src/apps/asana/dynamic-data/list-tags/index.js b/packages/backend/src/apps/asana/dynamic-data/list-tags/index.js
new file mode 100644
index 00000000..dd7faf61
--- /dev/null
+++ b/packages/backend/src/apps/asana/dynamic-data/list-tags/index.js
@@ -0,0 +1,42 @@
+export default {
+ name: 'List tags',
+ key: 'listTags',
+
+ async run($) {
+ const tags = {
+ data: [],
+ };
+ const workspaceId = $.step.parameters.workspaceId;
+
+ if (!workspaceId) {
+ return workspaceId;
+ }
+
+ const params = {
+ limit: 100,
+ offset: undefined,
+ workspace: workspaceId,
+ };
+
+ do {
+ const {
+ data: { data, next_page },
+ } = await $.http.get('/1.0/tags', {
+ params,
+ });
+
+ params.offset = next_page?.offset;
+
+ if (data) {
+ for (const tag of data) {
+ tags.data.push({
+ value: tag.gid,
+ name: tag.name,
+ });
+ }
+ }
+ } while (params.offset);
+
+ return tags;
+ },
+};
diff --git a/packages/backend/src/apps/asana/dynamic-data/list-teams/index.js b/packages/backend/src/apps/asana/dynamic-data/list-teams/index.js
new file mode 100644
index 00000000..9ec2407c
--- /dev/null
+++ b/packages/backend/src/apps/asana/dynamic-data/list-teams/index.js
@@ -0,0 +1,42 @@
+export default {
+ name: 'List teams',
+ key: 'listTeams',
+
+ async run($) {
+ const teams = {
+ data: [],
+ };
+ const workspaceId = $.step.parameters.workspaceId;
+
+ if (!workspaceId) {
+ return workspaceId;
+ }
+
+ const params = {
+ limit: 100,
+ offset: undefined,
+ workspace: workspaceId,
+ };
+
+ do {
+ const {
+ data: { data, next_page },
+ } = await $.http.get('/1.0/teams', {
+ params,
+ });
+
+ params.offset = next_page?.offset;
+
+ if (data) {
+ for (const team of data) {
+ teams.data.push({
+ value: team.gid,
+ name: team.name,
+ });
+ }
+ }
+ } while (params.offset);
+
+ return teams;
+ },
+};
diff --git a/packages/backend/src/apps/asana/dynamic-data/list-users/index.js b/packages/backend/src/apps/asana/dynamic-data/list-users/index.js
new file mode 100644
index 00000000..ee1153ac
--- /dev/null
+++ b/packages/backend/src/apps/asana/dynamic-data/list-users/index.js
@@ -0,0 +1,42 @@
+export default {
+ name: 'List users',
+ key: 'listUsers',
+
+ async run($) {
+ const users = {
+ data: [],
+ };
+ const workspaceId = $.step.parameters.workspaceId;
+
+ if (!workspaceId) {
+ return workspaceId;
+ }
+
+ const params = {
+ limit: 100,
+ offset: undefined,
+ workspace: workspaceId,
+ };
+
+ do {
+ const {
+ data: { data, next_page },
+ } = await $.http.get('/1.0/users', {
+ params,
+ });
+
+ params.offset = next_page?.offset;
+
+ if (data) {
+ for (const user of data) {
+ users.data.push({
+ value: user.gid,
+ name: user.name,
+ });
+ }
+ }
+ } while (params.offset);
+
+ return users;
+ },
+};
diff --git a/packages/backend/src/apps/asana/index.js b/packages/backend/src/apps/asana/index.js
index ca4f41ca..db33924c 100644
--- a/packages/backend/src/apps/asana/index.js
+++ b/packages/backend/src/apps/asana/index.js
@@ -3,6 +3,7 @@ import addAuthHeader from './common/add-auth-header.js';
import auth from './auth/index.js';
import dynamicData from './dynamic-data/index.js';
import triggers from './triggers/index.js';
+import actions from './actions/index.js';
export default defineApp({
name: 'Asana',
@@ -17,4 +18,5 @@ export default defineApp({
auth,
dynamicData,
triggers,
+ actions,
});
diff --git a/packages/docs/pages/.vitepress/config.js b/packages/docs/pages/.vitepress/config.js
index 69ac3e1a..374f58dc 100644
--- a/packages/docs/pages/.vitepress/config.js
+++ b/packages/docs/pages/.vitepress/config.js
@@ -54,7 +54,11 @@ export default defineConfig({
text: 'Asana',
collapsible: true,
collapsed: true,
- items: [{ text: 'Connection', link: '/apps/asana/connection' }],
+ items: [
+ { text: 'Triggers', link: '/apps/asana/triggers' },
+ { text: 'Actions', link: '/apps/asana/actions' },
+ { text: 'Connection', link: '/apps/asana/connection' },
+ ],
},
{
text: 'Carbone',
diff --git a/packages/docs/pages/apps/asana/actions.md b/packages/docs/pages/apps/asana/actions.md
new file mode 100644
index 00000000..e0c8088f
--- /dev/null
+++ b/packages/docs/pages/apps/asana/actions.md
@@ -0,0 +1,12 @@
+---
+favicon: /favicons/asana.svg
+items:
+ - name: Create task
+ desc: Creates a new task.
+---
+
+
+
+