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. +--- + + + +