From c68a4815c5f024250782c6aab940237491f61650 Mon Sep 17 00:00:00 2001 From: Chandra Date: Mon, 26 Aug 2019 19:03:14 +0530 Subject: [PATCH 01/62] BIM 360 Connector --- custom_connectors/oauth2/bim_360.rb | 3514 +++++++++++++++++++++++++++ 1 file changed, 3514 insertions(+) create mode 100644 custom_connectors/oauth2/bim_360.rb diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb new file mode 100644 index 00000000..151e268f --- /dev/null +++ b/custom_connectors/oauth2/bim_360.rb @@ -0,0 +1,3514 @@ +{ + title: 'BIM 360', + connection: { + fields: [ + { + name: 'client_id', + label: 'Client ID', + optional: false, + hint: 'To create client id, you need to register an application' \ + ' under Admin Console => Project => Oauth => Create Oauth app' + }, + { + name: 'client_secret', + label: 'Client secret', + control_type: 'password', + optional: false, + hint: 'To create client id, you need to register an application' \ + ' under Admin Console => Project => Oauth => Create Oauth app' + }, + { + name: 'account_id', + optional: false, + hint: 'The account ID of the project. This corresponds to hub ID in' \ + ' the Data Management API. To convert a hub ID into an account ID ' \ + 'you need to remove the “b.” prefix. For example, a hub ID of ' \ + 'b.c8b0c73d-3ae9 translates to an account ID of c8b0c73d-3ae9.' + } + ], + authorization: { + type: 'oauth2', + authorization_url: lambda do |connection| + scopes = 'user:read account:read data:write data:write data:read' \ + ' account:write' + 'https://developer.api.autodesk.com/authentication/v1/authorize?' \ + 'response_type=' \ + "code&client_id=#{connection['client_id']}&" \ + "scope=#{scopes}" + end, + + acquire: lambda do |connection, auth_code, redirect_uri| + response = post('https://developer.api.autodesk.com/authentication/' \ + 'v1/gettoken'). + payload(client_id: connection['client_id'], + client_secret: connection['client_secret'], + grant_type: 'authorization_code', + code: auth_code, + redirect_uri: redirect_uri). + request_format_www_form_urlencoded + [response, nil, nil] + end, + refresh_on: [401, 403], + refresh: lambda do |connection, refresh_token| + scopes = 'user:read account:read data:read data:write account:write' + post('https://developer.api.autodesk.com/authentication/v1/' \ + 'refreshtoken'). + payload(client_id: connection['client_id'], + client_secret: connection['client_secret'], + grant_type: 'refresh_token', + refresh_token: refresh_token, + scope: scopes). + request_format_www_form_urlencoded + end, + apply: lambda do |_connection, access_token| + headers(Authorization: "Bearer #{access_token}", + 'Content-Type': 'application/vnd.api+json') + end + }, + base_uri: lambda do |_connection| + 'https://developer.api.autodesk.com' + end + }, + test: lambda do |_connection| + get('/userprofile/v1/users/@me') + end, + methods: { + format_search: lambda do |input| + if input.is_a?(Hash) + input.map do |key, value| + value = call('format_search', value) + if %w[limit offset].include?(key) + { "page[#{key}]" => value } + elsif %w[include_voided assigned_to target_urn due_date synced_after + created_at created_by search + ng_issue_type_id ng_issue_subtype_id status].include?(key) + { "filter[#{key}]" => value } + elsif %w[rfis].include?(key) + { "fields[#{key}]" => value } + else + { key => value } + end + end.inject(:merge) + else + input + end + end, + make_schema_builder_fields_sticky: lambda do |input| + input.map do |field| + if field[:properties].present? + field[:properties] = call('make_schema_builder_fields_sticky', + field[:properties]) + elsif field['properties'].present? + field['properties'] = call('make_schema_builder_fields_sticky', + field['properties']) + end + field[:sticky] = true + field + end + end, + sample_data_export_job: lambda do + { + 'id': '433d07ec-32a2-44eb-a5eb-b41090bfe932', + 'status': 'completed', + 'data': { + 'versionUrn': 'dXJuOmFkc2sud2lwcWE6ZnMuZmlsZTp2Zi5wZjNm' \ + 'clUwZ1RaYU9vdEtYZzJoMUZ3P3ZlcnNpb249MQ', + 'resourceId': "urn:adsk.viewing:fs.file:dXJuOmFkc2sud2lwcWE6Zn' \ + 'MuZmlsZTp2Zi5wZjNmclUwZ1RaYU9vdEtYZzJoMUZ3P3ZlcnNpb249MQ/output' \ + '/qXP_ZA5_3EqJoq5zqvnLHA/h8YAl4KMcEe9-L5SaEXY6A.pdf", + 'link': "https://developer.api.autodesk.com/modelderivative/v2/' \ + 'designdata/dXJuOmFkc2sud2lwcWE6ZnMuZmlsZTp2Zi5wZjNmclUwZ1RaYU9v' \ + 'dEtYZzJoMUZ3P3ZlcnNpb249MQ/manifest/urn%3Aadsk.viewing%3Afs.file' \ + '%3AdXJuOmFkc2sud2lwcWE6ZnMuZmlsZTp2Zi5wZjNmclUwZ1RaYU9vdEtYZzJo' \ + 'MUZ3P3ZlcnNpb249MQ%2Foutput%2FqXP_ZA5_3EqJoq5zqvnLHA%2Fh8YAl4KM' \ + 'cEe9-L5SaEXY6A.pdf" + } + } + end + }, + object_definitions: { + project: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'id', label: 'Project ID' }, + { name: 'account_id', label: 'Account ID' }, + { name: 'name', label: 'Project name' }, + { name: 'start_date', type: 'date' }, + { name: 'end_date', type: 'date' }, + { name: 'project_type', + control_type: 'select', pick_list: 'project_types', + toggle_hint: 'Select project type', + toggle_field: { + name: 'project_type', + type: 'string', + control_type: 'text', + label: 'Project type', + toggle_hint: 'Use custom value' + }, + hint: 'Refer to the preconfigured ' \ + "project_type list in the " \ + 'Parameters guide' }, + { name: 'value', label: 'Monetary value' }, + { name: 'currency', control_type: 'select', + pick_list: 'currency_list', + toggle_hint: 'Select currency', + toggle_field: { + name: 'currency', + type: 'string', + control_type: 'text', + label: 'Project type', + toggle_hint: 'Use custom value' + } }, + { name: 'status', control_type: 'select', + pick_list: 'status_list', + toggle_hint: 'Select status', + toggle_field: { + name: 'status', + type: 'string', + control_type: 'text', + label: 'Status', + toggle_hint: 'Use custom value' + } }, + { name: 'job_number' }, + { name: 'address_line_1' }, + { name: 'address_line_2' }, + { name: 'city' }, + { name: 'state_or_province' }, + { name: 'postal_code' }, + { name: 'country' }, + { name: 'postal_code' }, + { name: 'country' }, + { name: 'business_unit_id' }, + { name: 'timezone', hint: 'Refer to the preconfigured ' \ + "project_type list in the " \ + 'Parameters guide' }, + { name: 'language', control_type: 'select', pick_list: + [%w[English en], %w[German de]] }, + { name: 'construction_type', hint: 'Refer to the preconfigured ' \ + "project_type list in the " \ + 'Parameters guide' }, + { name: 'contract_type', hint: 'Refer to the preconfigured ' \ + "project_type list in the " \ + 'Parameters guide' }, + { name: 'last_sign_in', hint: 'Timestamp of the last sign in,' \ + ' YYYY-MM-DDThh:mm:ss.sssZ format' } + ] + end + }, + issue: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'id', label: 'Issue ID' }, + { name: 'type', + hint: 'The type of the object; will always be' \ + ' quality_issues' }, + { name: 'links', type: 'object', properties: [ + { name: 'self', hint: 'A reference to the issue itself.' } + ] }, + { name: 'attributes', type: 'object', properties: [ + { name: 'created_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'created, in the following format: YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'synced_at', type: 'date_time', + hint: 'The date and time the issue was synced with BIM 360, ' \ + 'in the following format: YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'updated_at', type: 'date_time', + hint: 'The last time the issue’s attributes were updated, in '\ + 'the following format: YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'close_version', + hint: 'The version of the issue when it was closed.' }, + { name: 'closed_at', type: 'date_time', + hint: 'The timestamp of the data and time the issue was ' \ + 'closed, in the following format: YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'closed_by', + hint: 'The Autodesk ID of the user who closed the issue.' }, + { name: 'created_by', + hint: 'The Autodesk ID of the user who created the issue.' }, + { name: 'starting_version', type: 'integer', + hint: 'The first version of the issue' }, + { name: 'title', label: 'Issue title' }, + { name: 'description', + hint: 'The description of the purpose of the issue.' }, + { name: 'location_description', + hint: 'The location of the issue.' }, + { name: 'markup_metadata' }, + { name: 'tags', type: 'object' }, + { name: 'resource_urns' }, + { name: 'target_urn', + hint: 'The item ID of the document associated with the ' \ + 'pushpin issue.' }, + { name: 'target_urn_page' }, + { name: 'collection_urn' }, + { name: 'due_date', type: 'date_time', + hint: 'The timestamp of the issue’s specified due date,' \ + ' in the following format: YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'identifier', type: 'integer', + hint: 'The identifier of the issue.' }, + { name: 'status', control_type: 'select', + pick_list: 'issue_status_list', + toggle_hint: 'Select status', + toggle_field: { + name: 'status', label: 'Status', type: 'string', + control_type: 'text', toggle_hint: 'Use custom value', + hint: 'Allowed values are :open, work_complete, + ready_to_inspect, not_approved, close in_dispute, void.' + } }, + { name: 'assigned_to', hint: 'The Autodesk ID of the user' }, + { name: 'assigned_to_type', hint: 'The type of subject this ' \ + 'issue is assigned to. Possible values: user, company, role' }, + { name: 'answer' }, + { name: 'answered_at', type: 'date_time', + hint: 'The date and time the issue was answered, in the ' \ + 'following format: YYYY-MM-DDThh:mm:ss.sz.', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'answered_by', + hint: 'The user who suggested an answer for the issue.' }, + { name: 'pushpin_attributes', + hint: 'The type and location of the pushpin' }, + { name: 'owner', + hint: 'The Autodesk ID of the user who owns this issue.' }, + { name: 'issue_type_id' }, + { name: 'issue_type' }, + { name: 'issue_sub_type' }, + { name: 'root_cause_id' }, + { name: 'root_cause' }, + { name: 'quality_urns', type: 'object' }, + { name: 'permitted_statuses', type: 'array', of: 'string', + hint: 'A list of statuses accessible to the current user.' }, + { name: 'permitted_attributes', type: 'array', of: 'string', + hint: 'A list of attributes accessible to the current user.' }, + { name: 'comment_count', type: 'integer', + hint: 'The number of comments added to this issue.' }, + { name: 'attachment_count', + hint: 'The number of attachments added to this issue.' }, + { name: 'permitted_actions', + hint: 'The actions that are permitted for the issue in' \ + ' this state.' }, + { name: 'lbs_location', + hint: 'The ID of the location that relates to the issue.' }, + { name: 'sheet_metadata' }, + { name: 'ng_issue_subtype_id', label: 'Issue subtype ID', + hint: 'The ID of the issue subtype' }, + { name: 'ng_issue_type_id', label: 'Issue type ID', + hint: 'The ID of the issue type.' } + ] }, + # To Do + { name: 'custom_attributes', type: 'array', of: 'object' }, + { name: 'trades', type: 'array', of: 'object' }, + { name: 'comments_attributes', type: 'array', of: 'object', + properties: [ + { name: 'id', label: 'Comment ID' }, + { name: 'type' }, + { name: 'attributes', type: 'object', properties: [ + { name: 'created_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'created, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'synced_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'synced, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'updated_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'updated, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'issue_id' }, + { name: 'rfi_id' }, + { name: 'body' }, + { name: 'created_by', + hint: 'The ID of the user who created the attachment.' } + ] } + ] }, + { name: 'attachments_attributes', type: 'array', of: 'object', + properties: [ + { name: 'id', label: 'Attachment ID' }, + { name: 'type' }, + { name: 'attributes', type: 'object', properties: [ + { name: 'created_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'created, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'created_by' }, + { name: 'synced_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'synced, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'updated_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'updated, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'attachment_type' }, + { name: 'deleted_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'deleted, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'deleted_by', hint: 'The ID of the user who deleted' \ + ' the attachment. This is only relevant for deleted' \ + ' attachments.' }, + { name: 'rfi_id' }, + { name: 'name' }, + { name: 'resource_urns', type: 'array', of: 'string' }, + { name: 'url' }, + { name: 'urn' }, + { name: 'urn_page' }, + { name: 'urn_type' }, + { name: 'urn_version' }, + { name: 'permitted_actions' } + ] } + ] }, + { name: 'snapshot_urn' }, + { name: 'relationships', type: 'object', properties: [ + { name: 'container', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self' }, + { name: 'related' } + ] } + ] }, + { name: 'activity_batches', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self' }, + { name: 'related' } + ] } + ] }, + { name: 'comments', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self' }, + { name: 'related' } + ] } + ] }, + { name: 'attachments', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self' }, + { name: 'related' } + ] } + ] }, + { name: 'root_cause_obj', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self' }, + { name: 'related' } + ] } + ] }, + { name: 'issue_type_obj', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self' }, + { name: 'related' } + ] } + ] } + ] } + ] + end + }, + create_issue: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'title', label: 'Issue title' }, + { name: 'description', + hint: 'The description of the purpose of the issue.' }, + { name: 'status', control_type: 'select', + pick_list: %w[draft open]. + map { |option| [option.labelize, option] }, + toggle_hint: 'Select status', + toggle_field: { + name: 'status', label: 'Status', type: 'string', + control_type: 'text', toggle_hint: 'Use custom value', + hint: 'The status of the issue. Possible values:draft, ' \ + 'open. The default is draft' + } }, + { name: 'starting_version', type: 'integer', + hint: 'The first version of the issue' }, + { name: 'due_date', type: 'date_time', + hint: 'The timestamp of the issue’s specified due date,' \ + ' in the following format: YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'location_description' }, + { name: 'created_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'created, in the following format: YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'assigned_to', + hint: 'The Autodesk ID (uid) of the user you want to assign' \ + ' to this issue.' }, + { name: 'assigned_to_type', hint: 'The type of subject this ' \ + 'issue is assigned to. Possible values: user, company, role' }, + { name: 'owner', + hint: 'The BIM 360 ID of the user who owns this issue.' }, + { name: 'ng_issue_type_id', label: 'Issue type ID', + hint: 'The ID of the issue type.' }, + { name: 'ng_issue_subtype_id', label: 'Issue subtype ID', + hint: 'The ID of the issue subtype' }, + { name: 'root_cause_id', + hint: 'The ID of the type of root cause for this issue.' }, + { name: 'quality_urns', type: 'object' } + ] + end + }, + update_issue: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'id', label: 'Issue ID', + optional: 'false' }, + { name: 'title', label: 'Issue title', + optional: 'false' }, + { name: 'description', + hint: 'The description of the purpose of the issue.' }, + { name: 'status', control_type: 'select', + pick_list: 'issue_status_list', + toggle_hint: 'Select status', + toggle_field: { + name: 'status', label: 'Status', type: 'string', + control_type: 'text', toggle_hint: 'Use custom value', + hint: 'The status of the issue. Possible values:draft, ' \ + 'open. The default is draft' + } }, + { name: 'due_date', type: 'date_time', + hint: 'The timestamp of the issue’s specified due date,' \ + ' in the following format: YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'location_description' }, + { name: 'assigned_to', + hint: 'The Autodesk ID (uid) of the user you want to assign' \ + ' to this issue.' }, + { name: 'assigned_to_type', hint: 'The type of subject this ' \ + 'issue is assigned to. Possible values: user, company, role' }, + { name: 'owner', + hint: 'The BIM 360 ID of the user who owns this issue.' }, + { name: 'ng_issue_type_id', label: 'Issue type ID', + hint: 'The ID of the issue type. You can only configure this' \ + ' attribute when the issue is in draft state' }, + { name: 'ng_issue_subtype_id', label: 'Issue subtype ID', + hint: 'The ID of the issue subtype. You can configure this ' \ + 'attribute when the issue is in draft or open state' }, + { name: 'root_cause_id', + hint: 'The ID of the type of root cause for this issue.' }, + { name: 'quality_urns', type: 'object' }, + { name: 'close_version' } + ] + end + }, + rfi: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'id', hint: 'RFI ID' }, + { name: 'type', label: 'Objec type', + hint: 'The type of object; will always be rfis.' }, + { name: 'links', type: 'object', properties: [ + { name: 'self' }, + { name: 'first', hint: 'A link to the first page.' }, + { name: 'prev', hint: 'A link to the previous page.' }, + { name: 'next', hint: 'A link to the next page.' }, + { name: 'last', hint: 'A link to the last page.' } + ] }, + { name: 'attributes', type: 'object', properties: [ + { name: 'created_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'created, in the following format: YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'synced_at', type: 'date_time', + hint: 'The date and time the issue was synced with BIM 360, ' \ + 'in the following format: YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'updated_at', type: 'date_time', + hint: 'The last time the issue’s attributes were updated, in '\ + 'the following format: YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'answer', hint: 'An answer for the RFI.' }, + { name: 'answered_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'The last time the RFI answer attribute was updated, ' \ + 'in the following format: YYYY-MM-DDThh:mm:ss.sz<\b>.' }, + { name: 'answered_by', + hint: 'The Autodesk ID of the user who updated the RFI answer' \ + ' attribute' }, + { name: 'manager', + hint: 'The last actual manager (GC) of the RFI' }, + { name: 'reviewer', + hint: 'The last actual reviewer (CM or Arch) of the RFI.' }, + { name: 'assigned_to', hint: 'The Autodesk ID of the user' }, + { name: 'assigned_to_type', + control_type: 'select', + pick_list: 'assigned_type_list', + toggle_hint: 'Select assigned type', + toggle_field: { + name: 'assigned_to_type', + type: 'string', + control_type: 'text', + label: 'Assigned Type', + toggle_hint: 'Use custom value', + hint: 'The type of assignee the RFI is assigned to. ' \ + 'Possible values: user, company, role' + } }, + { name: 'assignees', type: 'array', of: 'object', properties: [ + { name: 'id' }, + { name: 'type' } + ] }, + { name: 'attachment_count', + hint: 'The number of attachments associated with the RFI.' }, + { name: 'close_version' }, + { name: 'closed_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'The timestamp of the date and time the RFI was closed' }, + { name: 'closed_by', + hint: 'The Autodesk ID of the user who closed the RFI.' }, + { name: 'co_reviewers', hint: 'A list of alternative reviewers.' \ + ' Provide comma separated list of values.' }, + { name: 'collection_urn' }, + { name: 'comment_count', + hint: 'The number of comments added to the RFI.' }, + { name: 'created_by', + hint: 'The Autodesk ID of the user who created the RFI.' }, + { name: 'description' }, + { name: 'due_date', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'The timestamp of the due date for the RFI, in the ' \ + 'following format: YYYY-MM-DDThh:mm:ss.sz' }, + { name: 'identifier', + hint: 'The identifier of the RFI. This corresponds to the RFI' \ + ' ID number in the UI' }, + { name: 'custom_identifier', + hint: 'A custom identifier of the RFI selected by the user.' }, + { name: 'identifier_minor', type: 'integer' }, + { name: 'location_description', + hint: 'A description of the location of the RFI in the ' \ + 'construction project.' }, + { name: 'markup_metadata' }, + { name: 'permitted_actions', hint: 'A list of actions that are' \ + ' permitted for the user.' }, + { name: 'permitted_attributes', + hint: 'A list of attributes the user can modify.' }, + { name: 'permitted_statuses', hint: 'array of strings' }, + { name: 'permitted_transitions', type: 'array', of: 'object', + hint: 'A list of potential transitions.', + properties: [ + { name: 'id' }, + { name: 'is_specific_assignee', control_type: 'checkbox', + hint: 'Is the RFI can be assigned to a specific user', + type: 'boolean', toggle_hint: 'Select from options list', + toggle_field: { + name: 'is_specific_assignee', + type: 'string', + control_type: 'text', + label: 'Specific assignee', + hint: 'Is the RFI can be assigned to a specific user', + toggle_hint: 'Provide custom vlaue. ' \ + 'Allowed values are true, false' + } }, + { name: 'status', control_type: 'select', + pick_list: 'rfi_transaction_status_list', + hint: 'The status of the RFI after the transition', + toggle_hint: 'Select status', + toggle_field: { + name: 'status', + label: 'Status', + type: 'string', + control_type: 'text', + toggle_hint: 'Provie custom value', + hint: 'Possible values: draft, submitted, open, ' \ + 'rejected, answered, closed, void' + } }, + { name: 'title' }, + { name: 'assignees', type: 'array', of: 'object', properties: [ + { name: 'id' }, + { name: 'type' } + ] }, + { name: 'pushpin_attributes', type: 'object' }, + { name: 'resource_urns', hint: 'List of urns' }, + { name: 'sheet_metadata', type: 'object' }, + { name: 'starting_version', + hint: 'The first version of the RFI' }, + { name: 'suggested_answer', + hint: 'The suggested answer for the RFI.' }, + { name: 'tags' }, + { name: 'target_urn' }, + { name: 'target_urn_page' }, + { name: 'title' } + ] }, + { name: 'pushpin_attributes', type: 'object', properties: [ + { name: 'type' }, + { name: 'location', type: 'object', properties: [ + { name: 'x', type: 'number' }, + { name: 'y', type: 'number' }, + { name: 'z', type: 'number' } + ] }, + { name: 'resource_urns' }, + { name: 'sheet_metadata', type: 'object' }, + { name: 'starting_version', + hint: 'The first version of the RFI.' }, + { name: 'transition_attributes', type: 'array', of: 'object', + properties: [ + { name: 'id' }, + { name: 'is_specific_assignee', control_type: 'checkbox', + hint: 'Is the RFI can be assigned to a specific user', + type: 'boolean', toggle_hint: 'Select from options list', + toggle_field: { + name: 'is_specific_assignee', + type: 'string', + control_type: 'text', + label: 'Specific assignee', + hint: 'Is the RFI can be assigned to a specific user', + toggle_hint: 'Provide custom vlaue. ' \ + 'Allowed values are true, false' + } }, + { name: 'status', control_type: 'select', + pick_list: 'rfi_transaction_status_list', + hint: 'The status of the RFI after the transition', + toggle_hint: 'Select status', + toggle_field: { + name: 'status', + label: 'Status', + type: 'string', + control_type: 'text', + toggle_hint: 'Provie custom value', + hint: 'Possible values: draft, submitted, open, ' \ + 'rejected, answered, closed, void' + } }, + { name: 'title' }, + { name: 'is_required', control_type: 'checkbox', + type: 'boolean', toggle_hint: 'Select from options list', + toggle_field: { + name: 'is_required', + type: 'string', + control_type: 'text', + label: 'Is required', + toggle_hint: 'Provide custom vlaue. ' \ + 'Allowed values are true, false' + } } + ] }, + { name: 'workflow_state', type: 'object', properties: [ + { name: 'id' }, + { name: 'title' }, + { name: 'short_title' }, + { name: 'name' } + ] }, + { name: 'is_specific_assignee' }, + { name: 'object_id' }, + { name: 'viewer_state' }, + { name: 'created_at', type: 'date_time' }, + { name: 'created_by' }, + { name: 'created_doc_version', type: 'integer' }, + { name: 'hidden_at', type: 'date_time' }, + { name: 'hidden_by' }, + { name: 'hidden_doc_version', type: 'integer' } + ] }, + { name: 'resource_urns', hint: 'array of strings' }, + # TO UPDATE + { name: 'resource_urns' }, + { name: 'sheet_metadata', type: 'object' }, + { name: 'starting_version' }, + { name: 'status', control_type: 'select', + pick_list: 'rfi_transaction_status_list', + hint: 'The status of the RFI after the transition', + toggle_hint: 'Select status', + toggle_field: { + name: 'status', + label: 'Status', + type: 'string', + control_type: 'text', + toggle_hint: 'Provie custom value', + hint: 'Possible values: draft, submitted, open, ' \ + 'rejected, answered, closed, void' + } }, + { name: 'suggested_answer' }, + { name: 'tags', hint: 'array of strings' }, + { name: 'target_urn' }, + { name: 'target_urn_page' }, + { name: 'title' }, + { name: 'workflow_state', type: 'object', properties: [ + { name: 'id' }, + { name: 'title' }, + { name: 'short_title' }, + { name: 'name' } + ] }, + { name: 'current_allowed_assignees', type: 'array', of: 'object', + properties: [ + { name: 'id' }, + { name: 'type' } + ] }, + { name: 'distribution_list', + hint: 'Provide comma separated list of IDs' }, + { name: 'comments_attributes', type: 'array', of: 'object', + properties: [ + { name: 'id', label: 'Attachment ID' }, + { name: 'type' }, + { name: 'attributes', type: 'object', properties: [ + { name: 'created_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'created, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'created_by' }, + { name: 'synced_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'synced, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'updated_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'updated, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'rfi_id' }, + { name: 'body' } + ] } + ] }, + { name: 'attachments_attributes', type: 'array', of: 'object', + properties: [ + { name: 'id', label: 'Comment ID' }, + { name: 'type' }, + { name: 'attributes', type: 'object', properties: [ + { name: 'created_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'created, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'created_by' }, + { name: 'synced_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'synced, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'updated_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'updated, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'attachment_type' }, + { name: 'deleted_at', type: 'date_time', + hint: 'The timestamp of the date and time the issue was ' \ + 'deleted, in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'deleted_by', hint: 'The ID of the user who deleted' \ + ' the attachment. This is only relevant for deleted' \ + ' attachments.' }, + { name: 'rfi_id' }, + { name: 'name' }, + { name: 'resource_urns', type: 'array', of: 'string' }, + { name: 'url' }, + { name: 'urn' }, + { name: 'urn_page' }, + { name: 'urn_type' }, + { name: 'urn_version' }, + { name: 'permitted_actions' } + ] } + ] } + ] }, + { name: 'included', type: 'array', of: 'object' }, + { name: 'meta', type: 'object', properties: [ + { name: 'record_count', type: 'integer', control_type: 'number' }, + { name: 'page', type: 'object', properties: [ + { name: 'offset', type: 'integer' }, + { name: 'limit', type: 'integer' } + ] } + ] } + ] + end + }, + modify_rfi: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'transition_id', + hint: 'This field is mandatory when tranistioning the RFI.' }, + { name: 'assigned_to', + hint: 'The Autodesk ID of the user you want to assign ' \ + 'the RFI to.' }, + { name: 'co_reviewers', + hint: 'Add members who can contribute to the RFI response. ' \ + 'Note that although you can only add co-reviewers in the UI ' \ + 'when the RFI is in open status, you can use the endpoint to' \ + ' also set up co-reviewers in other statuses.' \ + 'To delete all co-reviewers, call the endpoint with an empty' \ + ' array.' }, + { name: 'description' }, + { name: 'due_date', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'The timestamp of the due date for the RFI, in the ' \ + 'following format: YYYY-MM-DDThh:mm:ss.sz.' }, + { name: 'reserve_custom_identifier', + hint: 'This field allows to reserve a custom identifier for ' \ + 'future use (for example, in draft or submitted status). No ' \ + 'other RFI will be able to use or reserve this identifier for' \ + ' 2 minutes.' }, + { name: 'custom_identifier', + hint: 'Identifier of the RFI given by user. When non-present in' \ + ' transitions to any status, except “draft” or “submitted”, ' \ + 'will be populated automatically.' }, + { name: 'location_description' }, + { name: 'answer', hint: 'An answer for the RFI.' }, + { name: 'suggested_answer' }, + { name: 'title' }, + { name: 'distribution_list', + hint: 'Provide comma seaprated list of values multiple values' } + ] + end + }, + search_criteria: { + fields: lambda do |_connection, _config_fields| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide project ID e.g. b.baf-0871-4aca-82e8-3dd6db' + } + }, + { name: 'target_urn', sticky: true }, + { name: 'due_date', + sticky: true, + hint: 'Retrieves issues due by the specified due date. matchValue' \ + ' is the timestamp of the due date in the following format' \ + ' : YYYY-MM-DDThh:mm:ss.sz, or a date range in the following' \ + ' format: YYYY-MM-DDThh:mm:ss.sz...YYYY-MM-DDThh:mm:ss.sz.' }, + { name: 'synced_after', type: 'date_time', + sticky: true, + hint: 'Retrieves issues updated after the specified date' }, + { name: 'created_at', + sticky: true, + hint: 'Retrieves issues created after the specified due date.' \ + ' matchValue' \ + ' is the timestamp of the due date in the following format' \ + ' : YYYY-MM-DDThh:mm:ss.sz, or a date range in the following' \ + ' format: YYYY-MM-DDThh:mm:ss.sz...YYYY-MM-DDThh:mm:ss.sz.' }, + { name: 'created_by', + sticky: true, + hint: 'Retrieves issues created by the user.' \ + ' matchValue is the unique identifier of the user who ' \ + 'created the issue.' }, + { name: 'ng_issue_type_id', + sticky: true, + hint: 'Retrieves issues associated with the specified issue type' }, + { name: 'ng_issue_subtype_id', + sticky: true, + hint: 'Retrieves issues associated with the specified ' \ + 'issue subtype.' }, + { name: 'limit', type: 'integer', + sticky: true, + hint: 'Number of issues to return in the response.' \ + ' Acceptable values: 1-100. Default value: 10' }, + { name: 'offset', + sticky: true, + hint: 'The page number that you want to begin' \ + ' issue results from.' }, + { name: 'sort', + sticky: true, + hint: 'Sort the issues by status, created_at,' \ + ' and updated_a. To sort in descending order add a ' \ + '- before the sort criteria' }, + { + name: 'include', + sticky: true, + label: 'Include additional data', + control_type: 'multiselect', + pick_list: 'issue_child_objects', + pick_list_params: {}, + delimiter: ',', + toggle_hint: 'Select from list', + toggle_field: { + name: 'include', + label: 'Include additinal data', + type: :string, + control_type: 'text', + optional: true, + hint: 'Multiple values separated by comma.', + toggle_hint: 'Comma separated list of values. Allowed values ' \ + 'are: attachments, comments, container' + } + } + ] + end + }, + rfis_criteria: { + fields: lambda do |_connection, _config_fields| + [ + { + name: 'status', control_type: 'select', + pick_list: 'rfi_status_list', + sticky: true, + hint: 'Retrieves RFIs with the specified status', + toggle_hint: 'Select status', + toggle_field: { + name: 'status', + label: 'Status', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are
draft, open, close
.' + } + }, + { + name: 'include_voided', control_type: 'checkbox', + type: 'boolean', + sticky: true, + hint: 'Include voided RFIs in the response. true returns ' \ + 'voided RFIs; false does not return voided RFIs', + toggle_hint: 'Select from options list', + toggle_field: { + name: 'include_voided', + label: 'Include voided', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are true, false.' \ + ' Note that status overrides this filter' + } + }, + { name: 'target_urn', sticky: true, + hint: 'Retrieves RFIs in the project that' \ + ' were linked to the specified document or documents, using' \ + 'the documents`s URN. e.g. urn:adsk.wipprod:dm.lineage:' \ + 'tFbo9zuDTW-nPh45gnM4gA' }, + { name: 'assigned_to', sticky: true, + hint: 'Retrieves RFIs in the project that' \ + " were assigned to the specified user, using the user's " \ + ' Autodesk ID. e.g PER8KQPK2JRT' }, + { name: 'created_at', sticky: true, + hint: 'Retrieves RFIs created at the specfied date. matchValue ' \ + 'is the timestamp of the date in the following format: ' \ + 'YYYY-MM-DDThh:mm:ss.sz, or a date range in the following' \ + ' format: YYYY-MM-DDThh:mm:ss.sz...YYYY-MM-DDThh:mm:ss.sz.' }, + { name: 'due_date', sticky: true, + hint: 'Retrieves RFIs due by the specified due date. matchValue' \ + ' is the timestamp of the due date in the following format' \ + ' : YYYY-MM-DDThh:mm:ss.sz, or a date range in the following' \ + ' format: YYYY-MM-DDThh:mm:ss.sz...YYYY-MM-DDThh:mm:ss.sz.' }, + { name: 'search', sticky: true, + hint: 'Free search in RFIs of the current container. The search' \ + ' is been performed in identifier, title, description and ' \ + 'answer fields.' }, + { name: 'sort', sticky: true, + hint: 'Sort the issues by status, due_date,' \ + ' and title, target_urn, location_description, identifier,' \ + ' created_at, updated_at. To sort in descending order add a ' \ + '- before the sort criteria. Separate multiple values' \ + ' with commas' }, + { name: 'limit', type: 'integer', sticky: true, + hint: 'The number of RFIs to return in the response payload.' \ + ' Acceptable values: 1-100. Default value: 10' }, + { name: 'offset', sticky: true, + hint: 'the page number that you want to begin RFI results from.' }, + { + name: 'include', sticky: true, + label: 'Include additional data', + control_type: 'multiselect', + pick_list: 'rfi_child_objects', + pick_list_params: {}, + delimiter: ',', + toggle_hint: 'Select from list', + toggle_field: { + name: 'include', + label: 'Include additinal data', + type: :string, + control_type: 'text', + optional: true, + hint: 'Multiple values separated by comma.', + toggle_hint: 'Comma separated list of values. Allowed values ' \ + 'are: attachments, comments,activity_batches, container' + } + } + ] + end + }, + hub_container_ids: { + fields: lambda do |_connection, _config_fields| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'container_id', + label: 'Project name', + control_type: 'select', + pick_list: 'issue_container_lists', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select container', + toggle_field: { + name: 'container_id', + label: 'Container ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { name: 'folder_id', + label: 'Folder', + control_type: 'tree', + hint: 'Select folder', + toggle_hint: 'Select Folder', + tree_options: { selectable_folder: true }, + pick_list: :folders, + optional: false, + toggle_field: { + name: 'folder_id', + type: 'string', + control_type: 'text', + label: 'Folder ID', + toggle_hint: 'Use Folder ID', + hint: 'Use Folder ID' + } } + ] + end + }, + folder_file: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'type' }, + { name: 'id' }, + { name: 'attributes', type: 'object', properties: [ + { name: 'type' }, + { name: 'name' }, + { name: 'displayName' }, + { name: 'createTime', type: 'date_time' }, + { name: 'createUserId' }, + { name: 'createUserName' }, + { name: 'lastModifiedTime', type: 'date_time' }, + { name: 'lastModifiedUserId' }, + { name: 'lastModifiedUserName' }, + { name: 'lastModifiedTimeRollup', type: 'date_time' }, + { name: 'objectCount', type: 'integer' }, + { name: 'hidden', type: 'boolean', control_type: 'checkbox' }, + { name: 'reserved', type: 'boolean', control_type: 'checkbox' }, + { name: 'extension', type: 'object', properties: [ + { name: 'type' }, + { name: 'version' }, + { name: 'data', type: 'object', properties: [ + { name: 'sourceFileName', hint: 'Applicable for file' }, + { name: 'visibleTypes', hint: 'Array of strings' }, + { name: 'actions', hint: 'Array of strings' }, + { name: 'allowedTypes', hint: 'Array of strings' } + ] } + ] } + ] } + ] + end + }, + item: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'included', type: 'array', of: 'object', + properties: [ + { name: 'type' }, + { name: 'id' }, + { name: 'relationships', type: 'object', properties: [ + { name: 'item', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'type' }, + { name: 'id' } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'refs', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] }, + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'storage', type: 'object', properties: [ + { name: 'meta', type: 'object', properties: [ + { name: 'link', type: 'object', properties: [ + { name: 'href' } + ] } + ] }, + { name: 'data', type: 'object', properties: [ + { name: 'type' }, + { name: 'id' } + ] } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] } + ] }, + { name: 'data', type: 'object', properties: [ + { name: 'id' }, + { name: 'type' }, + { name: 'relationships', type: 'object', properties: [ + { name: 'refs', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] }, + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'tip', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'type' }, + { name: 'id' } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] } + ] }, + { name: 'parent', type: 'object', properties: [ + { name: 'data', properties: [ + { name: 'type' }, + { name: 'id' } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'versions', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] } + ] }, + { name: 'attributes', type: 'object', properties: [ + { name: 'type' }, + { name: 'name' }, + { name: 'displayName' }, + { name: 'createTime', type: 'date_time' }, + { name: 'createUserId' }, + { name: 'createUserName' }, + { name: 'lastModifiedTime', type: 'date_time' }, + { name: 'lastModifiedUserId' }, + { name: 'lastModifiedUserName' }, + { name: 'lastModifiedTimeRollup', type: 'date_time' }, + { name: 'objectCount', type: 'integer' }, + { name: 'hidden', type: 'boolean', control_type: 'checkbox' }, + { name: 'reserved', type: 'boolean', control_type: 'checkbox' }, + { name: 'extension', type: 'object', properties: [ + { name: 'type' }, + { name: 'version' }, + { name: 'data', type: 'object', properties: [ + { name: 'sourceFileName', hint: 'Applicable for file' }, + { name: 'visibleTypes', hint: 'Array of strings' }, + { name: 'actions', hint: 'Array of strings' }, + { name: 'allowedTypes', hint: 'Array of strings' } + ] } + ] } + ] } + ] } + + ] + end + }, + version: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'type' }, + { name: 'id' }, + { name: 'attributes', type: 'object', properties: [ + { name: 'name' }, + { name: 'displayName' }, + { name: 'createTime', type: 'date_time' }, + { name: 'createUserId' }, + { name: 'createUserName' }, + { name: 'lastModifiedTime' }, + { name: 'lastModifiedUserId' }, + { name: 'lastModifiedUserName' }, + { name: 'versionNumber', type: 'integer' }, + { name: 'storageSize' }, + { name: 'fileType' }, + { name: 'extension', type: 'object', properties: [ + { name: 'type' }, + { name: 'version' }, + { name: 'data', type: 'object', properties: [ + { name: 'processState' }, + { name: 'extractionState' }, + { name: 'splittingState' }, + { name: 'reviewState' }, + { name: 'revisionDisplayLabel' }, + { name: 'sourceFileName' } + ] } + ] } + ] } + ] + end + }, + export_status: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'id', label: 'Export job ID' }, + { name: 'status' }, + { name: 'data', type: 'object', properties: [ + { name: 'versionUrn', label: 'Version URN' }, + { name: 'resourceId' }, + { name: 'link' } + ] } + ] + end + }, + custom_action_input: { + fields: lambda do |_connection, config_fields| + input_schema = parse_json(config_fields.dig('input', 'schema') || '[]') + + [ + { + name: 'path', + optional: false, + hint: 'Base URI is https://developer.api.autodesk.com - ' \ + 'path will be appended to this URI. ' \ + 'Use absolute URI to override this base URI.' + }, + ( + if %w[get delete].include?(config_fields['verb']) + { + name: 'input', + type: 'object', + control_type: 'form-schema-builder', + sticky: input_schema.blank?, + label: 'URL parameters', + add_field_label: 'Add URL parameter', + properties: [ + { + name: 'schema', + extends_schema: true, + sticky: input_schema.blank? + }, + ( + if input_schema.present? + { + name: 'data', + type: 'object', + properties: call('make_schema_builder_fields_sticky', + input_schema) + } + end + ) + ].compact + } + else + { + name: 'input', + type: 'object', + properties: [ + { + name: 'schema', + extends_schema: true, + schema_neutral: true, + control_type: 'schema-designer', + sample_data_type: 'json_input', + sticky: input_schema.blank?, + label: 'Request body parameters', + add_field_label: 'Add request body parameter' + }, + ( + if input_schema.present? + { + name: 'data', + type: 'object', + properties: input_schema. + each { |field| field[:sticky] = true } + } + end + ) + ].compact + } + end + ), + { + name: 'output', + control_type: 'schema-designer', + sample_data_type: 'json_http', + extends_schema: true, + schema_neutral: true, + sticky: true + } + ] + end + }, + + custom_action_output: { + fields: lambda do |_connection, config_fields| + parse_json(config_fields['output'] || '[]') + end + } + }, + actions: { + custom_action: { + description: "Custom action " \ + "in BIM 360", + help: { + body: 'Build your own BIM 360 action with an HTTP request', + learn_more_url: 'https://forge.autodesk.com/en/docs/bim360/v1/reference/http/', + learn_more_text: 'BIM 360 API Documentation' + }, + config_fields: [{ + name: 'verb', + label: 'Request type', + hint: 'Select HTTP method of the request', + optional: false, + control_type: 'select', + pick_list: %w[get post patch delete].map { |verb| [verb.upcase, verb] } + }], + input_fields: lambda do |object_definitions| + object_definitions['custom_action_input'] + end, + execute: lambda do |_connection, input| + verb = input['verb'] + if %w[get post patch delete].exclude?(verb) + error("#{verb} not supported") + end + data = input.dig('input', 'data').presence || {} + case verb + when 'get' + response = + get(input['path'], data). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.compact + if response.is_a?(Array) + array_name = parse_json(input['output'] || '[]'). + dig(0, 'name') || 'array' + { array_name.to_s => response } + elsif response.is_a?(Hash) + response + else + error('API response is not a JSON') + end + when 'post' + post(input['path'], data). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.compact + when 'patch' + patch(input['path'], data). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.compact + when 'delete' + delete(input['path'], data). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.compact + end + end, + output_fields: lambda do |object_definitions| + object_definitions['custom_action_output'] + end + }, + search_issues_in_project: { + title: 'Search issues in a project', + description: 'Search issues in'\ + ' a project in BIM 360', + help: { + body: 'Retrieves information about all the BIM 360 issues in a ' \ + 'project, including details about their associated comments ' \ + 'and attachments.' + }, + input_fields: lambda do |object_definitions| + object_definitions['search_criteria'] + end, + execute: lambda do |_connection, input| + hub_id = input.delete('hub_id') + project_id = input.delete('project_id') + filter_criteria = call('format_search', input) + container_id = get("/project/v1/hubs/#{hub_id}" \ + "/projects/#{project_id}")&. + dig('data', 'relationships', 'issues', 'data', 'id') + { issues: get("/issues/v1/containers/#{container_id}/quality-issues", + filter_criteria)['data'] } + end, + output_fields: lambda do |object_definitions| + [{ name: 'issues', type: 'array', of: 'object', + properties: object_definitions['issue'] }] + end, + sample_output: lambda do |_connection, input| + project_id = input['project_id'] + container_id = get("/project/v1/#{input['hub_id']}" \ + "/projects/#{project_id}")&. + dig('data', 'relationships', 'issues', 'data', 'id') + { issues: get("/issues/v1/containers/#{container_id}/" \ + 'quality-issues?page[limit]=1')&.dig('data', 0) || {} } + end + + }, + create_issue_in_project: { + title: 'Create issue in a project', + description: 'Create issue in'\ + ' a project in BIM 360', + help: { + body: 'Adds a BIM 360 issue to a project. You can create both ' \ + 'document-related (pushpin) issues, and project-related issues.' + }, + input_fields: lambda do |object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'container_id', + label: 'Container name', + control_type: 'select', + pick_list: 'issue_container_lists', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select container', + toggle_field: { + name: 'container_id', + label: 'Container ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + } + ].concat(object_definitions['create_issue']. + required('title', 'ng_issue_type_id', 'ng_issue_subtype_id')) + end, + execute: lambda do |_connection, input| + input.delete('hub_id') + container_id = input.delete('container_id') + payload = { + type: 'quality_issues', + attributes: input + } + post("/issues/v1/containers/#{container_id}/quality-issues"). + payload({ data: payload }). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end['data'] + end, + output_fields: lambda do |object_definitions| + object_definitions['issue'] + end, + sample_output: lambda do |_connection, input| + project_id = input['project_id'] + container_id = get("/project/v1/#{input['hub_id']}" \ + "/projects/#{project_id}")&. + dig('data', 'relationships', 'issues', 'data', 'id') + get("/issues/v1/containers/#{container_id}/" \ + 'quality-issues?page[limit]=1')&.dig('data', 0) || {} + end + }, + update_issue_in_project: { + title: 'Updated issue in a project', + description: 'Update issue in'\ + ' BIM 360', + help: { + body: 'BIM 360 issues are managed either in the BIM 360 Document' \ + ' Management module or the BIM 360 Field Management module.
' \ + 'The following users can update issues:
' \ + '
    Project admins
' \ + 'Project members who are assigned either create, view and ' \ + 'create, or full control Field Management permissions.' + }, + input_fields: lambda do |object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'container_id', + label: 'Container name', + control_type: 'select', + pick_list: 'issue_container_lists', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select container', + toggle_field: { + name: 'container_id', + label: 'Container ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide container id e.g. baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'id', label: 'Issue ID', + optional: false + } + ].concat(object_definitions['update_issue']) + end, + execute: lambda do |_connection, input| + input.delete('hub_id') + id = input.delete('id') + payload = { + id: id, + type: 'quality_issues', + attributes: input + } + patch("/issues/v1/containers/#{input.delete('container_id')}/" \ + "quality-issues/#{id}"). + payload({ data: payload }). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end['data'] + end, + output_fields: lambda do |object_definitions| + object_definitions['issue'] + end, + sample_output: lambda do |_connection, input| + project_id = input['project_id'] + container_id = get("/project/v1/#{input['hub_id']}" \ + "/projects/#{project_id}")&. + dig('data', 'relationships', 'issues', 'data', 'id') + get("/issues/v1/containers/#{container_id}/" \ + 'quality-issues?page[limit]=1')&.dig('data', 0) || {} + end + }, + get_issue_in_project: { + description: 'Get issue in a project in'\ + ' BIM 360', + help: { + body: 'Retrieves detailed information about a single BIM 360 issue. ' \ + 'Get issue action uses the' \ + " Get issue" \ + ' API.' + }, + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'container_id', + label: 'Container name', + control_type: 'select', + pick_list: 'issue_container_lists', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select container', + toggle_field: { + name: 'container_id', + label: 'Container ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { name: 'issue_id', optional: false } + ] + end, + execute: lambda do |_connection, input| + get("/issues/v1/containers/#{input['container_id']}/" \ + "quality-issues/#{input['issue_id']}"). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end['data'] + end, + output_fields: lambda do |object_definitions| + object_definitions['issue'] + end, + sample_output: lambda do |_connection, input| + project_id = input['project_id'] + container_id = get("/project/v1/#{input['hub_id']}" \ + "/projects/#{project_id}")&. + dig('data', 'relationships', 'issues', 'data', 'id') + get("/issues/v1/containers/#{container_id}/" \ + 'quality-issues?page[limit]=1')&.dig('data', 0) || {} + end + }, + get_project_details: { + description: 'Get project details in'\ + ' BIM 360', + help: { + body: 'Returns a project for a given project_id. Note that for ' \ + 'BIM 360 Docs, a hub ID corresponds to an account ID in the BIM ' \ + '360 API. To convert an account ID into a hub ID you need to add' \ + ' a “b.” prefix. For example, an account ID of c8b0c73d-3ae9 ' \ + 'translates to a hub ID of b.c8b0c73d-3ae9.' + }, + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: + 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + } + ] + end, + execute: lambda do |_connection, input| + get("/project/v1/hubs/#{input['hub_id']}/projects/" \ + "#{input['project_id']}"). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end['data'] + end, + output_fields: lambda do |object_definitions| + object_definitions['project'] + end, + sample_output: lambda do |_connection, _input| + id = get('/project/v1/hubs')&.dig('data', 0)&.[]('id') + get("/project/v1/hubs/#{id}/projects")&.dig('data', 0) || {} + end + }, + search_projects_in_account: { + title: 'Search projects in account', + description: 'Search projects details in'\ + ' BIM 360', + help: { + body: 'Returns a collection of projects for a given hub_id. A ' \ + 'project represents a BIM 360 Team project, a Fusion Team project,' \ + ' a BIM 360 Docs project, or an A360 Personal project. Multiple ' \ + 'projects can be created within a single hub.
' \ + 'Note that for BIM 360 Docs, a hub ID corresponds to an account ID' \ + ' in the BIM 360 API. To convert an account ID into a hub ID you need' \ + ' to add a “b.” prefix. For example, an account ID of c8b0c73d-3ae9' \ + ' translates to a hub ID of b.c8b0c73d-3ae9.' + }, + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'id', + label: 'Project name', + control_type: 'multiselect', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'id', + label: 'Project IDs', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: + 'Provide multiple ID\'s as comma separated e.g. ' \ + 'b.baf-0871-4aca-82e8-3dd6db00,b.baf-0871-4aca-' \ + '82e8-3dd6db01' + } + }, + { name: 'type', label: 'Project type', + sticky: true, + hint: 'Provide the project type e.g. for Project i.e. ' \ + 'projects:autodesk.bim360:Project' } + ] + end, + execute: lambda do |_connection, input| + filter = { 'filter[id]' => input['id'], + 'filter[extension.type]' => input['type'] }.compact + { projects: get("/project/v1/hubs/#{input.delete('hub_id')}/projects/", + filter)['data'] } + end, + output_fields: lambda do |object_definitions| + [{ name: 'projects', type: 'array', of: 'object', + properties: object_definitions['project'] }] + end, + sample_output: lambda do |_connection, _input| + id = get('/project/v1/hubs')&.dig('data', 0)&.[]('id') + { projects: get("/project/v1/hubs/#{id}/projects")&. + dig('data', 0) || {} } + end + }, + search_rfis_in_project: { + title: 'Search RFIs in project', + description: 'Search RFIs in a project in'\ + ' BIM 360', + help: { + body: 'Retrieves information about all the BIM 360 RFIs (requests ' \ + 'for information) in a project, including details about their ' \ + 'associated comments and attachments.' + }, + input_fields: lambda do |object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'container_id', + label: 'Container name', + control_type: 'select', + pick_list: 'rfis_container_lists', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select container', + toggle_field: { + name: 'container_id', + label: 'Container ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + } + ].concat(object_definitions['rfis_criteria']) + end, + execute: lambda do |_connection, input| + input.delete('hub_id') + container_id = input.delete('container_id') + filter_criteria = call('format_search', input) + { rfis: get("/bim360/rfis/v1/containers/#{container_id}/rfis", + filter_criteria)['data'] } + end, + output_fields: lambda do |object_definitions| + [{ name: 'rfis', type: 'array', of: 'object', + properties: object_definitions['rfi'] }] + end, + sample_output: lambda do |_connection, input| + { rfis: + get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. + dig('data', 0) || {} } + end + }, + get_rfi_in_project: { + title: 'Get RFI in a project', + description: 'Get RFI in'\ + ' a project in BIM 360', + help: { + body: 'Retrieves detailed information about a single BIM 360 RFI' \ + ' (request for information).' + }, + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'container_id', + label: 'Container name', + control_type: 'select', + pick_list: 'rfis_container_lists', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select container', + toggle_field: { + name: 'container_id', + label: 'Container ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { name: 'id', optional: false, label: 'RFI ID' } + ] + end, + execute: lambda do |_connection, input| + get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis/" \ + "#{input['id']}"). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end['data'] + end, + output_fields: lambda do |object_definitions| + object_definitions['rfi'] + end, + sample_output: lambda do |_connection, input| + get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. + dig('data', 0) || {} + end + }, + create_rfi_in_project: { + title: 'Create RFI in a project', + description: 'Create RFI in'\ + ' a project in BIM 360', + help: { + body: 'Adds a BIM 360 RFI (request for information) to a project. ' \ + 'Users can create RFIs if they have been assigned either creator ' \ + '(sc) or manager (gc) workflow roles. Project admins are ' \ + 'automatically assigned the creator workflow role.' + }, + input_fields: lambda do |object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'container_id', + label: 'Container name', + control_type: 'select', + pick_list: 'rfis_container_lists', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select container', + toggle_field: { + name: 'container_id', + label: 'Container ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + } + ].concat(object_definitions['modify_rfi']. + ignored('transition_id', 'assigned_to', 'answer')) + end, + execute: lambda do |_connection, input| + input.delete('hub_id') + container_id = input.delete('container_id') + input_payload = input&.map do |key, value| + if %w[distribution_list co_reviewers].include?(key) + { key => value.split(',') } + else + { key => value } + end + end&.inject(:merge) + payload = { + type: 'rfis', + attributes: input_payload + } + post("/bim360/rfis/v1/containers/#{container_id}/rfis"). + payload({ data: payload }). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end['data'] + end, + output_fields: lambda do |object_definitions| + object_definitions['rfi'] + end, + sample_output: lambda do |_connection, input| + get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. + dig('data', 0) || {} + end + }, + update_rfi_in_project: { + title: 'Updated RFI in a project', + description: 'Update RFI in a project in'\ + ' BIM 360', + help: { + body: 'Updates a BIM 360 Project Management RFI. If the RFI is in ' \ + 'Draft status, it can only be updated by the user who created the ' \ + 'RFI. For all other statuses, it can only be updated by the user who' \ + ' was assigned to the RFI.' + }, + input_fields: lambda do |object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'container_id', + label: 'Container name', + control_type: 'select', + pick_list: 'rfis_container_lists', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select container', + toggle_field: { + name: 'container_id', + label: 'Container ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { name: 'id', optional: false, label: 'RFI ID' } + ].concat(object_definitions['modify_rfi']. + ignored('suggested_answer')) + end, + execute: lambda do |_connection, input| + input.delete('hub_id') + container_id = input.delete('container_id') + id = input.delete('id') + input_payload = input&.map do |key, value| + if %w[distribution_list co_reviewers].include?(key) + { key => value.split(',') } + else + { key => value } + end + end&.inject(:merge) + payload = { + id: id, + type: 'rfis', + attributes: input_payload + } + patch("/bim360/rfis/v1/containers/#{container_id}/rfis/#{id}"). + payload({ data: payload }). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end['data'] + end, + output_fields: lambda do |object_definitions| + object_definitions['rfi'] + end, + sample_output: lambda do |_connection, input| + get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. + dig('data', 0) || {} + end + }, + export_project_plan: { + title: 'Export drawing in a project', + description: 'Export drawing in'\ + ' a project in BIM 360', + help: { + body: 'Note that you can only export a page from a PDF file that ' \ + 'was uploaded to the Plans folder or to a folder nested under the ' \ + 'Plans folder. BIM 360 Document Management splits these files into ' \ + 'separate pages (sheets) when they are uploaded, and assigns a ' \ + 'separate ID to each page.' + }, + config_fields: + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: + 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { name: 'folder_id', + label: 'Folder name', + control_type: 'tree', + hint: 'Select folder', + toggle_hint: 'Select Folder', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, + tree_options: { selectable_folder: true }, + pick_list: :folders_list, + optional: false, + toggle_field: { + name: 'folder_id', + type: 'string', + control_type: 'text', + label: 'Folder ID', + toggle_hint: 'Use Folder ID', + hint: 'Use Folder ID' + } }, + { + name: 'item_id', + label: 'File name', + control_type: 'select', + pick_list: 'folder_items', + pick_list_params: { project_id: 'project_id', + folder_id: 'folder_id' }, + optional: false, + toggle_hint: 'Select file', + toggle_field: { + name: 'item_id', + type: 'string', + control_type: 'text', + label: 'File ID', + toggle_hint: 'Use file ID', + hint: 'Use file/item ID' + } + }, + { + name: 'version_number', + control_type: 'select', + pick_list: 'item_versions', + sticky: true, + pick_list_params: { project_id: 'project_id', item_id: 'item_id' }, + optional: true, + toggle_hint: 'Select version', + toggle_field: { + name: 'version_number', + label: 'Version number', + type: 'string', + control_type: 'text', + optional: true, + toggle_hint: 'Use custom value', + hint: 'Use version number' + } + } + ], + execute: lambda do |_connection, input| + # Step 1 find the version id of the file to export + input.delete('hub_id') + input.delete('folder_id') + version_number = input['version_number'] || get('/data/v1/projects/' \ + "#{input['project_id']}/items/#{input['item_id']}/" \ + 'versions')&.dig('data', 0, 'id') + version_url = version_number.encode_url + # Step 2 upload the file + project_id = input.delete('project_id').gsub('b.', '') + post("/bim360/docs/v1/projects/#{project_id}/versions" \ + "/#{version_url}/exports"). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + end, + output_fields: lambda do |_object_definitions| + [ + { name: 'id', label: 'Export ID' }, + { name: 'status' } + ] + end, + sample_output: lambda do |_connection, _input| + { + "id": '345eb2fb-d5b0-44c9-a50a-2c792d833f3f', + "status": 'committed' + } + end + }, + get_folder_details: { + title: 'Get folder info in a project', + description: 'Get folder info in'\ + ' a project in BIM 360', + help: { + body: 'Returns the folder by ID for any folder within a given ' \ + 'project. All folders or sub-folders within a project are associated' \ + ' with their own unique ID, including the root folder.' + }, + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: + 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { name: 'folder_id', + label: 'Folder', + control_type: 'tree', + hint: 'Select folder', + toggle_hint: 'Select Folder', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, + tree_options: { selectable_folder: true }, + pick_list: :folders_list, + optional: false, + toggle_field: { + name: 'folder_id', + type: 'string', + control_type: 'text', + label: 'Folder ID', + toggle_hint: 'Use Folder ID', + hint: 'Use Folder ID' + } } + ] + end, + execute: lambda do |_connection, input| + get("/data/v1/projects/#{input['project_id']}/folders" \ + "/#{input['folder_id']}")['data'] + end, + output_fields: lambda do |object_definitions| + object_definitions['folder_file'] + end, + sample_output: lambda do |_connection, input| + get("project/v1/hubs/#{input['hub_id']}/projects/" \ + "#{input['project_id']}/topFolders?filter[type]=folders")&. + dig('data', 0) || {} + end + }, + get_folder_contents: { + description: 'Get folder contents in'\ + ' BIM 360', + help: { + body: 'Returns a collection of items and folders within a folder.' \ + ' Items represent word documents, fusion design files, drawings,' \ + ' spreadsheets, etc.' + }, + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: + 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { name: 'folder_id', + label: 'Folder', + control_type: 'tree', + hint: 'Select folder', + toggle_hint: 'Select Folder', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, + tree_options: { selectable_folder: true }, + pick_list: :folders_list, + optional: false, + toggle_field: { + name: 'folder_id', + type: 'string', + control_type: 'text', + label: 'Folder ID', + toggle_hint: 'Use Folder ID', + hint: 'Use Folder ID' + } } + ] + end, + execute: lambda do |_connection, input| + get("/data/v1/projects/#{input['project_id']}/folders" \ + "/#{input['folder_id']}/contents") + end, + output_fields: lambda do |object_definitions| + [ + { name: 'data', type: 'array', of: 'object', + properties: object_definitions['folder_file'] }, + { name: 'included', type: 'array', of: 'object', + properties: object_definitions['version'] } + ] + end, + sample_output: lambda do |_connection, input| + folder_id = get("project/v1/hubs/#{input['hub_id']}/projects/" \ + "#{input['project_id']}/" \ + 'topFolders?filter[type]=folders')&. + dig('data', 0, 'id') + get("/data/v1/projects/#{input['project_id']}/folders" \ + "/#{folder_id}/contents") + end + }, + get_document_in_project: { + title: 'Get document in a project', + description: 'Get document in'\ + ' a project in BIM 360', + help: { + body: 'Retrieves metadata for a specified item. Items represent ' \ + 'word documents, fusion design files, drawings, spreadsheets, etc.' + }, + config_fields: + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: + 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { name: 'folder_id', + label: 'Folder', + control_type: 'tree', + hint: 'Select folder', + toggle_hint: 'Select Folder', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, + tree_options: { selectable_folder: true }, + pick_list: :folders_list, + optional: true, + toggle_field: { + name: 'folder_id', + type: 'string', + control_type: 'text', + label: 'Folder ID', + toggle_hint: 'Use Folder ID', + hint: 'Use Folder ID' + } }, + { name: 'item_id', + label: 'File name', + control_type: 'tree', + hint: 'Select folder', + toggle_hint: 'Select Folder', + pick_list: :folder_items, + pick_list_params: { project_id: 'project_id', + folder_id: 'folder_id' }, + optional: false, + toggle_field: { + name: 'item_id', + type: 'string', + control_type: 'text', + label: 'File ID', + toggle_hint: 'Use file ID', + hint: 'Provide file ID' + } } + ], + execute: lambda do |_connection, input| + get("/data/v1/projects/#{input['project_id']}/items/" \ + "#{input['item_id']}") + end, + output_fields: lambda do |object_definitions| + object_definitions['item'] + end, + sample_output: lambda do |_connection, input| + get("/data/v1/projects/#{input['project_id']}/items/" \ + "#{input['item_id']}") + end + }, + get_drawing_export_status: { + title: 'Get drwaing export status in a project', + description: 'Get drwaing export status in'\ + ' a project in BIM 360', + help: { + body: 'This action returns the status of a PDF export job, as well' \ + ' as data you need to download the exported file when the export is ' \ + 'complete. Get export job status action uses the' \ + " Get export job API." + }, + config_fields: + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: + 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { name: 'folder_id', + label: 'Folder', + control_type: 'tree', + hint: 'Select folder', + toggle_hint: 'Select Folder', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, + tree_options: { selectable_folder: true }, + pick_list: :folders_list, + optional: false, + toggle_field: { + name: 'folder_id', + type: 'string', + control_type: 'text', + label: 'Folder ID', + toggle_hint: 'Use Folder ID', + hint: 'Use Folder ID' + } }, + { + name: 'item_id', + label: 'File name', + control_type: 'select', + pick_list: 'folder_items', + pick_list_params: { project_id: 'project_id', + folder_id: 'folder_id' }, + optional: false, + toggle_hint: 'Select file', + toggle_field: { + name: 'item_id', + type: 'string', + control_type: 'text', + label: 'File ID', + toggle_hint: 'Use file ID', + hint: 'Use file ID' + } + }, + { + name: 'version_number', + control_type: 'select', + pick_list: 'item_versions', + sticky: true, + pick_list_params: { project_id: 'project_id', item_id: 'item_id' }, + optional: true, + toggle_hint: 'Select version', + toggle_field: { + name: 'version_number', + label: 'Version number', + type: 'integer', + control_type: 'number', + optional: true, + toggle_hint: 'Use custom value', + hint: 'Use version number' + } + } + ], + input_fields: lambda do |_object_definitions| + [ + { name: 'export_id', optional: false } + ] + end, + execute: lambda do |_connection, input| + version_number = input['version_number'] || get('/data/v1/projects/' \ + "#{input['project_id']}/items/#{input['item_id']}/" \ + 'versions')&.dig('data', 0, 'id') + version_url = version_number.encode_url + # version_url = version_number.encode_url + get("/bim360/docs/v1/projects/#{input['project_id']}/versions/" \ + "#{version_url}/exports/#{input['export_id']}") + end, + output_fields: lambda do |object_definitions| + object_definitions['export_status'] + end, + sample_output: lambda do |_connection, _input| + call('sample_data_export_job') + end + }, + download_document: { + description: 'Download document in'\ + ' a project in BIM 360', + config_fields: + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: + 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { name: 'folder_id', + label: 'Folder', + control_type: 'tree', + hint: 'Select folder', + toggle_hint: 'Select Folder', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, + tree_options: { selectable_folder: true }, + pick_list: :folders_list, + optional: false, + toggle_field: { + name: 'folder_id', + type: 'string', + control_type: 'text', + label: 'Folder ID', + toggle_hint: 'Use Folder ID', + hint: 'Use Folder ID' + } }, + { name: 'item_id', + label: 'File name', + control_type: 'tree', + hint: 'Select folder', + toggle_hint: 'Select Folder', + pick_list: :folder_items, + pick_list_params: { project_id: 'project_id', + folder_id: 'folder_id' }, + optional: false, + toggle_field: { + name: 'item_id', + type: 'string', + control_type: 'text', + label: 'File ID', + toggle_hint: 'Use file ID', + hint: 'Provide file ID' + } } + ], + execute: lambda do |_connection, input| + # 1 find the storage location of the item + file_url = get("/data/v1/projects/#{input['project_id']}/items/" \ + "#{input['item_id']}")&. + dig('included', 0, 'relationships', 'storage', 'meta', + 'link', 'href') + file_content = + get(file_url).response_format_raw. + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + { content: file_content } + end, + output_fields: lambda do |_object_definitions| + [{ name: 'content' }] + end + }, + upload_document_to_project: { + title: 'Upload document to a project', + description: 'Upload document to a project'\ + ' in BIM 360', + config_fields: [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: + 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { name: 'folder_id', + label: 'Folder', + control_type: 'tree', + hint: 'Select folder', + toggle_hint: 'Select Folder', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, + tree_options: { selectable_folder: true }, + pick_list: :folders_list, + optional: false, + toggle_field: { + name: 'folder_id', + type: 'string', + control_type: 'text', + label: 'Folder ID', + toggle_hint: 'Use Folder ID', + hint: 'Use Folder ID' + } } + ], + input_fields: lambda do |_object_definitions| + [ + { name: 'file_name', optional: false, + hint: 'File name should include extension of the file. e.g. ' \ + 'my_file.jpg' }, + { name: 'file_content', optional: false }, + { name: 'object_type', label: 'File type', + optional: false, + control_type: 'select', + pick_list: 'file_types', + toggle_hint: 'Select type', + toggle_field: { + name: 'object_type', + label: 'File type', + type: 'string', + control_type: 'text', + toggle_hint: 'File type ID', + hint: 'Only relevant for creating files - the type of file ' \ + 'extension. For BIM 360 Docs files, use items:autodesk.' \ + 'bim360:File, For all other services, use' \ + 'items:autodesk.core:File' + }, + hint: 'Only relevant for creating files - the type of file ' \ + 'extension. For BIM 360 Docs files, use items:autodesk.' \ + 'bim360:File, For all other services, use' \ + ' items:autodesk.core:File' }, + { name: 'parent_folder_id', + hint: 'The URN of the parent folder in which you want to create' \ + ' a version of a file or to copy a file to.' }, + { name: 'extension_version', + hint: 'The version of the version extension type ' } + ] + end, + execute: lambda do |_connection, input| + # 1 create storage location + payload = { + 'jsonapi' => { 'version': '1.0' }, + 'data' => { + 'type' => 'objects', + 'attributes' => { + 'name': input['file_name'] + }, + 'relationships' => { + 'target' => { + 'data' => { + 'type' => 'folders', + 'id' => input['folder_id'] + } + } + } + } + } + project_id = input.delete('project_id').gsub('b:', '') + object_id = + post('https://developer.api.autodesk.com/data/v1/' \ + "projects/#{project_id}/storage"). + payload(payload). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end&.dig('data', 'id') + # 2 Upload file to storage location + bucket_key = object_id.split('/').first.split('object:').last + object_name = object_id.split('/').last + response = put('https://developer.api.autodesk.com/oss/v2/buckets/' \ + "#{bucket_key}/objects/#{object_name}"). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + storage_object_id = response['objectId'] + # 3 create a first version of the File + version_payload = { + 'jsonapi' => { 'version' => '1.0' }, + 'data' => { + 'type' => 'items', + 'attributes' => { + 'displayName' => input['file_name'], + 'extension' => + { 'type' => input['object_type'], 'version' => '1.0' } + }, + 'relationships' => { + 'tip' => { + 'data' => { + 'type' => 'versions', + 'id' => '1' + } + }, + 'parent' => { + 'data' => { 'type' => 'folders', 'id' => input['folder_id'] } + } + } + }, + 'included' => [ + { + 'type' => 'versions', + 'id' => '1', + 'attributes' => { + 'name' => input['file_name'], + 'extension' => { + 'type' => input['object_type'], + 'version' => '1.0' + } + }, + 'relationships' => { + 'storage' => { + 'data' => { + 'type' => 'objects', + 'id' => storage_object_id + } + } + # , + # 'refs' => { + # 'data' => { + # 'type' => 'versions', + # 'id' => '1.0' + # }, + # 'meta' => { + # 'refType' => 'xrefs', + # 'direction' => '', + # 'extension' => { + # 'type' => 'xrefs:autodesk.core:Xref', + # 'version' => '1.1.0.', + # 'data' => { + # 'nestedType' => 'attachment' + # } + # } + # } + # } + } + } + ] + } + item_id = + post("/data/v1/projects/#{project_id}/items"). + request_body(version_payload.to_json). + headers(Accept: 'application/vnd.api+json'). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.dig('data', 'id') + # 4 Update version of the file + update_version = { + 'jsonapi' => '1.0', + 'data' => { + 'type' => 'versions', + 'attributes': { + 'extension' => { + 'type' => 'versions:autodesk.core:File"', + 'version' => '1.0' + } + }, + 'relationships' => { + 'item' => { + 'data' => { + 'type' => 'items', + 'id' => item_id + } + }, + 'storage' => { + 'data' => { + 'type' => 'objects', + 'id' => storage_object_id + } + } + } + } + } + post("/data/v1/projects/#{project_id}/versions"). + payload(update_version). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + end, + output_fields: lambda do |object_definitions| + object_definitions['folder_file'] + end + } + }, + triggers: { + new_rfi_in_project: { + title: 'New RFI in a project', + description: 'New RFI in'\ + ' a project in BIM 360', + help: { + body: 'Triggers when a RFI in a project is created.' + }, + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'since', + label: 'When first started, this recipe should pick up events from', + hint: 'When you start recipe for the first time, ' \ + 'it picks up trigger events from this specified date and time. ' \ + 'Leave empty to get records created or updated one hour ago', + sticky: true, + type: 'timestamp' + } + ] + end, + poll: lambda do |_connection, input, closure| + project_id = closure&.[]('project_id') || input['project_id'] + container_id = closure&.[]('container_id') || + get("/project/v1/hubs/#{input['hub_id']}" \ + "/projects/#{project_id}")&. + dig('data', 'relationships', 'issues', 'data', 'id') + from_date = closure&.[]('from_date') || + (input['since'] || 1.hour.ago). + to_time.strftime('%Y-%m-%dT%H:%M:%H.%s%z') + limit = 10 + skip = closure&.[]('skip') || 0 + include = closure&.[]('include') || input['include'] + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get("/bim360/rfis/v1/containers/#{container_id}/rfis"). + params(page: { limit: limit, + skip: skip }, + filter: { + created_at: from_date + }, + include: 'attachments,comments', + sort: 'created_at') + end + closure = if (next_page_url = response.dig('links', 'next')).present? + { 'skip' => skip + limit, + 'container_id' => container_id, + 'project_id' => project_id, + 'include' => include, + 'from_date' => from_date, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'include' => include, + 'from_date' => now.to_time. + strftime('%Y-%m-%dT%H:%M:%H.%s%z'), + 'container_id' => container_id, + 'project_id' => project_id } + end + rfis = response['data']&. + map { |o| o.merge({ project_id: project_id }) } + { + events: rfis || [], + next_poll: closure, + can_poll_more: response.dig('links', 'next').present? + } + end, + dedup: lambda do |rfi| + "#{rfi['id']}@#{rfi.dig('attributes', 'created_at')}" + end, + output_fields: lambda do |object_definitions| + [{ name: 'project_id' }].concat(object_definitions['rfi']) + end, + sample_output: lambda do |_connection, input| + project_id = input['project_id'] + container_id = get("/project/v1/hubs/#{input['hub_id']}" \ + "/projects/#{project_id}")&. + dig('data', 'relationships', 'issues', 'data', 'id') + get("/bim360/rfis/v1/containers/#{container_id}/rfis")&. + dig('data', 0) || {} + end + }, + new_updated_issue_in_project: { + title: 'New/updated issue in a project', + description: 'New/updated issue in'\ + ' a project in BIM 360', + help: { + body: 'Triggers when a issue in a project is created/updated.' + }, + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'include', + sticky: true, + label: 'Include additional data', + hint: 'Include additional data about attachments, comments,' \ + ' and the project (container) in the response.', + control_type: 'multiselect', + pick_list: 'issue_child_objects', + pick_list_params: {}, + delimiter: ',', + toggle_hint: 'Select from list', + toggle_field: { + name: 'include', + label: 'Include additinal data', + type: :string, + control_type: 'text', + optional: true, + hint: 'Multiple values separated by comma.', + toggle_hint: 'Comma separated list of values. Allowed values ' \ + 'are: attachments, comments, container' + } + }, + { + name: 'since', + label: 'When first started, this recipe should pick up events from', + hint: 'When you start recipe for the first time, ' \ + 'it picks up trigger events from this specified date and time. ' \ + 'Leave empty to get records created or updated one hour ago', + sticky: true, + type: 'timestamp' + } + ] + end, + poll: lambda do |_connection, input, closure| + project_id = closure&.[]('project_id') || input['project_id'] + container_id = closure&.[]('container_id') || + get("/project/v1/hubs/#{input['hub_id']}" \ + "/projects/#{project_id}")&. + dig('data', 'relationships', 'issues', 'data', 'id') + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 10 + skip = closure&.[]('skip') || 0 + include = closure&.[]('include') || input['include'] + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get("/issues/v1/containers/#{container_id}/" \ + 'quality-issues'). + params(page: { limit: limit, + skip: skip }, + filter: { synced_after: updated_after }, + sort: 'updated_at', + included: include) + end + closure = if (next_page_url = response.dig('links', 'next')).present? + { 'skip' => skip + limit, + 'container_id' => container_id, + 'project_id' => project_id, + 'include' => include, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'container_id' => container_id, + 'project_id' => project_id, + 'include' => include, + 'updated_after' => now.to_time.utc.iso8601 } + end + issues = response['data']&. + map { |o| o.merge({ project_id: project_id }) } + { + events: issues || [], + next_poll: closure, + can_poll_more: response.dig('links', 'next').present? + } + end, + dedup: lambda do |issue| + "#{issue['id']}&#{issue.dig('attributes', 'updated_at')}" + end, + output_fields: lambda do |object_definitions| + [{ name: 'project_id' }].concat(object_definitions['issue']).compact + end, + sample_output: lambda do |_connection, input| + project_id = input['project_id'] + container_id = get("/project/v1/#{input['hub_id']}" \ + "/projects/#{project_id}")&. + dig('relationships', 'rfis', 'data', 'id') + get("/issues/v1/containers/#{container_id}/" \ + 'quality-issues?page[limit]=1')&.dig('data', 0) || {} + end + }, + new_updated_document_in_project: { + title: 'New/updated document in a project', + description: 'New/updated document in'\ + ' a project in BIM 360', + help: { + body: 'Triggers when a document in a project is created/updated.' + }, + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + } + }, + { name: 'folder_id', + label: 'Folder', + control_type: 'tree', + hint: 'Select folder', + toggle_hint: 'Select Folder', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, + tree_options: { selectable_folder: true }, + pick_list: :folders_list, + optional: false, + toggle_field: { + name: 'folder_id', + type: 'string', + control_type: 'text', + label: 'Folder ID', + toggle_hint: 'Use Folder ID', + hint: 'Use Folder ID' + } }, + { + name: 'since', + label: 'When first started, this recipe should pick up events from', + hint: 'When you start recipe for the first time, ' \ + 'it picks up trigger events from this specified date and time. ' \ + 'Leave empty to get records created or updated one hour ago', + sticky: true, + type: 'timestamp' + } + ] + end, + poll: lambda do |_connection, input, closure| + project_id = closure&.[]('project_id') || input['project_id'] + folder_id = closure&.[]('folder_id') || input['folder_id'] + + last_modified_time = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 10 + skip = closure&.[]('skip') || 0 + include = closure&.[]('include') || input['include'] + + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + query_params = + 'filter[type]=items&filter[lastModifiedTimeRollup]-ge=' \ + "#{last_modified_time}&" \ + "page[limit]=#{limit}&page[skip]=#{skip}" + get("/data/v1/projects/#{project_id}/folders/" \ + "#{folder_id}/contents", query_params) + end + + items = response['data']&. + map { |o| o.merge({ project_id: project_id }) } + closure = if (next_page_url = response.dig('links', 'next')).present? + { 'skip' => skip + limit, + 'folder_id' => folder_id, + 'project_id' => project_id, + 'include' => include, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'folder_id' => folder_id, + 'project_id' => project_id, + 'include' => include, + 'updated_after' => now.to_time.utc.iso8601 } + end + { + events: items || [], + next_poll: closure, + can_poll_more: response.dig('links', 'next').present? + } + end, + dedup: lambda do |item| + "#{item['id']}&#{item.dig('attributes', 'lastModifiedTime')}" + end, + output_fields: lambda do |object_definitions| + [{ name: 'project_id' }].concat(object_definitions['folder_file']). + compact + end, + sample_output: lambda do |_connection, input| + get("/data/v1/projects/#{input['project_id']}/folders/" \ + "#{input['folder_id']}/contents?page[limit]=1")&.dig('data', 0) || {} + end + } + }, + pick_lists: { + hub_list: lambda do |_connection| + get('/project/v1/hubs')['data']&.map do |hub| + [hub.dig('attributes', 'name'), hub['id']] + end + end, + file_types: lambda do |_connection| + [ + ['BIM 360 Docs files', 'items:autodesk.bim360:File'], + ['All other service', 'items:autodesk.core:File'] + ] + end, + folder_items: lambda do |_connection, project_id:, folder_id:| + get("/data/v1/projects/#{project_id}/folders/#{folder_id}/" \ + 'contents?filter[type]=items')['data']&. + map do |item| + [item.dig('attributes', 'displayName'), item['id']] + end + end, + item_versions: lambda do |_connection, project_id:, item_id:| + get("/data/v1/projects/#{project_id}/items/#{item_id}/" \ + 'versions')['data']&. + map do |version| + ["Version #{version.dig('attributes', 'versionNumber')}", + version.dig('id')] + end + end, + folders_list: lambda do |_connection, **args| + hub_id = args[:hub_id] + project_id = args[:project_id] + parent_id = args&.[](:__parent_id) + if parent_id.present? + get("/data/v1/projects/#{project_id}/folders/#{parent_id}/" \ + 'contents?filter[type]=folders')['data']&. + map do |folder| + [folder.dig('attributes', 'displayName'), + folder['id'], folder['id'], true] + end + else + get("project/v1/hubs/#{hub_id}/projects/#{project_id}/" \ + 'topFolders?filter[type]=folders')['data']&. + map do |folder| + [folder.dig('attributes', 'displayName'), + folder['id'], folder['id'], true] + end || [] + end + end, + rfi_child_objects: lambda do |_connection| + %w[attachments comments activity_batches container]&. + map { |option| [option.labelize, option] } + end, + rfi_transaction_status_list: lambda do |_connection| + %w[draft submitted open rejected answered closed void]&. + map { |option| [option.labelize, option] } + end, + issue_child_objects: lambda do |_connection| + %w[attachments comments container]&. + map { |option| [option.labelize, option] } + end, + project_list: lambda do |_connection, hub_id:| + get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| + [project.dig('attributes', 'name'), project['id']] + end + end, + issue_container_lists: lambda do |_connection, hub_id:| + get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| + [project.dig('attributes', 'name'), + project.dig('relationships', 'issues', 'data', 'id')] + end + end, + rfis_container_lists: lambda do |_connection, hub_id:| + get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| + [project.dig('attributes', 'name'), + project.dig('relationships', 'rfis', 'data', 'id')] + end + end, + rfi_objects: lambda do |_connection| + %w[attachments comments activity_batches container]&. + map { |option| [option.labelize, option] } + end, + project_types: lambda do + [ + %w[Commercial Commercial], ['Convention Center', 'Convention Center'], + ['Data Center', 'Data Center'], ['Hotel / Motel', 'Hotel / Motel'], + %w[Office Office], + ['Parking Structure / Garage', 'Parking Structure / Garage'], + ['Performing Arts', 'Performing Arts'], %w[Retail Retail], + ['Stadium/Arena', 'Stadium/Arena'], ['Theme Park', 'Theme Park'], + ['Warehouse (non-manufacturing)', 'Warehouse (non-manufacturing)'], + %w[Healthcare Healthcare], + ['Assisted Living / Nursing Home', 'Assisted Living / Nursing Home'], + %w[Hospital Hospital], ['Medical Laboratory', 'Medical Laboratory'], + ['Medical Office', 'Medical Office'], + ['OutPatient Surgery Center', 'OutPatient Surgery Center'], + %w[Institutional Institutional], ['Court House', 'Court House'], + %w[Dormitory Dormitory], ['Education Facility', 'Education Facility'], + ['Government Building', 'Government Building'], %w[Library Library], + ['Military Facility', 'Military Facility'], %w[Museum Museum], + ['Prison / Correctional Facility', 'Prison / Correctional Facility'], + ['Recreation Building', 'Recreation Building'], + ['Religious Building', 'Religious Building'], + ['Research Facility / Laboratory', 'Research Facility / Laboratory'], + %w[Residential Residential], + ['Multi-Family Housing', 'Multi-Family Housing'], + ['Single-Family Housing', 'Single-Family Housing'], + %w[Infrastructure Infrastructure], %w[Airport Airport], + %w[Bridge Bridge], ['Canal / Waterway', 'Canal / Waterway'], + ['Dams / Flood Control / Reservoirs', + 'Dams / Flood Control / Reservoirs'], + ['Harbor / River Development', 'Harbor / River Development'], + %w[Rail Rail], %w[Seaport Seaport], + ['Streets / Roads / Highways', 'Streets / Roads / Highways'], + ['Transportation Building', 'Transportation Building'], + %w[Tunnel Tunnel], ['Waste Water / Sewers', 'Waste Water / Sewers'], + ['Water Supply', 'Water Supply'], + ['Industrial & Energy', 'Industrial & Energy'], + ['Manufacturing / Factory', 'Manufacturing / Factory'], + ['Oil & Gas', 'Oil & Gas'], + %w[Plant Plant], ['Power Plant', 'Power Plant'], + ['Solar Far', 'Solar Far'], %w[Utilities Utilities], + ['Wind Farm', 'Wind Farm'], ['Sample Projects', 'Sample Projects'], + ['Demonstration Project', 'Demonstration Project'], + ['Template Project', 'Template Project'], + ['Training Project', 'Training Project'] + ] + end, + assigned_type_list: lambda do |_connection| + %w[user company role]&.map { |el| [el.labelize, el] } + end, + rfi_status_list: lambda do |_connection| + %w[draft open close]&.map { |el| [el.labelize, el] } + end, + status_list: lambda do |_connection| + %w[active pending inactive archived]&.map { |el| [el.labelize, el] } + end, + issue_status_list: lambda do |_connection| + %w[open work_complete ready_to_inspect not_approved close in_dispute + void]&.map { |el| [el.labelize, el] } + end, + service_types: lambda do |_connection| + [ + ['Field Service', 'field'], + ['Glue Service', 'glue'], + ['Schedule Service', 'schedule'], + ['Plan Service', 'plan'], + ['Docs Service', 'doc_manager'] + ] + end + } +} From b3dddcc07618a3a11b456dd6516e5400a52166fb Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 13:23:11 -0400 Subject: [PATCH 02/62] update `modify_rfi` object definition to match order of inputs --- custom_connectors/oauth2/bim_360.rb | 30 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 151e268f..7ce872fc 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -851,11 +851,23 @@ modify_rfi: { fields: lambda do |_connection, _config_fields| [ - { name: 'transition_id', - hint: 'This field is mandatory when tranistioning the RFI.' }, + { name: 'title' }, + { name: 'description', label: 'Question' }, + { name: 'suggested_answer', label: 'Suggested Answer' }, + { name: 'answer', hint: 'An answer for the RFI.' }, { name: 'assigned_to', hint: 'The Autodesk ID of the user you want to assign ' \ 'the RFI to.' }, + { name: 'location_description' }, + { name: 'due_date', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'The timestamp of the due date for the RFI, in the ' \ + 'following format: YYYY-MM-DDThh:mm:ss.sz.' }, + { name: 'distribution_list', + hint: 'Provide comma seaprated list of values multiple values' }, + { name: 'transition_id', + hint: 'This field is mandatory when tranistioning the RFI.' }, { name: 'co_reviewers', hint: 'Add members who can contribute to the RFI response. ' \ 'Note that although you can only add co-reviewers in the UI ' \ @@ -863,12 +875,6 @@ ' also set up co-reviewers in other statuses.' \ 'To delete all co-reviewers, call the endpoint with an empty' \ ' array.' }, - { name: 'description' }, - { name: 'due_date', type: 'date_time', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp', - hint: 'The timestamp of the due date for the RFI, in the ' \ - 'following format: YYYY-MM-DDThh:mm:ss.sz.' }, { name: 'reserve_custom_identifier', hint: 'This field allows to reserve a custom identifier for ' \ 'future use (for example, in draft or submitted status). No ' \ @@ -877,13 +883,7 @@ { name: 'custom_identifier', hint: 'Identifier of the RFI given by user. When non-present in' \ ' transitions to any status, except “draft” or “submitted”, ' \ - 'will be populated automatically.' }, - { name: 'location_description' }, - { name: 'answer', hint: 'An answer for the RFI.' }, - { name: 'suggested_answer' }, - { name: 'title' }, - { name: 'distribution_list', - hint: 'Provide comma seaprated list of values multiple values' } + 'will be populated automatically.' } ] end }, From f73b5163b7a482bcbfe08e62d84335bf6fff1e3f Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 13:23:43 -0400 Subject: [PATCH 03/62] update `rfi` object definition, remove unnecessary info --- custom_connectors/oauth2/bim_360.rb | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 7ce872fc..a8c4ab35 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -520,16 +520,7 @@ rfi: { fields: lambda do |_connection, _config_fields| [ - { name: 'id', hint: 'RFI ID' }, - { name: 'type', label: 'Objec type', - hint: 'The type of object; will always be rfis.' }, - { name: 'links', type: 'object', properties: [ - { name: 'self' }, - { name: 'first', hint: 'A link to the first page.' }, - { name: 'prev', hint: 'A link to the previous page.' }, - { name: 'next', hint: 'A link to the next page.' }, - { name: 'last', hint: 'A link to the last page.' } - ] }, + { name: 'id', label: 'RFI ID' }, { name: 'attributes', type: 'object', properties: [ { name: 'created_at', type: 'date_time', hint: 'The timestamp of the date and time the issue was ' \ From cc6f3caae0d5cf94c23e023230074af417828f38 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 13:25:22 -0400 Subject: [PATCH 04/62] update `new rfi` trigger to include `hub_id`, `project_id`, and `container_id` --- custom_connectors/oauth2/bim_360.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index a8c4ab35..04f39d9b 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2991,7 +2991,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -3007,7 +3007,7 @@ }, { name: 'project_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -3034,6 +3034,7 @@ ] end, poll: lambda do |_connection, input, closure| + hub_id = closure&.[]('hub_id') || input['hub_id'] project_id = closure&.[]('project_id') || input['project_id'] container_id = closure&.[]('container_id') || get("/project/v1/hubs/#{input['hub_id']}" \ @@ -3061,6 +3062,7 @@ { 'skip' => skip + limit, 'container_id' => container_id, 'project_id' => project_id, + 'hub_id' => hub_id, 'include' => include, 'from_date' => from_date, 'next_page_url' => next_page_url } @@ -3070,10 +3072,11 @@ 'from_date' => now.to_time. strftime('%Y-%m-%dT%H:%M:%H.%s%z'), 'container_id' => container_id, - 'project_id' => project_id } + 'project_id' => project_id, + 'hub_id' => hub_id } end rfis = response['data']&. - map { |o| o.merge({ project_id: project_id }) } + map { |o| o.merge({ project_id: project_id }).merge({ hub_id: hub_id }).merge({ container_id: container_id }) } { events: rfis || [], next_poll: closure, @@ -3084,7 +3087,7 @@ "#{rfi['id']}@#{rfi.dig('attributes', 'created_at')}" end, output_fields: lambda do |object_definitions| - [{ name: 'project_id' }].concat(object_definitions['rfi']) + [{ name: 'hub_id' }, { name: 'project_id' }, { name: 'container_id' }].concat(object_definitions['rfi']) end, sample_output: lambda do |_connection, input| project_id = input['project_id'] From 4b45f45051999fc811aa96b398f753568eb4ff61 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 13:26:02 -0400 Subject: [PATCH 05/62] update `rfis_container_lists` picklist so it does not error when `hub_id` is dynamic value --- custom_connectors/oauth2/bim_360.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 04f39d9b..66d1b810 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -3427,9 +3427,11 @@ end end, rfis_container_lists: lambda do |_connection, hub_id:| - get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| - [project.dig('attributes', 'name'), - project.dig('relationships', 'rfis', 'data', 'id')] + if hub_id.length === 38 + get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| + [project.dig('attributes', 'name'), + project.dig('relationships', 'rfis', 'data', 'id')] + end end end, rfi_objects: lambda do |_connection| From 9d8742c0c5b93e04b5bd5f37e8a1f87b9a6f50f0 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 13:26:27 -0400 Subject: [PATCH 06/62] update `project_list` pick list to not error when `hub_id` is dynamically entered --- custom_connectors/oauth2/bim_360.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 66d1b810..cf712f47 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -3416,8 +3416,10 @@ map { |option| [option.labelize, option] } end, project_list: lambda do |_connection, hub_id:| - get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| - [project.dig('attributes', 'name'), project['id']] + if hub_id.length === 38 + get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| + [project.dig('attributes', 'name'), project['id']] + end end end, issue_container_lists: lambda do |_connection, hub_id:| From a6a3060935e319d2a334bab84c88136b22a59972 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 15:48:33 -0400 Subject: [PATCH 07/62] update `issue` object definition, remove unnecessary fields --- custom_connectors/oauth2/bim_360.rb | 59 ++--------------------------- 1 file changed, 3 insertions(+), 56 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index cf712f47..428d4561 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -203,12 +203,6 @@ fields: lambda do |_connection, _config_fields| [ { name: 'id', label: 'Issue ID' }, - { name: 'type', - hint: 'The type of the object; will always be' \ - ' quality_issues' }, - { name: 'links', type: 'object', properties: [ - { name: 'self', hint: 'A reference to the issue itself.' } - ] }, { name: 'attributes', type: 'object', properties: [ { name: 'created_at', type: 'date_time', hint: 'The timestamp of the date and time the issue was ' \ @@ -243,14 +237,9 @@ hint: 'The description of the purpose of the issue.' }, { name: 'location_description', hint: 'The location of the issue.' }, - { name: 'markup_metadata' }, - { name: 'tags', type: 'object' }, - { name: 'resource_urns' }, { name: 'target_urn', hint: 'The item ID of the document associated with the ' \ 'pushpin issue.' }, - { name: 'target_urn_page' }, - { name: 'collection_urn' }, { name: 'due_date', type: 'date_time', hint: 'The timestamp of the issue’s specified due date,' \ ' in the following format: YYYY-MM-DDThh:mm:ss.sz', @@ -282,9 +271,6 @@ hint: 'The type and location of the pushpin' }, { name: 'owner', hint: 'The Autodesk ID of the user who owns this issue.' }, - { name: 'issue_type_id' }, - { name: 'issue_type' }, - { name: 'issue_sub_type' }, { name: 'root_cause_id' }, { name: 'root_cause' }, { name: 'quality_urns', type: 'object' }, @@ -302,10 +288,10 @@ { name: 'lbs_location', hint: 'The ID of the location that relates to the issue.' }, { name: 'sheet_metadata' }, - { name: 'ng_issue_subtype_id', label: 'Issue subtype ID', - hint: 'The ID of the issue subtype' }, { name: 'ng_issue_type_id', label: 'Issue type ID', - hint: 'The ID of the issue type.' } + hint: 'The ID of the issue type.' }, + { name: 'ng_issue_subtype_id', label: 'Issue subtype ID', + hint: 'The ID of the issue subtype' } ] }, # To Do { name: 'custom_attributes', type: 'array', of: 'object' }, @@ -384,46 +370,7 @@ { name: 'urn_version' }, { name: 'permitted_actions' } ] } - ] }, - { name: 'snapshot_urn' }, - { name: 'relationships', type: 'object', properties: [ - { name: 'container', type: 'object', properties: [ - { name: 'links', type: 'object', properties: [ - { name: 'self' }, - { name: 'related' } - ] } - ] }, - { name: 'activity_batches', type: 'object', properties: [ - { name: 'links', type: 'object', properties: [ - { name: 'self' }, - { name: 'related' } - ] } - ] }, - { name: 'comments', type: 'object', properties: [ - { name: 'links', type: 'object', properties: [ - { name: 'self' }, - { name: 'related' } - ] } - ] }, - { name: 'attachments', type: 'object', properties: [ - { name: 'links', type: 'object', properties: [ - { name: 'self' }, - { name: 'related' } - ] } - ] }, - { name: 'root_cause_obj', type: 'object', properties: [ - { name: 'links', type: 'object', properties: [ - { name: 'self' }, - { name: 'related' } - ] } - ] }, - { name: 'issue_type_obj', type: 'object', properties: [ - { name: 'links', type: 'object', properties: [ - { name: 'self' }, - { name: 'related' } - ] } ] } - ] } ] end }, From 83fcf221dcab846c672792b0e2d007989c168aeb Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 15:49:23 -0400 Subject: [PATCH 08/62] update `create issue` action, output `hub_id` and `container_id` in result --- custom_connectors/oauth2/bim_360.rb | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 428d4561..89a54605 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -1474,7 +1474,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1490,26 +1490,26 @@ }, { name: 'container_id', - label: 'Container name', + label: 'Project Name', control_type: 'select', pick_list: 'issue_container_lists', pick_list_params: { hub_id: 'hub_id' }, optional: false, - toggle_hint: 'Select container', + toggle_hint: 'Select project', toggle_field: { name: 'container_id', label: 'Container ID', type: 'string', control_type: 'text', toggle_hint: 'Use custom value', - hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + hint: 'Provide container id e.g. edac0659-639a-4a87-8614-d2c521b246b0' } } ].concat(object_definitions['create_issue']. required('title', 'ng_issue_type_id', 'ng_issue_subtype_id')) end, execute: lambda do |_connection, input| - input.delete('hub_id') + hub_id = input.delete('hub_id') container_id = input.delete('container_id') payload = { type: 'quality_issues', @@ -1517,12 +1517,16 @@ } post("/issues/v1/containers/#{container_id}/quality-issues"). payload({ data: payload }). + headers('Content-Type': 'application/vnd.api+json'). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end['data'] + end['data']&.merge({ container_id: container_id }).merge({ hub_id: hub_id }) end, output_fields: lambda do |object_definitions| - object_definitions['issue'] + [ + { name: 'hub_id' }, + { name: 'container_id' } + ].concat(object_definitions['issue']) end, sample_output: lambda do |_connection, input| project_id = input['project_id'] From bb06a4625f15707d8ec2a9934c81bd4470ab3bde Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 15:50:36 -0400 Subject: [PATCH 09/62] update `search issues` action, output `hub_id`, `project_id`, and `container_id` in result --- custom_connectors/oauth2/bim_360.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 89a54605..82517514 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -1446,10 +1446,14 @@ "/projects/#{project_id}")&. dig('data', 'relationships', 'issues', 'data', 'id') { issues: get("/issues/v1/containers/#{container_id}/quality-issues", - filter_criteria)['data'] } + filter_criteria)['data'] }.merge({ hub_id: hub_id }).merge({ container_id: container_id }).merge({ project_id: project_id }) end, output_fields: lambda do |object_definitions| - [{ name: 'issues', type: 'array', of: 'object', + [ + {name: 'hub_id' }, + { name: 'project_id' }, + { name: 'container_id' }, + { name: 'issues', type: 'array', of: 'object', properties: object_definitions['issue'] }] end, sample_output: lambda do |_connection, input| From 5b51e4db901aa4ec14083e904b6e4881622f6f66 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 15:51:29 -0400 Subject: [PATCH 10/62] update `update issue` action, include correct headers, output `hub_id` and `container_id` in result --- custom_connectors/oauth2/bim_360.rb | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 82517514..6363facf 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -1592,25 +1592,30 @@ name: 'id', label: 'Issue ID', optional: false } - ].concat(object_definitions['update_issue']) + ].concat(object_definitions['update_issue'].ignored('id')) end, execute: lambda do |_connection, input| - input.delete('hub_id') + hub_id = input.delete('hub_id') + container_id = input.delete('container_id') id = input.delete('id') payload = { id: id, type: 'quality_issues', attributes: input } - patch("/issues/v1/containers/#{input.delete('container_id')}/" \ + patch("/issues/v1/containers/#{container_id}/" \ "quality-issues/#{id}"). payload({ data: payload }). + headers('Content-Type': 'application/vnd.api+json'). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end['data'] + end['data']&.merge({ hub_id: hub_id }).merge({ container_id: container_id }) end, output_fields: lambda do |object_definitions| - object_definitions['issue'] + [ + { name: 'hub_id' }, + { name: 'container_id' } + ].concat( object_definitions['issue'] ) end, sample_output: lambda do |_connection, input| project_id = input['project_id'] From 55f304c94c0aa0142e7cef7263bc17b3e26449dd Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 15:51:56 -0400 Subject: [PATCH 11/62] update `get issue` action, output `hub_id` and `container_id` --- custom_connectors/oauth2/bim_360.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 6363facf..650460c9 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -1656,19 +1656,19 @@ }, { name: 'container_id', - label: 'Container name', + label: 'Project Name', control_type: 'select', pick_list: 'issue_container_lists', pick_list_params: { hub_id: 'hub_id' }, optional: false, - toggle_hint: 'Select container', + toggle_hint: 'Select project', toggle_field: { name: 'container_id', label: 'Container ID', type: 'string', control_type: 'text', toggle_hint: 'Use custom value', - hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + hint: 'Provide container id e.g. edac0659-639a-4a87-8614-d2c521b246b0' } }, { name: 'issue_id', optional: false } @@ -1679,10 +1679,13 @@ "quality-issues/#{input['issue_id']}"). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end['data'] + end['data'].merge({ hub_id: input['hub_id'] }).merge({ container_id: input['container_id'] }) end, output_fields: lambda do |object_definitions| - object_definitions['issue'] + [ + { name: 'hub_id' }, + { name: 'container_id' } + ].concat( object_definitions['issue'] ) end, sample_output: lambda do |_connection, input| project_id = input['project_id'] From 1c2e35efa5ee747c89d1bc694c0b376cb594082c Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 15:52:53 -0400 Subject: [PATCH 12/62] update `new issue..` trigger, remove additional `include` parameters, output `hub_id`, `project_id`, and `container_id` --- custom_connectors/oauth2/bim_360.rb | 39 ++++++++--------------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 650460c9..275bd5be 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -3062,17 +3062,17 @@ end }, new_updated_issue_in_project: { - title: 'New/updated issue in a project', - description: 'New/updated issue in'\ + title: 'New or updated issue in a project', + description: 'New or updated issue in'\ ' a project in BIM 360', help: { - body: 'Triggers when a issue in a project is created/updated.' + body: 'Triggers when a issue in a project is created or updated.' }, input_fields: lambda do |_object_definitions| [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -3088,7 +3088,7 @@ }, { name: 'project_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -3103,28 +3103,6 @@ hint: 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' } }, - { - name: 'include', - sticky: true, - label: 'Include additional data', - hint: 'Include additional data about attachments, comments,' \ - ' and the project (container) in the response.', - control_type: 'multiselect', - pick_list: 'issue_child_objects', - pick_list_params: {}, - delimiter: ',', - toggle_hint: 'Select from list', - toggle_field: { - name: 'include', - label: 'Include additinal data', - type: :string, - control_type: 'text', - optional: true, - hint: 'Multiple values separated by comma.', - toggle_hint: 'Comma separated list of values. Allowed values ' \ - 'are: attachments, comments, container' - } - }, { name: 'since', label: 'When first started, this recipe should pick up events from', @@ -3137,6 +3115,7 @@ ] end, poll: lambda do |_connection, input, closure| + hub_id = closure&.[]('hub_id') || input['hub_id'] project_id = closure&.[]('project_id') || input['project_id'] container_id = closure&.[]('container_id') || get("/project/v1/hubs/#{input['hub_id']}" \ @@ -3162,17 +3141,19 @@ { 'skip' => skip + limit, 'container_id' => container_id, 'project_id' => project_id, + 'hub_id' => hub_id, 'include' => include, 'next_page_url' => next_page_url } else { 'offset' => 0, 'container_id' => container_id, 'project_id' => project_id, + 'hub_id' => hub_id, 'include' => include, 'updated_after' => now.to_time.utc.iso8601 } end issues = response['data']&. - map { |o| o.merge({ project_id: project_id }) } + map { |o| o.merge({ project_id: project_id }).merge({ hub_id: hub_id }).merge({ container_id: container_id }) } { events: issues || [], next_poll: closure, @@ -3183,7 +3164,7 @@ "#{issue['id']}&#{issue.dig('attributes', 'updated_at')}" end, output_fields: lambda do |object_definitions| - [{ name: 'project_id' }].concat(object_definitions['issue']).compact + [{ name: 'hub_id' }, { name: 'project_id' }, { name: 'container_id' }].concat(object_definitions['issue']).compact end, sample_output: lambda do |_connection, input| project_id = input['project_id'] From 80ba213184ca93093a3d371d3b48d8c42e2a319f Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 15:53:32 -0400 Subject: [PATCH 13/62] update `issue_container_lists` picklist to ignore dynamic `hub_id` --- custom_connectors/oauth2/bim_360.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 275bd5be..408e0cf7 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -3367,9 +3367,11 @@ end end, issue_container_lists: lambda do |_connection, hub_id:| - get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| - [project.dig('attributes', 'name'), - project.dig('relationships', 'issues', 'data', 'id')] + if hub_id.length === 38 + get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| + [project.dig('attributes', 'name'), + project.dig('relationships', 'issues', 'data', 'id')] + end end end, rfis_container_lists: lambda do |_connection, hub_id:| From f71b5044d79b8d371cec6bc05fb4c6df566b9d93 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 15:55:04 -0400 Subject: [PATCH 14/62] update `rfi` object definition, remove unnecessary output --- custom_connectors/oauth2/bim_360.rb | 8 -------- 1 file changed, 8 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 408e0cf7..6b76f2ee 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -774,14 +774,6 @@ { name: 'permitted_actions' } ] } ] } - ] }, - { name: 'included', type: 'array', of: 'object' }, - { name: 'meta', type: 'object', properties: [ - { name: 'record_count', type: 'integer', control_type: 'number' }, - { name: 'page', type: 'object', properties: [ - { name: 'offset', type: 'integer' }, - { name: 'limit', type: 'integer' } - ] } ] } ] end From 2131b69760391a4be343e5701c4a732165600e3a Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 15:57:47 -0400 Subject: [PATCH 15/62] update `search rfis...` action, output `hub_id` and `container_id` in result --- custom_connectors/oauth2/bim_360.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 6b76f2ee..c06dee7e 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -1872,15 +1872,19 @@ ].concat(object_definitions['rfis_criteria']) end, execute: lambda do |_connection, input| - input.delete('hub_id') + hub_id = input.delete('hub_id') container_id = input.delete('container_id') filter_criteria = call('format_search', input) { rfis: get("/bim360/rfis/v1/containers/#{container_id}/rfis", - filter_criteria)['data'] } + filter_criteria)['data'] }.merge({ hub_id: hub_id }).merge({ container_id: container_id }) end, output_fields: lambda do |object_definitions| - [{ name: 'rfis', type: 'array', of: 'object', - properties: object_definitions['rfi'] }] + [ + { name: 'hub_id' }, + { name: 'container_id' }, + { name: 'rfis', label: 'RFIs', type: 'array', of: 'object', + properties: object_definitions['rfi'] } + ] end, sample_output: lambda do |_connection, input| { rfis: From 8d2d83ed4fec5be0b976faa65385110a7a77601d Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 15:58:50 -0400 Subject: [PATCH 16/62] update `get rfi` action, include `hub_id` and `container_id` in result --- custom_connectors/oauth2/bim_360.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index c06dee7e..b6b9fed5 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -1904,7 +1904,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1920,19 +1920,19 @@ }, { name: 'container_id', - label: 'Container name', + label: 'Project Name', control_type: 'select', pick_list: 'rfis_container_lists', pick_list_params: { hub_id: 'hub_id' }, optional: false, - toggle_hint: 'Select container', + toggle_hint: 'Select project', toggle_field: { name: 'container_id', label: 'Container ID', type: 'string', control_type: 'text', toggle_hint: 'Use custom value', - hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + hint: 'Provide container ID e.g. edac0659-639a-4a87-8614-d2c521b246b0' } }, { name: 'id', optional: false, label: 'RFI ID' } @@ -1943,10 +1943,10 @@ "#{input['id']}"). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end['data'] + end['data'].merge({ hub_id: input['hub_id'] }).merge({ container_id: input['container_id'] }) end, output_fields: lambda do |object_definitions| - object_definitions['rfi'] + [{ name: 'hub_id' }, { name: 'container_id' }].concat(object_definitions['rfi']) end, sample_output: lambda do |_connection, input| get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. From 60f8248b233b4ce41777a3875924e36af97c92b7 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 15:59:41 -0400 Subject: [PATCH 17/62] update `create rfi...` action, include correct headers, output `hub_id` and `container_id` --- custom_connectors/oauth2/bim_360.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index b6b9fed5..0ba59af3 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -1967,7 +1967,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1983,26 +1983,26 @@ }, { name: 'container_id', - label: 'Container name', + label: 'Project Name', control_type: 'select', pick_list: 'rfis_container_lists', pick_list_params: { hub_id: 'hub_id' }, optional: false, - toggle_hint: 'Select container', + toggle_hint: 'Select project', toggle_field: { name: 'container_id', label: 'Container ID', type: 'string', control_type: 'text', toggle_hint: 'Use custom value', - hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + hint: 'Provide container ID e.g. edac0659-639a-4a87-8614-d2c521b246b0' } } ].concat(object_definitions['modify_rfi']. ignored('transition_id', 'assigned_to', 'answer')) end, execute: lambda do |_connection, input| - input.delete('hub_id') + hub_id = input.delete('hub_id') container_id = input.delete('container_id') input_payload = input&.map do |key, value| if %w[distribution_list co_reviewers].include?(key) @@ -2017,12 +2017,13 @@ } post("/bim360/rfis/v1/containers/#{container_id}/rfis"). payload({ data: payload }). + headers('Content-Type': 'application/vnd.api+json' ). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end['data'] + end['data'].merge({ hub_id: hub_id }).merge({ container_id: container_id }) end, output_fields: lambda do |object_definitions| - object_definitions['rfi'] + [{ name: 'hub_id' }, { name: 'container_id' }].concat(object_definitions['rfi']) end, sample_output: lambda do |_connection, input| get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. From b85968b915f703a515a1f2792c4fac34bf320491 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 16:00:30 -0400 Subject: [PATCH 18/62] update `update rfi..` action, include correct headers, output `hub_id` and `container_id` --- custom_connectors/oauth2/bim_360.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 0ba59af3..2e955709 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2044,7 +2044,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -2060,19 +2060,19 @@ }, { name: 'container_id', - label: 'Container name', + label: 'Project Name', control_type: 'select', pick_list: 'rfis_container_lists', pick_list_params: { hub_id: 'hub_id' }, optional: false, - toggle_hint: 'Select container', + toggle_hint: 'Select project', toggle_field: { name: 'container_id', label: 'Container ID', type: 'string', control_type: 'text', toggle_hint: 'Use custom value', - hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + hint: 'Provide container ID e.g. edac0659-639a-4a87-8614-d2c521b246b0' } }, { name: 'id', optional: false, label: 'RFI ID' } @@ -2080,7 +2080,7 @@ ignored('suggested_answer')) end, execute: lambda do |_connection, input| - input.delete('hub_id') + hub_id = input.delete('hub_id') container_id = input.delete('container_id') id = input.delete('id') input_payload = input&.map do |key, value| @@ -2097,12 +2097,13 @@ } patch("/bim360/rfis/v1/containers/#{container_id}/rfis/#{id}"). payload({ data: payload }). + headers('Content-Type': 'application/vnd.api+json' ). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end['data'] + end['data'].merge({ hub_id: hub_id }).merge({ container_id: container_id }) end, output_fields: lambda do |object_definitions| - object_definitions['rfi'] + [{ name: 'hub_id' }, { name: 'container_id' }].concat(object_definitions['rfi']) end, sample_output: lambda do |_connection, input| get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. From c39b277780f3d5cec555599c4009ea6e69bea426 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 16:31:00 -0400 Subject: [PATCH 19/62] update title for `get issue...` action --- custom_connectors/oauth2/bim_360.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 2e955709..9039512a 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -1536,7 +1536,7 @@ update_issue_in_project: { title: 'Updated issue in a project', description: 'Update issue in'\ - ' BIM 360', + ' a project in BIM 360', help: { body: 'BIM 360 issues are managed either in the BIM 360 Document' \ ' Management module or the BIM 360 Field Management module.
' \ From 8aaf73803a62f2982a7e67239b23ef3f4d29b783 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 28 Aug 2019 22:48:29 -0400 Subject: [PATCH 20/62] remove `search projects..` action --- custom_connectors/oauth2/bim_360.rb | 78 +---------------------------- 1 file changed, 2 insertions(+), 76 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 9039512a..345bcf54 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -1702,7 +1702,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1718,7 +1718,7 @@ }, { name: 'project_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -1751,80 +1751,6 @@ get("/project/v1/hubs/#{id}/projects")&.dig('data', 0) || {} end }, - search_projects_in_account: { - title: 'Search projects in account', - description: 'Search projects details in'\ - ' BIM 360', - help: { - body: 'Returns a collection of projects for a given hub_id. A ' \ - 'project represents a BIM 360 Team project, a Fusion Team project,' \ - ' a BIM 360 Docs project, or an A360 Personal project. Multiple ' \ - 'projects can be created within a single hub.
' \ - 'Note that for BIM 360 Docs, a hub ID corresponds to an account ID' \ - ' in the BIM 360 API. To convert an account ID into a hub ID you need' \ - ' to add a “b.” prefix. For example, an account ID of c8b0c73d-3ae9' \ - ' translates to a hub ID of b.c8b0c73d-3ae9.' - }, - input_fields: lambda do |_object_definitions| - [ - { - name: 'hub_id', - label: 'Hub name', - control_type: 'select', - pick_list: 'hub_list', - optional: false, - toggle_hint: 'Select hub', - toggle_field: { - name: 'hub_id', - label: 'Hub ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' - } - }, - { - name: 'id', - label: 'Project name', - control_type: 'multiselect', - pick_list: 'project_list', - pick_list_params: { hub_id: 'hub_id' }, - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'id', - label: 'Project IDs', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: - 'Provide multiple ID\'s as comma separated e.g. ' \ - 'b.baf-0871-4aca-82e8-3dd6db00,b.baf-0871-4aca-' \ - '82e8-3dd6db01' - } - }, - { name: 'type', label: 'Project type', - sticky: true, - hint: 'Provide the project type e.g. for Project i.e. ' \ - 'projects:autodesk.bim360:Project' } - ] - end, - execute: lambda do |_connection, input| - filter = { 'filter[id]' => input['id'], - 'filter[extension.type]' => input['type'] }.compact - { projects: get("/project/v1/hubs/#{input.delete('hub_id')}/projects/", - filter)['data'] } - end, - output_fields: lambda do |object_definitions| - [{ name: 'projects', type: 'array', of: 'object', - properties: object_definitions['project'] }] - end, - sample_output: lambda do |_connection, _input| - id = get('/project/v1/hubs')&.dig('data', 0)&.[]('id') - { projects: get("/project/v1/hubs/#{id}/projects")&. - dig('data', 0) || {} } - end - }, search_rfis_in_project: { title: 'Search RFIs in project', description: 'Search RFIs in a project in'\ From a62db51de50dae21865b86b8f07742f3438c44ba Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 00:19:28 -0400 Subject: [PATCH 21/62] update `items` object definition --- custom_connectors/oauth2/bim_360.rb | 224 ++++++++++++++-------------- 1 file changed, 113 insertions(+), 111 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 345bcf54..6b6ad3a7 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -1100,122 +1100,124 @@ item: { fields: lambda do |_connection, _config_fields| [ - { name: 'included', type: 'array', of: 'object', - properties: [ - { name: 'type' }, - { name: 'id' }, - { name: 'relationships', type: 'object', properties: [ - { name: 'item', type: 'object', properties: [ - { name: 'data', type: 'object', properties: [ - { name: 'type' }, - { name: 'id' } - ] }, - { name: 'links', type: 'object', properties: [ - { name: 'related', type: 'object', properties: [ - { name: 'href' } - ] } - ] } - ] }, - { name: 'refs', type: 'object', properties: [ - { name: 'links', type: 'object', properties: [ - { name: 'self', type: 'object', properties: [ - { name: 'href' } - ] }, - { name: 'related', type: 'object', properties: [ - { name: 'href' } - ] } - ] } - ] }, - { name: 'storage', type: 'object', properties: [ - { name: 'meta', type: 'object', properties: [ - { name: 'link', type: 'object', properties: [ - { name: 'href' } - ] } - ] }, - { name: 'data', type: 'object', properties: [ - { name: 'type' }, - { name: 'id' } - ] } - ] }, - { name: 'links', type: 'object', properties: [ - { name: 'self', type: 'object', properties: [ - { name: 'href' } - ] } - ] } - ] } - ] }, + #{ name: 'included', type: 'array', of: 'object', + # properties: [ + # { name: 'type' }, + # { name: 'id' }, + # { name: 'relationships', type: 'object', properties: [ + # { name: 'item', type: 'object', properties: [ + # { name: 'data', type: 'object', properties: [ + # { name: 'type' }, + # { name: 'id' } + # ] }, + # { name: 'links', type: 'object', properties: [ + # { name: 'related', type: 'object', properties: [ + # { name: 'href' } + # ] } + # ] } + # ] }, + # { name: 'refs', type: 'object', properties: [ + # { name: 'links', type: 'object', properties: [ + # { name: 'self', type: 'object', properties: [ + # { name: 'href' } + # ] }, + # { name: 'related', type: 'object', properties: [ + # { name: 'href' } + # ] } + # ] } + # ] }, + # { name: 'storage', type: 'object', properties: [ + # { name: 'meta', type: 'object', properties: [ + # { name: 'link', type: 'object', properties: [ + # { name: 'href' } + # ] } + # ] }, + # { name: 'data', type: 'object', properties: [ + # { name: 'type' }, + # { name: 'id' } + # ] } + # ] }, + # { name: 'links', type: 'object', properties: [ + # { name: 'self', type: 'object', properties: [ + # { name: 'href' } + # ] } + # ] } + # ] } + # ] }, { name: 'data', type: 'object', properties: [ - { name: 'id' }, - { name: 'type' }, - { name: 'relationships', type: 'object', properties: [ - { name: 'refs', type: 'object', properties: [ - { name: 'links', type: 'object', properties: [ - { name: 'self', type: 'object', properties: [ - { name: 'href' } - ] }, - { name: 'related', type: 'object', properties: [ - { name: 'href' } - ] } - ] } - ] }, - { name: 'tip', type: 'object', properties: [ - { name: 'data', type: 'object', properties: [ - { name: 'type' }, - { name: 'id' } - ] }, - { name: 'links', type: 'object', properties: [ - { name: 'related', type: 'object', properties: [ - { name: 'href' } - ] } - ] } - ] }, - { name: 'links', type: 'object', properties: [ - { name: 'self', type: 'object', properties: [ - { name: 'href' } - ] } - ] }, - { name: 'parent', type: 'object', properties: [ - { name: 'data', properties: [ - { name: 'type' }, - { name: 'id' } - ] }, - { name: 'links', type: 'object', properties: [ - { name: 'related', type: 'object', properties: [ - { name: 'href' } - ] } - ] } - ] }, - { name: 'versions', type: 'object', properties: [ - { name: 'links', type: 'object', properties: [ - { name: 'related', type: 'object', properties: [ - { name: 'href' } - ] } - ] } - ] } - ] }, + { name: 'id', label: 'Item ID' }, + # { name: 'type' }, + # { name: 'relationships', type: 'object', properties: [ + # { name: 'refs', type: 'object', properties: [ + # { name: 'links', type: 'object', properties: [ + # { name: 'self', type: 'object', properties: [ + # { name: 'href' } + # ] }, + # { name: 'related', type: 'object', properties: [ + # { name: 'href' } + # ] } + # ] } + # ] }, + # { name: 'tip', type: 'object', properties: [ + # { name: 'data', type: 'object', properties: [ + # { name: 'type' }, + # { name: 'id' } + # ] }, + # { name: 'links', type: 'object', properties: [ + # { name: 'related', type: 'object', properties: [ + # { name: 'href' } + # ] } + # ] } + # ] }, + # { name: 'links', type: 'object', properties: [ + # { name: 'self', type: 'object', properties: [ + # { name: 'href' } + # ] } + # ] }, + # { name: 'parent', type: 'object', properties: [ + # { name: 'data', properties: [ + # { name: 'type' }, + # { name: 'id' } + # ] }, + # { name: 'links', type: 'object', properties: [ + # { name: 'related', type: 'object', properties: [ + # { name: 'href' } + # ] } + # ] } + # ] }, + # { name: 'versions', type: 'object', properties: [ + # { name: 'links', type: 'object', properties: [ + # { name: 'related', type: 'object', properties: [ + # { name: 'href' } + # ] } + # ] } + # ] } + # ] }, + { name: 'attributes', type: 'object', properties: [ - { name: 'type' }, - { name: 'name' }, - { name: 'displayName' }, - { name: 'createTime', type: 'date_time' }, - { name: 'createUserId' }, - { name: 'createUserName' }, - { name: 'lastModifiedTime', type: 'date_time' }, - { name: 'lastModifiedUserId' }, - { name: 'lastModifiedUserName' }, - { name: 'lastModifiedTimeRollup', type: 'date_time' }, - { name: 'objectCount', type: 'integer' }, + #{ name: 'type' }, + #{ name: 'name' }, + { name: 'displayName', label: 'Name' }, + { name: 'createTime', label: 'Created at', type: 'date_time' }, + { name: 'createUserId', label: 'Created by (User ID)' }, + { name: 'createUserName', label: 'Created by (User Name)' }, + { name: 'lastModifiedTime', label: 'Last modified at', type: 'date_time' }, + { name: 'lastModifiedUserId', label: 'Last modified by (User ID)' }, + { name: 'lastModifiedUserName', label: 'Last modified by (User Name)' }, + #{ name: 'lastModifiedTimeRollup', type: 'date_time' }, + #{ name: 'objectCount', type: 'integer' }, { name: 'hidden', type: 'boolean', control_type: 'checkbox' }, { name: 'reserved', type: 'boolean', control_type: 'checkbox' }, + # { name: 'pathInProject', label: 'Path' }, { name: 'extension', type: 'object', properties: [ - { name: 'type' }, - { name: 'version' }, - { name: 'data', type: 'object', properties: [ - { name: 'sourceFileName', hint: 'Applicable for file' }, - { name: 'visibleTypes', hint: 'Array of strings' }, - { name: 'actions', hint: 'Array of strings' }, - { name: 'allowedTypes', hint: 'Array of strings' } - ] } + #{ name: 'type' }, + { name: 'version' } #, + #{ name: 'data', type: 'object', properties: [ + #{ name: 'sourceFileName', hint: 'Applicable for file' }, + #{ name: 'visibleTypes', hint: 'Array of strings' }, + #{ name: 'actions', hint: 'Array of strings' }, + #{ name: 'allowedTypes', hint: 'Array of strings' } + #] } ] } ] } ] } From 9e389df6252960b5a2b57c6db8a502facf50b0e9 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 00:19:54 -0400 Subject: [PATCH 22/62] update `folder_files` object definition --- custom_connectors/oauth2/bim_360.rb | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 6b6ad3a7..9da28521 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -1067,31 +1067,31 @@ folder_file: { fields: lambda do |_connection, _config_fields| [ - { name: 'type' }, - { name: 'id' }, + { name: 'id', label: 'Item ID' }, + { name: 'type', label: 'Item Type' }, { name: 'attributes', type: 'object', properties: [ - { name: 'type' }, - { name: 'name' }, - { name: 'displayName' }, - { name: 'createTime', type: 'date_time' }, - { name: 'createUserId' }, - { name: 'createUserName' }, - { name: 'lastModifiedTime', type: 'date_time' }, - { name: 'lastModifiedUserId' }, - { name: 'lastModifiedUserName' }, - { name: 'lastModifiedTimeRollup', type: 'date_time' }, - { name: 'objectCount', type: 'integer' }, + # { name: 'type' }, + # { name: 'name' }, + { name: 'displayName', label: 'Name' }, + { name: 'createTime', label: 'Created at', type: 'date_time' }, + { name: 'createUserId', label: 'Created by (User ID)' }, + { name: 'createUserName', label: 'Created by (User Name)' }, + { name: 'lastModifiedTime', label: 'Last modified at', type: 'date_time' }, + { name: 'lastModifiedUserId', label: 'Last modified by (User ID)' }, + { name: 'lastModifiedUserName', label: 'Last modified by (User Name)' }, + #{ name: 'lastModifiedTimeRollup', type: 'date_time' }, + #{ name: 'objectCount', type: 'integer' }, { name: 'hidden', type: 'boolean', control_type: 'checkbox' }, { name: 'reserved', type: 'boolean', control_type: 'checkbox' }, { name: 'extension', type: 'object', properties: [ - { name: 'type' }, - { name: 'version' }, - { name: 'data', type: 'object', properties: [ - { name: 'sourceFileName', hint: 'Applicable for file' }, - { name: 'visibleTypes', hint: 'Array of strings' }, - { name: 'actions', hint: 'Array of strings' }, - { name: 'allowedTypes', hint: 'Array of strings' } - ] } + #{ name: 'type' }, + { name: 'version' } #, + #{ name: 'data', type: 'object', properties: [ + #{ name: 'sourceFileName', hint: 'Applicable for file' }, + #{ name: 'visibleTypes', hint: 'Array of strings' }, + #{ name: 'actions', hint: 'Array of strings' }, + #{ name: 'allowedTypes', hint: 'Array of strings' } + #] } ] } ] } ] From eec5d3e05fd8a36a52bb759f42e58f4107b61b20 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 00:20:41 -0400 Subject: [PATCH 23/62] update `get folder details...` action, output `hub_id`, `project_id`, and `folder_id` --- custom_connectors/oauth2/bim_360.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 9da28521..7864ff5d 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2181,7 +2181,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -2197,7 +2197,7 @@ }, { name: 'project_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -2234,10 +2234,14 @@ end, execute: lambda do |_connection, input| get("/data/v1/projects/#{input['project_id']}/folders" \ - "/#{input['folder_id']}")['data'] + "/#{input['folder_id']}")['data'].merge({ hub_id: input['hub_id']} ).merge({ project_id: input['project_id'] }).merge({ folder_id: input['folder_id'] }) end, output_fields: lambda do |object_definitions| - object_definitions['folder_file'] + [ + { name: 'hub_id' }, + { name: 'project_id' }, + { name: 'folder_id' }, + ].concat(object_definitions['folder_file']) end, sample_output: lambda do |_connection, input| get("project/v1/hubs/#{input['hub_id']}/projects/" \ From 963e8db1aedb3e41802550893383a4d5a5479509 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 00:21:26 -0400 Subject: [PATCH 24/62] update `get folder contents...` action, include `filters` parameter, output `hub_id`, `project_id`, and `folder_id` --- custom_connectors/oauth2/bim_360.rb | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 7864ff5d..d8d77ec6 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2261,7 +2261,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -2277,7 +2277,7 @@ }, { name: 'project_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -2309,19 +2309,26 @@ label: 'Folder ID', toggle_hint: 'Use Folder ID', hint: 'Use Folder ID' - } } + } }, + { name: 'filters', + label: 'Filters', + control_type: 'text', + hint: 'Enter filters for the search. A list of filters can be found at https://forge.autodesk.com/en/docs/data/v2/developers_guide/filtering.', + optional: true + } ] end, execute: lambda do |_connection, input| get("/data/v1/projects/#{input['project_id']}/folders" \ - "/#{input['folder_id']}/contents") + "/#{input['folder_id']}/contents?#{input['filters']}").merge({ hub_id: input['hub_id'] }).merge({ project_id: input['project_id'] }).merge({ folder_id: input['folder_id']}) end, output_fields: lambda do |object_definitions| [ + { name: 'hub_id' }, + { name: 'project_id' }, + { name: 'folder_id' }, { name: 'data', type: 'array', of: 'object', - properties: object_definitions['folder_file'] }, - { name: 'included', type: 'array', of: 'object', - properties: object_definitions['version'] } + properties: object_definitions['folder_file'] } ] end, sample_output: lambda do |_connection, input| From 7dce31db9398c465c1f19ca9a5874693a91f8fbc Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 00:21:54 -0400 Subject: [PATCH 25/62] update `get documents...` action, output `hub_id` and `project_id` --- custom_connectors/oauth2/bim_360.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index d8d77ec6..9649e4c6 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2352,7 +2352,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -2368,7 +2368,7 @@ }, { name: 'project_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -2405,7 +2405,7 @@ label: 'File name', control_type: 'tree', hint: 'Select folder', - toggle_hint: 'Select Folder', + toggle_hint: 'Select Item', pick_list: :folder_items, pick_list_params: { project_id: 'project_id', folder_id: 'folder_id' }, @@ -2421,10 +2421,13 @@ ], execute: lambda do |_connection, input| get("/data/v1/projects/#{input['project_id']}/items/" \ - "#{input['item_id']}") + "#{input['item_id']}").merge({ project_id: input['project_id'] }).merge({ hub_id: input['hub_id'] }) end, output_fields: lambda do |object_definitions| - object_definitions['item'] + [ + { name: 'hub_id' }, + { name: 'project_id' }, + ].concat(object_definitions['item']) end, sample_output: lambda do |_connection, input| get("/data/v1/projects/#{input['project_id']}/items/" \ From 7b4a6b350fe6de9d8a8c7d6b138beffaaac3e41f Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 00:23:17 -0400 Subject: [PATCH 26/62] update `download document` action, remove required field for `folder` --- custom_connectors/oauth2/bim_360.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 9649e4c6..97566958 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2605,7 +2605,6 @@ pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, tree_options: { selectable_folder: true }, pick_list: :folders_list, - optional: false, toggle_field: { name: 'folder_id', type: 'string', @@ -2638,11 +2637,16 @@ "#{input['item_id']}")&. dig('included', 0, 'relationships', 'storage', 'meta', 'link', 'href') - file_content = - get(file_url).response_format_raw. - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end + if file_url.present? + file_content = + get(file_url).headers('Accept-Encoding': 'Accept-Encoding:gzip'). + response_format_raw. + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + else + error("Invalid URL" ) + end { content: file_content } end, output_fields: lambda do |_object_definitions| From ef1b395d02ba59525dd486b60daf58c946696717 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 00:24:20 -0400 Subject: [PATCH 27/62] update `upload document...` action, remove `object_type`, include `file_content` in `PUT` payload, output `hub_id` and `project_id` --- custom_connectors/oauth2/bim_360.rb | 148 +++++++++++----------------- 1 file changed, 59 insertions(+), 89 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 97566958..4842c2ed 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2657,10 +2657,15 @@ title: 'Upload document to a project', description: 'Upload document to a project'\ ' in BIM 360', + help: { + body: 'Note that you cannot upload documents to the root folder in ' \ + 'BIM 360 Docs; you can only upload documents to the Project Files ' \ + 'folder or to a folder nested under the Project Files folder' + }, config_fields: [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -2676,7 +2681,7 @@ }, { name: 'project_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -2712,35 +2717,10 @@ ], input_fields: lambda do |_object_definitions| [ - { name: 'file_name', optional: false, + { name: 'file_name', optional: false, label: 'File Name', hint: 'File name should include extension of the file. e.g. ' \ 'my_file.jpg' }, - { name: 'file_content', optional: false }, - { name: 'object_type', label: 'File type', - optional: false, - control_type: 'select', - pick_list: 'file_types', - toggle_hint: 'Select type', - toggle_field: { - name: 'object_type', - label: 'File type', - type: 'string', - control_type: 'text', - toggle_hint: 'File type ID', - hint: 'Only relevant for creating files - the type of file ' \ - 'extension. For BIM 360 Docs files, use items:autodesk.' \ - 'bim360:File, For all other services, use' \ - 'items:autodesk.core:File' - }, - hint: 'Only relevant for creating files - the type of file ' \ - 'extension. For BIM 360 Docs files, use items:autodesk.' \ - 'bim360:File, For all other services, use' \ - ' items:autodesk.core:File' }, - { name: 'parent_folder_id', - hint: 'The URN of the parent folder in which you want to create' \ - ' a version of a file or to copy a file to.' }, - { name: 'extension_version', - hint: 'The version of the version extension type ' } + { name: 'file_content', optional: false } ] end, execute: lambda do |_connection, input| @@ -2762,23 +2742,28 @@ } } } + hub_id = input.delete('hub_id') project_id = input.delete('project_id').gsub('b:', '') - object_id = + response_storage = post('https://developer.api.autodesk.com/data/v1/' \ "projects/#{project_id}/storage"). + headers('Content-Type': 'application/vnd.api+json', + 'Accept': 'application/vnd.api+json'). payload(payload). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end&.dig('data', 'id') + end + object_id = response_storage&.dig('data', 'id') + # 2 Upload file to storage location bucket_key = object_id.split('/').first.split('object:').last object_name = object_id.split('/').last response = put('https://developer.api.autodesk.com/oss/v2/buckets/' \ - "#{bucket_key}/objects/#{object_name}"). + "#{bucket_key}/objects/#{object_name}", input['file_content'] ). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end - storage_object_id = response['objectId'] + object_urn = response['objectId'] # 3 create a first version of the File version_payload = { 'jsonapi' => { 'version' => '1.0' }, @@ -2787,7 +2772,7 @@ 'attributes' => { 'displayName' => input['file_name'], 'extension' => - { 'type' => input['object_type'], 'version' => '1.0' } + { 'type' => 'items:autodesk.bim360:File', 'version' => '1.0' } }, 'relationships' => { 'tip' => { @@ -2808,7 +2793,7 @@ 'attributes' => { 'name' => input['file_name'], 'extension' => { - 'type' => input['object_type'], + 'type' => 'versions:autodesk.bim360:File', #input['object_type'], 'version' => '1.0' } }, @@ -2816,73 +2801,58 @@ 'storage' => { 'data' => { 'type' => 'objects', - 'id' => storage_object_id + 'id' => object_urn } } - # , - # 'refs' => { - # 'data' => { - # 'type' => 'versions', - # 'id' => '1.0' - # }, - # 'meta' => { - # 'refType' => 'xrefs', - # 'direction' => '', - # 'extension' => { - # 'type' => 'xrefs:autodesk.core:Xref', - # 'version' => '1.1.0.', - # 'data' => { - # 'nestedType' => 'attachment' - # } - # } - # } - # } } } ] } item_id = post("/data/v1/projects/#{project_id}/items"). - request_body(version_payload.to_json). - headers(Accept: 'application/vnd.api+json'). + payload(version_payload). + headers('Content-Type': 'application/vnd.api+json'). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end.dig('data', 'id') + end&.dig('data').merge({ hub_id: hub_id }).merge({ project_id: project_id }) # 4 Update version of the file - update_version = { - 'jsonapi' => '1.0', - 'data' => { - 'type' => 'versions', - 'attributes': { - 'extension' => { - 'type' => 'versions:autodesk.core:File"', - 'version' => '1.0' - } - }, - 'relationships' => { - 'item' => { - 'data' => { - 'type' => 'items', - 'id' => item_id - } - }, - 'storage' => { - 'data' => { - 'type' => 'objects', - 'id' => storage_object_id - } - } - } - } - } - post("/data/v1/projects/#{project_id}/versions"). - payload(update_version). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end + # update_version = { + # 'jsonapi' => '1.0', + # 'data' => { + # 'type' => 'versions', + # 'attributes': { + # 'extension' => { + # 'type' => 'versions:autodesk.core:File"', + # 'version' => '1.0' + # } + # }, + # 'relationships' => { + # 'item' => { + # 'data' => { + # 'type' => 'items', + # 'id' => item_id + # } + # }, + # 'storage' => { + # 'data' => { + # 'type' => 'objects', + # 'id' => object_urn + # } + # } + # } + # } + # } + # post("/data/v1/projects/#{project_id}/versions"). + # payload(update_version). + # after_error_response(/.*/) do |_code, body, _header, message| + # error("#{message}: #{body}") + # end end, output_fields: lambda do |object_definitions| - object_definitions['folder_file'] + [ + { name: 'hub_id' }, + { name: 'project_id' } + ].concat(object_definitions['folder_file']) end } }, From 61f7fc0c182bb4ba54a7f4abf2fb06d2ee28f0b7 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 00:25:01 -0400 Subject: [PATCH 28/62] update `new or updated document...` trigger, output `hub_id`, `project_id`, and `folder_id` --- custom_connectors/oauth2/bim_360.rb | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 4842c2ed..6bbdd02d 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -3090,17 +3090,17 @@ end }, new_updated_document_in_project: { - title: 'New/updated document in a project', - description: 'New/updated document in'\ - ' a project in BIM 360', + title: 'New or updated document in a project folder', + description: 'New or updated document in'\ + ' a project folder in BIM 360', help: { - body: 'Triggers when a document in a project is created/updated.' + body: 'Triggers when a document in a project is created or updated in the specified folder.' }, input_fields: lambda do |_object_definitions| [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -3116,7 +3116,7 @@ }, { name: 'project_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -3160,6 +3160,7 @@ ] end, poll: lambda do |_connection, input, closure| + hub_id = closure&.[]('hub_id') || input['hub_id'] project_id = closure&.[]('project_id') || input['project_id'] folder_id = closure&.[]('folder_id') || input['folder_id'] @@ -3181,17 +3182,19 @@ end items = response['data']&. - map { |o| o.merge({ project_id: project_id }) } + map { |o| o.merge({ project_id: project_id }).merge({ hub_id: hub_id }).merge({ folder_id: folder_id }) } closure = if (next_page_url = response.dig('links', 'next')).present? { 'skip' => skip + limit, 'folder_id' => folder_id, 'project_id' => project_id, + 'hub_id' => hub_id, 'include' => include, 'next_page_url' => next_page_url } else { 'offset' => 0, 'folder_id' => folder_id, 'project_id' => project_id, + 'hub_id' => hub_id, 'include' => include, 'updated_after' => now.to_time.utc.iso8601 } end @@ -3205,7 +3208,7 @@ "#{item['id']}&#{item.dig('attributes', 'lastModifiedTime')}" end, output_fields: lambda do |object_definitions| - [{ name: 'project_id' }].concat(object_definitions['folder_file']). + [{ name: 'hub_id' }, { name: 'project_id' }, { name: 'folder_id' }].concat(object_definitions['folder_file']). compact end, sample_output: lambda do |_connection, input| From 12fbbeefc9a90824ffebbaf7171b79d0c604e217 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 00:25:22 -0400 Subject: [PATCH 29/62] update `folder_items` picklist to not error if project_id is dynamic --- custom_connectors/oauth2/bim_360.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 6bbdd02d..f0a2334a 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -3230,11 +3230,13 @@ ] end, folder_items: lambda do |_connection, project_id:, folder_id:| - get("/data/v1/projects/#{project_id}/folders/#{folder_id}/" \ - 'contents?filter[type]=items')['data']&. - map do |item| - [item.dig('attributes', 'displayName'), item['id']] - end + if project_id.length === 38 && folder_id.present? + get("/data/v1/projects/#{project_id}/folders/#{folder_id}/" \ + 'contents?filter[type]=items')['data']&. + map do |item| + [item.dig('attributes', 'displayName'), item['id']] + end + end end, item_versions: lambda do |_connection, project_id:, item_id:| get("/data/v1/projects/#{project_id}/items/#{item_id}/" \ From 79d19e09e1115dc0b50e212982a83e6d05f66903 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 00:25:49 -0400 Subject: [PATCH 30/62] update `folders_list` picklist to not error when `project_id` is dynamic --- custom_connectors/oauth2/bim_360.rb | 30 +++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index f0a2334a..b6b624a0 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -3250,20 +3250,22 @@ hub_id = args[:hub_id] project_id = args[:project_id] parent_id = args&.[](:__parent_id) - if parent_id.present? - get("/data/v1/projects/#{project_id}/folders/#{parent_id}/" \ - 'contents?filter[type]=folders')['data']&. - map do |folder| - [folder.dig('attributes', 'displayName'), - folder['id'], folder['id'], true] - end - else - get("project/v1/hubs/#{hub_id}/projects/#{project_id}/" \ - 'topFolders?filter[type]=folders')['data']&. - map do |folder| - [folder.dig('attributes', 'displayName'), - folder['id'], folder['id'], true] - end || [] + if project_id.length === 38 + if parent_id.present? + get("/data/v1/projects/#{project_id}/folders/#{parent_id}/" \ + 'contents?filter[type]=folders')['data']&. + map do |folder| + [folder.dig('attributes', 'displayName'), + folder['id'], folder['id'], true] + end + else + get("project/v1/hubs/#{hub_id}/projects/#{project_id}/" \ + 'topFolders?filter[type]=folders')['data']&. + map do |folder| + [folder.dig('attributes', 'displayName'), + folder['id'], folder['id'], true] + end || [] + end end end, rfi_child_objects: lambda do |_connection| From c827043c25d7d13d54dd5cc3458932e53b1a4853 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 00:26:36 -0400 Subject: [PATCH 31/62] misc edits from Chandra's connector version --- custom_connectors/oauth2/bim_360.rb | 33 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index b6b624a0..0ee39d9a 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -61,8 +61,9 @@ request_format_www_form_urlencoded end, apply: lambda do |_connection, access_token| - headers(Authorization: "Bearer #{access_token}", - 'Content-Type': 'application/vnd.api+json') + headers(Authorization: "Bearer #{access_token}") +# headers(Authorization: "Bearer #{access_token}", +# 'Content-Type': 'application/vnd.api+json') end }, base_uri: lambda do |_connection| @@ -2435,17 +2436,13 @@ end }, get_drawing_export_status: { - title: 'Get drwaing export status in a project', + title: 'Get drawaing export status in a project', description: 'Get drwaing export status in'\ ' a project in BIM 360', help: { body: 'This action returns the status of a PDF export job, as well' \ ' as data you need to download the exported file when the export is ' \ - 'complete. Get export job status action uses the' \ - " Get export job API." + 'complete.' }, config_fields: [ @@ -2519,21 +2516,22 @@ } }, { - name: 'version_number', + name: 'version_urn', control_type: 'select', + label: 'Version number', pick_list: 'item_versions', sticky: true, pick_list_params: { project_id: 'project_id', item_id: 'item_id' }, optional: true, toggle_hint: 'Select version', toggle_field: { - name: 'version_number', - label: 'Version number', - type: 'integer', - control_type: 'number', + name: 'version_urn', + label: 'Version URN', + type: 'string', + control_type: 'text', optional: true, toggle_hint: 'Use custom value', - hint: 'Use version number' + hint: 'Use version number e.g. e7e2a39a-2ead-4dcd-9760-5f7af' } } ], @@ -2543,12 +2541,13 @@ ] end, execute: lambda do |_connection, input| - version_number = input['version_number'] || get('/data/v1/projects/' \ + version_number = input['version_urn'] || get('/data/v1/projects/' \ "#{input['project_id']}/items/#{input['item_id']}/" \ 'versions')&.dig('data', 0, 'id') - version_url = version_number.encode_url + version_url = version_number.split('?').first.encode_url # version_url = version_number.encode_url - get("/bim360/docs/v1/projects/#{input['project_id']}/versions/" \ + project_id = input['project_id'].split('.').last + get("/bim360/docs/v1/projects/#{project_id}/versions/" \ "#{version_url}/exports/#{input['export_id']}") end, output_fields: lambda do |object_definitions| From b446430f2f8411f6252ee2ab5161afaf2176df5e Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 08:30:45 -0400 Subject: [PATCH 32/62] updated to meet rubocop guidelines --- custom_connectors/oauth2/bim_360.rb | 317 ++++++++++++++++++++-------- 1 file changed, 225 insertions(+), 92 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 0ee39d9a..da12bed3 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -30,7 +30,7 @@ type: 'oauth2', authorization_url: lambda do |connection| scopes = 'user:read account:read data:write data:write data:read' \ - ' account:write' + ' data:create account:write' 'https://developer.api.autodesk.com/authentication/v1/authorize?' \ 'response_type=' \ "code&client_id=#{connection['client_id']}&" \ @@ -62,8 +62,8 @@ end, apply: lambda do |_connection, access_token| headers(Authorization: "Bearer #{access_token}") -# headers(Authorization: "Bearer #{access_token}", -# 'Content-Type': 'application/vnd.api+json') + # headers(Authorization: "Bearer #{access_token}", + # 'Content-Type': 'application/vnd.api+json') end }, base_uri: lambda do |_connection| @@ -1077,22 +1077,24 @@ { name: 'createTime', label: 'Created at', type: 'date_time' }, { name: 'createUserId', label: 'Created by (User ID)' }, { name: 'createUserName', label: 'Created by (User Name)' }, - { name: 'lastModifiedTime', label: 'Last modified at', type: 'date_time' }, + { name: 'lastModifiedTime', + label: 'Last modified at', type: 'date_time' }, { name: 'lastModifiedUserId', label: 'Last modified by (User ID)' }, - { name: 'lastModifiedUserName', label: 'Last modified by (User Name)' }, - #{ name: 'lastModifiedTimeRollup', type: 'date_time' }, - #{ name: 'objectCount', type: 'integer' }, + { name: 'lastModifiedUserName', + label: 'Last modified by (User Name)' }, + # { name: 'lastModifiedTimeRollup', type: 'date_time' }, + # { name: 'objectCount', type: 'integer' }, { name: 'hidden', type: 'boolean', control_type: 'checkbox' }, { name: 'reserved', type: 'boolean', control_type: 'checkbox' }, { name: 'extension', type: 'object', properties: [ - #{ name: 'type' }, - { name: 'version' } #, - #{ name: 'data', type: 'object', properties: [ - #{ name: 'sourceFileName', hint: 'Applicable for file' }, - #{ name: 'visibleTypes', hint: 'Array of strings' }, - #{ name: 'actions', hint: 'Array of strings' }, - #{ name: 'allowedTypes', hint: 'Array of strings' } - #] } + # { name: 'type' }, + { name: 'version' } # , + # { name: 'data', type: 'object', properties: [ + # { name: 'sourceFileName', hint: 'Applicable for file' }, + # { name: 'visibleTypes', hint: 'Array of strings' }, + # { name: 'actions', hint: 'Array of strings' }, + # { name: 'allowedTypes', hint: 'Array of strings' } + # ] } ] } ] } ] @@ -1101,7 +1103,7 @@ item: { fields: lambda do |_connection, _config_fields| [ - #{ name: 'included', type: 'array', of: 'object', + # { name: 'included', type: 'array', of: 'object', # properties: [ # { name: 'type' }, # { name: 'id' }, @@ -1196,29 +1198,32 @@ # ] }, { name: 'attributes', type: 'object', properties: [ - #{ name: 'type' }, - #{ name: 'name' }, + # { name: 'type' }, + # { name: 'name' }, { name: 'displayName', label: 'Name' }, { name: 'createTime', label: 'Created at', type: 'date_time' }, { name: 'createUserId', label: 'Created by (User ID)' }, { name: 'createUserName', label: 'Created by (User Name)' }, - { name: 'lastModifiedTime', label: 'Last modified at', type: 'date_time' }, - { name: 'lastModifiedUserId', label: 'Last modified by (User ID)' }, - { name: 'lastModifiedUserName', label: 'Last modified by (User Name)' }, - #{ name: 'lastModifiedTimeRollup', type: 'date_time' }, - #{ name: 'objectCount', type: 'integer' }, + { name: 'lastModifiedTime', + label: 'Last modified at', type: 'date_time' }, + { name: 'lastModifiedUserId', + label: 'Last modified by (User ID)' }, + { name: 'lastModifiedUserName', + label: 'Last modified by (User Name)' }, + # { name: 'lastModifiedTimeRollup', type: 'date_time' }, + # { name: 'objectCount', type: 'integer' }, { name: 'hidden', type: 'boolean', control_type: 'checkbox' }, { name: 'reserved', type: 'boolean', control_type: 'checkbox' }, # { name: 'pathInProject', label: 'Path' }, { name: 'extension', type: 'object', properties: [ - #{ name: 'type' }, - { name: 'version' } #, - #{ name: 'data', type: 'object', properties: [ - #{ name: 'sourceFileName', hint: 'Applicable for file' }, - #{ name: 'visibleTypes', hint: 'Array of strings' }, - #{ name: 'actions', hint: 'Array of strings' }, - #{ name: 'allowedTypes', hint: 'Array of strings' } - #] } + # { name: 'type' }, + { name: 'version' } # , + # { name: 'data', type: 'object', properties: [ + # { name: 'sourceFileName', hint: 'Applicable for file' }, + # { name: 'visibleTypes', hint: 'Array of strings' }, + # { name: 'actions', hint: 'Array of strings' }, + # { name: 'allowedTypes', hint: 'Array of strings' } + # ] } ] } ] } ] } @@ -1441,15 +1446,18 @@ "/projects/#{project_id}")&. dig('data', 'relationships', 'issues', 'data', 'id') { issues: get("/issues/v1/containers/#{container_id}/quality-issues", - filter_criteria)['data'] }.merge({ hub_id: hub_id }).merge({ container_id: container_id }).merge({ project_id: project_id }) + filter_criteria)['data'] }&. + merge({ hub_id: hub_id, container_id: container_id, + project_id: project_id }) end, output_fields: lambda do |object_definitions| - [ - {name: 'hub_id' }, - { name: 'project_id' }, - { name: 'container_id' }, + [ + { name: 'hub_id' }, + { name: 'project_id' }, + { name: 'container_id' }, { name: 'issues', type: 'array', of: 'object', - properties: object_definitions['issue'] }] + properties: object_definitions['issue'] } + ] end, sample_output: lambda do |_connection, input| project_id = input['project_id'] @@ -1501,7 +1509,8 @@ type: 'string', control_type: 'text', toggle_hint: 'Use custom value', - hint: 'Provide container id e.g. edac0659-639a-4a87-8614-d2c521b246b0' + hint: 'Provide container id e.g. ' \ + 'edac0659-639a-4a87-8614-d2c521b246b0' } } ].concat(object_definitions['create_issue']. @@ -1519,7 +1528,7 @@ headers('Content-Type': 'application/vnd.api+json'). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end['data']&.merge({ container_id: container_id }).merge({ hub_id: hub_id }) + end['data']&.merge({ container_id: container_id, hub_id: hub_id }) end, output_fields: lambda do |object_definitions| [ @@ -1604,13 +1613,13 @@ headers('Content-Type': 'application/vnd.api+json'). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end['data']&.merge({ hub_id: hub_id }).merge({ container_id: container_id }) + end['data']&.merge({ hub_id: hub_id, container_id: container_id }) end, output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, { name: 'container_id' } - ].concat( object_definitions['issue'] ) + ].concat(object_definitions['issue']) end, sample_output: lambda do |_connection, input| project_id = input['project_id'] @@ -1663,7 +1672,8 @@ type: 'string', control_type: 'text', toggle_hint: 'Use custom value', - hint: 'Provide container id e.g. edac0659-639a-4a87-8614-d2c521b246b0' + hint: 'Provide container id e.g. ' \ + 'edac0659-639a-4a87-8614-d2c521b246b0' } }, { name: 'issue_id', optional: false } @@ -1674,13 +1684,15 @@ "quality-issues/#{input['issue_id']}"). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end['data'].merge({ hub_id: input['hub_id'] }).merge({ container_id: input['container_id'] }) + end['data']. + merge({ hub_id: input['hub_id'], + container_id: input['container_id'] }) end, output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, { name: 'container_id' } - ].concat( object_definitions['issue'] ) + ].concat(object_definitions['issue']) end, sample_output: lambda do |_connection, input| project_id = input['project_id'] @@ -1805,15 +1817,16 @@ container_id = input.delete('container_id') filter_criteria = call('format_search', input) { rfis: get("/bim360/rfis/v1/containers/#{container_id}/rfis", - filter_criteria)['data'] }.merge({ hub_id: hub_id }).merge({ container_id: container_id }) + filter_criteria)['data'] }&. + merge({ hub_id: hub_id, container_id: container_id }) end, output_fields: lambda do |object_definitions| [ - { name: 'hub_id' }, + { name: 'hub_id' }, { name: 'container_id' }, { name: 'rfis', label: 'RFIs', type: 'array', of: 'object', - properties: object_definitions['rfi'] } - ] + properties: object_definitions['rfi'] } + ] end, sample_output: lambda do |_connection, input| { rfis: @@ -1861,7 +1874,8 @@ type: 'string', control_type: 'text', toggle_hint: 'Use custom value', - hint: 'Provide container ID e.g. edac0659-639a-4a87-8614-d2c521b246b0' + hint: 'Provide container ID e.g. ' \ + 'edac0659-639a-4a87-8614-d2c521b246b0' } }, { name: 'id', optional: false, label: 'RFI ID' } @@ -1872,10 +1886,13 @@ "#{input['id']}"). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end['data'].merge({ hub_id: input['hub_id'] }).merge({ container_id: input['container_id'] }) + end['data']&. + merge({ hub_id: input['hub_id'], + container_id: input['container_id'] }) end, output_fields: lambda do |object_definitions| - [{ name: 'hub_id' }, { name: 'container_id' }].concat(object_definitions['rfi']) + [{ name: 'hub_id' }, { name: 'container_id' }]. + concat(object_definitions['rfi']) end, sample_output: lambda do |_connection, input| get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. @@ -1924,7 +1941,8 @@ type: 'string', control_type: 'text', toggle_hint: 'Use custom value', - hint: 'Provide container ID e.g. edac0659-639a-4a87-8614-d2c521b246b0' + hint: 'Provide container ID e.g. ' \ + 'edac0659-639a-4a87-8614-d2c521b246b0' } } ].concat(object_definitions['modify_rfi']. @@ -1946,13 +1964,14 @@ } post("/bim360/rfis/v1/containers/#{container_id}/rfis"). payload({ data: payload }). - headers('Content-Type': 'application/vnd.api+json' ). + headers('Content-Type': 'application/vnd.api+json'). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end['data'].merge({ hub_id: hub_id }).merge({ container_id: container_id }) + end['data']&.merge({ hub_id: hub_id, container_id: container_id }) end, output_fields: lambda do |object_definitions| - [{ name: 'hub_id' }, { name: 'container_id' }].concat(object_definitions['rfi']) + [{ name: 'hub_id' }, { name: 'container_id' }]&. + concat(object_definitions['rfi']) end, sample_output: lambda do |_connection, input| get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. @@ -2001,7 +2020,8 @@ type: 'string', control_type: 'text', toggle_hint: 'Use custom value', - hint: 'Provide container ID e.g. edac0659-639a-4a87-8614-d2c521b246b0' + hint: 'Provide container ID e.g. ' \ + 'edac0659-639a-4a87-8614-d2c521b246b0' } }, { name: 'id', optional: false, label: 'RFI ID' } @@ -2026,13 +2046,14 @@ } patch("/bim360/rfis/v1/containers/#{container_id}/rfis/#{id}"). payload({ data: payload }). - headers('Content-Type': 'application/vnd.api+json' ). + headers('Content-Type': 'application/vnd.api+json'). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end['data'].merge({ hub_id: hub_id }).merge({ container_id: container_id }) + end['data'].merge({ hub_id: hub_id, container_id: container_id }) end, output_fields: lambda do |object_definitions| - [{ name: 'hub_id' }, { name: 'container_id' }].concat(object_definitions['rfi']) + [{ name: 'hub_id' }, { name: 'container_id' }]&. + concat(object_definitions['rfi']) end, sample_output: lambda do |_connection, input| get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. @@ -2235,13 +2256,15 @@ end, execute: lambda do |_connection, input| get("/data/v1/projects/#{input['project_id']}/folders" \ - "/#{input['folder_id']}")['data'].merge({ hub_id: input['hub_id']} ).merge({ project_id: input['project_id'] }).merge({ folder_id: input['folder_id'] }) + "/#{input['folder_id']}")['data']&. + merge({ hub_id: input['hub_id'], project_id: input['project_id'], + folder_id: input['folder_id'] }) end, output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, { name: 'project_id' }, - { name: 'folder_id' }, + { name: 'folder_id' } ].concat(object_definitions['folder_file']) end, sample_output: lambda do |_connection, input| @@ -2314,14 +2337,17 @@ { name: 'filters', label: 'Filters', control_type: 'text', - hint: 'Enter filters for the search. A list of filters can be found at https://forge.autodesk.com/en/docs/data/v2/developers_guide/filtering.', - optional: true - } + sticky: true, + hint: 'Enter filters for the search. A list of filters can be' \ + ' found at https://forge.autodesk.com/en/docs/data/v2/' \ + 'developers_guide/filtering.' } ] end, execute: lambda do |_connection, input| get("/data/v1/projects/#{input['project_id']}/folders" \ - "/#{input['folder_id']}/contents?#{input['filters']}").merge({ hub_id: input['hub_id'] }).merge({ project_id: input['project_id'] }).merge({ folder_id: input['folder_id']}) + "/#{input['folder_id']}/contents?#{input['filters']}")&. + merge({ hub_id: input['hub_id'], project_id: input['project_id'], + folder_id: input['folder_id'] }) end, output_fields: lambda do |object_definitions| [ @@ -2422,12 +2448,13 @@ ], execute: lambda do |_connection, input| get("/data/v1/projects/#{input['project_id']}/items/" \ - "#{input['item_id']}").merge({ project_id: input['project_id'] }).merge({ hub_id: input['hub_id'] }) + "#{input['item_id']}")&. + merge({ project_id: input['project_id'], hub_id: input['hub_id'] }) end, output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, - { name: 'project_id' }, + { name: 'project_id' } ].concat(object_definitions['item']) end, sample_output: lambda do |_connection, input| @@ -2644,7 +2671,7 @@ error("#{message}: #{body}") end else - error("Invalid URL" ) + error('Invalid URL') end { content: file_content } end, @@ -2718,8 +2745,61 @@ [ { name: 'file_name', optional: false, label: 'File Name', hint: 'File name should include extension of the file. e.g. ' \ - 'my_file.jpg' }, - { name: 'file_content', optional: false } + 'my_file.jpg. The name of the file (1-255 characters). ' \ + 'Reserved characters: <, >, :, ", /, \, |, ?, *, `, \n, \r, \t,' \ + ' \0, \f, ¢, ™, $, ®' }, + { name: 'file_content', optional: false }, + { name: 'file_extension', control_type: 'select', + pick_list: 'file_types', + toggle_hint: 'Select file extension', + toggle_field: { + name: 'file_extension', + type: 'string', + control_type: 'text', + label: 'File extension', + toggle_hint: 'Use custom value', + hint: 'Only relevant for creating files - the type of file ' \ + 'extension.
. For BIM 360 Docs files, use ' \ + 'items:autodesk.bim360:File.
' \ + 'For all other services, use items:autodesk.core:File.' + } }, + # { name: 'resource_type', label: 'Type of the resource', + # control_type: 'select', pick_list: 'resource_types', + # toggle_hint: 'Select resource type', + # toggle_field: { + # name: 'resource_type', + # label: 'Resource type', + # type: 'string', + # control_type: 'text', + # toggle_hint: 'Use custom value', + # hint: 'The type of the resource. Possible values: attachment,' \ + # ' overlay' + # } }, + # { name: 'file_extension_version', + # hint: 'The version of the file extension type. The current ' \ + # 'version is 1.0.' }, + { name: 'version_type', label: 'Type of version', + hint: 'Only relevant for creating files - the type of version.', + control_type: 'select', + pick_list: 'version_types', + toggle_hint: 'Select version type', + toggle_field: { + name: 'version_type', + label: 'Type of version', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Only relevant for creating files - the type of version.' \ + '
For BIM 360 Docs files, use versions:autodesk.bim360:File' \ + '
For A360 composite design files, use versions:autodesk.' \ + 'a360:CompositeDesign
' \ + 'For A360 Personal, Fusion Team, or BIM 360 Team files, use' \ + ' versions:autodesk.core:File.' + } }, + { name: 'extension_type_version', + hint: 'The version of the version extension type. The current ' \ + 'version is 1.0 ' } + ] end, execute: lambda do |_connection, input| @@ -2758,30 +2838,47 @@ bucket_key = object_id.split('/').first.split('object:').last object_name = object_id.split('/').last response = put('https://developer.api.autodesk.com/oss/v2/buckets/' \ - "#{bucket_key}/objects/#{object_name}", input['file_content'] ). + "#{bucket_key}/objects/#{object_name}", + input['file_content']). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end object_urn = response['objectId'] # 3 create a first version of the File + # folder_urn = get("/data/v1/projects/#{input['project_id']}/folders" \ + # "/#{input['folder_id']}")['data'] version_payload = { 'jsonapi' => { 'version' => '1.0' }, 'data' => { + # type of the resource 'type' => 'items', + # The attributes of the data object. 'attributes' => { 'displayName' => input['file_name'], + # Extended information on the resource. 'extension' => - { 'type' => 'items:autodesk.bim360:File', 'version' => '1.0' } + { + # relevant for creating files + 'type' => input['file_extension'], + 'version' => '1.0' + } }, 'relationships' => { + # The information on the tip version of this resource. 'tip' => { 'data' => { 'type' => 'versions', 'id' => '1' } }, + # Information on the parent resource of this resource. 'parent' => { - 'data' => { 'type' => 'folders', 'id' => input['folder_id'] } + 'data' => { + 'type' => 'folders', + # The URN of the parent folder in which you want to create + # a version of a file or to copy a file to. + 'id' => input['folder_id'] + } } } }, @@ -2792,8 +2889,9 @@ 'attributes' => { 'name' => input['file_name'], 'extension' => { - 'type' => 'versions:autodesk.bim360:File', #input['object_type'], - 'version' => '1.0' + # input['object_type'] + 'type' => input['version_type'], + 'version' => input['extension_type_version'] || '1.0' } }, 'relationships' => { @@ -2802,18 +2900,25 @@ 'type' => 'objects', 'id' => object_urn } - } + } # , + # 'refs' => { + # 'data' => { + # 'type' => 'versions', + # 'id' => 'version_urn' + # } + # } } } ] } - item_id = - post("/data/v1/projects/#{project_id}/items"). + # item_id = + post("/data/v1/projects/#{project_id}/items"). payload(version_payload). - headers('Content-Type': 'application/vnd.api+json'). + headers('Content-Type': 'application/vnd.api+json', + Accept: 'application/vnd.api+json'). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end&.dig('data').merge({ hub_id: hub_id }).merge({ project_id: project_id }) + end&.dig('data')&.merge({ hub_id: hub_id, project_id: project_id }) # 4 Update version of the file # update_version = { # 'jsonapi' => '1.0', @@ -2952,7 +3057,10 @@ 'hub_id' => hub_id } end rfis = response['data']&. - map { |o| o.merge({ project_id: project_id }).merge({ hub_id: hub_id }).merge({ container_id: container_id }) } + map do |o| + o.merge({ project_id: project_id, hub_id: hub_id, + container_id: container_id }) + end { events: rfis || [], next_poll: closure, @@ -2963,7 +3071,8 @@ "#{rfi['id']}@#{rfi.dig('attributes', 'created_at')}" end, output_fields: lambda do |object_definitions| - [{ name: 'hub_id' }, { name: 'project_id' }, { name: 'container_id' }].concat(object_definitions['rfi']) + [{ name: 'hub_id' }, { name: 'project_id' }, { name: 'container_id' }]. + concat(object_definitions['rfi']) end, sample_output: lambda do |_connection, input| project_id = input['project_id'] @@ -3066,7 +3175,10 @@ 'updated_after' => now.to_time.utc.iso8601 } end issues = response['data']&. - map { |o| o.merge({ project_id: project_id }).merge({ hub_id: hub_id }).merge({ container_id: container_id }) } + map do |o| + o.merge({ project_id: project_id, hub_id: hub_id, + container_id: container_id }) + end { events: issues || [], next_poll: closure, @@ -3077,7 +3189,11 @@ "#{issue['id']}&#{issue.dig('attributes', 'updated_at')}" end, output_fields: lambda do |object_definitions| - [{ name: 'hub_id' }, { name: 'project_id' }, { name: 'container_id' }].concat(object_definitions['issue']).compact + [ + { name: 'hub_id' }, + { name: 'project_id' }, + { name: 'container_id' } + ].concat(object_definitions['issue']).compact end, sample_output: lambda do |_connection, input| project_id = input['project_id'] @@ -3093,7 +3209,8 @@ description: 'New or updated document in'\ ' a project folder in BIM 360', help: { - body: 'Triggers when a document in a project is created or updated in the specified folder.' + body: 'Triggers when a document in a project is created or updated' \ + ' in the specified folder.' }, input_fields: lambda do |_object_definitions| [ @@ -3181,7 +3298,10 @@ end items = response['data']&. - map { |o| o.merge({ project_id: project_id }).merge({ hub_id: hub_id }).merge({ folder_id: folder_id }) } + map do |o| + o.merge({ project_id: project_id, hub_id: hub_id, + folder_id: folder_id }) + end closure = if (next_page_url = response.dig('links', 'next')).present? { 'skip' => skip + limit, 'folder_id' => folder_id, @@ -3207,7 +3327,8 @@ "#{item['id']}&#{item.dig('attributes', 'lastModifiedTime')}" end, output_fields: lambda do |object_definitions| - [{ name: 'hub_id' }, { name: 'project_id' }, { name: 'folder_id' }].concat(object_definitions['folder_file']). + [{ name: 'hub_id' }, { name: 'project_id' }, { name: 'folder_id' }]. + concat(object_definitions['folder_file']). compact end, sample_output: lambda do |_connection, input| @@ -3229,7 +3350,7 @@ ] end, folder_items: lambda do |_connection, project_id:, folder_id:| - if project_id.length === 38 && folder_id.present? + if project_id.length == 38 && folder_id.present? get("/data/v1/projects/#{project_id}/folders/#{folder_id}/" \ 'contents?filter[type]=items')['data']&. map do |item| @@ -3245,11 +3366,23 @@ version.dig('id')] end end, + version_types: lambda do |_connection| + [ + ['BIM 360 Docs files', 'versions:autodesk.bim360:File'], + ['A360 composite design files', + 'versions:autodesk.a360:CompositeDesign'], + ['A360 Personal, Fusion Team', 'versions:autodesk.core:File'], + ['BIM 360 Team files', 'versions:autodesk.core:File'] + ] + end, + resource_types: lambda do |_connection| + %w[attachment overlay].map { |type| [type.labelize, type] } + end, folders_list: lambda do |_connection, **args| hub_id = args[:hub_id] project_id = args[:project_id] parent_id = args&.[](:__parent_id) - if project_id.length === 38 + if project_id.length == 38 if parent_id.present? get("/data/v1/projects/#{project_id}/folders/#{parent_id}/" \ 'contents?filter[type]=folders')['data']&. @@ -3280,14 +3413,14 @@ map { |option| [option.labelize, option] } end, project_list: lambda do |_connection, hub_id:| - if hub_id.length === 38 + if hub_id.length == 38 get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| [project.dig('attributes', 'name'), project['id']] end end end, issue_container_lists: lambda do |_connection, hub_id:| - if hub_id.length === 38 + if hub_id.length == 38 get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| [project.dig('attributes', 'name'), project.dig('relationships', 'issues', 'data', 'id')] @@ -3295,7 +3428,7 @@ end end, rfis_container_lists: lambda do |_connection, hub_id:| - if hub_id.length === 38 + if hub_id.length == 38 get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| [project.dig('attributes', 'name'), project.dig('relationships', 'rfis', 'data', 'id')] From b7905c2ff02fb74e5a5ea7c2baf1822b5565b7d1 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 15:28:46 -0400 Subject: [PATCH 33/62] update based on Chandra's edits for rubocop guidelines --- custom_connectors/oauth2/bim_360.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index da12bed3..698f47d1 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2911,11 +2911,13 @@ } ] } + user_id = get('/userprofile/v1/users/@me')['userId'] # item_id = post("/data/v1/projects/#{project_id}/items"). payload(version_payload). headers('Content-Type': 'application/vnd.api+json', - Accept: 'application/vnd.api+json'). + Accept: 'application/vnd.api+json', + 'x-user-id': user_id). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end&.dig('data')&.merge({ hub_id: hub_id, project_id: project_id }) From bfabfe0db055df20c9a576f5a522ac4d18a572ef Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 15:32:08 -0400 Subject: [PATCH 34/62] update `project` object definition, comment out incorrect object output --- custom_connectors/oauth2/bim_360.rb | 182 ++++++++++++++++++---------- 1 file changed, 117 insertions(+), 65 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 698f47d1..884cd3bc 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -132,71 +132,123 @@ fields: lambda do |_connection, _config_fields| [ { name: 'id', label: 'Project ID' }, - { name: 'account_id', label: 'Account ID' }, - { name: 'name', label: 'Project name' }, - { name: 'start_date', type: 'date' }, - { name: 'end_date', type: 'date' }, - { name: 'project_type', - control_type: 'select', pick_list: 'project_types', - toggle_hint: 'Select project type', - toggle_field: { - name: 'project_type', - type: 'string', - control_type: 'text', - label: 'Project type', - toggle_hint: 'Use custom value' - }, - hint: 'Refer to the preconfigured ' \ - "project_type list in the " \ - 'Parameters guide' }, - { name: 'value', label: 'Monetary value' }, - { name: 'currency', control_type: 'select', - pick_list: 'currency_list', - toggle_hint: 'Select currency', - toggle_field: { - name: 'currency', - type: 'string', - control_type: 'text', - label: 'Project type', - toggle_hint: 'Use custom value' - } }, - { name: 'status', control_type: 'select', - pick_list: 'status_list', - toggle_hint: 'Select status', - toggle_field: { - name: 'status', - type: 'string', - control_type: 'text', - label: 'Status', - toggle_hint: 'Use custom value' - } }, - { name: 'job_number' }, - { name: 'address_line_1' }, - { name: 'address_line_2' }, - { name: 'city' }, - { name: 'state_or_province' }, - { name: 'postal_code' }, - { name: 'country' }, - { name: 'postal_code' }, - { name: 'country' }, - { name: 'business_unit_id' }, - { name: 'timezone', hint: 'Refer to the preconfigured ' \ - "project_type list in the " \ - 'Parameters guide' }, - { name: 'language', control_type: 'select', pick_list: - [%w[English en], %w[German de]] }, - { name: 'construction_type', hint: 'Refer to the preconfigured ' \ - "project_type list in the " \ - 'Parameters guide' }, - { name: 'contract_type', hint: 'Refer to the preconfigured ' \ - "project_type list in the " \ - 'Parameters guide' }, - { name: 'last_sign_in', hint: 'Timestamp of the last sign in,' \ - ' YYYY-MM-DDThh:mm:ss.sssZ format' } + { name: 'type' }, + { name: 'attributes', type: 'object', properties: [ + { name: 'name' } + ]}, + { name: 'relationships', type: 'object', properties: [ + { name: 'hub', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'id', label: 'Hub ID' } + ]} + ]}, + { name: 'rootFolder', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'id', label: 'Root Folder ID' } + ]} + ]}, + { name: 'issues', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'id', label: 'Issues Container ID' } + ]} + ]}, + { name: 'submittals', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'id', label: 'Submittals Container ID' } + ]} + ]}, + { name: 'rfis', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'id', label: 'RFIs Container ID' } + ]} + ]}, + { name: 'markups', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'id', label: 'Markups Container ID' } + ]} + ]}, + { name: 'checklists', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'id', label: 'Checklists Container ID' } + ]} + ]}, + { name: 'cost', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'id', label: 'Cost Container ID' } + ]} + ]}, + { name: 'location', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'id', label: 'Locations Container ID' } + ]} + ]} + ]} + + # These are not correct + # { name: 'name', label: 'Project name' }, + # { name: 'start_date', type: 'date' }, + # { name: 'end_date', type: 'date' }, + # { name: 'project_type', + # control_type: 'select', pick_list: 'project_types', + # toggle_hint: 'Select project type', + # toggle_field: { + # name: 'project_type', + # type: 'string', + # control_type: 'text', + # label: 'Project type', + # toggle_hint: 'Use custom value' + # }, + # hint: 'Refer to the preconfigured ' \ + # "project_type list in the " \ + # 'Parameters guide' }, + # { name: 'value', label: 'Monetary value' }, + # { name: 'currency', control_type: 'select', + # pick_list: 'currency_list', + # toggle_hint: 'Select currency', + # toggle_field: { + # name: 'currency', + # type: 'string', + # control_type: 'text', + # label: 'Project type', + # toggle_hint: 'Use custom value' + # } }, + # { name: 'status', control_type: 'select', + # pick_list: 'status_list', + # toggle_hint: 'Select status', + # toggle_field: { + # name: 'status', + # type: 'string', + # control_type: 'text', + # label: 'Status', + # toggle_hint: 'Use custom value' + # } }, + # { name: 'job_number' }, + # { name: 'address_line_1' }, + # { name: 'address_line_2' }, + # { name: 'city' }, + # { name: 'state_or_province' }, + # { name: 'postal_code' }, + # { name: 'country' }, + # { name: 'postal_code' }, + # { name: 'country' }, + # { name: 'business_unit_id' }, + # { name: 'timezone', hint: 'Refer to the preconfigured ' \ + # "project_type list in the " \ + # 'Parameters guide' }, + # { name: 'language', control_type: 'select', pick_list: + # [%w[English en], %w[German de]] }, + # { name: 'construction_type', hint: 'Refer to the preconfigured ' \ + # "project_type list in the " \ + # 'Parameters guide' }, + # { name: 'contract_type', hint: 'Refer to the preconfigured ' \ + # "project_type list in the " \ + # 'Parameters guide' }, + # { name: 'last_sign_in', hint: 'Timestamp of the last sign in,' \ + # ' YYYY-MM-DDThh:mm:ss.sssZ format' } ] end }, From 15c576dcc2a4005a8b84ec6e26593e692b140c42 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 15:36:34 -0400 Subject: [PATCH 35/62] update `export drawing...` action, include markups and hyperlinks parameters, output `hub_id`, `projct_id`, and `item_id` in result --- custom_connectors/oauth2/bim_360.rb | 55 ++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 884cd3bc..d62b8ed9 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2127,7 +2127,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -2143,7 +2143,7 @@ }, { name: 'project_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -2160,7 +2160,7 @@ } }, { name: 'folder_id', - label: 'Folder name', + label: 'Folder Name', control_type: 'tree', hint: 'Select folder', toggle_hint: 'Select Folder', @@ -2211,11 +2211,41 @@ toggle_hint: 'Use custom value', hint: 'Use version number' } + }, + { + name: 'includeMarkups', control_type: 'checkbox', + type: 'boolean', label: 'Include Markups', + sticky: true, + hint: 'Include markups in the export', + toggle_hint: 'Select from options list', + toggle_field: { + name: 'includeMarkups', + label: 'Include Markups', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are true, false.' + } + }, + { + name: 'includeHyperlinks', control_type: 'checkbox', + type: 'boolean', label: 'Include Hyperlinks', + sticky: true, + hint: 'Include hyperlinks in the export', + toggle_hint: 'Select from options list', + toggle_field: { + name: 'includeHyperlinks', + label: 'Include Hyperlinks', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are true, false.' + } } ], execute: lambda do |_connection, input| # Step 1 find the version id of the file to export - input.delete('hub_id') + hub_id = input.delete('hub_id') input.delete('folder_id') version_number = input['version_number'] || get('/data/v1/projects/' \ "#{input['project_id']}/items/#{input['item_id']}/" \ @@ -2223,14 +2253,29 @@ version_url = version_number.encode_url # Step 2 upload the file project_id = input.delete('project_id').gsub('b.', '') + item_id = input.delete('item_id') + # create payload with `true`/`false` booleans + input_payload = {} + input&.map do |key, value| + if value.to_s.downcase === 'true' + input_payload[key] = true + else + input_payload[key] = false + end + end post("/bim360/docs/v1/projects/#{project_id}/versions" \ "/#{version_url}/exports"). + payload(input_payload). + headers('content-type': 'application/json'). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end + end&.merge({ hub_id: hub_id }).merge({ project_id: 'b.' + project_id }).merge({ item_id: item_id }) end, output_fields: lambda do |_object_definitions| [ + { name: 'hub_id' }, + { name: 'project_id' }, + { name: 'item_id' }, { name: 'id', label: 'Export ID' }, { name: 'status' } ] From b60a69f56d632e942d3de37024dd15c4e1071aeb Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 15:40:48 -0400 Subject: [PATCH 36/62] update `get drawing export status...`, remove unnecessary fields, output `hub_id`, `project_id`, and `item_id` in result --- custom_connectors/oauth2/bim_360.rb | 55 +++++++---------------------- 1 file changed, 13 insertions(+), 42 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index d62b8ed9..0a22155d 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2572,7 +2572,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -2588,7 +2588,7 @@ }, { name: 'project_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -2604,26 +2604,9 @@ 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' } }, - { name: 'folder_id', - label: 'Folder', - control_type: 'tree', - hint: 'Select folder', - toggle_hint: 'Select Folder', - pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, - tree_options: { selectable_folder: true }, - pick_list: :folders_list, - optional: false, - toggle_field: { - name: 'folder_id', - type: 'string', - control_type: 'text', - label: 'Folder ID', - toggle_hint: 'Use Folder ID', - hint: 'Use Folder ID' - } }, { name: 'item_id', - label: 'File name', + label: 'File Name', control_type: 'select', pick_list: 'folder_items', pick_list_params: { project_id: 'project_id', @@ -2636,26 +2619,7 @@ control_type: 'text', label: 'File ID', toggle_hint: 'Use file ID', - hint: 'Use file ID' - } - }, - { - name: 'version_urn', - control_type: 'select', - label: 'Version number', - pick_list: 'item_versions', - sticky: true, - pick_list_params: { project_id: 'project_id', item_id: 'item_id' }, - optional: true, - toggle_hint: 'Select version', - toggle_field: { - name: 'version_urn', - label: 'Version URN', - type: 'string', - control_type: 'text', - optional: true, - toggle_hint: 'Use custom value', - hint: 'Use version number e.g. e7e2a39a-2ead-4dcd-9760-5f7af' + hint: 'Use File/Item ID' } } ], @@ -2672,10 +2636,17 @@ # version_url = version_number.encode_url project_id = input['project_id'].split('.').last get("/bim360/docs/v1/projects/#{project_id}/versions/" \ - "#{version_url}/exports/#{input['export_id']}") + "#{version_url}/exports/#{input['export_id']}"). + merge({ hub_id: input['hub_id'] }). + merge({ project_id: input['project_id'] }). + merge({ item_id: input['item_id'] }) end, output_fields: lambda do |object_definitions| - object_definitions['export_status'] + [ + { name: 'hub_id' }, + { name: 'project_id' }, + { name: 'item_id' } + ].concat(object_definitions['export_status']) end, sample_output: lambda do |_connection, _input| call('sample_data_export_job') From 4815452a11ebf2cd35bfe9890e95480b111f0b84 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 15:41:48 -0400 Subject: [PATCH 37/62] add `download drawing export...` action --- custom_connectors/oauth2/bim_360.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 0a22155d..1d740b4f 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2112,6 +2112,27 @@ dig('data', 0) || {} end }, + download_drawing_export: { + description: 'Download drawing export in'\ + ' a project in BIM 360', + input_fields: lambda do |object_definitions| + [ + { name: 'export_link', label: 'Export Link', optional: false} + ] + end, + execute: lambda do |_connection, input| + file_content = + get(input['export_link']).headers('Accept-Encoding': 'Accept-Encoding:gzip'). + response_format_raw. + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + { content: file_content } + end, + output_fields: lambda do |_object_definitions| + [{ name: 'content' }] + end + }, export_project_plan: { title: 'Export drawing in a project', description: 'Export drawing in'\ From 5916c2b1da311768c47cc39fb408f8c5d761512d Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 15:45:56 -0400 Subject: [PATCH 38/62] update `upload document...` action, use `request_body` hash to send file contents --- custom_connectors/oauth2/bim_360.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 1d740b4f..04150d54 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2927,11 +2927,12 @@ bucket_key = object_id.split('/').first.split('object:').last object_name = object_id.split('/').last response = put('https://developer.api.autodesk.com/oss/v2/buckets/' \ - "#{bucket_key}/objects/#{object_name}", - input['file_content']). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end + "#{bucket_key}/objects/#{object_name}"). + request_body(input['file_content']). + headers('Content-Type': 'application/octet-stream'). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end object_urn = response['objectId'] # 3 create a first version of the File # folder_urn = get("/data/v1/projects/#{input['project_id']}/folders" \ @@ -3000,13 +3001,12 @@ } ] } - user_id = get('/userprofile/v1/users/@me')['userId'] + # item_id = post("/data/v1/projects/#{project_id}/items"). payload(version_payload). headers('Content-Type': 'application/vnd.api+json', - Accept: 'application/vnd.api+json', - 'x-user-id': user_id). + Accept: 'application/vnd.api+json'). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end&.dig('data')&.merge({ hub_id: hub_id, project_id: project_id }) From 5473b0a8bbdc056e60aba6de5a3a19c02a99c986 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 16:45:05 -0400 Subject: [PATCH 39/62] update field naming convention --- custom_connectors/oauth2/bim_360.rb | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 04150d54..6d9020f9 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -875,7 +875,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -891,7 +891,7 @@ }, { name: 'project_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -1067,7 +1067,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1083,7 +1083,7 @@ }, { name: 'container_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'issue_container_lists', pick_list_params: { hub_id: 'hub_id' }, @@ -1613,7 +1613,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1629,7 +1629,7 @@ }, { name: 'container_id', - label: 'Container name', + label: 'Container Name', control_type: 'select', pick_list: 'issue_container_lists', pick_list_params: { hub_id: 'hub_id' }, @@ -1696,7 +1696,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1831,7 +1831,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1847,7 +1847,7 @@ }, { name: 'container_id', - label: 'Container name', + label: 'Container Name', control_type: 'select', pick_list: 'rfis_container_lists', pick_list_params: { hub_id: 'hub_id' }, @@ -2199,7 +2199,7 @@ } }, { name: 'item_id', - label: 'File name', + label: 'File Name', control_type: 'select', pick_list: 'folder_items', pick_list_params: { project_id: 'project_id', @@ -2547,7 +2547,7 @@ hint: 'Use Folder ID' } }, { name: 'item_id', - label: 'File name', + label: 'File Name', control_type: 'tree', hint: 'Select folder', toggle_hint: 'Select Item', @@ -2680,7 +2680,7 @@ [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub Name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -2696,7 +2696,7 @@ }, { name: 'project_id', - label: 'Project name', + label: 'Project Name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -2729,7 +2729,7 @@ hint: 'Use Folder ID' } }, { name: 'item_id', - label: 'File name', + label: 'File Name', control_type: 'tree', hint: 'Select folder', toggle_hint: 'Select Folder', From 4760c6279687ea29473c1d3bf38a20112ad3958a Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 6 Sep 2019 09:36:13 -0400 Subject: [PATCH 40/62] fix spelling error --- custom_connectors/oauth2/bim_360.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 6d9020f9..56d9e2e8 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2581,8 +2581,8 @@ end }, get_drawing_export_status: { - title: 'Get drawaing export status in a project', - description: 'Get drwaing export status in'\ + title: 'Get drawing export status in a project', + description: 'Get drawing export status in'\ ' a project in BIM 360', help: { body: 'This action returns the status of a PDF export job, as well' \ From 0be137fdae7f29a6b0e965576e30377daf56c685 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 6 Sep 2019 09:42:45 -0400 Subject: [PATCH 41/62] remove comments --- custom_connectors/oauth2/bim_360.rb | 58 +---------------------------- 1 file changed, 1 insertion(+), 57 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 56d9e2e8..39afaf13 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -62,8 +62,6 @@ end, apply: lambda do |_connection, access_token| headers(Authorization: "Bearer #{access_token}") - # headers(Authorization: "Bearer #{access_token}", - # 'Content-Type': 'application/vnd.api+json') end }, base_uri: lambda do |_connection| @@ -2852,21 +2850,6 @@ 'items:autodesk.bim360:File.
' \ 'For all other services, use items:autodesk.core:File.' } }, - # { name: 'resource_type', label: 'Type of the resource', - # control_type: 'select', pick_list: 'resource_types', - # toggle_hint: 'Select resource type', - # toggle_field: { - # name: 'resource_type', - # label: 'Resource type', - # type: 'string', - # control_type: 'text', - # toggle_hint: 'Use custom value', - # hint: 'The type of the resource. Possible values: attachment,' \ - # ' overlay' - # } }, - # { name: 'file_extension_version', - # hint: 'The version of the file extension type. The current ' \ - # 'version is 1.0.' }, { name: 'version_type', label: 'Type of version', hint: 'Only relevant for creating files - the type of version.', control_type: 'select', @@ -2979,7 +2962,6 @@ 'attributes' => { 'name' => input['file_name'], 'extension' => { - # input['object_type'] 'type' => input['version_type'], 'version' => input['extension_type_version'] || '1.0' } @@ -2990,13 +2972,7 @@ 'type' => 'objects', 'id' => object_urn } - } # , - # 'refs' => { - # 'data' => { - # 'type' => 'versions', - # 'id' => 'version_urn' - # } - # } + } } } ] @@ -3010,38 +2986,6 @@ after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end&.dig('data')&.merge({ hub_id: hub_id, project_id: project_id }) - # 4 Update version of the file - # update_version = { - # 'jsonapi' => '1.0', - # 'data' => { - # 'type' => 'versions', - # 'attributes': { - # 'extension' => { - # 'type' => 'versions:autodesk.core:File"', - # 'version' => '1.0' - # } - # }, - # 'relationships' => { - # 'item' => { - # 'data' => { - # 'type' => 'items', - # 'id' => item_id - # } - # }, - # 'storage' => { - # 'data' => { - # 'type' => 'objects', - # 'id' => object_urn - # } - # } - # } - # } - # } - # post("/data/v1/projects/#{project_id}/versions"). - # payload(update_version). - # after_error_response(/.*/) do |_code, body, _header, message| - # error("#{message}: #{body}") - # end end, output_fields: lambda do |object_definitions| [ From 8a79ab92f7667f1ff714569a3fae32a528ff71b5 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sun, 8 Sep 2019 22:47:31 -0400 Subject: [PATCH 42/62] remove RFIs from connector --- custom_connectors/oauth2/bim_360.rb | 884 ---------------------------- 1 file changed, 884 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 39afaf13..c2952a46 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -515,359 +515,6 @@ ] end }, - rfi: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'id', label: 'RFI ID' }, - { name: 'attributes', type: 'object', properties: [ - { name: 'created_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'created, in the following format: YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'synced_at', type: 'date_time', - hint: 'The date and time the issue was synced with BIM 360, ' \ - 'in the following format: YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'updated_at', type: 'date_time', - hint: 'The last time the issue’s attributes were updated, in '\ - 'the following format: YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'answer', hint: 'An answer for the RFI.' }, - { name: 'answered_at', type: 'date_time', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp', - hint: 'The last time the RFI answer attribute was updated, ' \ - 'in the following format: YYYY-MM-DDThh:mm:ss.sz<\b>.' }, - { name: 'answered_by', - hint: 'The Autodesk ID of the user who updated the RFI answer' \ - ' attribute' }, - { name: 'manager', - hint: 'The last actual manager (GC) of the RFI' }, - { name: 'reviewer', - hint: 'The last actual reviewer (CM or Arch) of the RFI.' }, - { name: 'assigned_to', hint: 'The Autodesk ID of the user' }, - { name: 'assigned_to_type', - control_type: 'select', - pick_list: 'assigned_type_list', - toggle_hint: 'Select assigned type', - toggle_field: { - name: 'assigned_to_type', - type: 'string', - control_type: 'text', - label: 'Assigned Type', - toggle_hint: 'Use custom value', - hint: 'The type of assignee the RFI is assigned to. ' \ - 'Possible values: user, company, role' - } }, - { name: 'assignees', type: 'array', of: 'object', properties: [ - { name: 'id' }, - { name: 'type' } - ] }, - { name: 'attachment_count', - hint: 'The number of attachments associated with the RFI.' }, - { name: 'close_version' }, - { name: 'closed_at', type: 'date_time', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp', - hint: 'The timestamp of the date and time the RFI was closed' }, - { name: 'closed_by', - hint: 'The Autodesk ID of the user who closed the RFI.' }, - { name: 'co_reviewers', hint: 'A list of alternative reviewers.' \ - ' Provide comma separated list of values.' }, - { name: 'collection_urn' }, - { name: 'comment_count', - hint: 'The number of comments added to the RFI.' }, - { name: 'created_by', - hint: 'The Autodesk ID of the user who created the RFI.' }, - { name: 'description' }, - { name: 'due_date', type: 'date_time', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp', - hint: 'The timestamp of the due date for the RFI, in the ' \ - 'following format: YYYY-MM-DDThh:mm:ss.sz' }, - { name: 'identifier', - hint: 'The identifier of the RFI. This corresponds to the RFI' \ - ' ID number in the UI' }, - { name: 'custom_identifier', - hint: 'A custom identifier of the RFI selected by the user.' }, - { name: 'identifier_minor', type: 'integer' }, - { name: 'location_description', - hint: 'A description of the location of the RFI in the ' \ - 'construction project.' }, - { name: 'markup_metadata' }, - { name: 'permitted_actions', hint: 'A list of actions that are' \ - ' permitted for the user.' }, - { name: 'permitted_attributes', - hint: 'A list of attributes the user can modify.' }, - { name: 'permitted_statuses', hint: 'array of strings' }, - { name: 'permitted_transitions', type: 'array', of: 'object', - hint: 'A list of potential transitions.', - properties: [ - { name: 'id' }, - { name: 'is_specific_assignee', control_type: 'checkbox', - hint: 'Is the RFI can be assigned to a specific user', - type: 'boolean', toggle_hint: 'Select from options list', - toggle_field: { - name: 'is_specific_assignee', - type: 'string', - control_type: 'text', - label: 'Specific assignee', - hint: 'Is the RFI can be assigned to a specific user', - toggle_hint: 'Provide custom vlaue. ' \ - 'Allowed values are true, false' - } }, - { name: 'status', control_type: 'select', - pick_list: 'rfi_transaction_status_list', - hint: 'The status of the RFI after the transition', - toggle_hint: 'Select status', - toggle_field: { - name: 'status', - label: 'Status', - type: 'string', - control_type: 'text', - toggle_hint: 'Provie custom value', - hint: 'Possible values: draft, submitted, open, ' \ - 'rejected, answered, closed, void' - } }, - { name: 'title' }, - { name: 'assignees', type: 'array', of: 'object', properties: [ - { name: 'id' }, - { name: 'type' } - ] }, - { name: 'pushpin_attributes', type: 'object' }, - { name: 'resource_urns', hint: 'List of urns' }, - { name: 'sheet_metadata', type: 'object' }, - { name: 'starting_version', - hint: 'The first version of the RFI' }, - { name: 'suggested_answer', - hint: 'The suggested answer for the RFI.' }, - { name: 'tags' }, - { name: 'target_urn' }, - { name: 'target_urn_page' }, - { name: 'title' } - ] }, - { name: 'pushpin_attributes', type: 'object', properties: [ - { name: 'type' }, - { name: 'location', type: 'object', properties: [ - { name: 'x', type: 'number' }, - { name: 'y', type: 'number' }, - { name: 'z', type: 'number' } - ] }, - { name: 'resource_urns' }, - { name: 'sheet_metadata', type: 'object' }, - { name: 'starting_version', - hint: 'The first version of the RFI.' }, - { name: 'transition_attributes', type: 'array', of: 'object', - properties: [ - { name: 'id' }, - { name: 'is_specific_assignee', control_type: 'checkbox', - hint: 'Is the RFI can be assigned to a specific user', - type: 'boolean', toggle_hint: 'Select from options list', - toggle_field: { - name: 'is_specific_assignee', - type: 'string', - control_type: 'text', - label: 'Specific assignee', - hint: 'Is the RFI can be assigned to a specific user', - toggle_hint: 'Provide custom vlaue. ' \ - 'Allowed values are true, false' - } }, - { name: 'status', control_type: 'select', - pick_list: 'rfi_transaction_status_list', - hint: 'The status of the RFI after the transition', - toggle_hint: 'Select status', - toggle_field: { - name: 'status', - label: 'Status', - type: 'string', - control_type: 'text', - toggle_hint: 'Provie custom value', - hint: 'Possible values: draft, submitted, open, ' \ - 'rejected, answered, closed, void' - } }, - { name: 'title' }, - { name: 'is_required', control_type: 'checkbox', - type: 'boolean', toggle_hint: 'Select from options list', - toggle_field: { - name: 'is_required', - type: 'string', - control_type: 'text', - label: 'Is required', - toggle_hint: 'Provide custom vlaue. ' \ - 'Allowed values are true, false' - } } - ] }, - { name: 'workflow_state', type: 'object', properties: [ - { name: 'id' }, - { name: 'title' }, - { name: 'short_title' }, - { name: 'name' } - ] }, - { name: 'is_specific_assignee' }, - { name: 'object_id' }, - { name: 'viewer_state' }, - { name: 'created_at', type: 'date_time' }, - { name: 'created_by' }, - { name: 'created_doc_version', type: 'integer' }, - { name: 'hidden_at', type: 'date_time' }, - { name: 'hidden_by' }, - { name: 'hidden_doc_version', type: 'integer' } - ] }, - { name: 'resource_urns', hint: 'array of strings' }, - # TO UPDATE - { name: 'resource_urns' }, - { name: 'sheet_metadata', type: 'object' }, - { name: 'starting_version' }, - { name: 'status', control_type: 'select', - pick_list: 'rfi_transaction_status_list', - hint: 'The status of the RFI after the transition', - toggle_hint: 'Select status', - toggle_field: { - name: 'status', - label: 'Status', - type: 'string', - control_type: 'text', - toggle_hint: 'Provie custom value', - hint: 'Possible values: draft, submitted, open, ' \ - 'rejected, answered, closed, void' - } }, - { name: 'suggested_answer' }, - { name: 'tags', hint: 'array of strings' }, - { name: 'target_urn' }, - { name: 'target_urn_page' }, - { name: 'title' }, - { name: 'workflow_state', type: 'object', properties: [ - { name: 'id' }, - { name: 'title' }, - { name: 'short_title' }, - { name: 'name' } - ] }, - { name: 'current_allowed_assignees', type: 'array', of: 'object', - properties: [ - { name: 'id' }, - { name: 'type' } - ] }, - { name: 'distribution_list', - hint: 'Provide comma separated list of IDs' }, - { name: 'comments_attributes', type: 'array', of: 'object', - properties: [ - { name: 'id', label: 'Attachment ID' }, - { name: 'type' }, - { name: 'attributes', type: 'object', properties: [ - { name: 'created_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'created, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'created_by' }, - { name: 'synced_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'synced, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'updated_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'updated, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'rfi_id' }, - { name: 'body' } - ] } - ] }, - { name: 'attachments_attributes', type: 'array', of: 'object', - properties: [ - { name: 'id', label: 'Comment ID' }, - { name: 'type' }, - { name: 'attributes', type: 'object', properties: [ - { name: 'created_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'created, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'created_by' }, - { name: 'synced_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'synced, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'updated_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'updated, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'attachment_type' }, - { name: 'deleted_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'deleted, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'deleted_by', hint: 'The ID of the user who deleted' \ - ' the attachment. This is only relevant for deleted' \ - ' attachments.' }, - { name: 'rfi_id' }, - { name: 'name' }, - { name: 'resource_urns', type: 'array', of: 'string' }, - { name: 'url' }, - { name: 'urn' }, - { name: 'urn_page' }, - { name: 'urn_type' }, - { name: 'urn_version' }, - { name: 'permitted_actions' } - ] } - ] } - ] } - ] - end - }, - modify_rfi: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'title' }, - { name: 'description', label: 'Question' }, - { name: 'suggested_answer', label: 'Suggested Answer' }, - { name: 'answer', hint: 'An answer for the RFI.' }, - { name: 'assigned_to', - hint: 'The Autodesk ID of the user you want to assign ' \ - 'the RFI to.' }, - { name: 'location_description' }, - { name: 'due_date', type: 'date_time', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp', - hint: 'The timestamp of the due date for the RFI, in the ' \ - 'following format: YYYY-MM-DDThh:mm:ss.sz.' }, - { name: 'distribution_list', - hint: 'Provide comma seaprated list of values multiple values' }, - { name: 'transition_id', - hint: 'This field is mandatory when tranistioning the RFI.' }, - { name: 'co_reviewers', - hint: 'Add members who can contribute to the RFI response. ' \ - 'Note that although you can only add co-reviewers in the UI ' \ - 'when the RFI is in open status, you can use the endpoint to' \ - ' also set up co-reviewers in other statuses.' \ - 'To delete all co-reviewers, call the endpoint with an empty' \ - ' array.' }, - { name: 'reserve_custom_identifier', - hint: 'This field allows to reserve a custom identifier for ' \ - 'future use (for example, in draft or submitted status). No ' \ - 'other RFI will be able to use or reserve this identifier for' \ - ' 2 minutes.' }, - { name: 'custom_identifier', - hint: 'Identifier of the RFI given by user. When non-present in' \ - ' transitions to any status, except “draft” or “submitted”, ' \ - 'will be populated automatically.' } - ] - end - }, search_criteria: { fields: lambda do |_connection, _config_fields| [ @@ -969,97 +616,6 @@ ] end }, - rfis_criteria: { - fields: lambda do |_connection, _config_fields| - [ - { - name: 'status', control_type: 'select', - pick_list: 'rfi_status_list', - sticky: true, - hint: 'Retrieves RFIs with the specified status', - toggle_hint: 'Select status', - toggle_field: { - name: 'status', - label: 'Status', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are
draft, open, close
.' - } - }, - { - name: 'include_voided', control_type: 'checkbox', - type: 'boolean', - sticky: true, - hint: 'Include voided RFIs in the response. true returns ' \ - 'voided RFIs; false does not return voided RFIs', - toggle_hint: 'Select from options list', - toggle_field: { - name: 'include_voided', - label: 'Include voided', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are true, false.' \ - ' Note that status overrides this filter' - } - }, - { name: 'target_urn', sticky: true, - hint: 'Retrieves RFIs in the project that' \ - ' were linked to the specified document or documents, using' \ - 'the documents`s URN. e.g. urn:adsk.wipprod:dm.lineage:' \ - 'tFbo9zuDTW-nPh45gnM4gA' }, - { name: 'assigned_to', sticky: true, - hint: 'Retrieves RFIs in the project that' \ - " were assigned to the specified user, using the user's " \ - ' Autodesk ID. e.g PER8KQPK2JRT' }, - { name: 'created_at', sticky: true, - hint: 'Retrieves RFIs created at the specfied date. matchValue ' \ - 'is the timestamp of the date in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz, or a date range in the following' \ - ' format: YYYY-MM-DDThh:mm:ss.sz...YYYY-MM-DDThh:mm:ss.sz.' }, - { name: 'due_date', sticky: true, - hint: 'Retrieves RFIs due by the specified due date. matchValue' \ - ' is the timestamp of the due date in the following format' \ - ' : YYYY-MM-DDThh:mm:ss.sz, or a date range in the following' \ - ' format: YYYY-MM-DDThh:mm:ss.sz...YYYY-MM-DDThh:mm:ss.sz.' }, - { name: 'search', sticky: true, - hint: 'Free search in RFIs of the current container. The search' \ - ' is been performed in identifier, title, description and ' \ - 'answer fields.' }, - { name: 'sort', sticky: true, - hint: 'Sort the issues by status, due_date,' \ - ' and title, target_urn, location_description, identifier,' \ - ' created_at, updated_at. To sort in descending order add a ' \ - '- before the sort criteria. Separate multiple values' \ - ' with commas' }, - { name: 'limit', type: 'integer', sticky: true, - hint: 'The number of RFIs to return in the response payload.' \ - ' Acceptable values: 1-100. Default value: 10' }, - { name: 'offset', sticky: true, - hint: 'the page number that you want to begin RFI results from.' }, - { - name: 'include', sticky: true, - label: 'Include additional data', - control_type: 'multiselect', - pick_list: 'rfi_child_objects', - pick_list_params: {}, - delimiter: ',', - toggle_hint: 'Select from list', - toggle_field: { - name: 'include', - label: 'Include additinal data', - type: :string, - control_type: 'text', - optional: true, - hint: 'Multiple values separated by comma.', - toggle_hint: 'Comma separated list of values. Allowed values ' \ - 'are: attachments, comments,activity_batches, container' - } - } - ] - end - }, hub_container_ids: { fields: lambda do |_connection, _config_fields| [ @@ -1406,7 +962,6 @@ ] end }, - custom_action_output: { fields: lambda do |_connection, config_fields| parse_json(config_fields['output'] || '[]') @@ -1816,300 +1371,6 @@ get("/project/v1/hubs/#{id}/projects")&.dig('data', 0) || {} end }, - search_rfis_in_project: { - title: 'Search RFIs in project', - description: 'Search RFIs in a project in'\ - ' BIM 360', - help: { - body: 'Retrieves information about all the BIM 360 RFIs (requests ' \ - 'for information) in a project, including details about their ' \ - 'associated comments and attachments.' - }, - input_fields: lambda do |object_definitions| - [ - { - name: 'hub_id', - label: 'Hub Name', - control_type: 'select', - pick_list: 'hub_list', - optional: false, - toggle_hint: 'Select hub', - toggle_field: { - name: 'hub_id', - label: 'Hub ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' - } - }, - { - name: 'container_id', - label: 'Container Name', - control_type: 'select', - pick_list: 'rfis_container_lists', - pick_list_params: { hub_id: 'hub_id' }, - optional: false, - toggle_hint: 'Select container', - toggle_field: { - name: 'container_id', - label: 'Container ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' - } - } - ].concat(object_definitions['rfis_criteria']) - end, - execute: lambda do |_connection, input| - hub_id = input.delete('hub_id') - container_id = input.delete('container_id') - filter_criteria = call('format_search', input) - { rfis: get("/bim360/rfis/v1/containers/#{container_id}/rfis", - filter_criteria)['data'] }&. - merge({ hub_id: hub_id, container_id: container_id }) - end, - output_fields: lambda do |object_definitions| - [ - { name: 'hub_id' }, - { name: 'container_id' }, - { name: 'rfis', label: 'RFIs', type: 'array', of: 'object', - properties: object_definitions['rfi'] } - ] - end, - sample_output: lambda do |_connection, input| - { rfis: - get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. - dig('data', 0) || {} } - end - }, - get_rfi_in_project: { - title: 'Get RFI in a project', - description: 'Get RFI in'\ - ' a project in BIM 360', - help: { - body: 'Retrieves detailed information about a single BIM 360 RFI' \ - ' (request for information).' - }, - input_fields: lambda do |_object_definitions| - [ - { - name: 'hub_id', - label: 'Hub Name', - control_type: 'select', - pick_list: 'hub_list', - optional: false, - toggle_hint: 'Select hub', - toggle_field: { - name: 'hub_id', - label: 'Hub ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' - } - }, - { - name: 'container_id', - label: 'Project Name', - control_type: 'select', - pick_list: 'rfis_container_lists', - pick_list_params: { hub_id: 'hub_id' }, - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'container_id', - label: 'Container ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide container ID e.g. ' \ - 'edac0659-639a-4a87-8614-d2c521b246b0' - } - }, - { name: 'id', optional: false, label: 'RFI ID' } - ] - end, - execute: lambda do |_connection, input| - get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis/" \ - "#{input['id']}"). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end['data']&. - merge({ hub_id: input['hub_id'], - container_id: input['container_id'] }) - end, - output_fields: lambda do |object_definitions| - [{ name: 'hub_id' }, { name: 'container_id' }]. - concat(object_definitions['rfi']) - end, - sample_output: lambda do |_connection, input| - get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. - dig('data', 0) || {} - end - }, - create_rfi_in_project: { - title: 'Create RFI in a project', - description: 'Create RFI in'\ - ' a project in BIM 360', - help: { - body: 'Adds a BIM 360 RFI (request for information) to a project. ' \ - 'Users can create RFIs if they have been assigned either creator ' \ - '(sc) or manager (gc) workflow roles. Project admins are ' \ - 'automatically assigned the creator workflow role.' - }, - input_fields: lambda do |object_definitions| - [ - { - name: 'hub_id', - label: 'Hub Name', - control_type: 'select', - pick_list: 'hub_list', - optional: false, - toggle_hint: 'Select hub', - toggle_field: { - name: 'hub_id', - label: 'Hub ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' - } - }, - { - name: 'container_id', - label: 'Project Name', - control_type: 'select', - pick_list: 'rfis_container_lists', - pick_list_params: { hub_id: 'hub_id' }, - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'container_id', - label: 'Container ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide container ID e.g. ' \ - 'edac0659-639a-4a87-8614-d2c521b246b0' - } - } - ].concat(object_definitions['modify_rfi']. - ignored('transition_id', 'assigned_to', 'answer')) - end, - execute: lambda do |_connection, input| - hub_id = input.delete('hub_id') - container_id = input.delete('container_id') - input_payload = input&.map do |key, value| - if %w[distribution_list co_reviewers].include?(key) - { key => value.split(',') } - else - { key => value } - end - end&.inject(:merge) - payload = { - type: 'rfis', - attributes: input_payload - } - post("/bim360/rfis/v1/containers/#{container_id}/rfis"). - payload({ data: payload }). - headers('Content-Type': 'application/vnd.api+json'). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end['data']&.merge({ hub_id: hub_id, container_id: container_id }) - end, - output_fields: lambda do |object_definitions| - [{ name: 'hub_id' }, { name: 'container_id' }]&. - concat(object_definitions['rfi']) - end, - sample_output: lambda do |_connection, input| - get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. - dig('data', 0) || {} - end - }, - update_rfi_in_project: { - title: 'Updated RFI in a project', - description: 'Update RFI in a project in'\ - ' BIM 360', - help: { - body: 'Updates a BIM 360 Project Management RFI. If the RFI is in ' \ - 'Draft status, it can only be updated by the user who created the ' \ - 'RFI. For all other statuses, it can only be updated by the user who' \ - ' was assigned to the RFI.' - }, - input_fields: lambda do |object_definitions| - [ - { - name: 'hub_id', - label: 'Hub Name', - control_type: 'select', - pick_list: 'hub_list', - optional: false, - toggle_hint: 'Select hub', - toggle_field: { - name: 'hub_id', - label: 'Hub ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' - } - }, - { - name: 'container_id', - label: 'Project Name', - control_type: 'select', - pick_list: 'rfis_container_lists', - pick_list_params: { hub_id: 'hub_id' }, - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'container_id', - label: 'Container ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide container ID e.g. ' \ - 'edac0659-639a-4a87-8614-d2c521b246b0' - } - }, - { name: 'id', optional: false, label: 'RFI ID' } - ].concat(object_definitions['modify_rfi']. - ignored('suggested_answer')) - end, - execute: lambda do |_connection, input| - hub_id = input.delete('hub_id') - container_id = input.delete('container_id') - id = input.delete('id') - input_payload = input&.map do |key, value| - if %w[distribution_list co_reviewers].include?(key) - { key => value.split(',') } - else - { key => value } - end - end&.inject(:merge) - payload = { - id: id, - type: 'rfis', - attributes: input_payload - } - patch("/bim360/rfis/v1/containers/#{container_id}/rfis/#{id}"). - payload({ data: payload }). - headers('Content-Type': 'application/vnd.api+json'). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end['data'].merge({ hub_id: hub_id, container_id: container_id }) - end, - output_fields: lambda do |object_definitions| - [{ name: 'hub_id' }, { name: 'container_id' }]&. - concat(object_definitions['rfi']) - end, - sample_output: lambda do |_connection, input| - get("/bim360/rfis/v1/containers/#{input['container_id']}/rfis")&. - dig('data', 0) || {} - end - }, download_drawing_export: { description: 'Download drawing export in'\ ' a project in BIM 360', @@ -2996,128 +2257,6 @@ } }, triggers: { - new_rfi_in_project: { - title: 'New RFI in a project', - description: 'New RFI in'\ - ' a project in BIM 360', - help: { - body: 'Triggers when a RFI in a project is created.' - }, - input_fields: lambda do |_object_definitions| - [ - { - name: 'hub_id', - label: 'Hub Name', - control_type: 'select', - pick_list: 'hub_list', - optional: false, - toggle_hint: 'Select hub', - toggle_field: { - name: 'hub_id', - label: 'Hub ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' - } - }, - { - name: 'project_id', - label: 'Project Name', - control_type: 'select', - pick_list: 'project_list', - pick_list_params: { hub_id: 'hub_id' }, - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_id', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' - } - }, - { - name: 'since', - label: 'When first started, this recipe should pick up events from', - hint: 'When you start recipe for the first time, ' \ - 'it picks up trigger events from this specified date and time. ' \ - 'Leave empty to get records created or updated one hour ago', - sticky: true, - type: 'timestamp' - } - ] - end, - poll: lambda do |_connection, input, closure| - hub_id = closure&.[]('hub_id') || input['hub_id'] - project_id = closure&.[]('project_id') || input['project_id'] - container_id = closure&.[]('container_id') || - get("/project/v1/hubs/#{input['hub_id']}" \ - "/projects/#{project_id}")&. - dig('data', 'relationships', 'issues', 'data', 'id') - from_date = closure&.[]('from_date') || - (input['since'] || 1.hour.ago). - to_time.strftime('%Y-%m-%dT%H:%M:%H.%s%z') - limit = 10 - skip = closure&.[]('skip') || 0 - include = closure&.[]('include') || input['include'] - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) - else - get("/bim360/rfis/v1/containers/#{container_id}/rfis"). - params(page: { limit: limit, - skip: skip }, - filter: { - created_at: from_date - }, - include: 'attachments,comments', - sort: 'created_at') - end - closure = if (next_page_url = response.dig('links', 'next')).present? - { 'skip' => skip + limit, - 'container_id' => container_id, - 'project_id' => project_id, - 'hub_id' => hub_id, - 'include' => include, - 'from_date' => from_date, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'include' => include, - 'from_date' => now.to_time. - strftime('%Y-%m-%dT%H:%M:%H.%s%z'), - 'container_id' => container_id, - 'project_id' => project_id, - 'hub_id' => hub_id } - end - rfis = response['data']&. - map do |o| - o.merge({ project_id: project_id, hub_id: hub_id, - container_id: container_id }) - end - { - events: rfis || [], - next_poll: closure, - can_poll_more: response.dig('links', 'next').present? - } - end, - dedup: lambda do |rfi| - "#{rfi['id']}@#{rfi.dig('attributes', 'created_at')}" - end, - output_fields: lambda do |object_definitions| - [{ name: 'hub_id' }, { name: 'project_id' }, { name: 'container_id' }]. - concat(object_definitions['rfi']) - end, - sample_output: lambda do |_connection, input| - project_id = input['project_id'] - container_id = get("/project/v1/hubs/#{input['hub_id']}" \ - "/projects/#{project_id}")&. - dig('data', 'relationships', 'issues', 'data', 'id') - get("/bim360/rfis/v1/containers/#{container_id}/rfis")&. - dig('data', 0) || {} - end - }, new_updated_issue_in_project: { title: 'New or updated issue in a project', description: 'New or updated issue in'\ @@ -3435,14 +2574,6 @@ end end end, - rfi_child_objects: lambda do |_connection| - %w[attachments comments activity_batches container]&. - map { |option| [option.labelize, option] } - end, - rfi_transaction_status_list: lambda do |_connection| - %w[draft submitted open rejected answered closed void]&. - map { |option| [option.labelize, option] } - end, issue_child_objects: lambda do |_connection| %w[attachments comments container]&. map { |option| [option.labelize, option] } @@ -3462,18 +2593,6 @@ end end end, - rfis_container_lists: lambda do |_connection, hub_id:| - if hub_id.length == 38 - get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| - [project.dig('attributes', 'name'), - project.dig('relationships', 'rfis', 'data', 'id')] - end - end - end, - rfi_objects: lambda do |_connection| - %w[attachments comments activity_batches container]&. - map { |option| [option.labelize, option] } - end, project_types: lambda do [ %w[Commercial Commercial], ['Convention Center', 'Convention Center'], @@ -3523,9 +2642,6 @@ assigned_type_list: lambda do |_connection| %w[user company role]&.map { |el| [el.labelize, el] } end, - rfi_status_list: lambda do |_connection| - %w[draft open close]&.map { |el| [el.labelize, el] } - end, status_list: lambda do |_connection| %w[active pending inactive archived]&.map { |el| [el.labelize, el] } end, From 0167da8649d4944fe2ae9595fd8a207f8f23ef00 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sun, 8 Sep 2019 22:49:10 -0400 Subject: [PATCH 43/62] remove commented fields --- custom_connectors/oauth2/bim_360.rb | 185 +--------------------------- 1 file changed, 2 insertions(+), 183 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index c2952a46..be9417b9 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -181,72 +181,6 @@ ]} ]} ]} - - # These are not correct - # { name: 'name', label: 'Project name' }, - # { name: 'start_date', type: 'date' }, - # { name: 'end_date', type: 'date' }, - # { name: 'project_type', - # control_type: 'select', pick_list: 'project_types', - # toggle_hint: 'Select project type', - # toggle_field: { - # name: 'project_type', - # type: 'string', - # control_type: 'text', - # label: 'Project type', - # toggle_hint: 'Use custom value' - # }, - # hint: 'Refer to the preconfigured ' \ - # "project_type list in the " \ - # 'Parameters guide' }, - # { name: 'value', label: 'Monetary value' }, - # { name: 'currency', control_type: 'select', - # pick_list: 'currency_list', - # toggle_hint: 'Select currency', - # toggle_field: { - # name: 'currency', - # type: 'string', - # control_type: 'text', - # label: 'Project type', - # toggle_hint: 'Use custom value' - # } }, - # { name: 'status', control_type: 'select', - # pick_list: 'status_list', - # toggle_hint: 'Select status', - # toggle_field: { - # name: 'status', - # type: 'string', - # control_type: 'text', - # label: 'Status', - # toggle_hint: 'Use custom value' - # } }, - # { name: 'job_number' }, - # { name: 'address_line_1' }, - # { name: 'address_line_2' }, - # { name: 'city' }, - # { name: 'state_or_province' }, - # { name: 'postal_code' }, - # { name: 'country' }, - # { name: 'postal_code' }, - # { name: 'country' }, - # { name: 'business_unit_id' }, - # { name: 'timezone', hint: 'Refer to the preconfigured ' \ - # "project_type list in the " \ - # 'Parameters guide' }, - # { name: 'language', control_type: 'select', pick_list: - # [%w[English en], %w[German de]] }, - # { name: 'construction_type', hint: 'Refer to the preconfigured ' \ - # "project_type list in the " \ - # 'Parameters guide' }, - # { name: 'contract_type', hint: 'Refer to the preconfigured ' \ - # "project_type list in the " \ - # 'Parameters guide' }, - # { name: 'last_sign_in', hint: 'Timestamp of the last sign in,' \ - # ' YYYY-MM-DDThh:mm:ss.sssZ format' } ] end }, @@ -677,8 +611,6 @@ { name: 'id', label: 'Item ID' }, { name: 'type', label: 'Item Type' }, { name: 'attributes', type: 'object', properties: [ - # { name: 'type' }, - # { name: 'name' }, { name: 'displayName', label: 'Name' }, { name: 'createTime', label: 'Created at', type: 'date_time' }, { name: 'createUserId', label: 'Created by (User ID)' }, @@ -688,19 +620,10 @@ { name: 'lastModifiedUserId', label: 'Last modified by (User ID)' }, { name: 'lastModifiedUserName', label: 'Last modified by (User Name)' }, - # { name: 'lastModifiedTimeRollup', type: 'date_time' }, - # { name: 'objectCount', type: 'integer' }, { name: 'hidden', type: 'boolean', control_type: 'checkbox' }, { name: 'reserved', type: 'boolean', control_type: 'checkbox' }, { name: 'extension', type: 'object', properties: [ - # { name: 'type' }, - { name: 'version' } # , - # { name: 'data', type: 'object', properties: [ - # { name: 'sourceFileName', hint: 'Applicable for file' }, - # { name: 'visibleTypes', hint: 'Array of strings' }, - # { name: 'actions', hint: 'Array of strings' }, - # { name: 'allowedTypes', hint: 'Array of strings' } - # ] } + { name: 'version' } ] } ] } ] @@ -709,103 +632,9 @@ item: { fields: lambda do |_connection, _config_fields| [ - # { name: 'included', type: 'array', of: 'object', - # properties: [ - # { name: 'type' }, - # { name: 'id' }, - # { name: 'relationships', type: 'object', properties: [ - # { name: 'item', type: 'object', properties: [ - # { name: 'data', type: 'object', properties: [ - # { name: 'type' }, - # { name: 'id' } - # ] }, - # { name: 'links', type: 'object', properties: [ - # { name: 'related', type: 'object', properties: [ - # { name: 'href' } - # ] } - # ] } - # ] }, - # { name: 'refs', type: 'object', properties: [ - # { name: 'links', type: 'object', properties: [ - # { name: 'self', type: 'object', properties: [ - # { name: 'href' } - # ] }, - # { name: 'related', type: 'object', properties: [ - # { name: 'href' } - # ] } - # ] } - # ] }, - # { name: 'storage', type: 'object', properties: [ - # { name: 'meta', type: 'object', properties: [ - # { name: 'link', type: 'object', properties: [ - # { name: 'href' } - # ] } - # ] }, - # { name: 'data', type: 'object', properties: [ - # { name: 'type' }, - # { name: 'id' } - # ] } - # ] }, - # { name: 'links', type: 'object', properties: [ - # { name: 'self', type: 'object', properties: [ - # { name: 'href' } - # ] } - # ] } - # ] } - # ] }, { name: 'data', type: 'object', properties: [ { name: 'id', label: 'Item ID' }, - # { name: 'type' }, - # { name: 'relationships', type: 'object', properties: [ - # { name: 'refs', type: 'object', properties: [ - # { name: 'links', type: 'object', properties: [ - # { name: 'self', type: 'object', properties: [ - # { name: 'href' } - # ] }, - # { name: 'related', type: 'object', properties: [ - # { name: 'href' } - # ] } - # ] } - # ] }, - # { name: 'tip', type: 'object', properties: [ - # { name: 'data', type: 'object', properties: [ - # { name: 'type' }, - # { name: 'id' } - # ] }, - # { name: 'links', type: 'object', properties: [ - # { name: 'related', type: 'object', properties: [ - # { name: 'href' } - # ] } - # ] } - # ] }, - # { name: 'links', type: 'object', properties: [ - # { name: 'self', type: 'object', properties: [ - # { name: 'href' } - # ] } - # ] }, - # { name: 'parent', type: 'object', properties: [ - # { name: 'data', properties: [ - # { name: 'type' }, - # { name: 'id' } - # ] }, - # { name: 'links', type: 'object', properties: [ - # { name: 'related', type: 'object', properties: [ - # { name: 'href' } - # ] } - # ] } - # ] }, - # { name: 'versions', type: 'object', properties: [ - # { name: 'links', type: 'object', properties: [ - # { name: 'related', type: 'object', properties: [ - # { name: 'href' } - # ] } - # ] } - # ] } - # ] }, - { name: 'attributes', type: 'object', properties: [ - # { name: 'type' }, - # { name: 'name' }, { name: 'displayName', label: 'Name' }, { name: 'createTime', label: 'Created at', type: 'date_time' }, { name: 'createUserId', label: 'Created by (User ID)' }, @@ -816,20 +645,10 @@ label: 'Last modified by (User ID)' }, { name: 'lastModifiedUserName', label: 'Last modified by (User Name)' }, - # { name: 'lastModifiedTimeRollup', type: 'date_time' }, - # { name: 'objectCount', type: 'integer' }, { name: 'hidden', type: 'boolean', control_type: 'checkbox' }, { name: 'reserved', type: 'boolean', control_type: 'checkbox' }, - # { name: 'pathInProject', label: 'Path' }, { name: 'extension', type: 'object', properties: [ - # { name: 'type' }, - { name: 'version' } # , - # { name: 'data', type: 'object', properties: [ - # { name: 'sourceFileName', hint: 'Applicable for file' }, - # { name: 'visibleTypes', hint: 'Array of strings' }, - # { name: 'actions', hint: 'Array of strings' }, - # { name: 'allowedTypes', hint: 'Array of strings' } - # ] } + { name: 'version' } ] } ] } ] } From 553080762fbecd9ef75e156133ac614a4380a99b Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sun, 8 Sep 2019 23:12:49 -0400 Subject: [PATCH 44/62] update triggers to output input fields --- custom_connectors/oauth2/bim_360.rb | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index be9417b9..a387931c 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2134,7 +2134,7 @@ project_id = closure&.[]('project_id') || input['project_id'] container_id = closure&.[]('container_id') || get("/project/v1/hubs/#{input['hub_id']}" \ - "/projects/#{project_id}")&. + "/projects/#{input['project_id']}")&. dig('data', 'relationships', 'issues', 'data', 'id') updated_after = closure&.[]('updated_after') || (input['since'] || 1.hour.ago).to_time.utc.iso8601 @@ -2169,8 +2169,11 @@ end issues = response['data']&. map do |o| - o.merge({ project_id: project_id, hub_id: hub_id, - container_id: container_id }) + o.merge({ + project_id: input['project_id'], + hub_id: input['hub_id'], + container_id: container_id + }) end { events: issues || [], @@ -2286,14 +2289,14 @@ 'filter[type]=items&filter[lastModifiedTimeRollup]-ge=' \ "#{last_modified_time}&" \ "page[limit]=#{limit}&page[skip]=#{skip}" - get("/data/v1/projects/#{project_id}/folders/" \ - "#{folder_id}/contents", query_params) + get("/data/v1/projects/#{input['project_id']}/folders/" \ + "#{input['folder_id']}/contents", query_params) end items = response['data']&. map do |o| - o.merge({ project_id: project_id, hub_id: hub_id, - folder_id: folder_id }) + o.merge({ project_id: input['project_id'], hub_id: input['hub_id'], + folder_id: input['folder_id'] }) end closure = if (next_page_url = response.dig('links', 'next')).present? { 'skip' => skip + limit, From 51664f74d4cb7d63978c302f85a41cc9bb3f2960 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Mon, 9 Sep 2019 14:20:41 -0400 Subject: [PATCH 45/62] update connector based on comments from Chandra --- custom_connectors/oauth2/bim_360.rb | 116 ++++++++++++++-------------- 1 file changed, 57 insertions(+), 59 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index a387931c..d7eac4d4 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -142,42 +142,42 @@ ]}, { name: 'rootFolder', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ - { name: 'id', label: 'Root Folder ID' } + { name: 'id', label: 'Root folder ID' } ]} ]}, { name: 'issues', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ - { name: 'id', label: 'Issues Container ID' } + { name: 'id', label: 'Issues container ID' } ]} ]}, { name: 'submittals', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ - { name: 'id', label: 'Submittals Container ID' } + { name: 'id', label: 'Submittals container ID' } ]} ]}, { name: 'rfis', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ - { name: 'id', label: 'RFIs Container ID' } + { name: 'id', label: 'RFIs container ID' } ]} ]}, { name: 'markups', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ - { name: 'id', label: 'Markups Container ID' } + { name: 'id', label: 'Markups container ID' } ]} ]}, { name: 'checklists', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ - { name: 'id', label: 'Checklists Container ID' } + { name: 'id', label: 'Checklists container ID' } ]} ]}, { name: 'cost', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ - { name: 'id', label: 'Cost Container ID' } + { name: 'id', label: 'Cost container ID' } ]} ]}, { name: 'location', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ - { name: 'id', label: 'Locations Container ID' } + { name: 'id', label: 'Locations container ID' } ]} ]} ]} @@ -454,7 +454,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -470,7 +470,7 @@ }, { name: 'project_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -555,7 +555,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -571,7 +571,7 @@ }, { name: 'container_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'issue_container_lists', pick_list_params: { hub_id: 'hub_id' }, @@ -609,12 +609,12 @@ fields: lambda do |_connection, _config_fields| [ { name: 'id', label: 'Item ID' }, - { name: 'type', label: 'Item Type' }, + { name: 'type', label: 'Item type' }, { name: 'attributes', type: 'object', properties: [ { name: 'displayName', label: 'Name' }, { name: 'createTime', label: 'Created at', type: 'date_time' }, { name: 'createUserId', label: 'Created by (User ID)' }, - { name: 'createUserName', label: 'Created by (User Name)' }, + { name: 'createUserName', label: 'Created by (User name)' }, { name: 'lastModifiedTime', label: 'Last modified at', type: 'date_time' }, { name: 'lastModifiedUserId', label: 'Last modified by (User ID)' }, @@ -638,7 +638,7 @@ { name: 'displayName', label: 'Name' }, { name: 'createTime', label: 'Created at', type: 'date_time' }, { name: 'createUserId', label: 'Created by (User ID)' }, - { name: 'createUserName', label: 'Created by (User Name)' }, + { name: 'createUserName', label: 'Created by (User name)' }, { name: 'lastModifiedTime', label: 'Last modified at', type: 'date_time' }, { name: 'lastModifiedUserId', @@ -905,7 +905,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -921,7 +921,7 @@ }, { name: 'container_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'issue_container_lists', pick_list_params: { hub_id: 'hub_id' }, @@ -985,7 +985,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1001,7 +1001,7 @@ }, { name: 'container_id', - label: 'Container Name', + label: 'Container name', control_type: 'select', pick_list: 'issue_container_lists', pick_list_params: { hub_id: 'hub_id' }, @@ -1068,7 +1068,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1084,7 +1084,7 @@ }, { name: 'container_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'issue_container_lists', pick_list_params: { hub_id: 'hub_id' }, @@ -1141,7 +1141,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1157,7 +1157,7 @@ }, { name: 'project_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -1195,7 +1195,7 @@ ' a project in BIM 360', input_fields: lambda do |object_definitions| [ - { name: 'export_link', label: 'Export Link', optional: false} + { name: 'export_link', label: 'Export link', optional: false} ] end, execute: lambda do |_connection, input| @@ -1226,7 +1226,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1242,7 +1242,7 @@ }, { name: 'project_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -1259,7 +1259,7 @@ } }, { name: 'folder_id', - label: 'Folder Name', + label: 'Folder name', control_type: 'tree', hint: 'Select folder', toggle_hint: 'Select Folder', @@ -1277,7 +1277,7 @@ } }, { name: 'item_id', - label: 'File Name', + label: 'File name', control_type: 'select', pick_list: 'folder_items', pick_list_params: { project_id: 'project_id', @@ -1313,13 +1313,13 @@ }, { name: 'includeMarkups', control_type: 'checkbox', - type: 'boolean', label: 'Include Markups', + type: 'boolean', label: 'Include markups', sticky: true, hint: 'Include markups in the export', toggle_hint: 'Select from options list', toggle_field: { name: 'includeMarkups', - label: 'Include Markups', + label: 'Include markups', type: 'string', control_type: 'text', toggle_hint: 'Use custom value', @@ -1328,13 +1328,13 @@ }, { name: 'includeHyperlinks', control_type: 'checkbox', - type: 'boolean', label: 'Include Hyperlinks', + type: 'boolean', label: 'Include hyperlinks', sticky: true, hint: 'Include hyperlinks in the export', toggle_hint: 'Select from options list', toggle_field: { name: 'includeHyperlinks', - label: 'Include Hyperlinks', + label: 'Include hyperlinks', type: 'string', control_type: 'text', toggle_hint: 'Use custom value', @@ -1368,7 +1368,7 @@ headers('content-type': 'application/json'). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end&.merge({ hub_id: hub_id }).merge({ project_id: 'b.' + project_id }).merge({ item_id: item_id }) + end&.merge({ hub_id: hub_id, project_id: 'b.' + project_id, item_id: item_id }) end, output_fields: lambda do |_object_definitions| [ @@ -1399,7 +1399,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1415,7 +1415,7 @@ }, { name: 'project_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -1481,7 +1481,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1497,7 +1497,7 @@ }, { name: 'project_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -1535,8 +1535,8 @@ control_type: 'text', sticky: true, hint: 'Enter filters for the search. A list of filters can be' \ - ' found at https://forge.autodesk.com/en/docs/data/v2/' \ - 'developers_guide/filtering.' } + ' found here.' } ] end, execute: lambda do |_connection, input| @@ -1575,7 +1575,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1591,7 +1591,7 @@ }, { name: 'project_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -1625,7 +1625,7 @@ hint: 'Use Folder ID' } }, { name: 'item_id', - label: 'File Name', + label: 'File name', control_type: 'tree', hint: 'Select folder', toggle_hint: 'Select Item', @@ -1671,7 +1671,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1687,7 +1687,7 @@ }, { name: 'project_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -1705,7 +1705,7 @@ }, { name: 'item_id', - label: 'File Name', + label: 'File name', control_type: 'select', pick_list: 'folder_items', pick_list_params: { project_id: 'project_id', @@ -1718,7 +1718,7 @@ control_type: 'text', label: 'File ID', toggle_hint: 'Use file ID', - hint: 'Use File/Item ID' + hint: 'Use file or item ID' } } ], @@ -1736,9 +1736,7 @@ project_id = input['project_id'].split('.').last get("/bim360/docs/v1/projects/#{project_id}/versions/" \ "#{version_url}/exports/#{input['export_id']}"). - merge({ hub_id: input['hub_id'] }). - merge({ project_id: input['project_id'] }). - merge({ item_id: input['item_id'] }) + merge({ hub_id: input['hub_id'], project_id: input['project_id'], item_id: input['item_id'] }) end, output_fields: lambda do |object_definitions| [ @@ -1758,7 +1756,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1774,7 +1772,7 @@ }, { name: 'project_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -1807,7 +1805,7 @@ hint: 'Use Folder ID' } }, { name: 'item_id', - label: 'File Name', + label: 'File name', control_type: 'tree', hint: 'Select folder', toggle_hint: 'Select Folder', @@ -1858,7 +1856,7 @@ config_fields: [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1874,7 +1872,7 @@ }, { name: 'project_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -1910,7 +1908,7 @@ ], input_fields: lambda do |_object_definitions| [ - { name: 'file_name', optional: false, label: 'File Name', + { name: 'file_name', optional: false, label: 'File name', hint: 'File name should include extension of the file. e.g. ' \ 'my_file.jpg. The name of the file (1-255 characters). ' \ 'Reserved characters: <, >, :, ", /, \, |, ?, *, `, \n, \r, \t,' \ @@ -2087,7 +2085,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -2103,7 +2101,7 @@ }, { name: 'project_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, @@ -2212,7 +2210,7 @@ [ { name: 'hub_id', - label: 'Hub Name', + label: 'Hub name', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -2228,7 +2226,7 @@ }, { name: 'project_id', - label: 'Project Name', + label: 'Project name', control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, From 585a062b31148ab91a56d65e5a957ae2ef47ccb3 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Mon, 2 Mar 2020 17:17:41 -0500 Subject: [PATCH 46/62] update to latest version provided by Workato on 01.07.2020 --- custom_connectors/oauth2/bim_360.rb | 2187 ++++++++++++++++----------- 1 file changed, 1266 insertions(+), 921 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index d7eac4d4..6b559696 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -1,130 +1,106 @@ { title: 'BIM 360', + connection: { - fields: [ - { - name: 'client_id', - label: 'Client ID', - optional: false, - hint: 'To create client id, you need to register an application' \ - ' under Admin Console => Project => Oauth => Create Oauth app' - }, - { - name: 'client_secret', - label: 'Client secret', - control_type: 'password', - optional: false, - hint: 'To create client id, you need to register an application' \ - ' under Admin Console => Project => Oauth => Create Oauth app' - }, - { - name: 'account_id', - optional: false, - hint: 'The account ID of the project. This corresponds to hub ID in' \ - ' the Data Management API. To convert a hub ID into an account ID ' \ - 'you need to remove the “b.” prefix. For example, a hub ID of ' \ - 'b.c8b0c73d-3ae9 translates to an account ID of c8b0c73d-3ae9.' - } - ], authorization: { type: 'oauth2', + authorization_url: lambda do |connection| - scopes = 'user:read account:read data:write data:write data:read' \ - ' data:create account:write' - 'https://developer.api.autodesk.com/authentication/v1/authorize?' \ - 'response_type=' \ - "code&client_id=#{connection['client_id']}&" \ - "scope=#{scopes}" + 'https://developer.api.autodesk.com/authentication/v1/authorize?response_type=' \ + "code&scope=user:read account:read data:write data:write data:read data:create account:write" end, acquire: lambda do |connection, auth_code, redirect_uri| - response = post('https://developer.api.autodesk.com/authentication/' \ - 'v1/gettoken'). - payload(client_id: connection['client_id'], - client_secret: connection['client_secret'], - grant_type: 'authorization_code', - code: auth_code, - redirect_uri: redirect_uri). - request_format_www_form_urlencoded - [response, nil, nil] + post('https://developer.api.autodesk.com/authentication/v1/gettoken'). + payload(client_id: "#{'client_id'}", + client_secret: "#{'client_secret'}", + grant_type: 'authorization_code', + code: auth_code, + redirect_uri: redirect_uri).request_format_www_form_urlencoded end, + refresh_on: [401, 403], + refresh: lambda do |connection, refresh_token| - scopes = 'user:read account:read data:read data:write account:write' - post('https://developer.api.autodesk.com/authentication/v1/' \ - 'refreshtoken'). - payload(client_id: connection['client_id'], - client_secret: connection['client_secret'], + post('https://developer.api.autodesk.com/authentication/v1/refreshtoken'). + payload(client_id: "#{'client_id'}", + client_secret: "#{'client_secret'}", grant_type: 'refresh_token', refresh_token: refresh_token, - scope: scopes). - request_format_www_form_urlencoded + scope: 'user:read account:read data:read data:write account:write').request_format_www_form_urlencoded end, + apply: lambda do |_connection, access_token| headers(Authorization: "Bearer #{access_token}") end }, + base_uri: lambda do |_connection| 'https://developer.api.autodesk.com' end }, + test: lambda do |_connection| get('/userprofile/v1/users/@me') end, + methods: { + + format_output_response: lambda do |res, keys| + keys.each do |key| + res[key] = res[key]&.map { |value| { 'value' => value } } if res&.has_key?(key) + end + end, + format_search: lambda do |input| if input.is_a?(Hash) - input.map do |key, value| + input.each_with_object({}) do |(key, value), hash| value = call('format_search', value) if %w[limit offset].include?(key) - { "page[#{key}]" => value } + hash["page[#{key}]"] = value elsif %w[include_voided assigned_to target_urn due_date synced_after created_at created_by search ng_issue_type_id ng_issue_subtype_id status].include?(key) - { "filter[#{key}]" => value } - elsif %w[rfis].include?(key) - { "fields[#{key}]" => value } + hash["filter[#{key}]"] = value + elsif key == "rfis" + hash["fields[#{key}]"] = value else - { key => value } + hash[key] = value end - end.inject(:merge) + end else input end end, + make_schema_builder_fields_sticky: lambda do |input| input.map do |field| if field[:properties].present? - field[:properties] = call('make_schema_builder_fields_sticky', - field[:properties]) + field[:properties] = call('make_schema_builder_fields_sticky', field[:properties]) elsif field['properties'].present? - field['properties'] = call('make_schema_builder_fields_sticky', - field['properties']) + field['properties'] = call('make_schema_builder_fields_sticky', field['properties']) end field[:sticky] = true field end end, + sample_data_export_job: lambda do { 'id': '433d07ec-32a2-44eb-a5eb-b41090bfe932', 'status': 'completed', 'data': { - 'versionUrn': 'dXJuOmFkc2sud2lwcWE6ZnMuZmlsZTp2Zi5wZjNm' \ - 'clUwZ1RaYU9vdEtYZzJoMUZ3P3ZlcnNpb249MQ', - 'resourceId': "urn:adsk.viewing:fs.file:dXJuOmFkc2sud2lwcWE6Zn' \ - 'MuZmlsZTp2Zi5wZjNmclUwZ1RaYU9vdEtYZzJoMUZ3P3ZlcnNpb249MQ/output' \ + 'versionUrn': 'dXJuOmFkc2sud2lwcWE6ZnMuZmlsZTp2Zi5wZjNmclUwZ1RaYU9vdEtYZzJoMUZ3P3ZlcnNpb249MQ', + 'resourceId': "urn:adsk.viewing:fs.file:dXJuOmFkc2sud2lwcWE6ZnMuZmlsZTp2Zi5wZjNmclUwZ1RaYU9vdEtYZzJoMUZ3P3ZlcnNpb249MQ/output' \ '/qXP_ZA5_3EqJoq5zqvnLHA/h8YAl4KMcEe9-L5SaEXY6A.pdf", - 'link': "https://developer.api.autodesk.com/modelderivative/v2/' \ - 'designdata/dXJuOmFkc2sud2lwcWE6ZnMuZmlsZTp2Zi5wZjNmclUwZ1RaYU9v' \ - 'dEtYZzJoMUZ3P3ZlcnNpb249MQ/manifest/urn%3Aadsk.viewing%3Afs.file' \ - '%3AdXJuOmFkc2sud2lwcWE6ZnMuZmlsZTp2Zi5wZjNmclUwZ1RaYU9vdEtYZzJo' \ - 'MUZ3P3ZlcnNpb249MQ%2Foutput%2FqXP_ZA5_3EqJoq5zqvnLHA%2Fh8YAl4KM' \ - 'cEe9-L5SaEXY6A.pdf" + 'link': "https://developer.api.autodesk.com/modelderivative/v2/designdata/dXJuOmFkc2sud2lwcWE6ZnMuZmlsZTp2Zi5wZjNmclUwZ1RaYU9v' \ + 'dEtYZzJoMUZ3P3ZlcnNpb249MQ/manifest/urn%3Aadsk.viewing%3Afs.file%3AdXJuOmFkc2sud2lwcWE6ZnMuZmlsZTp2Zi5wZjNmclUwZ1RaYU9vdEtYZzJo' \ + 'MUZ3P3ZlcnNpb249MQ%2Foutput%2FqXP_ZA5_3EqJoq5zqvnLHA%2Fh8YAl4KMcEe9-L5SaEXY6A.pdf" } } end }, + object_definitions: { project: { fields: lambda do |_connection, _config_fields| @@ -132,89 +108,168 @@ { name: 'id', label: 'Project ID' }, { name: 'type' }, { name: 'attributes', type: 'object', properties: [ - { name: 'name' } - ]}, + { name: 'name' }, + { name: 'scopes', type: 'array', of: 'object', properties:[ + { name: "value" } + ] }, + { name: 'extension', type: 'object', properties: [ + { name: 'type' }, + { name: 'version' }, + { name: 'schema', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'links', type: 'object', properties:[ + { name: 'self', type: 'object', properties:[ + { name: 'href' } + ] } + ] }, { name: 'relationships', type: 'object', properties: [ { name: 'hub', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ { name: 'id', label: 'Hub ID' } - ]} - ]}, + ] }, + { name: 'links', type: 'object', properties:[ + { name: 'self', type: 'object', properties:[ + { name: 'href' } + ] } + ] } + ] }, { name: 'rootFolder', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ - { name: 'id', label: 'Root folder ID' } - ]} - ]}, + { name: 'id', label: 'Root folder ID' }, + { name: 'type' } + ] }, + { name: 'meta', type: 'object', properties: [ + { name: 'link', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'topFolders', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, { name: 'issues', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ + { name: 'type' }, { name: 'id', label: 'Issues container ID' } - ]} - ]}, + ] }, + { name: 'meta', type: 'object', properties: [ + { name: 'link', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, { name: 'submittals', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ + { name: 'type' }, { name: 'id', label: 'Submittals container ID' } - ]} - ]}, + ] }, + { name: 'meta', type: 'object', properties: [ + { name: 'link', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, { name: 'rfis', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ + { name: 'type' }, { name: 'id', label: 'RFIs container ID' } - ]} - ]}, + ] }, + { name: 'meta', type: 'object', properties: [ + { name: 'link', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, { name: 'markups', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ + { name: 'type' }, { name: 'id', label: 'Markups container ID' } - ]} - ]}, + ] }, + { name: 'meta', type: 'object', properties: [ + { name: 'link', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, { name: 'checklists', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ + { name: 'type' }, { name: 'id', label: 'Checklists container ID' } - ]} - ]}, + ] }, + { name: 'meta', type: 'object', properties: [ + { name: 'link', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, { name: 'cost', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ + { name: 'type' }, { name: 'id', label: 'Cost container ID' } - ]} - ]}, + ] }, + { name: 'meta', type: 'object', properties: [ + { name: 'link', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, { name: 'location', type: 'object', properties: [ { name: 'data', type: 'object', properties: [ + { name: 'type' }, { name: 'id', label: 'Locations container ID' } - ]} - ]} - ]} + ] } + ] }, + { name: 'meta', type: 'object', properties: [ + { name: 'link', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] } ] end }, + issue: { fields: lambda do |_connection, _config_fields| [ { name: 'id', label: 'Issue ID' }, + { name: 'type' }, + { name: 'links', type: 'object', properties:[ + { name: 'self' } + ] }, { name: 'attributes', type: 'object', properties: [ { name: 'created_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'created, in the following format: YYYY-MM-DDThh:mm:ss.sz', + hint: 'The timestamp of the date and time the issue was created, in the following format: YYYY-MM-DDThh:mm:ss.sz', render_input: 'render_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'synced_at', type: 'date_time', - hint: 'The date and time the issue was synced with BIM 360, ' \ - 'in the following format: YYYY-MM-DDThh:mm:ss.sz', + hint: 'The date and time the issue was synced with BIM 360, in the following format: YYYY-MM-DDThh:mm:ss.sz', render_input: 'render_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'updated_at', type: 'date_time', - hint: 'The last time the issue’s attributes were updated, in '\ - 'the following format: YYYY-MM-DDThh:mm:ss.sz', + hint: 'The last time the issue’s attributes were updated, in the following format: YYYY-MM-DDThh:mm:ss.sz', render_input: 'render_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, - { name: 'close_version', + { name: 'close_version', type: :integer, control_type: :integer, hint: 'The version of the issue when it was closed.' }, { name: 'closed_at', type: 'date_time', - hint: 'The timestamp of the data and time the issue was ' \ - 'closed, in the following format: YYYY-MM-DDThh:mm:ss.sz', + hint: 'The timestamp of the data and time the issue was closed, in the following format: YYYY-MM-DDThh:mm:ss.sz', render_input: 'render_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'closed_by', hint: 'The Autodesk ID of the user who closed the issue.' }, { name: 'created_by', hint: 'The Autodesk ID of the user who created the issue.' }, + { name: 'opened_at' }, + { name: 'opened_by' }, + { name: 'updated_by' }, { name: 'starting_version', type: 'integer', hint: 'The first version of the issue' }, { name: 'title', label: 'Issue title' }, @@ -222,12 +277,16 @@ hint: 'The description of the purpose of the issue.' }, { name: 'location_description', hint: 'The location of the issue.' }, + { name: 'markup_metadata' }, + { name: 'tags' }, + { name: 'resource_urns' }, { name: 'target_urn', - hint: 'The item ID of the document associated with the ' \ - 'pushpin issue.' }, + hint: 'The item ID of the document associated with the pushpin issue.' }, + { name: 'target_urn_page' }, + { name: 'collection_urn' }, + { name: 'snapshot_urn' }, { name: 'due_date', type: 'date_time', - hint: 'The timestamp of the issue’s specified due date,' \ - ' in the following format: YYYY-MM-DDThh:mm:ss.sz', + hint: 'The timestamp of the issue’s specified due date, in the following format: YYYY-MM-DDThh:mm:ss.sz', render_input: 'render_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'identifier', type: 'integer', @@ -237,128 +296,110 @@ toggle_hint: 'Select status', toggle_field: { name: 'status', label: 'Status', type: 'string', - control_type: 'text', toggle_hint: 'Use custom value', - hint: 'Allowed values are :open, work_complete, - ready_to_inspect, not_approved, close in_dispute, void.' + control_type: 'text', toggle_hint: 'Enter status value', + hint: 'Allowed values are :open, work_complete, ready_to_inspect, not_approved, close in_dispute, void.' } }, { name: 'assigned_to', hint: 'The Autodesk ID of the user' }, - { name: 'assigned_to_type', hint: 'The type of subject this ' \ - 'issue is assigned to. Possible values: user, company, role' }, + { name: 'assigned_to_type', + hint: 'The type of subject this issue is assigned to. Possible values: user, company, role' }, { name: 'answer' }, { name: 'answered_at', type: 'date_time', - hint: 'The date and time the issue was answered, in the ' \ - 'following format: YYYY-MM-DDThh:mm:ss.sz.', + hint: 'The date and time the issue was answered, in the following format: YYYY-MM-DDThh:mm:ss.sz.', render_input: 'render_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'answered_by', hint: 'The user who suggested an answer for the issue.' }, - { name: 'pushpin_attributes', - hint: 'The type and location of the pushpin' }, + { name: 'pushpin_attributes' }, { name: 'owner', hint: 'The Autodesk ID of the user who owns this issue.' }, + { name: 'issue_type_id' }, + { name: 'issue_type' }, + { name: 'issue_sub_type' }, { name: 'root_cause_id' }, { name: 'root_cause' }, - { name: 'quality_urns', type: 'object' }, - { name: 'permitted_statuses', type: 'array', of: 'string', + { name: 'quality_urns' }, + { name: 'permitted_statuses', type: 'array', of: 'object', properties: [ + { name: "value" }], hint: 'A list of statuses accessible to the current user.' }, - { name: 'permitted_attributes', type: 'array', of: 'string', + { name: 'permitted_attributes', type: 'array', of: 'object', properties: [ + { name: "value" }], hint: 'A list of attributes accessible to the current user.' }, { name: 'comment_count', type: 'integer', hint: 'The number of comments added to this issue.' }, - { name: 'attachment_count', + { name: 'attachment_count', type: 'integer', control_type: 'integer', hint: 'The number of attachments added to this issue.' }, - { name: 'permitted_actions', - hint: 'The actions that are permitted for the issue in' \ - ' this state.' }, + { name: 'permitted_actions', type: 'array', of: 'object', properties: [ + { name: "value" }], + hint: 'The actions that are permitted for the issue in this state.' }, { name: 'lbs_location', hint: 'The ID of the location that relates to the issue.' }, { name: 'sheet_metadata' }, { name: 'ng_issue_type_id', label: 'Issue type ID', hint: 'The ID of the issue type.' }, { name: 'ng_issue_subtype_id', label: 'Issue subtype ID', - hint: 'The ID of the issue subtype' } + hint: 'The ID of the issue subtype' }, + { name: 'issue_template_id' }, + { name: 'trades' }, + { name: 'comments_attributes' }, + { name: 'attachments_attributes' } ] }, - # To Do - { name: 'custom_attributes', type: 'array', of: 'object' }, - { name: 'trades', type: 'array', of: 'object' }, - { name: 'comments_attributes', type: 'array', of: 'object', - properties: [ - { name: 'id', label: 'Comment ID' }, - { name: 'type' }, - { name: 'attributes', type: 'object', properties: [ - { name: 'created_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'created, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'synced_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'synced, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'updated_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'updated, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'issue_id' }, - { name: 'rfi_id' }, - { name: 'body' }, - { name: 'created_by', - hint: 'The ID of the user who created the attachment.' } + { name: 'relationships', type: 'object', properties:[ + { name: 'container', type: 'object', properties:[ + { name: 'links', type: 'object', properties:[ + { name: 'self' }, + { name: 'related' } ] } ] }, - { name: 'attachments_attributes', type: 'array', of: 'object', - properties: [ - { name: 'id', label: 'Attachment ID' }, - { name: 'type' }, - { name: 'attributes', type: 'object', properties: [ - { name: 'created_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'created, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'created_by' }, - { name: 'synced_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'synced, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'updated_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'updated, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'attachment_type' }, - { name: 'deleted_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'deleted, in the following format: ' \ - 'YYYY-MM-DDThh:mm:ss.sz', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'deleted_by', hint: 'The ID of the user who deleted' \ - ' the attachment. This is only relevant for deleted' \ - ' attachments.' }, - { name: 'rfi_id' }, - { name: 'name' }, - { name: 'resource_urns', type: 'array', of: 'string' }, - { name: 'url' }, - { name: 'urn' }, - { name: 'urn_page' }, - { name: 'urn_type' }, - { name: 'urn_version' }, - { name: 'permitted_actions' } + { name: 'attachments', type: 'object', properties:[ + { name: 'links', type: 'object', properties:[ + { name: 'self' }, + { name: 'related' } + ] } + ] }, + { name: 'activity_batches', type: 'object', properties:[ + { name: 'links', type: 'object', properties:[ + { name: 'self' }, + { name: 'related' } + ] } + ] }, + { name: 'comments', type: 'object', properties:[ + { name: 'links', type: 'object', properties:[ + { name: 'self' }, + { name: 'related' } + ] } + ] }, + { name: 'root_cause_obj', label: "Root cause object", type: 'object', properties:[ + { name: 'links', type: 'object', properties:[ + { name: 'self' }, + { name: 'related' } + ] } + ] }, + { name: 'changesets', type: 'object', properties:[ + { name: 'links', type: 'object', properties:[ + { name: 'self' }, + { name: 'related' } + ] } + ] }, + { name: 'issue_type_obj', label: "Issue type object", type: 'object', properties:[ + { name: 'links', type: 'object', properties:[ + { name: 'self' }, + { name: 'related' } ] } ] } + ] }, + # To Do + { name: 'custom_attributes', type: 'array', of: 'object', properties: [ + { name: 'value' } + ] }, + { name: 'trades', type: 'array', of: 'object', properties: [ + { name: 'value' } + ] }, + { name: 'comments_attributes' }, + { name: 'attachments_attributes' } ] end }, + create_issue: { fields: lambda do |_connection, _config_fields| [ @@ -366,45 +407,36 @@ { name: 'description', hint: 'The description of the purpose of the issue.' }, { name: 'status', control_type: 'select', - pick_list: %w[draft open]. - map { |option| [option.labelize, option] }, + pick_list: %w[draft open].map { |option| [option.labelize, option] }, toggle_hint: 'Select status', toggle_field: { name: 'status', label: 'Status', type: 'string', - control_type: 'text', toggle_hint: 'Use custom value', - hint: 'The status of the issue. Possible values:draft, ' \ - 'open. The default is draft' + control_type: 'text', toggle_hint: 'Enter status value', + hint: 'The status of the issue. Possible values:draft, open. The default is draft' } }, { name: 'starting_version', type: 'integer', hint: 'The first version of the issue' }, { name: 'due_date', type: 'date_time', - hint: 'The timestamp of the issue’s specified due date,' \ - ' in the following format: YYYY-MM-DDThh:mm:ss.sz', + hint: 'The timestamp of the date and time the issue created.', render_input: 'render_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'location_description' }, { name: 'created_at', type: 'date_time', - hint: 'The timestamp of the date and time the issue was ' \ - 'created, in the following format: YYYY-MM-DDThh:mm:ss.sz', + hint: 'The timestamp of the date and time the issue created.', render_input: 'render_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'assigned_to', - hint: 'The Autodesk ID (uid) of the user you want to assign' \ - ' to this issue.' }, - { name: 'assigned_to_type', hint: 'The type of subject this ' \ - 'issue is assigned to. Possible values: user, company, role' }, + hint: 'The Autodesk ID (uid) of the user you want to assign to this issue. If you specify this attribute you need to also specify assigned_to_type.' }, + { name: 'assigned_to_type', + hint: 'The type of subject this issue is assigned to. Possible values: user. If you specify this attribute you need to also specify assigned_to.' }, { name: 'owner', hint: 'The BIM 360 ID of the user who owns this issue.' }, - { name: 'ng_issue_type_id', label: 'Issue type ID', - hint: 'The ID of the issue type.' }, - { name: 'ng_issue_subtype_id', label: 'Issue subtype ID', - hint: 'The ID of the issue subtype' }, { name: 'root_cause_id', - hint: 'The ID of the type of root cause for this issue.' }, - { name: 'quality_urns', type: 'object' } + hint: 'The ID of the type of root cause for this issue.' } ] end }, + update_issue: { fields: lambda do |_connection, _config_fields| [ @@ -419,36 +451,31 @@ toggle_hint: 'Select status', toggle_field: { name: 'status', label: 'Status', type: 'string', - control_type: 'text', toggle_hint: 'Use custom value', - hint: 'The status of the issue. Possible values:draft, ' \ - 'open. The default is draft' + control_type: 'text', toggle_hint: 'Enter status value', + hint: 'The status of the issue. Possible values:draft, open. The default is draft' } }, { name: 'due_date', type: 'date_time', - hint: 'The timestamp of the issue’s specified due date,' \ - ' in the following format: YYYY-MM-DDThh:mm:ss.sz', + hint: 'The timestamp of the date and time the issue updated.', render_input: 'render_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'location_description' }, { name: 'assigned_to', - hint: 'The Autodesk ID (uid) of the user you want to assign' \ - ' to this issue.' }, - { name: 'assigned_to_type', hint: 'The type of subject this ' \ - 'issue is assigned to. Possible values: user, company, role' }, + hint: 'The Autodesk ID (uid) of the user you want to assign to this issue. If you specify this attribute you need to also specify assigned_to_type.' }, + { name: 'assigned_to_type', + hint: 'The type of subject this issue is assigned to. Possible values: user. If you specify this attribute you need to also specify assigned_to.' }, { name: 'owner', hint: 'The BIM 360 ID of the user who owns this issue.' }, { name: 'ng_issue_type_id', label: 'Issue type ID', - hint: 'The ID of the issue type. You can only configure this' \ - ' attribute when the issue is in draft state' }, + hint: 'The ID of the issue type. You can only configure this attribute when the issue is in draft state' }, { name: 'ng_issue_subtype_id', label: 'Issue subtype ID', - hint: 'The ID of the issue subtype. You can configure this ' \ - 'attribute when the issue is in draft or open state' }, + hint: 'The ID of the issue subtype. You can configure this attribute when the issue is in draft or open state' }, { name: 'root_cause_id', hint: 'The ID of the type of root cause for this issue.' }, - { name: 'quality_urns', type: 'object' }, { name: 'close_version' } ] end }, + search_criteria: { fields: lambda do |_connection, _config_fields| [ @@ -463,9 +490,11 @@ name: 'hub_id', label: 'Hub ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter hub ID', + hint: 'To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of c8b0c73d-3ae9 translates '\ + 'to a hub ID of b.c8b0c73d-3ae9. Get account ID from admin page.' } }, { @@ -479,54 +508,41 @@ toggle_field: { name: 'project_id', label: 'Project ID', + change_on_blur: true, type: 'string', control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide project ID e.g. b.baf-0871-4aca-82e8-3dd6db' + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' } }, { name: 'target_urn', sticky: true }, - { name: 'due_date', + { name: 'due_date', type: 'date_time', sticky: true, - hint: 'Retrieves issues due by the specified due date. matchValue' \ - ' is the timestamp of the due date in the following format' \ - ' : YYYY-MM-DDThh:mm:ss.sz, or a date range in the following' \ - ' format: YYYY-MM-DDThh:mm:ss.sz...YYYY-MM-DDThh:mm:ss.sz.' }, + hint: 'Retrieves issues due by the specified due date.' }, { name: 'synced_after', type: 'date_time', sticky: true, hint: 'Retrieves issues updated after the specified date' }, - { name: 'created_at', + { name: 'created_at', type: 'date_time', sticky: true, - hint: 'Retrieves issues created after the specified due date.' \ - ' matchValue' \ - ' is the timestamp of the due date in the following format' \ - ' : YYYY-MM-DDThh:mm:ss.sz, or a date range in the following' \ - ' format: YYYY-MM-DDThh:mm:ss.sz...YYYY-MM-DDThh:mm:ss.sz.' }, + hint: 'Retrieves issues created after the specified date.' }, { name: 'created_by', sticky: true, - hint: 'Retrieves issues created by the user.' \ - ' matchValue is the unique identifier of the user who ' \ - 'created the issue.' }, - { name: 'ng_issue_type_id', + hint: 'Retrieves issues created by the user. matchValue is the unique identifier of the user who created the issue.' }, + { name: 'ng_issue_type_id', label: 'Issue type ID', sticky: true, hint: 'Retrieves issues associated with the specified issue type' }, - { name: 'ng_issue_subtype_id', + { name: 'ng_issue_subtype_id', label: 'Issue subtype ID', sticky: true, - hint: 'Retrieves issues associated with the specified ' \ - 'issue subtype.' }, + hint: 'Retrieves issues associated with the specified issue subtype.' }, { name: 'limit', type: 'integer', sticky: true, - hint: 'Number of issues to return in the response.' \ - ' Acceptable values: 1-100. Default value: 10' }, + hint: 'Number of issues to return in the response. Acceptable values: 1-100. Default value: 10' }, { name: 'offset', sticky: true, - hint: 'The page number that you want to begin' \ - ' issue results from.' }, + hint: 'The page number that you want to begin issue results from.' }, { name: 'sort', sticky: true, - hint: 'Sort the issues by status, created_at,' \ - ' and updated_a. To sort in descending order add a ' \ - '- before the sort criteria' }, + hint: 'Sort the issues by status, created_at, and updated_a. To sort in descending order add a - before the sort criteria' }, { name: 'include', sticky: true, @@ -540,16 +556,17 @@ name: 'include', label: 'Include additinal data', type: :string, + change_on_blur: true, control_type: 'text', optional: true, hint: 'Multiple values separated by comma.', - toggle_hint: 'Comma separated list of values. Allowed values ' \ - 'are: attachments, comments, container' + toggle_hint: 'Comma separated list of values. Allowed values are: attachments, comments, container.' } } ] end }, + hub_container_ids: { fields: lambda do |_connection, _config_fields| [ @@ -565,8 +582,9 @@ label: 'Hub ID', type: 'string', control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + change_on_blur: true, + toggle_hint: 'Enter hub ID', + hint: 'Provide hub id for example, b.baf-0871-4aca-82e8-3dd6db00.' } }, { @@ -581,30 +599,33 @@ name: 'container_id', label: 'Container ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter container ID', + hint: 'Provide container id e.g. b.baf-0871-4aca-82e8-3dd6db00.' } }, { name: 'folder_id', label: 'Folder', control_type: 'tree', hint: 'Select folder', - toggle_hint: 'Select Folder', + toggle_hint: 'Select folder', tree_options: { selectable_folder: true }, pick_list: :folders, optional: false, toggle_field: { name: 'folder_id', type: 'string', + change_on_blur: true, control_type: 'text', label: 'Folder ID', - toggle_hint: 'Use Folder ID', - hint: 'Use Folder ID' + toggle_hint: 'Enter folder ID', + hint: 'Get ID from folder page.' } } ] end }, + folder_file: { fields: lambda do |_connection, _config_fields| [ @@ -620,19 +641,101 @@ { name: 'lastModifiedUserId', label: 'Last modified by (User ID)' }, { name: 'lastModifiedUserName', label: 'Last modified by (User Name)' }, + { name: 'lastModifiedTimeRollup', type: 'date_time' }, + { name: 'objectCount', type: 'integer' }, { name: 'hidden', type: 'boolean', control_type: 'checkbox' }, { name: 'reserved', type: 'boolean', control_type: 'checkbox' }, { name: 'extension', type: 'object', properties: [ - { name: 'version' } + { name: 'version' }, + { name: 'type' }, + { name: 'schema', type: 'object', properties:[ + { name: 'href' } + ] }, + { name: 'data', type: 'object', properties: [ + { name: 'sourceFileName' }, + { name: 'visibleTypes', type: 'array', of: 'object', properties: [{ name: "value" }] }, + { name: 'actions', type: 'array', of: 'object', properties: [{ name: "value" }] }, + { name: 'allowedTypes', type: 'array', of: 'object', properties: [{ name: "value" }] } + ] } + ] } + ] }, + { name: 'links', type: 'object', properties:[ + { name: 'self', type: 'object', properties:[ + { name: 'href' } + ] } + ] }, + { name: 'relationships', type: 'object', properties:[ + { name: 'tip', type: 'object', properties: [ + { name: 'data', type: 'object', properties:[ + { name: 'type' }, + { name: 'id' } + ] }, + { name: 'links', type: 'object', properties:[ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'versions', type: 'object', properties:[ + { name: 'links', type: 'object', properties:[ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'parent', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'type' }, + { name: 'id' } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'refs', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] }, + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'contents', type: 'object', properties:[ + { name: 'links', type: 'object', properties: [ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ]} + ] } ] } ] } ] end }, + item: { fields: lambda do |_connection, _config_fields| [ + { name: 'jsonapi', type: 'object', properties: [ + { name: 'version' } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] } + ] }, { name: 'data', type: 'object', properties: [ + { name: 'type' }, { name: 'id', label: 'Item ID' }, { name: 'attributes', type: 'object', properties: [ { name: 'displayName', label: 'Name' }, @@ -648,14 +751,181 @@ { name: 'hidden', type: 'boolean', control_type: 'checkbox' }, { name: 'reserved', type: 'boolean', control_type: 'checkbox' }, { name: 'extension', type: 'object', properties: [ - { name: 'version' } + { name: 'version' }, + { name: 'type' }, + { name: 'schema', type: 'object', properties: [ + { name: 'href' } + ] }, + { name: 'data', type: 'object', properties: [ + { name: 'sourceFileName' } + ] } + ] } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] } + ] }, + { name: 'relationships', type: 'object', properties: [ + { name: 'tip', type: 'object', properties: [ + { name: 'data', type: 'object', properties:[ + { name: 'type' }, + { name: 'id' } + ] }, + { name: 'links', type: 'object', properties:[ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'versions', type: 'object', properties:[ + { name: 'links', type: 'object', properties:[ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'parent', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'type' }, + { name: 'id' } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'refs', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] }, + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] } + ] } + ] }, + { name: 'included', type: 'array', of: 'object', properties: [ + { name: 'type' }, + { name: 'id' }, + { name: 'attributes', type: 'object', properties: [ + { name: 'name' }, + { name: 'displayName' }, + { name: 'createTime', type: 'date_time' }, + { name: 'createUserId' }, + { name: 'createUserName' }, + { name: 'lastModifiedTime', type: 'date_time' }, + { name: 'lastModifiedUserId' }, + { name: 'lastModifiedUserName' }, + { name: 'versionNumber', type: 'integer' }, + { name: 'storageSize', type: 'integer' }, + { name: 'fileType' }, + { name: 'extension', type: 'object', properties: [ + { name: 'type' }, + { name: 'version' }, + { name: 'schema', type: 'object', properties: [ + { name: 'href' } + ] }, + { name: 'data', type: 'object', properties: [ + { name: 'processState' }, + { name: 'extractionState' }, + { name: 'splittingState' }, + { name: 'reviewState' }, + { name: 'revisionDisplayLabel' }, + { name: 'sourceFileName' } + ] } + ] } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] } + ] }, + { name: 'relationships', type: 'object', properties: [ + { name: 'item', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'type' }, + { name: 'id' } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'links', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'refs', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'self', type: 'object', properties: [ + { name: 'href' } + ] }, + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'downloadFormats', type: 'object', properties: [ + { name: 'links', type: 'object', properties: [ + { name: 'related', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'derivatives', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'type' }, + { name: 'id' } + ] }, + { name: 'meta', type: 'object', properties: [ + { name: 'link', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'thumbnails', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'type' }, + { name: 'id' } + ] }, + { name: 'meta', type: 'object', properties: [ + { name: 'link', type: 'object', properties: [ + { name: 'href' } + ] } + ] } + ] }, + { name: 'storage', type: 'object', properties: [ + { name: 'data', type: 'object', properties: [ + { name: 'type' }, + { name: 'id' } + ] }, + { name: 'meta', type: 'object', properties: [ + { name: 'link', type: 'object', properties: [ + { name: 'href' } + ] } + ] } ] } ] } ] } - ] end }, + version: { fields: lambda do |_connection, _config_fields| [ @@ -689,6 +959,7 @@ ] end }, + export_status: { fields: lambda do |_connection, _config_fields| [ @@ -702,6 +973,7 @@ ] end }, + custom_action_input: { fields: lambda do |_connection, config_fields| input_schema = parse_json(config_fields.dig('input', 'schema') || '[]') @@ -710,9 +982,7 @@ { name: 'path', optional: false, - hint: 'Base URI is https://developer.api.autodesk.com - ' \ - 'path will be appended to this URI. ' \ - 'Use absolute URI to override this base URI.' + hint: 'Base URI is https://developer.api.autodesk.com - path will be appended to this URI. Use absolute URI to override this base URI.' }, ( if %w[get delete].include?(config_fields['verb']) @@ -734,8 +1004,7 @@ { name: 'data', type: 'object', - properties: call('make_schema_builder_fields_sticky', - input_schema) + properties: call('make_schema_builder_fields_sticky', input_schema) } end ) @@ -781,21 +1050,24 @@ ] end }, + custom_action_output: { fields: lambda do |_connection, config_fields| parse_json(config_fields['output'] || '[]') end } }, + actions: { custom_action: { - description: "Custom action " \ - "in BIM 360", + description: "Custom action in BIM 360", + help: { body: 'Build your own BIM 360 action with an HTTP request', learn_more_url: 'https://forge.autodesk.com/en/docs/bim360/v1/reference/http/', learn_more_text: 'BIM 360 API Documentation' }, + config_fields: [{ name: 'verb', label: 'Request type', @@ -804,25 +1076,24 @@ control_type: 'select', pick_list: %w[get post patch delete].map { |verb| [verb.upcase, verb] } }], + input_fields: lambda do |object_definitions| object_definitions['custom_action_input'] end, + execute: lambda do |_connection, input| - verb = input['verb'] - if %w[get post patch delete].exclude?(verb) - error("#{verb} not supported") + if %w[get post patch delete].exclude?(input['verb']) + error("#{input['verb']} not supported") end data = input.dig('input', 'data').presence || {} - case verb + case input['verb'] when 'get' - response = - get(input['path'], data). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end.compact + response = get(input['path'], data). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.compact if response.is_a?(Array) - array_name = parse_json(input['output'] || '[]'). - dig(0, 'name') || 'array' + array_name = parse_json(input['output'] || '[]').dig(0, 'name') || 'array' { array_name.to_s => response } elsif response.is_a?(Hash) response @@ -830,50 +1101,50 @@ error('API response is not a JSON') end when 'post' - post(input['path'], data). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end.compact + post(input['path'], data).after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.compact when 'patch' - patch(input['path'], data). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end.compact + patch(input['path'], data).after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.compact when 'delete' - delete(input['path'], data). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end.compact + delete(input['path'], data).after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.compact end end, + output_fields: lambda do |object_definitions| object_definitions['custom_action_output'] end }, + search_issues_in_project: { title: 'Search issues in a project', - description: 'Search issues in'\ - ' a project in BIM 360', + + description: 'Search issues in a project in BIM 360', + help: { - body: 'Retrieves information about all the BIM 360 issues in a ' \ - 'project, including details about their associated comments ' \ - 'and attachments.' + body: 'Retrieves information about all the BIM 360 issues in a project, including details about their associated comments and attachments.' }, + input_fields: lambda do |object_definitions| object_definitions['search_criteria'] end, + execute: lambda do |_connection, input| - hub_id = input.delete('hub_id') - project_id = input.delete('project_id') - filter_criteria = call('format_search', input) - container_id = get("/project/v1/hubs/#{hub_id}" \ - "/projects/#{project_id}")&. - dig('data', 'relationships', 'issues', 'data', 'id') - { issues: get("/issues/v1/containers/#{container_id}/quality-issues", - filter_criteria)['data'] }&. - merge({ hub_id: hub_id, container_id: container_id, - project_id: project_id }) + filter_criteria = call('format_search', input.except('hub_id', 'project_id')) + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}")&.dig('data', 'relationships', 'issues', 'data', 'id') || {} + issues = if container_id.present? + get("/issues/v1/containers/#{container_id}/quality-issues", filter_criteria)['data']&.each do |issue| + call(:format_output_response, issue['attributes'], %w(permitted_statuses permitted_actions permitted_attributes custom_attributes trades)) + issue + end + end + { issues: issues }&.merge({ hub_id: input['hub_id'], container_id: container_id, project_id: input['project_id'] }) end, + output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, @@ -883,24 +1154,23 @@ properties: object_definitions['issue'] } ] end, + sample_output: lambda do |_connection, input| - project_id = input['project_id'] - container_id = get("/project/v1/#{input['hub_id']}" \ - "/projects/#{project_id}")&. - dig('data', 'relationships', 'issues', 'data', 'id') - { issues: get("/issues/v1/containers/#{container_id}/" \ - 'quality-issues?page[limit]=1')&.dig('data', 0) || {} } + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}")&.dig('data', 'relationships', 'issues', 'data', 'id') || {} + { issues: get("/issues/v1/containers/#{container_id}/quality-issues?page[limit]=1")&.dig('data', 0) || {} } end }, + create_issue_in_project: { title: 'Create issue in a project', - description: 'Create issue in'\ - ' a project in BIM 360', + + description: 'Create issue in a project in BIM 360', + help: { - body: 'Adds a BIM 360 issue to a project. You can create both ' \ - 'document-related (pushpin) issues, and project-related issues.' + body: 'Adds a BIM 360 issue to a project. You can create both document-related (pushpin) issues, and project-related issues.' }, + input_fields: lambda do |object_definitions| [ { @@ -914,73 +1184,104 @@ name: 'hub_id', label: 'Hub ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' } }, { - name: 'container_id', + name: 'project_id', label: 'Project name', control_type: 'select', - pick_list: 'issue_container_lists', + pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, optional: false, toggle_hint: 'Select project', toggle_field: { - name: 'container_id', - label: 'Container ID', + name: 'project_id', + label: 'Project ID', + change_on_blur: true, type: 'string', control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide container id e.g. ' \ - 'edac0659-639a-4a87-8614-d2c521b246b0' + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { name: 'ng_issue_type_id', + label: 'Issue type', + control_type: 'select', + pick_list: 'issue_type', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, + optional: false, + toggle_hint: 'Select issue type', + toggle_field: { + name: 'ng_issue_type_id', + label: 'Issue type ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter issue type ID', + hint: 'The ID of the issue type for example, 2e310a74-90e1-484a-aa87-9e9205ec2372.' + } + }, + { name: 'ng_issue_subtype_id', + label: 'Issue subtype', + control_type: 'select', + pick_list: 'issue_sub_type', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id', ng_issue_type_id: 'ng_issue_type_id' }, + optional: false, + toggle_hint: 'Select issue subtype', + toggle_field: { + name: 'ng_issue_subtype_id', + label: 'Issue subtype ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter issue subtype ID', + hint: 'The ID of the issue subtype for example, ac0c58ec-cac0-4fea-a555-ecc97fa1bc1a.' } } - ].concat(object_definitions['create_issue']. - required('title', 'ng_issue_type_id', 'ng_issue_subtype_id')) + ].concat(object_definitions['create_issue'].required('title')) end, + execute: lambda do |_connection, input| - hub_id = input.delete('hub_id') - container_id = input.delete('container_id') - payload = { - type: 'quality_issues', - attributes: input - } - post("/issues/v1/containers/#{container_id}/quality-issues"). - payload({ data: payload }). - headers('Content-Type': 'application/vnd.api+json'). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end['data']&.merge({ container_id: container_id, hub_id: hub_id }) + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}")&.dig('data', 'relationships', 'issues', 'data', 'id') + response = if container_id.present? + post("/issues/v1/containers/#{container_id}/quality-issues"). + payload(data: { type: 'quality_issues', attributes: input.except('hub_id', 'project_id') }). + headers('Content-Type': 'application/vnd.api+json').after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end['data']&.merge({ container_id: container_id, hub_id: input['hub_id'] }) + end + call("format_output_response", response&.[]('attributes'), %w(permitted_statuses permitted_actions permitted_attributes custom_attributes trades)) + response end, + output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, { name: 'container_id' } ].concat(object_definitions['issue']) end, + sample_output: lambda do |_connection, input| - project_id = input['project_id'] - container_id = get("/project/v1/#{input['hub_id']}" \ - "/projects/#{project_id}")&. - dig('data', 'relationships', 'issues', 'data', 'id') - get("/issues/v1/containers/#{container_id}/" \ - 'quality-issues?page[limit]=1')&.dig('data', 0) || {} + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects")&.dig('data', 0, 'relationships', 'issues', 'data', 'id') || {} + get("/issues/v1/containers/#{container_id}/quality-issues?page[limit]=1")&.dig('data', 0) || {} end }, + update_issue_in_project: { - title: 'Updated issue in a project', - description: 'Update issue in'\ - ' a project in BIM 360', + title: 'Update issue in a project', + + description: 'Update issue in a project in BIM 360', + help: { - body: 'BIM 360 issues are managed either in the BIM 360 Document' \ - ' Management module or the BIM 360 Field Management module.
' \ - 'The following users can update issues:
' \ - '
    Project admins
' \ - 'Project members who are assigned either create, view and ' \ - 'create, or full control Field Management permissions.' + body: 'BIM 360 issues are managed either in the BIM 360 Document Management module or the BIM 360 Field Management module.
The following users can update issues:' \ + '
    Project admins
Project members who are assigned either create, view and create, or full control Field Management permissions.' }, + input_fields: lambda do |object_definitions| [ { @@ -994,81 +1295,114 @@ name: 'hub_id', label: 'Hub ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' } }, { - name: 'container_id', - label: 'Container name', + name: 'project_id', + label: 'Project name', control_type: 'select', - pick_list: 'issue_container_lists', + pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, optional: false, - toggle_hint: 'Select container', + toggle_hint: 'Select project', toggle_field: { - name: 'container_id', - label: 'Container ID', + name: 'project_id', + label: 'Project ID', + change_on_blur: true, type: 'string', control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide container id e.g. baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' } }, { name: 'id', label: 'Issue ID', optional: false + }, + { name: 'ng_issue_type_id', + label: 'Issue type', + control_type: 'select', + pick_list: 'issue_type', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, + optional: true, + hint: "Within BIM 360, once an Issue has been created, its Issue type cannot be updated." \ + " Only issues in draft mode can have its type updated.", + toggle_hint: 'Select issue type', + toggle_field: { + name: 'ng_issue_type_id', + label: 'Issue type ID', + type: 'string', + control_type: 'text', + change_on_blur: true, + toggle_hint: 'Enter issue type ID', + hint: "The ID of the issue type for example, 2e310a74-90e1-484a-aa87-9e9205ec2372. Within BIM 360, " \ + "once an Issue has been created, its Issue type cannot be updated." \ + " Only issues in draft mode can have its type updated." + } + }, + { name: 'ng_issue_subtype_id', + label: 'Issue subtype', + control_type: 'select', + pick_list: 'issue_sub_type', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id', ng_issue_type_id: 'ng_issue_type_id' }, + optional: false, + toggle_hint: 'Select issue subtype', + toggle_field: { + name: 'ng_issue_subtype_id', + label: 'Issue subtype ID', + type: 'string', + control_type: 'text', + change_on_blur: true, + toggle_hint: 'Enter issue subtype ID', + hint: 'The ID of the issue subtype for example, ac0c58ec-cac0-4fea-a555-ecc97fa1bc1a.' + } } - ].concat(object_definitions['update_issue'].ignored('id')) + ].concat(object_definitions['update_issue'].ignored('id', 'ng_issue_type_id', 'ng_issue_subtype_id')) end, + execute: lambda do |_connection, input| - hub_id = input.delete('hub_id') - container_id = input.delete('container_id') - id = input.delete('id') - payload = { - id: id, - type: 'quality_issues', - attributes: input - } - patch("/issues/v1/containers/#{container_id}/" \ - "quality-issues/#{id}"). - payload({ data: payload }). - headers('Content-Type': 'application/vnd.api+json'). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end['data']&.merge({ hub_id: hub_id, container_id: container_id }) + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}")&.dig('data', 'relationships', 'issues', 'data', 'id') + response = if container_id.present? + patch("/issues/v1/containers/#{container_id}/quality-issues/#{input['id']}"). + payload(data: { id: input['id'], type: 'quality_issues', attributes: input.except('hub_id', 'project_id', 'id') }). + headers('Content-Type': 'application/vnd.api+json').after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end['data']&.merge({ hub_id: input['hub_id'], container_id: container_id }) + end + call("format_output_response", response&.[]('attributes'), %w(permitted_statuses permitted_actions permitted_attributes custom_attributes trades)) + response end, + output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, { name: 'container_id' } ].concat(object_definitions['issue']) end, + sample_output: lambda do |_connection, input| - project_id = input['project_id'] - container_id = get("/project/v1/#{input['hub_id']}" \ - "/projects/#{project_id}")&. - dig('data', 'relationships', 'issues', 'data', 'id') - get("/issues/v1/containers/#{container_id}/" \ - 'quality-issues?page[limit]=1')&.dig('data', 0) || {} + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects")&.dig('data', 0, 'relationships', 'issues', 'data', 'id') || {} + get("/issues/v1/containers/#{container_id}/quality-issues?page[limit]=1")&.dig('data', 0) || {} end }, + get_issue_in_project: { - description: 'Get issue in a project in'\ - ' BIM 360', - help: { - body: 'Retrieves detailed information about a single BIM 360 issue. ' \ - 'Get issue action uses the' \ - " Get issue" \ - ' API.' - }, + title: 'Get issue in a project', + + description: 'Get issue in a project in BIM 360', + + help: 'Retrieves detailed information about a single BIM 360 issue.', + input_fields: lambda do |_object_definitions| [ { name: 'hub_id', - label: 'Hub name', + label: 'Hub', control_type: 'select', pick_list: 'hub_list', optional: false, @@ -1077,66 +1411,68 @@ name: 'hub_id', label: 'Hub ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' } }, { - name: 'container_id', - label: 'Project name', + name: 'project_id', + label: 'Project', control_type: 'select', - pick_list: 'issue_container_lists', + pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, optional: false, toggle_hint: 'Select project', toggle_field: { - name: 'container_id', - label: 'Container ID', + name: 'project_id', + label: 'Project ID', + change_on_blur: true, type: 'string', control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide container id e.g. ' \ - 'edac0659-639a-4a87-8614-d2c521b246b0' + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' } }, - { name: 'issue_id', optional: false } + { name: 'issue_id', + optional: false, + hint: 'Get ID from url of the issue page.' + } ] end, + execute: lambda do |_connection, input| - get("/issues/v1/containers/#{input['container_id']}/" \ - "quality-issues/#{input['issue_id']}"). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end['data']. - merge({ hub_id: input['hub_id'], - container_id: input['container_id'] }) + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}")&.dig('data', 'relationships', 'issues', 'data', 'id') + response = if container_id.present? + get("/issues/v1/containers/#{container_id}/quality-issues/#{input['issue_id']}").after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end['data'].merge(hub_id: input['hub_id'], container_id: container_id) + end + call("format_output_response", response&.[]('attributes'), %w(permitted_statuses permitted_actions permitted_attributes custom_attributes trades)) + response end, + output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, { name: 'container_id' } ].concat(object_definitions['issue']) end, + sample_output: lambda do |_connection, input| - project_id = input['project_id'] - container_id = get("/project/v1/#{input['hub_id']}" \ - "/projects/#{project_id}")&. - dig('data', 'relationships', 'issues', 'data', 'id') - get("/issues/v1/containers/#{container_id}/" \ - 'quality-issues?page[limit]=1')&.dig('data', 0) || {} + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects")&.dig('data', 0, 'relationships', 'issues', 'data', 'id') || {} + get("/issues/v1/containers/#{container_id}/quality-issues?page[limit]=1")&.dig('data', 0) || {} end }, + get_project_details: { - description: 'Get project details in'\ - ' BIM 360', - help: { - body: 'Returns a project for a given project_id. Note that for ' \ - 'BIM 360 Docs, a hub ID corresponds to an account ID in the BIM ' \ - '360 API. To convert an account ID into a hub ID you need to add' \ - ' a “b.” prefix. For example, an account ID of c8b0c73d-3ae9 ' \ - 'translates to a hub ID of b.c8b0c73d-3ae9.' - }, + title: 'Get project details', + + description: 'Get project details in BIM 360', + help: 'Retrieves detailed information about a project.', + input_fields: lambda do |_object_definitions| [ { @@ -1150,9 +1486,11 @@ name: 'hub_id', label: 'Hub ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' } }, { @@ -1167,61 +1505,73 @@ name: 'project_id', label: 'Project ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: - 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' } } ] end, + execute: lambda do |_connection, input| - get("/project/v1/hubs/#{input['hub_id']}/projects/" \ - "#{input['project_id']}"). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end['data'] + response = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}").after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end['data'] + call("format_output_response", response['attributes'], %w(scopes)) + response end, + output_fields: lambda do |object_definitions| object_definitions['project'] end, + sample_output: lambda do |_connection, _input| - id = get('/project/v1/hubs')&.dig('data', 0)&.[]('id') - get("/project/v1/hubs/#{id}/projects")&.dig('data', 0) || {} + id = get('/project/v1/hubs')&.dig('data', 0, 'id') + id.present? ? get("/project/v1/hubs/#{id}/projects")&.dig('data', 0) : {} end }, + download_drawing_export: { - description: 'Download drawing export in'\ - ' a project in BIM 360', - input_fields: lambda do |object_definitions| + title: 'Download drawing export in a project', + + description: 'Download drawing export in a project in BIM 360', + + input_fields: lambda do |_object_definitions| [ - { name: 'export_link', label: 'Export link', optional: false} + { name: 'export_link', label: 'Export link', optional: false } ] end, + execute: lambda do |_connection, input| - file_content = - get(input['export_link']).headers('Accept-Encoding': 'Accept-Encoding:gzip'). - response_format_raw. - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end + file_content = get(input['export_link']).headers('Accept-Encoding': 'Accept-Encoding:gzip').response_format_raw. + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end { content: file_content } end, + output_fields: lambda do |_object_definitions| [{ name: 'content' }] + end, + + sample_output: lambda do |_connection, _input| + { + "content": "" + } end }, + export_project_plan: { title: 'Export drawing in a project', - description: 'Export drawing in'\ - ' a project in BIM 360', + + description: 'Export drawing in a project in BIM 360', + help: { - body: 'Note that you can only export a page from a PDF file that ' \ - 'was uploaded to the Plans folder or to a folder nested under the ' \ - 'Plans folder. BIM 360 Document Management splits these files into ' \ - 'separate pages (sheets) when they are uploaded, and assigns a ' \ - 'separate ID to each page.' + body: 'Note that you can only export a page from a PDF file that was uploaded to the Plans folder or to a folder nested under the ' \ + 'Plans folder. BIM 360 Document Management splits these files into separate pages (sheets) when they are uploaded, and assigns a separate ID to each page.' }, + config_fields: [ { @@ -1235,9 +1585,11 @@ name: 'hub_id', label: 'Hub ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' } }, { @@ -1252,17 +1604,17 @@ name: 'project_id', label: 'Project ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: - 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' } }, { name: 'folder_id', label: 'Folder name', control_type: 'tree', hint: 'Select folder', - toggle_hint: 'Select Folder', + toggle_hint: 'Select folder', pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, tree_options: { selectable_folder: true }, pick_list: :folders_list, @@ -1270,27 +1622,28 @@ toggle_field: { name: 'folder_id', type: 'string', + change_on_blur: true, control_type: 'text', label: 'Folder ID', - toggle_hint: 'Use Folder ID', - hint: 'Use Folder ID' + toggle_hint: 'Enter folder ID', + hint: 'Get ID from url of the folder page.' } }, { name: 'item_id', label: 'File name', control_type: 'select', pick_list: 'folder_items', - pick_list_params: { project_id: 'project_id', - folder_id: 'folder_id' }, + pick_list_params: { project_id: 'project_id', folder_id: 'folder_id' }, optional: false, toggle_hint: 'Select file', toggle_field: { name: 'item_id', type: 'string', + change_on_blur: true, control_type: 'text', label: 'File ID', - toggle_hint: 'Use file ID', - hint: 'Use file/item ID' + toggle_hint: 'Enter file ID', + hint: 'Use file/item ID.' } }, { @@ -1299,16 +1652,18 @@ pick_list: 'item_versions', sticky: true, pick_list_params: { project_id: 'project_id', item_id: 'item_id' }, + hint: "Latest version will be used if no value is selected.", optional: true, toggle_hint: 'Select version', toggle_field: { name: 'version_number', label: 'Version number', type: 'string', + change_on_blur: true, control_type: 'text', optional: true, - toggle_hint: 'Use custom value', - hint: 'Use version number' + toggle_hint: 'Enter version number', + hint: 'Latest version will be used if no value is specified.' } }, { @@ -1320,9 +1675,10 @@ toggle_field: { name: 'includeMarkups', label: 'Include markups', + change_on_blur: true, type: 'string', control_type: 'text', - toggle_hint: 'Use custom value', + toggle_hint: 'Enter value to include markups', hint: 'Allowed values are true, false.' } }, @@ -1336,40 +1692,30 @@ name: 'includeHyperlinks', label: 'Include hyperlinks', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', + toggle_hint: 'Enter value to include hyperlinks', hint: 'Allowed values are true, false.' } } ], + execute: lambda do |_connection, input| # Step 1 find the version id of the file to export - hub_id = input.delete('hub_id') - input.delete('folder_id') - version_number = input['version_number'] || get('/data/v1/projects/' \ - "#{input['project_id']}/items/#{input['item_id']}/" \ - 'versions')&.dig('data', 0, 'id') - version_url = version_number.encode_url + version_number = input['version_number'] || get("/data/v1/projects/#{input['project_id']}/items/#{input['item_id']}/versions")&.dig('data', 0, 'id') + version_url = version_number.encode_url.gsub("+", "%20") # Step 2 upload the file - project_id = input.delete('project_id').gsub('b.', '') - item_id = input.delete('item_id') - # create payload with `true`/`false` booleans - input_payload = {} - input&.map do |key, value| - if value.to_s.downcase === 'true' - input_payload[key] = true - else - input_payload[key] = false - end - end - post("/bim360/docs/v1/projects/#{project_id}/versions" \ - "/#{version_url}/exports"). - payload(input_payload). - headers('content-type': 'application/json'). - after_error_response(/.*/) do |_code, body, _header, message| + # create payload with `true`/`false` booleansversion_number + input_payload = { 'version_number' => false } + input.except('hub_id', 'folder_id', 'project_id', 'item_id', 'version_number')&.map do |key, value| + input_payload[key] = value.is_true? + end + post("/bim360/docs/v1/projects/#{input['project_id'].gsub('b.', '')}/versions/#{version_url}/exports").payload(input_payload). + headers('content-type': 'application/json').after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end&.merge({ hub_id: hub_id, project_id: 'b.' + project_id, item_id: item_id }) + end&.merge({ hub_id: input['hub_id'], project_id: input['project_id'], item_id: input['item_id'] }) end, + output_fields: lambda do |_object_definitions| [ { name: 'hub_id' }, @@ -1379,6 +1725,7 @@ { name: 'status' } ] end, + sample_output: lambda do |_connection, _input| { "id": '345eb2fb-d5b0-44c9-a50a-2c792d833f3f', @@ -1386,15 +1733,17 @@ } end }, + get_folder_details: { title: 'Get folder info in a project', - description: 'Get folder info in'\ - ' a project in BIM 360', + + description: 'Get folder info in a project in BIM 360', + help: { - body: 'Returns the folder by ID for any folder within a given ' \ - 'project. All folders or sub-folders within a project are associated' \ + body: 'Returns the folder by ID for any folder within a given project. All folders or sub-folders within a project are associated' \ ' with their own unique ID, including the root folder.' }, + input_fields: lambda do |_object_definitions| [ { @@ -1409,8 +1758,10 @@ label: 'Hub ID', type: 'string', control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + change_on_blur: true, + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' } }, { @@ -1426,16 +1777,16 @@ label: 'Project ID', type: 'string', control_type: 'text', - toggle_hint: 'Use custom value', - hint: - 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + change_on_blur: true, + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' } }, { name: 'folder_id', label: 'Folder', control_type: 'tree', hint: 'Select folder', - toggle_hint: 'Select Folder', + toggle_hint: 'Select folder', pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, tree_options: { selectable_folder: true }, pick_list: :folders_list, @@ -1445,17 +1796,18 @@ type: 'string', control_type: 'text', label: 'Folder ID', - toggle_hint: 'Use Folder ID', - hint: 'Use Folder ID' + change_on_blur: true, + toggle_hint: 'Enter folder ID', + hint: 'Get ID from url of the folder page.' } } ] end, + execute: lambda do |_connection, input| - get("/data/v1/projects/#{input['project_id']}/folders" \ - "/#{input['folder_id']}")['data']&. - merge({ hub_id: input['hub_id'], project_id: input['project_id'], - folder_id: input['folder_id'] }) + get("/data/v1/projects/#{input['project_id']}/folders/#{input['folder_id']}")['data']&. + merge({ hub_id: input['hub_id'], project_id: input['project_id'], folder_id: input['folder_id'] }) end, + output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, @@ -1463,20 +1815,19 @@ { name: 'folder_id' } ].concat(object_definitions['folder_file']) end, + sample_output: lambda do |_connection, input| - get("project/v1/hubs/#{input['hub_id']}/projects/" \ - "#{input['project_id']}/topFolders?filter[type]=folders")&. - dig('data', 0) || {} + get("project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}/topFolders?filter[type]=folders")&.dig('data', 0) || {} end }, + get_folder_contents: { - description: 'Get folder contents in'\ - ' BIM 360', + description: 'Get folder contents in BIM 360', + help: { - body: 'Returns a collection of items and folders within a folder.' \ - ' Items represent word documents, fusion design files, drawings,' \ - ' spreadsheets, etc.' + body: 'Returns a collection of items and folders within a folder. Items represent word documents, fusion design files, drawings, spreadsheets, etc.' }, + input_fields: lambda do |_object_definitions| [ { @@ -1490,9 +1841,11 @@ name: 'hub_id', label: 'Hub ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' } }, { @@ -1507,10 +1860,10 @@ name: 'project_id', label: 'Project ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: - 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' } }, { name: 'folder_id', @@ -1525,10 +1878,11 @@ toggle_field: { name: 'folder_id', type: 'string', + change_on_blur: true, control_type: 'text', label: 'Folder ID', - toggle_hint: 'Use Folder ID', - hint: 'Use Folder ID' + toggle_hint: 'Enter Folder ID', + hint: 'Get ID from url of the folder page.' } }, { name: 'filters', label: 'Filters', @@ -1539,12 +1893,12 @@ 'developers_guide/filtering" target_blank">here.' } ] end, + execute: lambda do |_connection, input| - get("/data/v1/projects/#{input['project_id']}/folders" \ - "/#{input['folder_id']}/contents?#{input['filters']}")&. - merge({ hub_id: input['hub_id'], project_id: input['project_id'], - folder_id: input['folder_id'] }) + get("/data/v1/projects/#{input['project_id']}/folders/#{input['folder_id']}/contents?#{input['filters']}")&. + merge({ hub_id: input['hub_id'], project_id: input['project_id'], folder_id: input['folder_id'] }) end, + output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, @@ -1554,23 +1908,22 @@ properties: object_definitions['folder_file'] } ] end, + sample_output: lambda do |_connection, input| - folder_id = get("project/v1/hubs/#{input['hub_id']}/projects/" \ - "#{input['project_id']}/" \ - 'topFolders?filter[type]=folders')&. - dig('data', 0, 'id') - get("/data/v1/projects/#{input['project_id']}/folders" \ - "/#{folder_id}/contents") + folder_id = get("project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}/topFolders?filter[type]=folders")&.dig('data', 0, 'id') || {} + folder_id.present? ? get("/data/v1/projects/#{input['project_id']}/folders/#{folder_id}/contents") : {} end }, + get_document_in_project: { title: 'Get document in a project', - description: 'Get document in'\ - ' a project in BIM 360', + + description: 'Get document in a project in BIM 360', + help: { - body: 'Retrieves metadata for a specified item. Items represent ' \ - 'word documents, fusion design files, drawings, spreadsheets, etc.' + body: 'Retrieves metadata for a specified item. Items represent word documents, fusion design files, drawings, spreadsheets, etc.' }, + config_fields: [ { @@ -1584,9 +1937,11 @@ name: 'hub_id', label: 'Hub ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' } }, { @@ -1601,28 +1956,29 @@ name: 'project_id', label: 'Project ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: - 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' } }, { name: 'folder_id', label: 'Folder', control_type: 'tree', hint: 'Select folder', - toggle_hint: 'Select Folder', + toggle_hint: 'Select folder', pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, tree_options: { selectable_folder: true }, pick_list: :folders_list, - optional: true, + optional: false, toggle_field: { name: 'folder_id', type: 'string', control_type: 'text', label: 'Folder ID', - toggle_hint: 'Use Folder ID', - hint: 'Use Folder ID' + change_on_blur: true, + toggle_hint: 'Enter folder ID', + hint: 'Get ID from url of the folder page.' } }, { name: 'item_id', label: 'File name', @@ -1630,43 +1986,44 @@ hint: 'Select folder', toggle_hint: 'Select Item', pick_list: :folder_items, - pick_list_params: { project_id: 'project_id', - folder_id: 'folder_id' }, + pick_list_params: { project_id: 'project_id', folder_id: 'folder_id' }, optional: false, toggle_field: { name: 'item_id', type: 'string', control_type: 'text', + change_on_blur: true, label: 'File ID', - toggle_hint: 'Use file ID', - hint: 'Provide file ID' + toggle_hint: 'Enter file ID', + hint: 'Provide file ID.' } } ], + execute: lambda do |_connection, input| - get("/data/v1/projects/#{input['project_id']}/items/" \ - "#{input['item_id']}")&. - merge({ project_id: input['project_id'], hub_id: input['hub_id'] }) + get("/data/v1/projects/#{input['project_id']}/items/#{input['item_id']}")&.merge({ project_id: input['project_id'], hub_id: input['hub_id'] }) end, + output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, { name: 'project_id' } ].concat(object_definitions['item']) end, + sample_output: lambda do |_connection, input| - get("/data/v1/projects/#{input['project_id']}/items/" \ - "#{input['item_id']}") + get("/data/v1/projects/#{input['project_id']}/items/#{input['item_id']}") end }, + get_drawing_export_status: { title: 'Get drawing export status in a project', - description: 'Get drawing export status in'\ - ' a project in BIM 360', + + description: 'Get drawing export status in a project in BIM 360', + help: { - body: 'This action returns the status of a PDF export job, as well' \ - ' as data you need to download the exported file when the export is ' \ - 'complete.' + body: 'This action returns the status of a PDF export job, as well as data you need to download the exported file when the export is complete.' }, + config_fields: [ { @@ -1680,9 +2037,11 @@ name: 'hub_id', label: 'Hub ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' } }, { @@ -1697,10 +2056,30 @@ name: 'project_id', label: 'Project ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: - 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'folder_id', + label: 'Folder name', + control_type: 'tree', + hint: 'Select folder', + toggle_hint: 'Select folder', + pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, + tree_options: { selectable_folder: true }, + pick_list: :folders_list, + optional: false, + toggle_field: { + name: 'folder_id', + type: 'string', + change_on_blur: true, + control_type: 'text', + label: 'Folder ID', + toggle_hint: 'Enter folder ID', + hint: 'Get ID from url of the folder page.' } }, { @@ -1708,36 +2087,56 @@ label: 'File name', control_type: 'select', pick_list: 'folder_items', - pick_list_params: { project_id: 'project_id', - folder_id: 'folder_id' }, + pick_list_params: { project_id: 'project_id', folder_id: 'folder_id' }, optional: false, toggle_hint: 'Select file', toggle_field: { name: 'item_id', type: 'string', + change_on_blur: true, control_type: 'text', label: 'File ID', - toggle_hint: 'Use file ID', - hint: 'Use file or item ID' + toggle_hint: 'Enter file ID', + hint: 'Use file or item ID.' + } + }, + { + name: 'version_number', + control_type: 'select', + pick_list: 'item_versions', + sticky: true, + pick_list_params: { project_id: 'project_id', item_id: 'item_id' }, + hint: "Latest version will be used if no value is selected.", + optional: true, + toggle_hint: 'Select version', + toggle_field: { + name: 'version_number', + label: 'Version number', + type: 'string', + change_on_blur: true, + control_type: 'text', + optional: true, + toggle_hint: 'Enter version number', + hint: 'Latest version will be used if no value is specified.' } } ], + input_fields: lambda do |_object_definitions| [ { name: 'export_id', optional: false } ] end, + execute: lambda do |_connection, input| - version_number = input['version_urn'] || get('/data/v1/projects/' \ - "#{input['project_id']}/items/#{input['item_id']}/" \ - 'versions')&.dig('data', 0, 'id') - version_url = version_number.split('?').first.encode_url + version_number = input['version_number'] || get("/data/v1/projects/#{input['project_id']}/items/#{input['item_id']}/versions")&.dig('data', 0, 'id') + version_url = version_number.split('?').first.encode_url.gsub("+", "%20") # version_url = version_number.encode_url project_id = input['project_id'].split('.').last - get("/bim360/docs/v1/projects/#{project_id}/versions/" \ - "#{version_url}/exports/#{input['export_id']}"). - merge({ hub_id: input['hub_id'], project_id: input['project_id'], item_id: input['item_id'] }) + get("/bim360/docs/v1/projects/#{project_id}/versions/#{version_url}/exports/#{input['export_id']}"). + merge(hub_id: input['hub_id'], project_id: input['project_id'], item_id: input['item_id']) end, + output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, @@ -1745,13 +2144,19 @@ { name: 'item_id' } ].concat(object_definitions['export_status']) end, + sample_output: lambda do |_connection, _input| call('sample_data_export_job') end }, + download_document: { - description: 'Download document in'\ - ' a project in BIM 360', + title: 'Download document in a project', + + description: 'Download document in a project in BIM 360', + + help: 'Retrieve the content of a specific document in the project folder. This content can be used to upload the attachment into another application in subsequent recipe steps.', + config_fields: [ { @@ -1765,9 +2170,11 @@ name: 'hub_id', label: 'Hub ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' } }, { @@ -1782,77 +2189,85 @@ name: 'project_id', label: 'Project ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: - 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' } }, { name: 'folder_id', - label: 'Folder', + label: 'Folder name', control_type: 'tree', hint: 'Select folder', - toggle_hint: 'Select Folder', + toggle_hint: 'Select folder', pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, + optional: false, tree_options: { selectable_folder: true }, pick_list: :folders_list, toggle_field: { name: 'folder_id', type: 'string', control_type: 'text', + change_on_blur: true, label: 'Folder ID', - toggle_hint: 'Use Folder ID', - hint: 'Use Folder ID' + toggle_hint: 'Enter folder ID', + hint: 'Get ID from url of the folder page.' } }, { name: 'item_id', - label: 'File name', + label: 'File', control_type: 'tree', - hint: 'Select folder', - toggle_hint: 'Select Folder', + hint: 'Select file', + toggle_hint: 'Select file', pick_list: :folder_items, - pick_list_params: { project_id: 'project_id', - folder_id: 'folder_id' }, + pick_list_params: { project_id: 'project_id', folder_id: 'folder_id' }, optional: false, toggle_field: { name: 'item_id', type: 'string', control_type: 'text', + change_on_blur: true, label: 'File ID', - toggle_hint: 'Use file ID', - hint: 'Provide file ID' + toggle_hint: 'Enter file ID', + hint: 'Get file ID from url of the file page.' } } ], + execute: lambda do |_connection, input| # 1 find the storage location of the item - file_url = get("/data/v1/projects/#{input['project_id']}/items/" \ - "#{input['item_id']}")&. - dig('included', 0, 'relationships', 'storage', 'meta', - 'link', 'href') + file_url = get("/data/v1/projects/#{input['project_id']}/items/#{input['item_id']}")&. + dig('included', 0, 'relationships', 'storage', 'meta', 'link', 'href') if file_url.present? - file_content = - get(file_url).headers('Accept-Encoding': 'Accept-Encoding:gzip'). - response_format_raw. - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end + { content: get(file_url).headers('Accept-Encoding': 'Accept-Encoding:gzip'). + response_format_raw. + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end } else - error('Invalid URL') + error('File does not exist') end - { content: file_content } end, + output_fields: lambda do |_object_definitions| [{ name: 'content' }] + end, + + sample_output: lambda do |_connection, _input| + { + "content": "" + } end }, + upload_document_to_project: { title: 'Upload document to a project', - description: 'Upload document to a project'\ - ' in BIM 360', + + description: 'Upload document to a project in BIM 360', + help: { - body: 'Note that you cannot upload documents to the root folder in ' \ - 'BIM 360 Docs; you can only upload documents to the Project Files ' \ + body: 'Note that you cannot upload documents to the root folder in BIM 360 Docs; you can only upload documents to the Project Files ' \ 'folder or to a folder nested under the Project Files folder' }, + config_fields: [ { name: 'hub_id', @@ -1865,9 +2280,11 @@ name: 'hub_id', label: 'Hub ID', type: 'string', + change_on_blur: true, control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' } }, { @@ -1883,16 +2300,16 @@ label: 'Project ID', type: 'string', control_type: 'text', - toggle_hint: 'Use custom value', - hint: - 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' + change_on_blur: true, + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' } }, { name: 'folder_id', - label: 'Folder', + label: 'Folder name', control_type: 'tree', hint: 'Select folder', - toggle_hint: 'Select Folder', + toggle_hint: 'Select folder', pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, tree_options: { selectable_folder: true }, pick_list: :folders_list, @@ -1902,169 +2319,149 @@ type: 'string', control_type: 'text', label: 'Folder ID', - toggle_hint: 'Use Folder ID', - hint: 'Use Folder ID' + change_on_blur: true, + toggle_hint: 'Enter folder ID', + hint: 'Use folder ID.' } } ], + input_fields: lambda do |_object_definitions| [ { name: 'file_name', optional: false, label: 'File name', - hint: 'File name should include extension of the file. e.g. ' \ - 'my_file.jpg. The name of the file (1-255 characters). ' \ - 'Reserved characters: <, >, :, ", /, \, |, ?, *, `, \n, \r, \t,' \ - ' \0, \f, ¢, ™, $, ®' }, + hint: 'File name should include extension of the file. e.g. my_file.jpg. The name of the file (1-255 characters). ' \ + 'Reserved characters: <, >, :, ", /, \, |, ?, *, `, \n, \r, \t, \0, \f, ¢, ™, $, ®' }, { name: 'file_content', optional: false }, { name: 'file_extension', control_type: 'select', pick_list: 'file_types', + optional: false, toggle_hint: 'Select file extension', toggle_field: { name: 'file_extension', type: 'string', control_type: 'text', label: 'File extension', - toggle_hint: 'Use custom value', - hint: 'Only relevant for creating files - the type of file ' \ - 'extension.
. For BIM 360 Docs files, use ' \ - 'items:autodesk.bim360:File.
' \ - 'For all other services, use items:autodesk.core:File.' + toggle_hint: 'Enter file extension value', + hint: 'Only relevant for creating files - the type of file extension.
. For BIM 360 Docs files, use ' \ + 'items:autodesk.bim360:File.
For all other services, use items:autodesk.core:File.' } }, { name: 'version_type', label: 'Type of version', hint: 'Only relevant for creating files - the type of version.', control_type: 'select', pick_list: 'version_types', + optional: false, toggle_hint: 'Select version type', toggle_field: { name: 'version_type', label: 'Type of version', type: 'string', control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Only relevant for creating files - the type of version.' \ - '
For BIM 360 Docs files, use versions:autodesk.bim360:File' \ - '
For A360 composite design files, use versions:autodesk.' \ - 'a360:CompositeDesign
' \ - 'For A360 Personal, Fusion Team, or BIM 360 Team files, use' \ - ' versions:autodesk.core:File.' + toggle_hint: 'Enter version type value', + hint: 'Only relevant for creating files - the type of version.
For BIM 360 Docs files, use versions:autodesk.bim360:File' \ + '
For A360 composite design files, use versions:autodesk.a360:CompositeDesign
' \ + 'For A360 Personal, Fusion Team, or BIM 360 Team files, use versions:autodesk.core:File.' } }, { name: 'extension_type_version', - hint: 'The version of the version extension type. The current ' \ - 'version is 1.0 ' } + hint: 'The version of the version extension type. The current version is 1.0 ' } ] end, + execute: lambda do |_connection, input| # 1 create storage location - payload = { - 'jsonapi' => { 'version': '1.0' }, - 'data' => { - 'type' => 'objects', - 'attributes' => { - 'name': input['file_name'] - }, - 'relationships' => { - 'target' => { - 'data' => { - 'type' => 'folders', - 'id' => input['folder_id'] - } - } - } - } - } hub_id = input.delete('hub_id') project_id = input.delete('project_id').gsub('b:', '') - response_storage = - post('https://developer.api.autodesk.com/data/v1/' \ - "projects/#{project_id}/storage"). - headers('Content-Type': 'application/vnd.api+json', - 'Accept': 'application/vnd.api+json'). - payload(payload). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end + response_storage = post("https://developer.api.autodesk.com/data/v1/projects/#{project_id}/storage"). + headers('Content-Type' => 'application/vnd.api+json', 'Accept' => 'application/vnd.api+json'). + payload('jsonapi' => { 'version' => '1.0' }, + 'data' => { + 'type' => 'objects', + 'attributes' => { 'name' => input['file_name'] }, + 'relationships' => { + 'target' => { + 'data' => { 'type' => 'folders', 'id' => input['folder_id'] } + } + } + }). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end object_id = response_storage&.dig('data', 'id') # 2 Upload file to storage location bucket_key = object_id.split('/').first.split('object:').last object_name = object_id.split('/').last - response = put('https://developer.api.autodesk.com/oss/v2/buckets/' \ - "#{bucket_key}/objects/#{object_name}"). - request_body(input['file_content']). - headers('Content-Type': 'application/octet-stream'). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end - object_urn = response['objectId'] + response = put("https://developer.api.autodesk.com/oss/v2/buckets/#{bucket_key}/objects/#{object_name}"). + request_body(input['file_content']). + headers('Content-Type' => 'application/octet-stream'). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end # 3 create a first version of the File # folder_urn = get("/data/v1/projects/#{input['project_id']}/folders" \ # "/#{input['folder_id']}")['data'] - version_payload = { - 'jsonapi' => { 'version' => '1.0' }, - 'data' => { - # type of the resource - 'type' => 'items', - # The attributes of the data object. - 'attributes' => { - 'displayName' => input['file_name'], - # Extended information on the resource. - 'extension' => - { - # relevant for creating files - 'type' => input['file_extension'], - 'version' => '1.0' - } - }, - 'relationships' => { - # The information on the tip version of this resource. - 'tip' => { - 'data' => { - 'type' => 'versions', - 'id' => '1' - } - }, - # Information on the parent resource of this resource. - 'parent' => { - 'data' => { - 'type' => 'folders', - # The URN of the parent folder in which you want to create - # a version of a file or to copy a file to. - 'id' => input['folder_id'] - } - } - } - }, - 'included' => [ - { - 'type' => 'versions', - 'id' => '1', - 'attributes' => { - 'name' => input['file_name'], - 'extension' => { - 'type' => input['version_type'], - 'version' => input['extension_type_version'] || '1.0' - } - }, - 'relationships' => { - 'storage' => { - 'data' => { - 'type' => 'objects', - 'id' => object_urn - } - } - } - } - ] - } - # item_id = post("/data/v1/projects/#{project_id}/items"). - payload(version_payload). - headers('Content-Type': 'application/vnd.api+json', - Accept: 'application/vnd.api+json'). + payload('jsonapi' => { 'version' => '1.0' }, + 'data' => { + # type of the resource + 'type' => 'items', + # The attributes of the data object. + 'attributes' => { + 'displayName' => input['file_name'], + # Extended information on the resource. + 'extension' => + { + # relevant for creating files + 'type' => input['file_extension'], + 'version' => '1.0' + } + }, + 'relationships' => { + # The information on the tip version of this resource. + 'tip' => { + 'data' => { + 'type' => 'versions', + 'id' => '1' + } + }, + # Information on the parent resource of this resource. + 'parent' => { + 'data' => { + 'type' => 'folders', + # The URN of the parent folder in which you want to create + # a version of a file or to copy a file to. + 'id' => input['folder_id'] + } + } + } + }, + 'included' => [ + { + 'type' => 'versions', + 'id' => '1', + 'attributes' => { + 'name' => input['file_name'], + 'extension' => { + 'type' => input['version_type'], + 'version' => input['extension_type_version'] || '1.0' + } + }, + 'relationships' => { + 'storage' => { + 'data' => { + 'type' => 'objects', + 'id' => response['objectId'] + } + } + } + } + ]). + headers('Content-Type' => 'application/vnd.api+json', 'Accept' => 'application/vnd.api+json'). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end&.dig('data')&.merge({ hub_id: hub_id, project_id: project_id }) end, + output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, @@ -2073,14 +2470,17 @@ end } }, + triggers: { new_updated_issue_in_project: { title: 'New or updated issue in a project', - description: 'New or updated issue in'\ - ' a project in BIM 360', + + description: 'New or updated issue in a project in BIM 360', + help: { - body: 'Triggers when a issue in a project is created or updated.' + body: 'Triggers when an issue in a project is created or updated.' }, + input_fields: lambda do |_object_definitions| [ { @@ -2088,16 +2488,7 @@ label: 'Hub name', control_type: 'select', pick_list: 'hub_list', - optional: false, - toggle_hint: 'Select hub', - toggle_field: { - name: 'hub_id', - label: 'Hub ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' - } + optional: false }, { name: 'project_id', @@ -2105,16 +2496,7 @@ control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_id', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' - } + optional: false }, { name: 'since', @@ -2127,61 +2509,49 @@ } ] end, + poll: lambda do |_connection, input, closure| - hub_id = closure&.[]('hub_id') || input['hub_id'] - project_id = closure&.[]('project_id') || input['project_id'] - container_id = closure&.[]('container_id') || - get("/project/v1/hubs/#{input['hub_id']}" \ - "/projects/#{input['project_id']}")&. - dig('data', 'relationships', 'issues', 'data', 'id') - updated_after = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 10 - skip = closure&.[]('skip') || 0 - include = closure&.[]('include') || input['include'] - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) + closure ||= {} + updated_after = closure['updated_after'] || (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 100 + + response = if closure['next_page_url'].present? + get(closure['next_page_url']) else - get("/issues/v1/containers/#{container_id}/" \ - 'quality-issues'). - params(page: { limit: limit, - skip: skip }, + closure['container_id'] ||= get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}")&. + dig('data', 'relationships', 'issues', 'data', 'id') + get("/issues/v1/containers/#{closure['container_id']}/quality-issues"). + params(page: { limit: limit, offset: closure['offset'] || 0 }, filter: { synced_after: updated_after }, sort: 'updated_at', - included: include) + included: input['include']) end - closure = if (next_page_url = response.dig('links', 'next')).present? - { 'skip' => skip + limit, - 'container_id' => container_id, - 'project_id' => project_id, - 'hub_id' => hub_id, - 'include' => include, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'container_id' => container_id, - 'project_id' => project_id, - 'hub_id' => hub_id, - 'include' => include, - 'updated_after' => now.to_time.utc.iso8601 } - end - issues = response['data']&. - map do |o| - o.merge({ - project_id: input['project_id'], - hub_id: input['hub_id'], - container_id: container_id - }) - end + + if (next_page_url = response.dig('links', 'next')).present? + closure['next_page_url'] = next_page_url + else + closure['offset'] = 0 + closure['updated_after'] = Array.wrap(response['data']).last.dig('attributes', 'updated_at') + end + + issues = response['data']&.map do |out| + call(:format_output_response, + out['attributes'], + %w(permitted_statuses permitted_actions permitted_attributes custom_attributes trades)) + out.merge(project_id: input['project_id'], hub_id: input['hub_id'], container_id: closure['container_id']) + end { events: issues || [], next_poll: closure, can_poll_more: response.dig('links', 'next').present? } + end, + dedup: lambda do |issue| - "#{issue['id']}&#{issue.dig('attributes', 'updated_at')}" + "#{issue['id']}@#{issue.dig('attributes', 'updated_at')}" end, + output_fields: lambda do |object_definitions| [ { name: 'hub_id' }, @@ -2189,23 +2559,20 @@ { name: 'container_id' } ].concat(object_definitions['issue']).compact end, + sample_output: lambda do |_connection, input| - project_id = input['project_id'] - container_id = get("/project/v1/#{input['hub_id']}" \ - "/projects/#{project_id}")&. - dig('relationships', 'rfis', 'data', 'id') - get("/issues/v1/containers/#{container_id}/" \ - 'quality-issues?page[limit]=1')&.dig('data', 0) || {} + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}")&.dig('data', 'relationships', 'issues', 'data', 'id') || {} + get("/issues/v1/containers/#{container_id}/quality-issues?page[limit]=1")&.dig('data', 0) || {} end }, + new_updated_document_in_project: { title: 'New or updated document in a project folder', - description: 'New or updated document in'\ - ' a project folder in BIM 360', - help: { - body: 'Triggers when a document in a project is created or updated' \ - ' in the specified folder.' - }, + + description: 'New or updated document in a project folder in BIM 360', + + help: 'Triggers when a document in a project folder is created or updated.', + input_fields: lambda do |_object_definitions| [ { @@ -2213,16 +2580,7 @@ label: 'Hub name', control_type: 'select', pick_list: 'hub_list', - optional: false, - toggle_hint: 'Select hub', - toggle_field: { - name: 'hub_id', - label: 'Hub ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide hub id e.g. b.baf-0871-4aca-82e8-3dd6db00' - } + optional: false }, { name: 'project_id', @@ -2230,136 +2588,103 @@ control_type: 'select', pick_list: 'project_list', pick_list_params: { hub_id: 'hub_id' }, - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_id', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Provide project id e.g. b.baf-0871-4aca-82e8-3dd6db00' - } + optional: false }, { name: 'folder_id', label: 'Folder', control_type: 'tree', - hint: 'Select folder', - toggle_hint: 'Select Folder', + hint: 'Select the folder to monitor for documents. Sub-folders will also be monitored.', pick_list_params: { hub_id: 'hub_id', project_id: 'project_id' }, tree_options: { selectable_folder: true }, pick_list: :folders_list, - optional: false, - toggle_field: { - name: 'folder_id', - type: 'string', - control_type: 'text', - label: 'Folder ID', - toggle_hint: 'Use Folder ID', - hint: 'Use Folder ID' - } }, + optional: false + }, { name: 'since', label: 'When first started, this recipe should pick up events from', hint: 'When you start recipe for the first time, ' \ 'it picks up trigger events from this specified date and time. ' \ - 'Leave empty to get records created or updated one hour ago', + 'Leave empty to get records created or updated one hour ago.', sticky: true, type: 'timestamp' } ] end, + poll: lambda do |_connection, input, closure| - hub_id = closure&.[]('hub_id') || input['hub_id'] - project_id = closure&.[]('project_id') || input['project_id'] - folder_id = closure&.[]('folder_id') || input['folder_id'] - - last_modified_time = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 10 - skip = closure&.[]('skip') || 0 - include = closure&.[]('include') || input['include'] - - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) + closure ||= {} + last_modified_time = closure['updated_after'] || (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 100 + + response = if closure['next_page_url'].present? + get(closure['next_page_url']) else - query_params = - 'filter[type]=items&filter[lastModifiedTimeRollup]-ge=' \ - "#{last_modified_time}&" \ - "page[limit]=#{limit}&page[skip]=#{skip}" - get("/data/v1/projects/#{input['project_id']}/folders/" \ - "#{input['folder_id']}/contents", query_params) + get("/data/v1/projects/#{input['project_id']}/folders/#{input['folder_id']}/contents", + "filter[type]=items&filter[lastModifiedTimeRollup]-ge=#{last_modified_time}&page[limit]=#{limit}&page[number]=#{closure['number'] || 0}") end - items = response['data']&. - map do |o| - o.merge({ project_id: input['project_id'], hub_id: input['hub_id'], - folder_id: input['folder_id'] }) - end - closure = if (next_page_url = response.dig('links', 'next')).present? - { 'skip' => skip + limit, - 'folder_id' => folder_id, - 'project_id' => project_id, - 'hub_id' => hub_id, - 'include' => include, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'folder_id' => folder_id, - 'project_id' => project_id, - 'hub_id' => hub_id, - 'include' => include, - 'updated_after' => now.to_time.utc.iso8601 } - end + items = response['data']&.map do |out| + call(:format_output_response, out.dig('attributes', 'extension', 'data'), + %w(visibleTypes actions allowedTypes)) + out.merge(project_id: input['project_id'], hub_id: input['hub_id'], folder_id: input['folder_id']) + end&.sort_by { |res| res.dig('attributes', 'lastModifiedTime') } + if (next_page_url = response.dig('links', 'next')).present? + closure['next_page_url'] = next_page_url + else + closure['number'] = 0 + closure['updated_after'] = Array.wrap(response['data']).last.dig('attributes', 'lastModifiedTime') + end { events: items || [], next_poll: closure, can_poll_more: response.dig('links', 'next').present? } end, + dedup: lambda do |item| - "#{item['id']}&#{item.dig('attributes', 'lastModifiedTime')}" + "#{item['id']}@#{item.dig('attributes', 'lastModifiedTime')}" end, + output_fields: lambda do |object_definitions| [{ name: 'hub_id' }, { name: 'project_id' }, { name: 'folder_id' }]. concat(object_definitions['folder_file']). compact end, + sample_output: lambda do |_connection, input| - get("/data/v1/projects/#{input['project_id']}/folders/" \ - "#{input['folder_id']}/contents?page[limit]=1")&.dig('data', 0) || {} + get("/data/v1/projects/#{input['project_id']}/folders/#{input['folder_id']}/contents?page[limit]=1")&.dig('data', 0) || {} end } }, + pick_lists: { hub_list: lambda do |_connection| get('/project/v1/hubs')['data']&.map do |hub| [hub.dig('attributes', 'name'), hub['id']] end end, + file_types: lambda do |_connection| [ ['BIM 360 Docs files', 'items:autodesk.bim360:File'], ['All other service', 'items:autodesk.core:File'] ] end, + folder_items: lambda do |_connection, project_id:, folder_id:| if project_id.length == 38 && folder_id.present? - get("/data/v1/projects/#{project_id}/folders/#{folder_id}/" \ - 'contents?filter[type]=items')['data']&. - map do |item| - [item.dig('attributes', 'displayName'), item['id']] - end + get("/data/v1/projects/#{project_id}/folders/#{folder_id}/contents?filter[type]=items")['data']&.map do |item| + [item.dig('attributes', 'displayName'), item['id']] + end end end, + item_versions: lambda do |_connection, project_id:, item_id:| - get("/data/v1/projects/#{project_id}/items/#{item_id}/" \ - 'versions')['data']&. - map do |version| - ["Version #{version.dig('attributes', 'versionNumber')}", - version.dig('id')] + get("/data/v1/projects/#{project_id}/items/#{item_id}/versions")['data']&.map do |version| + ["Version #{version.dig('attributes', 'versionNumber')}", version.dig('id')] end end, + version_types: lambda do |_connection| [ ['BIM 360 Docs files', 'versions:autodesk.bim360:File'], @@ -2369,35 +2694,31 @@ ['BIM 360 Team files', 'versions:autodesk.core:File'] ] end, + resource_types: lambda do |_connection| %w[attachment overlay].map { |type| [type.labelize, type] } end, + folders_list: lambda do |_connection, **args| - hub_id = args[:hub_id] - project_id = args[:project_id] - parent_id = args&.[](:__parent_id) - if project_id.length == 38 - if parent_id.present? - get("/data/v1/projects/#{project_id}/folders/#{parent_id}/" \ - 'contents?filter[type]=folders')['data']&. + if args[:project_id].length == 38 + if (parent_id = args&.[](:__parent_id)).present? + get("/data/v1/projects/#{args[:project_id]}/folders/#{parent_id}/contents?filter[type]=folders")['data']&. map do |folder| - [folder.dig('attributes', 'displayName'), - folder['id'], folder['id'], true] + [folder.dig('attributes', 'displayName'), folder['id'], nil, true] end else - get("project/v1/hubs/#{hub_id}/projects/#{project_id}/" \ - 'topFolders?filter[type]=folders')['data']&. + get("project/v1/hubs/#{args[:hub_id]}/projects/#{args[:project_id]}/topFolders?filter[type]=folders")['data']&. map do |folder| - [folder.dig('attributes', 'displayName'), - folder['id'], folder['id'], true] + [folder.dig('attributes', 'displayName'), folder['id'], nil, true] end || [] end end end, + issue_child_objects: lambda do |_connection| - %w[attachments comments container]&. - map { |option| [option.labelize, option] } + %w[attachments comments container]&.map { |option| [option.labelize, option] } end, + project_list: lambda do |_connection, hub_id:| if hub_id.length == 38 get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| @@ -2405,14 +2726,34 @@ end end end, + issue_container_lists: lambda do |_connection, hub_id:| if hub_id.length == 38 get("project/v1/hubs/#{hub_id}/projects")['data']&.map do |project| - [project.dig('attributes', 'name'), - project.dig('relationships', 'issues', 'data', 'id')] + [project.dig('attributes', 'name'), project.dig('relationships', 'issues', 'data', 'id')] + end + end + end, + + issue_type: lambda do |_connection, hub_id:, project_id:| + container_id = get("/project/v1/hubs/#{hub_id}/projects/#{project_id}")&.dig('data', 'relationships', 'issues', 'data', 'id') + if container_id.present? + get("issues/v1/containers/#{container_id}/ng-issue-types")['results']&.map do |issue| + [issue['title'], issue['id']] + end + end + end, + + issue_sub_type: lambda do |_connection, hub_id:, project_id:, ng_issue_type_id:| + container_id = get("/project/v1/hubs/#{hub_id}/projects/#{project_id}")&.dig('data', 'relationships', 'issues', 'data', 'id') + if container_id.present? + issue_type = get("issues/v1/containers/#{container_id}/ng-issue-types?include=subtypes")['results']&.select { |issue| issue['id'] == ng_issue_type_id }.first + issue_type['subtypes']&.map do |subtype| + [subtype['title'], subtype['id']] end end end, + project_types: lambda do [ %w[Commercial Commercial], ['Convention Center', 'Convention Center'], @@ -2459,16 +2800,20 @@ ['Training Project', 'Training Project'] ] end, + assigned_type_list: lambda do |_connection| %w[user company role]&.map { |el| [el.labelize, el] } end, + status_list: lambda do |_connection| %w[active pending inactive archived]&.map { |el| [el.labelize, el] } end, + issue_status_list: lambda do |_connection| %w[open work_complete ready_to_inspect not_approved close in_dispute void]&.map { |el| [el.labelize, el] } end, + service_types: lambda do |_connection| [ ['Field Service', 'field'], From 28af024f9cfc308a7ffc936a2eec4a517831bba3 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Mon, 2 Mar 2020 17:19:39 -0500 Subject: [PATCH 47/62] add conditional to headers to accept `application/json` for cost endpoints --- custom_connectors/oauth2/bim_360.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 6b559696..35866e61 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -31,7 +31,11 @@ end, apply: lambda do |_connection, access_token| - headers(Authorization: "Bearer #{access_token}") + if current_url.include?('https://developer.api.autodesk.com/cost/') + headers('Authorization': "Bearer #{access_token}", 'Content-Type' => 'application/json') + else + headers('Authorization': "Bearer #{access_token}", 'Content-Type' => 'application/vnd.api+json') + end end }, From d99cc7d965e892d6e1c18c99ae289d29e55d380e Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Mon, 2 Mar 2020 17:21:37 -0500 Subject: [PATCH 48/62] add object definitions for cost endpoints --- custom_connectors/oauth2/bim_360.rb | 245 ++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 35866e61..efc644b7 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -978,6 +978,251 @@ end }, + budget: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'id' }, + { name: 'parentId' }, + { name: 'code' }, + { name: 'name' }, + { name: 'description' }, + { name: 'quantity', type: 'number' }, + { name: 'unitPrice' }, + { name: 'unit' }, + { name: 'originalAmount', type: 'number' }, + { name: 'internalAdjustment', type: 'number' }, + { name: 'approvedOwnerChanges', type: 'number' }, + { name: 'pendingOwnerChanges' , type: 'number'}, + { name: 'originalCommitment', type: 'number' }, + { name: 'approvedChangeOrders', type: 'number' }, + { name: 'approvedInScopeChangeOrders', type: 'number' }, + { name: 'pendingChangeOrders', type: 'number' }, + { name: 'reserves', type: 'number' }, + { name: 'actualCost', type: 'number' }, + { name: 'mainContractId' }, + { name: 'adjustments', type: 'object', properties: [ + { name: 'total', type: 'number'}, + { name: 'details', type: 'array', of: 'objects', properties: [ + { name: 'quantity', type: 'number' }, + { name: 'unitPrice', type: 'number' }, + { name: 'unit' } + ]}, + { name: 'updatedAt', type: 'date_time'} + ]}, + { name: 'uncommited', type: 'number' }, + { name: 'revised', type: 'number' }, + { name: 'projectedCost', type: 'number' }, + { name: 'projectedBudget', type: 'number' }, + { name: 'forecastFinalCost', type: 'number' }, + { name: 'forecastVariance', type: 'number' }, + { name: 'forecastCostComplete', type: 'number' }, + { name: 'varianceTotal', type: 'number' }, + { name: 'externalId' }, + { name: 'externalSystem' }, + { name: 'createdAt', type: 'date_time' }, + { name: 'updatedAt', type: 'date_time' } + ] + end + }, + + contract: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'id' }, + { name: 'code' }, + { name: 'name' }, + { name: 'description' }, + { name: 'companyId' }, + { name: 'type' }, + { name: 'contactId' }, + { name: 'signedBy' }, + { name: 'ownerId' }, + { name: 'statusId' }, + { name: 'status' }, + { name: 'changedBy' }, + { name: 'creatorId' }, + { name: 'awarded', type: 'number' }, + { name: 'changes', type: 'number' }, + { name: 'total', type: 'number' }, + { name: 'originalBudget', type: 'number' }, + { name: 'internalAdjustment', type: 'number' }, + { name: 'approvedOwnerChanges', type: 'number' }, + { name: 'pendingOwnerChanges', type: 'number' }, + { name: 'approvedChangeOrders', type: 'number' }, + { name: 'approvedInScopeChangeOrders', type: 'number' }, + { name: 'pendingChangeOrders', type: 'number' }, + { name: 'reserves', type: 'number' }, + { name: 'actualCost', type: 'number' }, + { name: 'uncommitted', type: 'number' }, + { name: 'revised', type: 'number' }, + { name: 'projectedCost', type: 'number' }, + { name: 'projectedBudget', type: 'number' }, + { name: 'forecastFinalCost', type: 'number' }, + { name: 'forecastVariance', type: 'number' }, + { name: 'forecastCostComplete', type: 'number' }, + { name: 'varianceTotal', type: 'number' }, + { name: 'awardedAt', type: 'date_time' }, + { name: 'statusChangedAt', type: 'date_time' }, + { name: 'documentGeneratedAt', type: 'date_time' }, + { name: 'sentAt', type: 'date_time' }, + { name: 'respondedAt', type: 'date_time' }, + { name: 'returnedAt', type: 'date_time' }, + { name: 'onsiteAt', type: 'date_time' }, + { name: 'offsiteAt', type: 'date_time' }, + { name: 'procuredAt', type: 'date_time' }, + { name: 'approvedAt', type: 'date_time' }, + { name: 'scopeOfWork' }, + { name: 'note' }, + { name: 'budgets', type: 'array', of: 'object', properties: [ + { name: 'id' }, + { name: 'mainContractId' } + ]}, + { name: 'adjustments', type: 'array', of: 'object', properties: [ + { name: 'total', type: 'number' }, + { name: 'details', type: 'array', of: 'object', properties: [ + { name: 'quantity', type: 'number' }, + { name: 'unitPrice', type: 'number' }, + { name: 'unit' } + ]}, + { name: 'updatedAt', type: 'date_time' } + ]}, + { name: 'externalId' }, + { name: 'externalSystem' }, + { name: 'createdAt', type: 'date_time' }, + { name: 'updatedAt', type: 'date_time' } + ] + end + }, + + change_order: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'id' }, + { name: 'number' }, + { name: 'name' }, + { name: 'description' }, + { name: 'scope' }, + { name: 'creatorId' }, + { name: 'ownerId' }, + { name: 'changedBy' }, + { name: 'budgetStatus' }, + { name: 'costStatus' }, + { name: 'estimated', type: 'number' }, + { name: 'proposed', type: 'number' }, + { name: 'submitted', type: 'number' }, + { name: 'approved', type: 'number' }, + { name: 'committed', type: 'number' }, + { name: 'scopeOfWork' }, + { name: 'note' }, + { name: 'externalId' }, + { name: 'externalSystem' }, + { name: 'createdAt', type: 'date_time' }, + { name: 'updatedAt', type: 'date_time' }, + { name: 'properties', type: 'array', of: 'object', properties: [ + { name: 'name' }, + { name: 'builtIn', type: 'boolean' }, + { name: 'position', type: 'number' }, + { name: 'propertyDefinitionId'}, + { name: 'type'}, + { name: 'value'} + ]}, + { name: 'costItems', type: 'array', of: 'object', properties: [ + { name: 'id' } + ]} + ] + end + }, + + cost_item: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'id' }, + { name: 'number' }, + { name: 'name' }, + { name: 'description' }, + { name: 'budgetStatus' }, + { name: 'costStatus' }, + { name: 'scope' }, + { name: 'type' }, + { name: 'isMarkup', type: 'boolean' }, + { name: 'estimated', type: 'number' }, + { name: 'proposed', type: 'number' }, + { name: 'submitted', type: 'number' }, + { name: 'approved', type: 'number' }, + { name: 'committed', type: 'number' }, + { name: 'scopeOfWork' }, + { name: 'note' }, + { name: 'createdAt', type: 'date_time' }, + { name: 'updatedAt', type: 'date_time' } + ] + end + }, + + cost_attachment: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'id' }, + { name: 'folderId' }, + { name: 'urn' }, + { name: 'type' }, + { name: 'name' }, + { name: 'associationId', label: 'Object ID' }, + { name: 'associationType', label: 'Object Type' }, + { name: 'createdAt', type: 'date_time' }, + { name: 'updatedAt', type: 'date_time' } + ] + end + }, + + cost_document: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'id' }, + { name: 'templateId' }, + { name: 'recipientId' }, + { name: 'signedBy' }, + { name: 'urn' }, + { name: 'signedUrn' }, + { name: 'status' }, + { name: 'jobId' }, + { name: 'errorInfo', type: 'object', properties: [ + { name: 'code' }, + { name: 'message' }, + { name: 'detail' } + ]}, + { name: 'associationId', label: 'Object ID' }, + { name: 'associationType', label: 'Object Type' }, + { name: 'createdAt', type: 'date_time' }, + { name: 'updatedAt', type: 'date_time' } + ] + end + }, + + cost_file_packages: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'id' }, + { name: 'recipient' }, + { name: 'urn' }, + { name: 'errorInfo', type: 'object', properties: [ + { name: 'code' }, + { name: 'message' }, + { name: 'detail' } + ]}, + { name: 'items', type: 'array', of: 'object', properties: [ + { name: 'id' }, + { name: 'urn' }, + { name: 'name' }, + { name: 'type' }, + { name: 'createdAt', type: 'date_time' }, + { name: 'updatedAt', type: 'date_time' } + ]}, + { name: 'createdAt', type: 'date_time' }, + { name: 'updatedAt', type: 'date_time' } + ] + end + }, + custom_action_input: { fields: lambda do |_connection, config_fields| input_schema = parse_json(config_fields.dig('input', 'schema') || '[]') From d49d9c73362bfa09fb71b63eef72ae4951bff474 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Mon, 2 Mar 2020 17:23:51 -0500 Subject: [PATCH 49/62] add pick lists for cost endpoints --- custom_connectors/oauth2/bim_360.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index efc644b7..f164bbc9 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -3071,6 +3071,27 @@ ['Plan Service', 'plan'], ['Docs Service', 'doc_manager'] ] + end, + + change_order_types: lambda do |_connection| + [ + ['PCO', 'pco'], + ['RFQ', 'rfq'], + ['RCO', 'rco'], + ['OCO', 'oco'], + ['SCO', 'sco'] + ] + end, + + cost_association_types: lambda do |_connection| + [ + ['Budget', 'Budget'], + ['Contract', 'Contract'], + ['Cost Item', 'CostItem'], + ['Form Instance', 'FormInstance'], + ['Payment', 'Payment'], + ['Budget Payment', 'BudgetPayment'] + ] end } } From cbfa800de64e5ac2e9f12aefbfc45060d1995191 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Mon, 2 Mar 2020 18:21:22 -0500 Subject: [PATCH 50/62] add method to handle cost search criterias --- custom_connectors/oauth2/bim_360.rb | 133 ++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index f164bbc9..68ee59a8 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -77,6 +77,21 @@ end end, + format_cost_search: lambda do |input| + if input.is_a?(Hash) + input.each_with_object({}) do |(key, value), hash| + value = call('format_search', value) + if %w[rootId externalSystem externalId code].include?(key) + hash["filter[#{key}]"] = value + else + hash[key] = value + end + end + else + input + end + end, + make_schema_builder_fields_sticky: lambda do |input| input.map do |field| if field[:properties].present? @@ -2717,6 +2732,124 @@ { name: 'project_id' } ].concat(object_definitions['folder_file']) end + }, + + search_budgets_in_project: { + title: 'Search budgets in a project', + + description: 'Search budgets in a project in' \ + ' BIM 360', + + help: { + body: 'This action searches for budgets in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'rootId', + hint: 'Filter by related subitems for the given root item ID. Separate multiple IDs with commas.' + }, + { + name: 'externalSystem', + hint: 'Filter by name of source if used in system integration.' + }, + { + name: 'externalId', + hint: 'Filter by item ID in the external system. Separate multiple IDs with commas.' + }, + { + name: 'code', + hint: 'Filter by item code.' + }, + { + name: 'offset', + type: 'number', + hint: 'Number of items to skip before starting to collect the result set.' + }, + { + name: 'limit', + type: 'number', + hint: 'Number of items to return.' + }, + { + name: 'sort', + hint: 'Order of items to sort. Each item can be followed by a direction modifier' \ + ' of either asc or desc. If no direction is specified then asc is assumed.' + } + ] + end, + + execute: lambda do |_connection, input| + filter_criteria = call('format_cost_search', input.except('hub_id', 'project_id')) + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + &.dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + get("/cost/v1/containers/#{container_id}/budgets", filter_criteria) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: input['hub_id'], container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat([ + { name: 'results', type: 'array', of: 'object', properties: object_definitions['budget'] }, + { name: 'pagination', type: 'object', properties: [ + { name: 'totalResults', type: 'number' }, + { name: 'limit', type: 'number' }, + { name: 'offset', type: 'number' } + ]} + ]) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + &.dig('data', 'relationships', 'cost', 'data', 'id') || {} + (get("/cost/v1/containers/#{container_id}/budgets?limit=1") || {}) + &.merge(hub_id: input['hub_id'], container_id: container_id) + end } }, From 8aa598541a0f818eb33c130b9512fd3f2d76e8d6 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Mon, 2 Mar 2020 21:21:45 -0500 Subject: [PATCH 51/62] add actions for budget endpoints (search, get, create, update) --- custom_connectors/oauth2/bim_360.rb | 399 +++++++++++++++++++++++++++- 1 file changed, 395 insertions(+), 4 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 68ee59a8..01765641 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -2784,7 +2784,8 @@ }, { name: 'rootId', - hint: 'Filter by related subitems for the given root item ID. Separate multiple IDs with commas.' + hint: 'Filter by related subitems for the given root item ID.' \ + ' Separate multiple IDs with commas.' }, { name: 'externalSystem', @@ -2792,7 +2793,8 @@ }, { name: 'externalId', - hint: 'Filter by item ID in the external system. Separate multiple IDs with commas.' + hint: 'Filter by item ID in the external system. ' \ + 'Separate multiple IDs with commas.' }, { name: 'code', @@ -2846,9 +2848,398 @@ sample_output: lambda do |_connection, input| container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") - &.dig('data', 'relationships', 'cost', 'data', 'id') || {} + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/budgets?limit=1") || {}) + .merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + + get_budget_in_project: { + title: 'Get budget in a project', + + description: 'Get budget in a project' \ + ' in BIM 360', + + help: { + body: 'This action returns a budget in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'budget_id', + label: 'Budget ID', + optional: false, + sticky: true + } + ] + end, + + execute: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + get("/cost/v1/containers/#{container_id}/budgets/#{input['budget_id']}") + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: input['hub_id'], container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['budget']) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/budgets?limit=1") || {}) + .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + + create_budget_in_project: { + title: 'Create budget in a project', + + description: 'Create budget in a ' \ + 'project in BIM 360', + + help: { + body: 'This action creates a budget in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'code', + optional: false, + sticky: true, + hint: 'Unique code that is compliant with the budget code template' \ + ' defined by the project admin. Max length of 255 characters.' + }, + { + name: 'name', + optional: false, + sticky: true, + hint: 'Name of the budget. Max length of 1024 characters.' + }, + { + name: 'parentId', + sticky: true, + hint: 'ID of the parent budget. Used only when creating sub-budgets.' + }, + { + name: 'quantity', + sticky: true, + type: 'integer', + render_input: 'integer_conversion', + parse_output: 'integer_conversion', + hint: 'Quantity of labor, material, etc, that is planned for a budget.' + }, + { + name: 'description', + sticky: true, + hint: 'Description of the budget.' + }, + { + name: 'unitPrice', + sticky: true, + type: 'integer', + render_input: 'integer_conversion', + parse_output: 'integer_conversion', + hint: 'Unit price of a budget.' + }, + { + name: 'unit', + sticky: true, + hint: 'Unit of measure used in the budget.' + } + ] + end, + + execute: lambda do |_connection, input| + hub_id = input.delete('hub_id') + project_id = input.delete('project_id') + + container_id = get("/project/v1/hubs/#{hub_id}/projects/#{project_id}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + post("/cost/v1/containers/#{container_id}/budgets") + .payload(input) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: hub_id, container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['budget']) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/budgets?limit=1") || {}) + .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + + update_budget_in_project: { + title: 'Update budget in a project', + + description: 'Update budget in a project' \ + ' in BIM 360', + + help: { + body: 'This action updates a budget in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'budgetId', + optional: false, + sticky: true, + hint: 'ID of the budget to update.' + }, + { + name: 'name', + sticky: true, + hint: 'Name of the budget. Max length of 1024 characters.' + }, + { + name: 'code', + sticky: true, + hint: 'Unique code that is compliant with the budget code template ' \ + 'defined by the project admin. Max length of 255 characters.' + }, + { + name: 'parentId', + sticky: true, + hint: 'ID of the parent budget. Used only when creating sub-budgets.' + }, + { + name: 'quantity', + sticky: true, + type: 'integer', + render_input: 'integer_conversion', + parse_output: 'integer_conversion', + hint: 'Quantity of labor, material, etc, that is planned for a budget.' + }, + { + name: 'description', + sticky: true, + hint: 'Description of the budget.' + }, + { + name: 'unitPrice', + sticky: true, + type: 'integer', + render_input: 'integer_conversion', + parse_output: 'integer_conversion', + hint: 'Unit price of a budget.' + }, + { + name: 'unit', + sticky: true, + hint: 'Unit of measure used in the budget.' + }, + { + name: 'actualCost', + sticky: true, + type: 'integer', + render_input: 'integer_conversion', + parse_output: 'integer_conversion', + hint: 'Total amount of actual cost of the budget.' + }, + { + name: 'adjustments', + sticky: true, + hint: 'Items to make and explain adjustments to actual cost ' \ + 'amounts to make forecast more accurate.', + type: 'object', properties: [ + { name: 'details', type: 'array', of: 'object', properties: [ + { + name: 'quantity', + sticky: true, + type: 'integer', + render_input: 'integer_conversion', + parse_output: 'integer_conversion', + hint: 'Quantity of actual adjustment.' + }, + { + name: 'unitPrice', + sticky: true, + type: 'number', + type: 'integer', + render_input: 'integer_conversion', + parse_output: 'integer_conversion', + hint: 'Unit price of the actual adjustment.' + }, + { + name: 'unit', + sticky: true, + hint: 'Unit of measurement of the actual adjustment.' + } + ]} + ] + } + ] + end, + + execute: lambda do |_connection, input| + hub_id = input.delete('hub_id') + project_id = input.delete('project_id') + budget_id = input.delete('budgetId') + + container_id = get("/project/v1/hubs/#{hub_id}/projects/#{project_id}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + patch("/cost/v1/containers/#{container_id}/budgets/#{budget_id}") + .headers("Content-Type": "application/json") + .payload(input) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: hub_id, container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['budget']) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + (get("/cost/v1/containers/#{container_id}/budgets?limit=1") || {}) - &.merge(hub_id: input['hub_id'], container_id: container_id) + .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) end } }, From 8727a0c58bd3e0c8bb3c3155c2b344aa1882db16 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Tue, 3 Mar 2020 13:11:21 -0500 Subject: [PATCH 52/62] add actions for contract endpoints (search, get, create, update) --- custom_connectors/oauth2/bim_360.rb | 522 +++++++++++++++++++++++++++- 1 file changed, 521 insertions(+), 1 deletion(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 01765641..243f3b4d 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -3241,7 +3241,527 @@ (get("/cost/v1/containers/#{container_id}/budgets?limit=1") || {}) .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) end - } + }, + + search_contracts_in_project: { + title: 'Search contracts in a project', + + description: 'Search contracts in a ' \ + 'project in BIM 360', + + help: { + body: 'This action searches for contracts in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'externalSystem', + hint: 'Filter by name of source if used in system integration.' + }, + { + name: 'externalId', + hint: 'Filter by item ID in the external system.' \ + ' Separate multiple IDs with commas.' + }, + { + name: 'code', + hint: 'Filter by item code.' + }, + { + name: 'include', + hint: 'Resources to include in the response.', + control_type: 'multiselect', + pick_list: [ + ['Budgets', 'budgets'], + ['Attributes', 'attributes'] + ], + delimiter: ',' + }, + { + name: 'offset', + type: 'number', + hint: 'Number of items to skip before starting to ' \ + 'collect the result set.' + }, + { + name: 'limit', + type: 'number', + hint: 'Number of items to return.' + }, + { + name: 'sort', + hint: 'Order of items to sort. Each item can be followed by a ' \ + 'direction modifier of either asc or desc. If no direction is ' \ + 'specified then asc is assumed.' + } + ] + end, + + execute: lambda do |_connection, input| + filter_criteria = call('format_cost_search', input.except('hub_id', 'project_id')) + + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + get("/cost/v1/containers/#{container_id}/contracts", filter_criteria) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: input['hub_id'], container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat([ + { name: 'results', type: 'array', of: 'object', properties: object_definitions['contract'] }, + { name: 'pagination', type: 'object', properties: [ + { name: 'totalResults', type: 'number' }, + { name: 'limit', type: 'number' }, + { name: 'offset', type: 'number' }, + { name: 'nextUrl' } + ]} + ]) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/contracts?limit=1") || {}) + .merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + + get_contract_in_project: { + title: 'Get contract in a project', + + description: 'Get contract in a ' \ + 'project in BIM 360', + + help: { + body: 'This action returns a contract in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'contract_id', + label: 'Contract ID', + optional: false, + sticky: true + } + ] + end, + + execute: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + get("/cost/v1/containers/#{container_id}/contracts/#{input['contract_id']}") + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: input['hub_id'], container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['contract']) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/contracts?limit=1") || {}) + .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + + create_contract_in_project: { + title: 'Create contract in a project', + + description: 'Create contract in a ' \ + 'project in BIM 360', + + help: { + body: 'This action creates a contract in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'code', + optional: false, + sticky: true, + hint: 'Code of the contract. Max lenght of 255 characters.' + }, + { + name: 'name', + optional: false, + sticky: true, + hint: 'Name of the contract. Max length of 1024 characters.' + }, + { + name: 'description', + sticky: true, + hint: 'Description of the contract. Max length of 2048 characters.' + }, + { + name: 'companyId', + sticky: true, + hint: 'ID of the supplier company managed by the BIM 360 admin.' + }, + { + name: 'type', + sticky: true, + hint: 'Type of the contract as specified by the project admin.' + }, + { + name: 'contactId', + sticky: true, + hint: 'ID of the user in BIM 360 for the contact of the supplier.' + }, + { + name: 'signedBy', + sticky: true, + hint: 'ID of the user in BIM 360 who signed the contract.' + }, + { + name: 'ownerId', + sticky: true, + hint: 'ID of the user in BIM 360 who is responsible for the purchase.' + }, + { + name: 'status', + sticky: true, + control_type: 'select', + pick_list: [ + ['Draft', 'draft'], + ['Open', 'open'], + ['Sent', 'sent'], + ['Executed', 'executed'], + ['Closed', 'closed'] + ], + toggle_hint: 'Select status', + toggle_field: { + name: 'status', + label: 'Status', + change_on_blur: true, + control_type: 'text', + type: 'string', + toggle_hint: 'Enter status', + hint: 'Status of the contract. Possible values include:' \ + ' draft, open, sent, executed, closed.' + } + } + ] + end, + + execute: lambda do |_connection, input| + hub_id = input.delete('hub_id') + project_id = input.delete('project_id') + + container_id = get("/project/v1/hubs/#{hub_id}/projects/#{project_id}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + post("/cost/v1/containers/#{container_id}/contracts") + .payload(input) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: hub_id, container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['contract']) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/contracts?limit=1") || {}) + .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + + update_contract_in_project: { + title: 'Update contract in a project', + + description: 'Update contract in a ' \ + 'project in BIM 360', + + help: { + body: 'This action updates a contract in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'contractId', + optional: false, + sticky: true, + hint: 'ID of the budget to update.' + }, + { + name: 'code', + sticky: true, + hint: 'Code of the contract. Max lenght of 255 characters.' + }, + { + name: 'name', + sticky: true, + hint: 'Name of the contract. Max length of 1024 characters.' + }, + { + name: 'description', + sticky: true, + hint: 'Description of the contract. Max length of 2048 characters.' + }, + { + name: 'companyId', + sticky: true, + hint: 'ID of the supplier company managed by the BIM 360 admin.' + }, + { + name: 'type', + sticky: true, + hint: 'Type of the contract as specified by the project admin.' + }, + { + name: 'contactId', + sticky: true, + hint: 'ID of the user in BIM 360 for the contact of the supplier.' + }, + { + name: 'signedBy', + sticky: true, + hint: 'ID of the user in BIM 360 who signed the contract.' + }, + { + name: 'ownerId', + sticky: true, + hint: 'ID of the user in BIM 360 who is responsible for the purchase.' + }, + { + name: 'status', + sticky: true, + control_type: 'select', + pick_list: [ + ['Draft', 'draft'], + ['Open', 'open'], + ['Sent', 'sent'], + ['Executed', 'executed'], + ['Closed', 'closed'] + ], + toggle_hint: 'Select status', + toggle_field: { + name: 'status', + label: 'Status', + change_on_blur: true, + control_type: 'text', + type: 'string', + toggle_hint: 'Enter status', + hint: 'Status of the contract. Possible values include:' \ + ' draft, open, sent, executed, closed.' + } + } + ] + end, + + execute: lambda do |_connection, input| + hub_id = input.delete('hub_id') + project_id = input.delete('project_id') + contract_id = input.delete('contractId') + + container_id = get("/project/v1/hubs/#{hub_id}/projects/#{project_id}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + patch("/cost/v1/containers/#{container_id}/contracts/#{contract_id}") + .payload(input) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: hub_id, container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['contract']) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/contracts?limit=1") || {}) + .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + }, triggers: { From ec26fe45372f3a7976b611671b3e4184b3dbc0a4 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Tue, 3 Mar 2020 13:20:31 -0500 Subject: [PATCH 53/62] add picklist for contract statuses --- custom_connectors/oauth2/bim_360.rb | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 243f3b4d..ad6d62f0 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -3553,13 +3553,7 @@ name: 'status', sticky: true, control_type: 'select', - pick_list: [ - ['Draft', 'draft'], - ['Open', 'open'], - ['Sent', 'sent'], - ['Executed', 'executed'], - ['Closed', 'closed'] - ], + pick_list: 'contract_status', toggle_hint: 'Select status', toggle_field: { name: 'status', @@ -3706,13 +3700,7 @@ name: 'status', sticky: true, control_type: 'select', - pick_list: [ - ['Draft', 'draft'], - ['Open', 'open'], - ['Sent', 'sent'], - ['Executed', 'executed'], - ['Closed', 'closed'] - ], + pick_list: 'contract_status', toggle_hint: 'Select status', toggle_field: { name: 'status', @@ -4136,6 +4124,16 @@ ['Payment', 'Payment'], ['Budget Payment', 'BudgetPayment'] ] + end, + + contract_status: lambda do |_connection| + [ + ['Draft', 'draft'], + ['Open', 'open'], + ['Sent', 'sent'], + ['Executed', 'executed'], + ['Closed', 'closed'] + ] end } } From 5b781cab5403200779ec822d84ab66dc906dd69e Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Tue, 3 Mar 2020 21:58:10 -0500 Subject: [PATCH 54/62] add actions for change order endpoints (search, get, create, update) --- custom_connectors/oauth2/bim_360.rb | 575 ++++++++++++++++++++++++++++ 1 file changed, 575 insertions(+) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index ad6d62f0..61b1a036 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -3750,6 +3750,577 @@ end }, + search_change_orders_in_project: { + title: 'Search change orders in a project', + + description: 'Search change orders' \ + ' in a project in BIM 360', + + help: { + body: 'This action searches for change orders in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'type', + label: 'Change Order Type', + control_type: 'select', + pick_list: 'change_order_types', + optional: false, + sticky: true, + toggle_hint: 'Select type', + toggle_field: { + name: 'type', + label: 'Change Order Type', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter type', + hint: 'Enter the change order type name. ' \ + 'Possible values are: pco, rfq, rco, oco, sco.' + } + }, + { + name: 'externalSystem', + label: 'External System', + hint: 'Filter by name of source if used in system integration.' + }, + { + name: 'externalId', + label: 'External ID', + hint: 'Filter by item ID in the external system. ' \ + 'Separate multiple IDs with commas.' + }, + { + name: 'contractId', + label: 'Contract ID', + hint: 'Filter by contract ID. ' \ + 'Separate multiple IDs with commas.' + }, + { + name: 'mainContractId', + label: 'Main Contract ID', + hint: 'Filter by main contract ID. Separate multiple IDs with commas.' + }, + { + name: 'budgetStatus', + label: 'Budget Status', + hint: 'Filter by budget status code. Separate multiple codes with commas.' + }, + { + name: 'costStatus', + label: 'Cost Status', + hint: 'Filter by cost status code. Separate multiple codes with commas.' + }, + { + name: 'include', + hint: 'Resources to include in the response.', + control_type: 'multiselect', + pick_list: [ + ['Cost Items', 'costItems'], + ['Attributes', 'attributes'] + ], + delimiter: ',' + }, + { + name: 'offset', + type: 'number', + hint: 'Number of items to skip before starting to collect the result set.' + }, + { + name: 'limit', + type: 'number', + hint: 'Number of items to return.' + }, + { + name: 'sort', + hint: 'Order of items to sort. Each item can be followed by a direction modifier' \ + ' of either asc or desc. If no direction is specified then asc is assumed.' + } + ] + end, + + execute: lambda do |_connection, input| + filter_criteria = call('format_cost_search', input.except('hub_id', 'project_id')) + + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + get("/cost/v1/containers/#{container_id}/change-orders/#{input['type']}", filter_criteria) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: input['hub_id'], container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat([ + { name: 'results', type: 'array', of: 'object', properties: object_definitions['change_order'] }, + { name: 'pagination', type: 'object', properties: [ + { name: 'totalResults', type: 'number' }, + { name: 'limit', type: 'number' }, + { name: 'offset', type: 'number' }, + { name: 'nextUrl' } + ]} + ]) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}")&.dig('data', 'relationships', 'cost', 'data', 'id') || {} + (get("/cost/v1/containers/#{container_id}/change-orders/pco?limit=1") || {})&.merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + + get_change_order_in_project: { + title: 'Get change order in a project', + + description: 'Get change order' \ + ' in a project in BIM 360', + + help: { + body: 'This action returns a change order in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'type', + label: 'Change Order Type', + control_type: 'select', + pick_list: 'change_order_types', + optional: false, + sticky: true, + toggle_hint: 'Select type', + toggle_field: { + name: 'type', + label: 'Change Order Type', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter type name', + hint: 'Enter the change order type name. ' \ + 'Possible values are: pco, rfq, rco, oco, sco.' + } + }, + { + name: 'id', + label: 'Change Order ID', + optional: false, + sticky: true + } + ] + end, + + execute: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + get("/cost/v1/containers/#{container_id}/change-orders/#{input['type']}/#{input['id']}") + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: input['hub_id'], container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['change_order']) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + (get("/cost/v1/containers/#{container_id}/change-orders/pco?limit=1") || {}) + .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + + create_change_order_in_project: { + title: 'Create change order in a project', + + description: 'Create change order' \ + ' in a project in BIM 360', + + help: { + body: 'This action creates a change order in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'type', + label: 'Change Order Type', + control_type: 'select', + pick_list: 'change_order_types', + optional: false, + sticky: true, + toggle_hint: 'Select type', + toggle_field: { + name: 'type', + label: 'Change Order Type', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter type name', + hint: 'Enter the change order type name. ' \ + 'Possible values are: pco, rfq, rco, oco, sco.' + } + }, + { + name: 'name', + sticky: true, + hint: 'Name of the change order. Max length of 1024 characters.' + }, + { + name: 'description', + sticky: true, + hint: 'Description of the change order. Max length of 2048 characters.' + }, + { + name: 'scope', + sticky: true, + label: 'Scope', + hint: 'Scope of the change order.', + control_type: 'select', + pick_list: 'change_order_scope', + toggle_hint: 'Select scope', + toggle_field: { + name: 'scope', + label: 'Scope', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter type name', + hint: 'Enter scope of change order. ' \ + 'Possible values are: out, in, tbd, contigency.' + } + }, + { + name: 'scopeOfWork', + optional: true, + sticky: true, + hint: 'Scope of work of the change order.' + }, + { + name: 'note', + optional: true, + sticky: true, + hint: 'Additional notes to the change order.' + } + ] + end, + + execute: lambda do |_connection, input| + hub_id = input.delete('hub_id') + project_id = input.delete('project_id') + type = input.delete('type') + + container_id = get("/project/v1/hubs/#{hub_id}/projects/#{project_id}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + post("/cost/v1/containers/#{container_id}/change-orders/#{type}") + .payload(input) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: hub_id, container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['change_order']) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + (get("/cost/v1/containers/#{container_id}/change-orders/pco?limit=1") || {}) + .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + + update_change_order_in_project: { + title: 'Update change order in a project', + + description: 'Update change order' \ + ' in a project in BIM 360', + + help: { + body: 'This action updates a change order in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'type', + label: 'Change Order Type', + control_type: 'select', + pick_list: 'change_order_types', + optional: false, + sticky: true, + toggle_hint: 'Select type', + toggle_field: { + name: 'type', + label: 'Change Order Type', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter type name', + hint: 'Enter the change order type name. ' \ + 'Possible values are: pco, rfq, rco, oco, sco.' + } + }, + { + name: 'id', + label: 'Change Order ID', + optional: false, + sticky: true, + hint: 'ID of the change order. Max length of 1024 characters.' + }, + { + name: 'name', + sticky: true, + hint: 'Name of the change order. Max length of 1024 characters.' + }, + { + name: 'description', + sticky: true, + hint: 'Description of the change order. Max length of 2048 characters.' + }, + { + name: 'scope', + sticky: true, + label: 'Scope', + hint: 'Scope of the change order.', + control_type: 'select', + pick_list: 'change_order_scope', + toggle_hint: 'Select scope', + toggle_field: { + name: 'scope', + label: 'Scope', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter type name', + hint: 'Enter scope of change order. ' \ + 'Possible values are: out, in, tbd, contigency.' + } + }, + { + name: 'scopeOfWork', + sticky: true, + hint: 'Scope of work of the change order.' + }, + { + name: 'note', + sticky: true, + hint: 'Additional notes to the change order.' + }, + { + name: 'recipients', + sticky: true, + hint: 'Users who will receive the generated documents.', + type: 'array', of: 'object', properties: [ + { name: 'id', hint: 'ID of the user in BIM 360.' }, + { name: 'isDefault', type: 'boolean', hint: 'Indicate whether the user is the default recipient.'} + ] + } + ] + end, + + execute: lambda do |_connection, input| + hub_id = input.delete('hub_id') + project_id = input.delete('project_id') + type = input.delete('type') + id = input.delete('id') + + container_id = get("/project/v1/hubs/#{hub_id}/projects/#{project_id}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + patch("/cost/v1/containers/#{container_id}/change-orders/#{type}/#{id}") + .payload(input) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: hub_id, container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['change_order']) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/change-orders/pco?limit=1") || {}) + .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + }, triggers: { @@ -4134,6 +4705,10 @@ ['Executed', 'executed'], ['Closed', 'closed'] ] + end, + + change_order_scope: lambda do |_connection| + %w[in out tbd contigency]&.map { |el| [el.labelize, el] } end } } From 7b247a3eada90d1028e79e02b9b8bae9ed1205be Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Tue, 3 Mar 2020 22:06:08 -0500 Subject: [PATCH 55/62] use .map to convert pick lists for `change_order_types` and `contract_status` --- custom_connectors/oauth2/bim_360.rb | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 61b1a036..5a8c6aac 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -4677,13 +4677,7 @@ end, change_order_types: lambda do |_connection| - [ - ['PCO', 'pco'], - ['RFQ', 'rfq'], - ['RCO', 'rco'], - ['OCO', 'oco'], - ['SCO', 'sco'] - ] + %w[pco rfq rco oco sco]&.map { |el| [el.upcase, el] } end, cost_association_types: lambda do |_connection| @@ -4698,13 +4692,7 @@ end, contract_status: lambda do |_connection| - [ - ['Draft', 'draft'], - ['Open', 'open'], - ['Sent', 'sent'], - ['Executed', 'executed'], - ['Closed', 'closed'] - ] + %w[draft open sent executed closed]&.map { |el| [el.labelize, el] } end, change_order_scope: lambda do |_connection| From 908bea264e71bccc10ac3b3fb1b631984ee17f7b Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Tue, 3 Mar 2020 22:50:24 -0500 Subject: [PATCH 56/62] add actions for cost item endpoints (search, get, create, update) --- custom_connectors/oauth2/bim_360.rb | 497 ++++++++++++++++++++++++++++ 1 file changed, 497 insertions(+) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 5a8c6aac..24b3faa3 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -4321,6 +4321,503 @@ end }, + search_cost_items_in_project: { + title: 'Search cost items in a project', + + description: 'Search cost items' \ + ' in a project in BIM 360', + + help: { + body: 'This action searches for cost items in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'changeOrderId', + label: 'Change Order', + hint: 'Filter by change order ID. Separate multiple IDs with commas.' + }, + { + name: 'budgetId', + label: 'Budget', + hint: 'Filter by budget ID. Separate multiple IDs with commas.' + }, + { + name: 'externalSystem', + label: 'External System', + hint: 'Filter by name of source if used in system integration.' + }, + { + name: 'externalId', + label: 'External ID', + hint: 'Filter by item ID in the external system. ' \ + 'Separate multiple IDs with commas.' + }, + { + name: 'include', + hint: 'Resources to include in the response.', + control_type: 'multiselect', + pick_list: [ + ['Budgets', 'budgets'], + ['Change Orders', 'changeOrders'], + ['Attributes', 'attributes'] + ], + delimiter: ',' + }, + { + name: 'offset', + type: 'number', + hint: 'Number of items to skip before starting to collect the result set.' + }, + { + name: 'limit', + type: 'number', + hint: 'Number of items to return.' + }, + { + name: 'sort', + hint: 'Order of items to sort. Each item can be followed by ' \ + 'a direction modifier of either asc or desc. ' \ + 'If no direction is specified then asc is assumed.' + } + ] + end, + + execute: lambda do |_connection, input| + filter_criteria = call('format_cost_search', input.except('hub_id', 'project_id', 'type')) + + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + get("/cost/v1/containers/#{container_id}/cost-items", filter_criteria) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: input['hub_id'], container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat([ + { name: 'results', type: 'array', of: 'object', properties: object_definitions['cost_item'] }, + { name: 'pagination', type: 'object', properties: [ + { name: 'totalResults', type: 'number' }, + { name: 'limit', type: 'number' }, + { name: 'offset', type: 'number' }, + { name: 'nextUrl' } + ]} + ]) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/cost-items?limit=1") || {}) + .merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + + get_cost_item_in_project: { + title: 'Get cost item in a project', + + description: 'Get cost item' \ + ' in a project in BIM 360', + + help: { + body: 'This action returns a cost item in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'id', + label: 'Cost Item ID', + optional: false, + sticky: true + } + ] + end, + + execute: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + get("/cost/v1/containers/#{container_id}/cost-items/#{input['id']}") + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: input['hub_id'], container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['cost_item']) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + (get("/cost/v1/containers/#{container_id}/cost-items?limit=1") || {}) + .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + + create_cost_item_in_project: { + title: 'Create cost item in a project', + + description: 'Create cost item' \ + ' in a project in BIM 360', + + help: { + body: 'This action creates a cost item in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'name', + optional: false, + sticky: true, + hint: 'Name of the cost item. Max length of 1024 characters.' + }, + { + name: 'changeOrderId', + sticky: true, + hint: 'ID of the change order that the cost item is created in.' + }, + { + name: 'budgetId', + sticky: true, + hint: 'ID of the budget that the cost item is linked to.' + }, + { + name: 'description', + sticky: true, + hint: 'Description of the cost item. Max length of 2048 characters.' + }, + { + name: 'estimated', + sticky: true, + type: 'number', + hint: 'Rough estimation of this item without a quotation.' + }, + { + name: 'proposed', + sticky: true, + type: 'number', + hint: 'Quoted cost of the cost item.' + }, + { + name: 'submitted', + sticky: true, + type: 'number', + hint: 'Amount submitted to the owner for approval.' + }, + { + name: 'approved', + sticky: true, + type: 'number', + hint: 'Amount approved by the owner.' + }, + { + name: 'committed', + sticky: true, + type: 'number', + hint: 'Amount committed to the supplier.' + } + ] + end, + + execute: lambda do |_connection, input| + hub_id = input.delete('hub_id') + project_id = input.delete('project_id') + + container_id = get("/project/v1/hubs/#{hub_id}/projects/#{project_id}") + .dig('data', 'relationships', 'cost', 'data', 'id') + response = if container_id.present? + post("/cost/v1/containers/#{container_id}/cost-items") + .payload(input) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: hub_id, container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['cost_item']) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/cost-items?limit=1") || {}) + .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + + update_cost_item_in_project: { + title: 'Update cost item in a project', + + description: 'Update cost item' \ + ' in a project in BIM 360', + + help: { + body: 'This action updates a cost item in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'id', + label: 'Cost Item ID', + optional: false, + sticky: true + }, + { + name: 'name', + sticky: true, + hint: 'Name of the cost item. Max length of 1024 characters.' + }, + { + name: 'changeOrderId', + sticky: true, + hint: 'ID of the change order that the cost item is created in.' + }, + { + name: 'budgetId', + sticky: true, + hint: 'ID of the budget that the cost item is linked to.' + }, + { + name: 'description', + sticky: true, + hint: 'Description of the cost item. Max length of 2048 characters.' + }, + { + name: 'estimated', + sticky: true, + type: 'number', + hint: 'Rough estimation of this item without a quotation.' + }, + { + name: 'proposed', + sticky: true, + type: 'number', + hint: 'Quoted cost of the cost item.' + }, + { + name: 'submitted', + sticky: true, + type: 'number', + hint: 'Amount submitted to the owner for approval.' + }, + { + name: 'approved', + sticky: true, + type: 'number', + hint: 'Amount approved by the owner.' + }, + { + name: 'committed', + sticky: true, + type: 'number', + hint: 'Amount committed to the supplier.' + } + ] + end, + + execute: lambda do |_connection, input| + hub_id = input.delete('hub_id') + project_id = input.delete('project_id') + cost_item_id = input.delete('id') + + container_id = get("/project/v1/hubs/#{hub_id}/projects/#{project_id}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + patch("/cost/v1/containers/#{container_id}/cost-items/#{cost_item_id}") + .payload(input) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: hub_id, container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['cost_item']) + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + (get("/cost/v1/containers/#{container_id}/cost-items?limit=1") || {}) + .dig('results', 0).merge(hub_id: input['hub_id'], container_id: container_id) + end + }, + }, triggers: { From 800ddf05916040ddfb5ddaf007fadfa5aeb5a805 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 4 Mar 2020 10:48:06 -0500 Subject: [PATCH 57/62] add actions for cost attachments (get, create) --- custom_connectors/oauth2/bim_360.rb | 394 ++++++++++++++++++++++++++++ 1 file changed, 394 insertions(+) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 24b3faa3..89cb00ba 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -4818,6 +4818,400 @@ end }, + get_cost_attachments_in_project: { + title: 'Get cost attachments in a project', + + description: 'Get cost attachments' \ + ' in a project in BIM 360', + + help: { + body: 'This action returns all attachments associated with a cost in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'associationId', + label: 'Object ID', + optional: false, + sticky: true, + hint: 'Object ID of the budget, contract, or cost item.' + }, + { + name: 'associationType', + label: 'Object Type', + optional: false, + sticky: true, + control_type: 'select', + pick_list: 'cost_association_types', + toggle_hint: 'Select object type', + toggle_field: { + name: 'associationType', + label: 'Object Type', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter object type', + hint: 'Possible values are: Budget, Contract, CostItem, ' \ + 'FormInstance, Payment, BudgetPayment' + } + } + ] + end, + + execute: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input.delete('hub_id')}/projects/#{input.delete('project_id')}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + get("/cost/v1/containers/#{container_id}/attachments", input) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + end + { results: response } + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'results', type: 'array', + of: 'object', properties: object_definitions['cost_attachment'] } + ] + end, + + sample_output: lambda do |_connection, input| + { + results: [ + { + "id": "F2D2ED17-C763-465B-8FAB-251C5A35D42F", + "folderId": "8E34872D-A56F-4096-B675-476F50F4EF51", + "urn": "urn:adsk.wipprod:fs.file:vf.PMbRnoPZR2mKDhau2uw4SQ?version=1", + "type": "Upload", + "name": "Architecture", + "associationId": "EDC42DF6-277A-436A-A50D-EF57F35E1248", + "associationType": "Budget", + "createdAt": "2019-01-06T01:24:22.678Z", + "updatedAt": "2019-09-05T01:00:12.989Z" + } + ] + } + end + }, + + create_cost_attachment_in_project: { + title: 'Create cost attachment in a project', + + description: 'Create cost attachment' \ + ' in a project in BIM 360', + + help: { + body: 'This action creates an attachment to a cost object in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'name', + optional: false, + sticky: true, + hint: 'Name of the attachment. Max length of 255 characters.' + }, + { + name: 'urn', + optional: false, + sticky: true, + hint: 'Version URN of the BIM 360 Docs file.' + }, + { + name: 'associationId', + optional: false, + sticky: true, + hint: 'Object ID of the budget, contract, or cost item.' + }, + { + name: 'associationType', + label: 'Object Type', + optional: false, + sticky: true, + control_type: 'select', + pick_list: 'cost_association_types', + toggle_hint: 'Select object type', + toggle_field: { + name: 'associationType', + label: 'Object Type', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter object type', + hint: 'Possible values are: Budget, Contract, CostItem,' \ + ' FormInstance, Payment, BudgetPayment' + } + } + ] + end, + + execute: lambda do |_connection, input| + hub_id = input.delete('hub_id') + project_id = input.delete('project_id') + container_id = get("/project/v1/hubs/#{hub_id}/projects/#{project_id}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + attachment_folder = post("/cost/v1/containers/#{container_id}/attachment-folders") + .payload( + 'associationId' => input['associationId'], + 'associationType' => input['associationType'] + ) + .dig('id') + + response = if container_id.present? + post("/cost/v1/containers/#{container_id}/attachments") + .payload( + 'name': input['name'], + 'folderId': attachment_folder, + 'urn': input['urn'], + 'associationId': input['associationId'], + 'associationType': input['associationType'] + ) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.merge(hub_id: hub_id, container_id: container_id) + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'container_id' } + ] + .concat(object_definitions['cost_attachment']) + end, + + sample_output: lambda do |_connection, input| + { + 'id': 'F2D2ED17-C763-465B-8FAB-251C5A35D42F', + 'folderId': '8E34872D-A56F-4096-B675-476F50F4EF51', + 'urn': 'urn:adsk.wipprod:fs.file:vf.PMbRnoPZR2mKDhau2uw4SQ?version=1', + 'type': 'Upload', + 'name': 'Architecture', + 'associationId': 'EDC42DF6-277A-436A-A50D-EF57F35E1248', + 'associationType': 'Budget', + 'createdAt': '2019-01-06T01:24:22.678Z', + 'updatedAt': '2019-09-05T01:00:12.989Z' + } + end + }, + + get_cost_documents_in_project: { + title: 'Get cost documents in a project', + + description: 'Get generated cost documents' \ + ' in a project in BIM 360', + + help: { + body: 'This action returns generated documents associated with cost in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'associationId', + label: 'Object ID', + optional: false, + sticky: true, + hint: 'Object ID of the item, such as budget, contract, or cost item.' + }, + { + name: 'associationType', + label: 'Object Type', + optional: false, + sticky: true, + control_type: 'select', + pick_list: 'cost_association_types', + toggle_hint: 'Select object type', + toggle_field: { + name: 'associationType', + label: 'Object Type', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter object type', + hint: 'Possible values are: Budget, Contract, CostItem, ' \ + 'FormInstance, Payment, BudgetPayment' + } + }, + { + name: 'filter[latest]', + label: 'Latest Version', + optional: true, + sticky: true, + type: 'boolean', + hint: 'Return only the latest version of a document if it has ' \ + 'been generated multiple times.' + }, + { + name: 'filter[signed]', + label: 'Signed Documents', + optional: true, + sticky: true, + type: 'boolean', + hint: 'Return only documents that have been signed.' + } + ] + end, + + execute: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input.delete('hub_id')}/projects/#{input.delete('project_id')}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + get("/cost/v1/containers/#{container_id}/documents", input) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + end + { results: response } + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'results', type: 'array', of: 'object', + properties: object_definitions['cost_document'] } + ] + end, + + sample_output: lambda do |_connection, input| + [ + { + "id": "1df59db0-9484-11e8-a7ec-7ddae203e404", + "templateId": "1df59db0-9484-11e8-a7ec-7ddae203e404", + "recipientId": "GF8XKPKWM38E", + "signedBy": "CED9LVTLHNXV", + "urn": "urn:adsk.wipprod:fs.file:vf.PMbRnoPZR2mKDhau2uw4SQ?version=1", + "signedUrn": "urn:adsk.wipprod:fs.file:vf.PMbRnoPZR2mKDhau2uw4SQ?version=1", + "status": "Completed", + "jobId": 1, + "errorInfo": { + "code": "missingTemplate", + "message": "Couldn't generate the document because the template is invalid.", + "detail": "Got timeout for POST upload URL." + }, + "associationId": "EDC42DF6-277A-436A-A50D-EF57F35E1248", + "associationType": "Budget", + "createdAt": "2019-01-06T01:24:22.678Z", + "updatedAt": "2019-09-05T01:00:12.989Z" + } + ] + end + }, + }, triggers: { From d7155bf2f97391a7eb199c3fa20944bdf035a0f5 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 4 Mar 2020 12:23:00 -0500 Subject: [PATCH 58/62] add actions for cost documents and file packages (get, search, download) --- custom_connectors/oauth2/bim_360.rb | 264 +++++++++++++++++++++++++--- 1 file changed, 239 insertions(+), 25 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 89cb00ba..d304a454 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -4915,7 +4915,7 @@ ] end, - sample_output: lambda do |_connection, input| + sample_output: lambda do |_connection| { results: [ { @@ -5058,7 +5058,7 @@ .concat(object_definitions['cost_attachment']) end, - sample_output: lambda do |_connection, input| + sample_output: lambda do |_connection| { 'id': 'F2D2ED17-C763-465B-8FAB-251C5A35D42F', 'folderId': '8E34872D-A56F-4096-B675-476F50F4EF51', @@ -5148,20 +5148,20 @@ } }, { - name: 'filter[latest]', + name: 'latest', label: 'Latest Version', - optional: true, sticky: true, type: 'boolean', + control_type: 'checkbox', hint: 'Return only the latest version of a document if it has ' \ 'been generated multiple times.' }, { - name: 'filter[signed]', + name: 'signed', label: 'Signed Documents', - optional: true, sticky: true, type: 'boolean', + control_type: 'checkbox', hint: 'Return only documents that have been signed.' } ] @@ -5182,36 +5182,250 @@ output_fields: lambda do |object_definitions| [ - { name: 'results', type: 'array', of: 'object', + { name: 'results', type: 'array', of: 'object', properties: object_definitions['cost_document'] } ] end, - sample_output: lambda do |_connection, input| + sample_output: lambda do |_connection| + { + "results": [ + { + "id": "1df59db0-9484-11e8-a7ec-7ddae203e404", + "templateId": "1df59db0-9484-11e8-a7ec-7ddae203e404", + "recipientId": "GF8XKPKWM38E", + "signedBy": "CED9LVTLHNXV", + "urn": "urn:adsk.wipprod:fs.file:vf.PMbRnoPZR2mKDhau2uw4SQ?version=1", + "signedUrn": "urn:adsk.wipprod:fs.file:vf.PMbRnoPZR2mKDhau2uw4SQ?version=1", + "status": "Completed", + "jobId": 1, + "errorInfo": { + "code": "missingTemplate", + "message": "Couldn't generate the document because the template is invalid.", + "detail": "Got timeout for POST upload URL." + }, + "associationId": "EDC42DF6-277A-436A-A50D-EF57F35E1248", + "associationType": "Budget", + "createdAt": "2019-01-06T01:24:22.678Z", + "updatedAt": "2019-09-05T01:00:12.989Z" + } + ] + } + end + }, + + download_cost_document_in_project: { + title: 'Download cost document in a project', + + description: 'Download generated cost document' \ + ' in a project in BIM 360', + + help: { + body: 'This action downloads generated document associated with cost in a project.' + }, + + input_fields: lambda do |_object_definitions| [ { - "id": "1df59db0-9484-11e8-a7ec-7ddae203e404", - "templateId": "1df59db0-9484-11e8-a7ec-7ddae203e404", - "recipientId": "GF8XKPKWM38E", - "signedBy": "CED9LVTLHNXV", - "urn": "urn:adsk.wipprod:fs.file:vf.PMbRnoPZR2mKDhau2uw4SQ?version=1", - "signedUrn": "urn:adsk.wipprod:fs.file:vf.PMbRnoPZR2mKDhau2uw4SQ?version=1", - "status": "Completed", - "jobId": 1, - "errorInfo": { - "code": "missingTemplate", - "message": "Couldn't generate the document because the template is invalid.", - "detail": "Got timeout for POST upload URL." - }, - "associationId": "EDC42DF6-277A-436A-A50D-EF57F35E1248", - "associationType": "Budget", - "createdAt": "2019-01-06T01:24:22.678Z", - "updatedAt": "2019-09-05T01:00:12.989Z" + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'urn', + optional: false, + sticky: true, + hint: 'The URN ID of the generated cost document.' } ] + end, + + execute: lambda do |_connection, input| + file_url = get("/data/v1/projects/#{input['project_id']}/versions/#{input['urn'].encode_url}") + .dig('data', 'relationships', 'storage', 'meta', 'link', 'href') + + if file_url.present? + { content: get(file_url).headers('Accept-Encoding': 'Accept-Encoding:gzip') + .response_format_raw + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end } + else + error('File does not exist') + end + end, + + output_fields: lambda do |_object_definitions| + [{ name: 'content' }] + end, + + sample_output: lambda do |_connection| + { + "content": "" + } end }, + search_cost_file_packages_in_project: { + title: 'Search cost file packages in a project', + + description: 'Search cost file packages' \ + ' in a project in BIM 360', + + help: { + body: 'This action returns file packages of cost objects in a project.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub', + control_type: 'select', + pick_list: 'hub_list', + optional: false, + toggle_hint: 'Select hub', + toggle_field: { + name: 'hub_id', + label: 'Hub ID', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter hub ID', + hint: 'Get account ID from admin page. To convert an account ID into a hub ID you need to add a “b.” prefix. For example, an account ID of '\ + 'c8b0c73d-3ae9 translates to a hub ID of b.c8b0c73d-3ae9.' + } + }, + { + name: 'project_id', + label: 'Project', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + change_on_blur: true, + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Get ID from url of the project page. For example, a project ID is b.baf-0871-4aca-82e8-3dd6db.' + } + }, + { + name: 'associationId', + label: 'Object ID', + sticky: true, + optional: false, + hint: 'The ID associated with a specific a budget, contract, ' \ + 'cost item, etc.' + }, + { + name: 'associationType', + label: 'Object Type', + sticky: true, + optional: false, + control_type: 'select', + pick_list: 'cost_association_types', + toggle_hint: 'Select object type', + toggle_field: { + name: 'associationType', + label: 'Object Type', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter object type', + hint: 'Possible values are: Budget, Contract, CostItem, ' \ + 'FormInstance, Payment, BudgetPayment' + } + } + ] + end, + + execute: lambda do |_connection, input| + filter_criteria = call('format_cost_search', input.except('hub_id', 'project_id')) + container_id = get("/project/v1/hubs/#{input.delete('hub_id')}/projects/#{input.delete('project_id')}") + .dig('data', 'relationships', 'cost', 'data', 'id') + + response = if container_id.present? + get("/cost/v1/containers/#{container_id}/file-packages", filter_criteria) + .after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + end + { results: response } + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'results', type: 'array', of: 'object', + properties: object_definitions['cost_file_packages'] } + ] + end, + + sample_output: lambda do |_connection, input| + { + "results": [ + { + "id": "a2e16076-d5bb-44b3-b451-fb1fb390e4fc", + "recipient": "GF8XKPKWM38E", + "urn": "urn:adsk.wipprod:fs.file:vf.PMbRnoPZR2mKDhau2uw4SQ?version=1", + "errorInfo": { + "code": "missingTemplate", + "message": "Couldn't generate the document because the template is invalid.", + "detail": "Got timeout for POST upload URL." + }, + "items": [ + { + "id": "a2e16076-d5bb-44b3-b451-fb1fb390e4fc", + "urn": "urn:adsk.wipprod:fs.file:vf.PMbRnoPZR2mKDhau2uw4SQ?version=1", + "name": "GC_001.John-Smith.docx", + "type": "Document", + "createdAt": "2019-01-06T01:24:22.678Z", + "updatedAt": "2019-09-05T01:00:12.989Z" + } + ], + "createdAt": "2019-01-06T01:24:22.678Z", + "updatedAt": "2019-09-05T01:00:12.989Z" + } + ] + } + end + } + }, triggers: { From c035c1a402b5b23b1fcc34e4e5b4f768abd0ec3d Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 4 Mar 2020 12:23:43 -0500 Subject: [PATCH 59/62] update list of cost filters --- custom_connectors/oauth2/bim_360.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index d304a454..eb89880f 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -81,7 +81,9 @@ if input.is_a?(Hash) input.each_with_object({}) do |(key, value), hash| value = call('format_search', value) - if %w[rootId externalSystem externalId code].include?(key) + if %w[rootId externalSystem externalId code + contractId mainContractId budgetStatus costStatus + changeOrderId budgetId associationId associationType].include?(key) hash["filter[#{key}]"] = value else hash[key] = value From c7b5d8d1d5168ae1789af11002c7f97b3f5819f8 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 6 Mar 2020 19:07:28 -0500 Subject: [PATCH 60/62] add `new or updated` triggers for budgets, contracts, change orders, and cost items --- custom_connectors/oauth2/bim_360.rb | 394 ++++++++++++++++++++++++++++ 1 file changed, 394 insertions(+) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index eb89880f..4d0a82be 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -5613,7 +5613,401 @@ sample_output: lambda do |_connection, input| get("/data/v1/projects/#{input['project_id']}/folders/#{input['folder_id']}/contents?page[limit]=1")&.dig('data', 0) || {} end + }, + + new_updated_budget_in_project: { + title: 'New or updated budget in a project', + + description: 'New or updated budget in a project in BIM 360', + + help: { + body: 'Triggers when a budget in a project is created or updated.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false + }, + { + name: 'since', + label: 'When first started, this recipe should pick up events from', + hint: 'When you start recipe for the first time, ' \ + 'it picks up trigger events from this specified date and time. ' \ + 'Leave empty to get records created or updated one hour ago', + sticky: true, + type: 'timestamp' + } + ] + end, + + poll: lambda do |_connection, input, closure| + closure ||= {} + updated_after = closure['updated_after'] || (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 100 + + response = if closure['next_page_url'].present? + get(closure['next_page_url']) + else + closure['container_id'] ||= get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}")&. + dig('data', 'relationships', 'cost', 'data', 'id') + + get("/cost/v1/containers/#{closure['container_id']}/budgets"). + params(limit: limit, + offset: closure['offset'] || 0, + filter: { lastModifiedSince: updated_after }, + sort: 'updatedAt') + end + + if (next_page_url = response.dig('pagination', 'nextUrl')).present? + closure['next_page_url'] = next_page_url + else + closure['offset'] = 0 + closure['updated_after'] = (Array.wrap(response['results']).last||{}).dig('updatedAt') + end + + records = response['results']&.map do |out| + out.merge(project_id: input['project_id'], hub_id: input['hub_id']) + end + { + events: records || [], + next_poll: closure, + can_poll_more: response.dig('pagination', 'nextUrl').present? + } + + end, + + dedup: lambda do |record| + "#{record['id']}@#{record.dig('updatedAt')}" + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'project_id' } + ].concat(object_definitions['budget']).compact + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/budgets?limit]=1")&.dig('results', 0) || {}) + .merge(hub_id: input['hub_id'], project_id: input['project_id']) + end + }, + + new_updated_contract_in_project: { + title: 'New or updated contract in a project', + + description: 'New or updated contract in a project in BIM 360', + + help: { + body: 'Triggers when a contract in a project is created or updated.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false + }, + { + name: 'since', + label: 'When first started, this recipe should pick up events from', + hint: 'When you start recipe for the first time, ' \ + 'it picks up trigger events from this specified date and time. ' \ + 'Leave empty to get records created or updated one hour ago', + sticky: true, + type: 'timestamp' + } + ] + end, + + poll: lambda do |_connection, input, closure| + closure ||= {} + updated_after = closure['updated_after'] || (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 100 + + response = if closure['next_page_url'].present? + get(closure['next_page_url']) + else + closure['container_id'] ||= get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}")&. + dig('data', 'relationships', 'cost', 'data', 'id') + + get("/cost/v1/containers/#{closure['container_id']}/contracts"). + params(limit: limit, + offset: closure['offset'] || 0, + filter: { lastModifiedSince: updated_after }, + sort: 'updatedAt') + end + + if (next_page_url = response.dig('pagination', 'nextUrl')).present? + closure['next_page_url'] = next_page_url + else + closure['offset'] = 0 + closure['updated_after'] = (Array.wrap(response['results']).last||{}).dig('updatedAt') + end + + records = response['results']&.map do |out| + out.merge(project_id: input['project_id'], hub_id: input['hub_id']) + end + { + events: records || [], + next_poll: closure, + can_poll_more: response.dig('pagination', 'nextUrl').present? + } + + end, + + dedup: lambda do |record| + "#{record['id']}@#{record.dig('updatedAt')}" + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'project_id' } + ].concat(object_definitions['contract']).compact + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/contracts?limit]=1")&.dig('results', 0) || {}) + .merge(hub_id: input['hub_id'], project_id: input['project_id']) + end + }, + + new_updated_change_order_in_project: { + title: 'New or updated change order in a project', + + description: 'New or updated change order in a project in BIM 360', + + help: { + body: 'Triggers when a change order in a project is created or updated.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false + }, + { + name: 'type', + label: 'Change Order Type', + control_type: 'select', + pick_list: 'change_order_types', + optional: false, + sticky: true, + toggle_hint: 'Select type', + toggle_field: { + name: 'type', + label: 'Change Order Type', + type: 'string', + change_on_blur: true, + control_type: 'text', + toggle_hint: 'Enter type name' + } + }, + { + name: 'since', + label: 'When first started, this recipe should pick up events from', + hint: 'When you start recipe for the first time, ' \ + 'it picks up trigger events from this specified date and time. ' \ + 'Leave empty to get records created or updated one hour ago', + sticky: true, + type: 'timestamp' + } + ] + end, + + poll: lambda do |_connection, input, closure| + closure ||= {} + updated_after = closure['updated_after'] || (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 100 + + response = if closure['next_page_url'].present? + get(closure['next_page_url']) + else + closure['container_id'] ||= get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}")&. + dig('data', 'relationships', 'cost', 'data', 'id') + + get("/cost/v1/containers/#{closure['container_id']}/change-orders/#{input['type']}"). + params(limit: limit, + offset: closure['offset'] || 0, + filter: { lastModifiedSince: updated_after }, + sort: 'updatedAt') + end + + if (next_page_url = response.dig('pagination', 'nextUrl')).present? + closure['next_page_url'] = next_page_url + else + closure['offset'] = 0 + closure['updated_after'] = (Array.wrap(response['results']).last||{}).dig('updatedAt') + end + + records = response['results']&.map do |out| + out.merge(project_id: input['project_id'], hub_id: input['hub_id']) + end + { + events: records || [], + next_poll: closure, + can_poll_more: response.dig('pagination', 'nextUrl').present? + } + + end, + + dedup: lambda do |record| + "#{record['id']}@#{record.dig('updatedAt')}" + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'project_id' } + ].concat(object_definitions['change_order']).compact + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/change-orders/pco?limit]=1")&.dig('results', 0) || {}) + .merge(hub_id: input['hub_id'], project_id: input['project_id']) + end + }, + + new_updated_cost_item_in_project: { + title: 'New or updated cost item in a project', + + description: 'New or updated cost item in a project in BIM 360', + + help: { + body: 'Triggers when a cost item in a project is created or updated.' + }, + + input_fields: lambda do |_object_definitions| + [ + { + name: 'hub_id', + label: 'Hub name', + control_type: 'select', + pick_list: 'hub_list', + optional: false + }, + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'project_list', + pick_list_params: { hub_id: 'hub_id' }, + optional: false + }, + { + name: 'since', + label: 'When first started, this recipe should pick up events from', + hint: 'When you start recipe for the first time, ' \ + 'it picks up trigger events from this specified date and time. ' \ + 'Leave empty to get records created or updated one hour ago', + sticky: true, + type: 'timestamp' + } + ] + end, + + poll: lambda do |_connection, input, closure| + closure ||= {} + updated_after = closure['updated_after'] || (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 100 + + response = if closure['next_page_url'].present? + get(closure['next_page_url']) + else + closure['container_id'] ||= get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}")&. + dig('data', 'relationships', 'cost', 'data', 'id') + + get("/cost/v1/containers/#{closure['container_id']}/cost-items"). + params(limit: limit, + offset: closure['offset'] || 0, + filter: { lastModifiedSince: updated_after }, + sort: 'updatedAt') + end + + if (next_page_url = response.dig('pagination', 'nextUrl')).present? + closure['next_page_url'] = next_page_url + else + closure['offset'] = 0 + closure['updated_after'] = (Array.wrap(response['results']).last||{}).dig('updatedAt') + end + + records = response['results']&.map do |out| + out.merge(project_id: input['project_id'], hub_id: input['hub_id']) + end + { + events: records || [], + next_poll: closure, + can_poll_more: response.dig('pagination', 'nextUrl').present? + } + + end, + + dedup: lambda do |record| + "#{record['id']}@#{record.dig('updatedAt')}" + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'hub_id' }, + { name: 'project_id' } + ].concat(object_definitions['cost_item']).compact + end, + + sample_output: lambda do |_connection, input| + container_id = get("/project/v1/hubs/#{input['hub_id']}/projects/#{input['project_id']}") + .dig('data', 'relationships', 'cost', 'data', 'id') || {} + + (get("/cost/v1/containers/#{container_id}/cost-items?limit]=1")&.dig('results', 0) || {}) + .merge(hub_id: input['hub_id'], project_id: input['project_id']) + end } + }, pick_lists: { From c2917ebbebb6176d627415dcfa3696ce62e60a77 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 6 Mar 2020 19:59:05 -0500 Subject: [PATCH 61/62] add `lastModifiedSince` filter to GET actions --- custom_connectors/oauth2/bim_360.rb | 58 +++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/custom_connectors/oauth2/bim_360.rb b/custom_connectors/oauth2/bim_360.rb index 4d0a82be..1c30be1d 100644 --- a/custom_connectors/oauth2/bim_360.rb +++ b/custom_connectors/oauth2/bim_360.rb @@ -83,7 +83,8 @@ value = call('format_search', value) if %w[rootId externalSystem externalId code contractId mainContractId budgetStatus costStatus - changeOrderId budgetId associationId associationType].include?(key) + changeOrderId budgetId associationId associationType + latest signed lastModifiedSince].include?(key) hash["filter[#{key}]"] = value else hash[key] = value @@ -2812,6 +2813,11 @@ type: 'number', hint: 'Number of items to return.' }, + { + name: 'lastModifiedSince', + hint: 'Filter to include only items updated since this datetime.', + type: 'date_time' + }, { name: 'sort', hint: 'Order of items to sort. Each item can be followed by a direction modifier' \ @@ -3327,6 +3333,21 @@ type: 'number', hint: 'Number of items to return.' }, + { + name: 'lastModifiedSince', + hint: 'Filter to include only items updated since this datetime.', + type: 'date_time' + }, + { + name: 'lastModifiedSince', + hint: 'Filter to include only items updated since this datetime.', + type: 'date_time' + }, + { + name: 'lastModifiedSince', + hint: 'Filter to include only items updated since this datetime.', + type: 'date_time' + }, { name: 'sort', hint: 'Order of items to sort. Each item can be followed by a ' \ @@ -3871,6 +3892,16 @@ type: 'number', hint: 'Number of items to return.' }, + { + name: 'lastModifiedSince', + hint: 'Filter to include only items updated since this datetime.', + type: 'date_time' + }, + { + name: 'lastModifiedSince', + hint: 'Filter to include only items updated since this datetime.', + type: 'date_time' + }, { name: 'sort', hint: 'Order of items to sort. Each item can be followed by a direction modifier' \ @@ -4893,16 +4924,24 @@ hint: 'Possible values are: Budget, Contract, CostItem, ' \ 'FormInstance, Payment, BudgetPayment' } + }, + { + name: 'lastModifiedSince', + hint: 'Filter to include only items updated since this datetime.', + type: 'date_time' } ] end, execute: lambda do |_connection, input| + filter_criteria = call('format_cost_search', input.except('hub_id', 'project_id', 'associationId', 'associationType')) container_id = get("/project/v1/hubs/#{input.delete('hub_id')}/projects/#{input.delete('project_id')}") .dig('data', 'relationships', 'cost', 'data', 'id') + filter_criteria['associationType'] = input['associationType'] + filter_criteria['associationId'] = input['associationId'] response = if container_id.present? - get("/cost/v1/containers/#{container_id}/attachments", input) + get("/cost/v1/containers/#{container_id}/attachments", filter_criteria) .after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end @@ -5165,16 +5204,24 @@ type: 'boolean', control_type: 'checkbox', hint: 'Return only documents that have been signed.' + }, + { + name: 'lastModifiedSince', + hint: 'Filter to include only items updated since this datetime.', + type: 'date_time' } ] end, execute: lambda do |_connection, input| + filter_criteria = call('format_cost_search', input.except('hub_id', 'project_id', 'associationId', 'associationType')) container_id = get("/project/v1/hubs/#{input.delete('hub_id')}/projects/#{input.delete('project_id')}") .dig('data', 'relationships', 'cost', 'data', 'id') + filter_criteria['associationType'] = input['associationType'] + filter_criteria['associationId'] = input['associationId'] response = if container_id.present? - get("/cost/v1/containers/#{container_id}/documents", input) + get("/cost/v1/containers/#{container_id}/documents", filter_criteria) .after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end @@ -5373,6 +5420,11 @@ hint: 'Possible values are: Budget, Contract, CostItem, ' \ 'FormInstance, Payment, BudgetPayment' } + }, + { + name: 'lastModifiedSince', + hint: 'Filter to include only items updated since this datetime.', + type: 'date_time' } ] end, From 9fa903c3b86bd192378e5691501c3035185cbad9 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Wed, 6 May 2020 15:25:04 -0400 Subject: [PATCH 62/62] initial commit for the Assemble (Autodesk) connector --- custom_connectors/oauth2/assemble.rb | 704 +++++++++++++++++++++++++++ 1 file changed, 704 insertions(+) create mode 100644 custom_connectors/oauth2/assemble.rb diff --git a/custom_connectors/oauth2/assemble.rb b/custom_connectors/oauth2/assemble.rb new file mode 100644 index 00000000..40908594 --- /dev/null +++ b/custom_connectors/oauth2/assemble.rb @@ -0,0 +1,704 @@ +{ + title: 'Assemble', + + connection: { + fields: [ + { + name: 'client_id', + optional: false + }, + { + name: 'client_secret', + optional: false, + type: 'password' + }, + { + name: 'subdomain', + optional: false, + control_type: 'subdomain', + url: '.tryassemble.com' + } + ], + + authorization: { + type: 'oauth2', + + authorization_url: lambda do |connection| + 'https://auth.tryassemble.com/connect/authorize?' + + 'acr_values=idp:forge&scope=tenant%20openid%20core_api.all%20offline_access&response_type=code' + + "&client_id=#{connection['client_id']}&redirect_uri=https%3A%2F%2Fwww.workato.com%2Foauth%2Fcallback" + end, + + acquire: lambda do |connection, auth_code, redirect_uri| + post('https://auth.tryassemble.com/connect/token'). + payload(client_id: connection['client_id'], + client_secret: connection['client_secret'], + code: auth_code, + grant_type: 'authorization_code', + redirect_uri: redirect_uri). + request_format_www_form_urlencoded + end, + + refresh_on: [400, 401, 403, 500], + + refresh: lambda do |connection, refresh_token| + post('https://auth.tryassemble.com/connect/token'). + payload( + client_id: connection['client_id'], + client_secret: connection['client_secret'], + grant_type: 'refresh_token', + refresh_token: refresh_token + ). + request_format_www_form_urlencoded + + end, + + apply: lambda do |_connection, access_token| + headers('Authorization' => "Bearer #{access_token}", 'Content-Type' => 'application/json') + end + + }, + + base_uri: lambda do |connection| + "https://#{connection['subdomain']}.tryassemble.com" + end + + }, + + test: lambda do |_connection| + get('/api/v1/powerbi/projects') + end, + + object_definitions: { + project: { + fields: lambda do |_connection| + [ + { name: 'id', type: 'number'}, + { name: 'name' }, + { name: 'description' }, + { name: 'jobCode' }, + { name: 'cardColorCode' }, + { name: 'isArchived', type: 'boolean' }, + { name: 'unitType' }, + { name: 'userPublishAlignment' }, + { name: 'isValidation', type: 'boolean' }, + { name: 'isApproved', type: 'boolean' }, + { name: 'modelCount', type: 'number' }, + { name: 'viewCount', type: 'number' }, + { name: 'lastActivityTime', type: 'date_time' }, + { name: 'imageAttachmentId' }, + { name: 'imgUrl' }, + { name: 'organizationId', type: 'number' }, + { name: 'approvedByName' }, + { name: 'approvedByDate', type: 'date_time' }, + { name: 'referencedBIM360ProjectData' } + ] + end + }, + model: { + fields: lambda do |_connection| + [ + { name: 'id', type: 'number'}, + { name: 'name' }, + { name: 'createdDate', type: 'date_time' }, + { name: 'createdBy' }, + { name: 'description' }, + { name: 'datasource' }, + { name: 'datasourceTitle' }, + { name: 'projectId', type: 'number' }, + { name: 'projectName' }, + { name: 'hasVersions', type: 'boolean' }, + { name: 'activeVersion', type: 'object', properties: [ + { name: 'id', type: 'number' }, + { name: 'name' }, + { name: 'guid' }, + { name: 'createdDate', type: 'date_time' }, + { name: 'createdBy' }, + { name: 'versionNumber', type: 'number' }, + { name: 'comments' }, + { name: 'projectId', type: 'number' }, + { name: 'projectName' }, + { name: 'modelId', type: 'number' }, + { name: 'modelName' }, + { name: 'datasource' }, + { name: 'source' }, + { name: 'instanceCount', type: 'number' }, + { name: 'hasExpandedEdit', type: 'boolean' }, + { name: 'isMerged', type: 'boolean' }, + { name: 'geometryResourceId' }, + { name: 'sheetMappingResourceId' }, + { name: 'hasGeometry', type: 'boolean' }, + { name: 'canUseWebWorkers', type: 'boolean' }, + { name: 'geometryFilteredCategories' }, + { name: 'estimatedOn' }, + { name: 'estimatedBy' }, + { name: 'formattedEstimatedOn' }, + { name: 'canEstimate' }, + { name: 'audits' }, + { name: 'origins', type: 'object', properties: [ + { name: 'x', type: 'number' }, + { name: 'y', type: 'number' }, + { name: 'z', type: 'number' } + ]}, + { name: 'rotation', type: 'object', properties: [ + { name: 'x', type: 'number' }, + { name: 'y', type: 'number' }, + { name: 'z', type: 'number' } + ]}, + { name: 'userAlignment' }, + { name: 'data' } + ]}, + { name: 'versions', type: 'array', of: 'object', properties: [ + { name: 'id', type: 'number' }, + { name: 'name' }, + { name: 'guid' }, + { name: 'createdDate', type: 'date_time' }, + { name: 'createdBy' }, + { name: 'versionNumber', type: 'number' }, + { name: 'comments' }, + { name: 'projectId', type: 'number' }, + { name: 'projectName' }, + { name: 'modelId', type: 'number' }, + { name: 'modelName' }, + { name: 'datasource' }, + { name: 'source' }, + { name: 'instanceCount', type: 'number' }, + { name: 'hasExpandedEdit', type: 'boolean' }, + { name: 'isMerged', type: 'boolean' }, + { name: 'geometryResourceId' }, + { name: 'sheetMappingResourceId' }, + { name: 'hasGeometry', type: 'boolean' }, + { name: 'canUseWebWorkers', type: 'boolean' }, + { name: 'geometryFilteredCategories' }, + { name: 'estimatedOn' }, + { name: 'estimatedBy' }, + { name: 'formattedEstimatedOn' }, + { name: 'canEstimate' }, + { name: 'audits' }, + { name: 'origins', type: 'object', properties: [ + { name: 'x', type: 'number' }, + { name: 'y', type: 'number' }, + { name: 'z', type: 'number' } + ]}, + { name: 'rotation', type: 'object', properties: [ + { name: 'x', type: 'number' }, + { name: 'y', type: 'number' }, + { name: 'z', type: 'number' } + ]}, + { name: 'userAlignment' }, + { name: 'data' } + ]} + ] + end + }, + model_version: { + fields: lambda do |_connection| + [ + { name: 'id', type: 'number' }, + { name: 'name' }, + { name: 'guid' }, + { name: 'createdDate', type: 'date_time' }, + { name: 'createdBy' }, + { name: 'versionNumber', type: 'number' }, + { name: 'comments' }, + { name: 'projectId', type: 'number' }, + { name: 'projectName' }, + { name: 'modelId', type: 'number' }, + { name: 'modelName' }, + { name: 'datasource' }, + { name: 'source' }, + { name: 'instanceCount', type: 'number' }, + { name: 'hasExpandedEdit', type: 'boolean' }, + { name: 'isMerged', type: 'boolean' }, + { name: 'geometryResourceId' }, + { name: 'sheetMappingResourceId' }, + { name: 'hasGeometry', type: 'boolean' }, + { name: 'canUseWebWorkers', type: 'boolean' }, + { name: 'geometryFilteredCategories' }, + { name: 'estimatedOn' }, + { name: 'estimatedBy' }, + { name: 'formattedEstimatedOn' }, + { name: 'canEstimate' }, + { name: 'audits' }, + { name: 'origins', type: 'object', properties: [ + { name: 'x', type: 'number' }, + { name: 'y', type: 'number' }, + { name: 'z', type: 'number' } + ]}, + { name: 'rotation', type: 'object', properties: [ + { name: 'x', type: 'number' }, + { name: 'y', type: 'number' }, + { name: 'z', type: 'number' } + ]}, + { name: 'userAlignment' }, + { name: 'data' } + ] + end + }, + properties: { + fields: lambda do |_connection| + [ + { name: 'modelVersionId', type: 'number' }, + { name: 'properties', type: 'array', of: 'object', properties: [ + { name: 'id' }, + { name: 'name' }, + { name: 'unit' }, + { name: 'dataType' }, + { name: 'type' }, + { name: 'source' } + ]} + ] + end + }, + grid_data: { + fields: lambda do |_connection| + [ + { name: 'Id' }, + { name: 'RowType' }, + { name: 'AssembleName' }, + { name: 'AssembleModelName' }, + { name: 'ModelVersionDataSource' }, + { name: 'TakeoffUnitAbbreviation' }, + { name: 'TakeoffQuantity' }, + { name: 'QuantityProperty' }, + { name: 'IsActiveTakeoffQuantity' }, + { name: 'TypeProperties' }, + { name: 'ChildSourceIds' }, + { name: 'ModelVersionId' }, + { name: 'ColorOverrides' }, + { name: 'InstanceCount' }, + { name: 'CategoryName:::string', label: 'CategoryName' }, + { name: 'FamilyName:::string', label: 'FamilyName' }, + { name: 'TypeName:::string', label: 'TypeName' }, + { name: 'UnitCost:::numeric', label: 'UnitCost' }, + { name: 'AssembleTotalCost:::numeric', label: 'AssembleTotalCost' }, + { name: 'BidPackage_AssembleProperty:::string', label: 'BidPackage_AssembleProperty'}, + { name: 'AssemblyCode:::string', label: 'AssemblyCode' }, + { name: 'SourceId:::numeric', label: 'SourceId' } + ] + end + }, + custom_action_input: { + fields: lambda do |_connection, config_fields| + input_schema = parse_json(config_fields.dig('input', 'schema') || '[]') + + [ + { + name: 'path', + optional: false, + hint: 'Base URI is https://demo.tryassemble.com - ' \ + 'path will be appended to this URI. ' \ + 'Use absolute URI to override this base URI.' + }, + ( + if %w[get delete].include?(config_fields['verb']) + { + name: 'input', + type: 'object', + control_type: 'form-schema-builder', + sticky: input_schema.blank?, + label: 'URL parameters', + add_field_label: 'Add URL parameter', + properties: [ + { + name: 'schema', + extends_schema: true, + sticky: input_schema.blank? + }, + ( + if input_schema.present? + { + name: 'data', + type: 'object', + properties: call('make_schema_builder_fields_sticky', + input_schema) + } + end + ) + ].compact + } + else + { + name: 'input', + type: 'object', + properties: [ + { + name: 'schema', + extends_schema: true, + schema_neutral: true, + control_type: 'schema-designer', + sample_data_type: 'json_input', + sticky: input_schema.blank?, + label: 'Request body parameters', + add_field_label: 'Add request body parameter' + }, + ( + if input_schema.present? + { + name: 'data', + type: 'object', + properties: input_schema. + each { |field| field[:sticky] = true } + } + end + ) + ].compact + } + end + ), + { + name: 'output', + control_type: 'schema-designer', + sample_data_type: 'json_http', + extends_schema: true, + schema_neutral: true, + sticky: true + } + ] + end + }, + custom_action_output: { + fields: lambda do |_connection, config_fields| + parse_json(config_fields['output'] || '[]') + end + } + }, + + actions: { + custom_action: { + description: "Custom action " \ + "in Assemble", + help: { + body: 'Build your own Assemble action with an HTTP request' + }, + config_fields: [{ + name: 'verb', + label: 'Request type', + hint: 'Select HTTP method of the request', + optional: false, + control_type: 'select', + pick_list: %w[get post patch delete].map { |verb| [verb.upcase, verb] } + }], + input_fields: lambda do |object_definitions| + object_definitions['custom_action_input'] + end, + execute: lambda do |_connection, input| + verb = input['verb'] + if %w[get post patch delete].exclude?(verb) + error("#{verb} not supported") + end + data = input.dig('input', 'data').presence || {} + case verb + when 'get' + response = + get(input['path'], data). + headers('Content-Type': 'application/vnd.api+json'). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.compact + if response.is_a?(Array) + array_name = parse_json(input['output'] || '[]'). + dig(0, 'name') || 'array' + { array_name.to_s => response } + elsif response.is_a?(Hash) + response + else + error('API response is not a JSON') + end + when 'post' + post(input['path'], data). + headers('Content-Type': 'application/vnd.api+json'). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.compact + when 'patch' + patch(input['path'], data). + headers('Content-Type': 'application/vnd.api+json'). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.compact + when 'delete' + delete(input['path'], data). + headers('Content-Type': 'application/vnd.api+json'). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end.compact + end + end, + output_fields: lambda do |object_definitions| + object_definitions['custom_action_output'] + end + }, + get_projects: { + title: 'Get projects', + description: 'Get projects in Assemble.', + + execute: lambda do |_connection, input| + { projects: get('/api/v1/powerbi/projects') } + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'projects', label: 'Projects', + type: 'array', of: 'object', properties: object_definitions['project'] } + ] + end, + + sample_output: lambda do |_connection, input| + { projects: get("/api/v1/powerbi/projects")&.dig(0) || {} } + end + + }, + get_models: { + title: 'Get models for a project', + description: 'Get models in a project in Assemble.', + + input_fields: lambda do |_object_definitions| + [ + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'projects_list', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Provide a project ID' + } + } + ] + end, + execute: lambda do |_connection, input| + { models: get("/api/v1/powerbi/projects/#{input['project_id']}/models") } + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'models', label: 'Models', + type: 'array', of: 'object', properties: object_definitions['model'] } + ] + end, + + sample_output: lambda do |_connection, input| + project = input['project_id'] || get("/api/v1/powerbi/projects")&.dig(0, 'id') || {} + { models: get("/api/v1/powerbi/projects/#{project}/models")&.dig(0) || {} } + end + + }, + get_model_versions: { + title: 'Get model versions for a project', + description: 'Get model versions in a project in Assemble.', + + input_fields: lambda do |_object_definitions| + [ + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'projects_list', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Provide a project ID' + } + } + ] + end, + execute: lambda do |_connection, input| + { versions: get("/api/v1/powerbi/projects/#{input['project_id']}/versions") } + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'versions', label: 'Versions', + type: 'array', of: 'object', properties: object_definitions['model_version'] } + ] + end, + + sample_output: lambda do |_connection, input| + project = input['project_id'] || get("/api/v1/powerbi/projects")&.dig(0, 'id') || {} + { versions: get("/api/v1/powerbi/projects/#{project}/versions")&.dig(0) || {} } + end + + }, + get_properties: { + title: 'Get properties for a project', + description: 'Get properties in a project in Assemble.', + + input_fields: lambda do |_object_definitions| + [ + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'projects_list', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Provide a project ID' + } + } + ] + end, + execute: lambda do |_connection, input| + { properties: get("/api/v1/powerbi/projects/#{input['project_id']}/properties") } + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'properties', label: 'Properties', + type: 'array', of: 'object', properties: object_definitions['properties'] } + ] + end, + + sample_output: lambda do |_connection, input| + project = input['project_id'] || get("/api/v1/powerbi/projects")&.dig(0, 'id') || {} + { properties: get("/api/v1/powerbi/projects/#{project}/properties")&.dig(0) || {} } + end + + }, + get_model_version_data: { + title: 'Get model version data for a project', + description: 'Get model version data in a project in Assemble.', + + input_fields: lambda do |_object_definitions| + [ + { + name: 'project_id', + label: 'Project name', + control_type: 'select', + pick_list: 'projects_list', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_id', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Provide a project ID' + } + }, + { + name: 'model_id', + label: 'Model version', + control_type: 'select', + pick_list: 'model_versions_list', + pick_list_params: { project_id: 'project_id' }, + optional: false, + toggle_hint: 'Select model version', + toggle_field: { + name: 'model_id', + label: 'Model ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use model ID', + hint: 'Provide a model ID' + } + }, + { + name: 'properties_select', + label: 'Select properties', + control_type: 'multiselect', + pick_list: 'project_properties_list', + pick_list_params: { project_id: 'project_id', model_id: 'model_id' }, + delimiter: ',', + optional: true, + sticky: true + }, + { + name: 'properties_define', + label: 'Define properties', + optional: true, + sticky: true, + type: 'array', + of: 'object', + properties: [ + { name: 'id' }, + { name: 'name' }, + { name: 'unit' }, + { name: 'dataType' }, + { name: 'type' }, + { name: 'source' } + ] + } + ] + end, + execute: lambda do |_connection, input| + if input['properties_select'].present? + properties = input['properties_select'].split(',').map do |property| + { + 'id': property.split('_')[0], + 'name': property.split('_')[1], + 'unit': property.split('_')[2], + 'dataType': property.split('_')[3], + 'type': property.split('_')[4], + 'source': property.split('_')[5] + } + end + else + properties = input['properties_define'] + end + + post("/api/v1/powerbi/projects/#{input['project_id']}/versiongriddata/#{input['model_id']}") + .request_body(properties.to_json) + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'records' }, + { name: 'rows', type: 'array', of: 'object', + properties: object_definitions['grid_data'] + } + ] + end, + + sample_output: lambda do |_connection, input| + project = input['project_id'] || get("/api/v1/powerbi/projects")&.dig(0, 'id') || {} + { properties: get("/api/v1/powerbi/projects/#{project}/properties")&.dig(0) || {} } + end + }, + }, + + pick_lists: { + projects_list: lambda do |_connection| + get('/api/v1/powerbi/projects')&.map do |project| + [ project.dig('name'), project.dig('id') ] + end + end, + model_versions_list: lambda do |_connection, project_id:| + if project_id.present? && project_id.slice(0,1) != '#' + get("/api/v1/powerbi/projects/#{project_id}/versions")&.map do |version| + [version.dig('name'), version['id']] + end + end + end, + project_properties_list: lambda do |_connection, project_id:, model_id:| + if project_id.present? && project_id.slice(0,1) != '#' + if model_id.present? && model_id.slice(0,1) != '#' + properties = get("/api/v1/powerbi/projects/#{project_id}/properties") + properties.where(['modelVersionId = ?', model_id]).first['properties'].map do |property| + [ property.dig('name'), + "#{property['id']}_#{property['name']}_#{property['unit']}_#{property['dataType']}_#{property['type']}_#{property['source']}" + ] + end + end + end + end, + } +}