From cb2572c529e74e418ff9addc6f4fd2f2fe2d94f4 Mon Sep 17 00:00:00 2001 From: Chandra Date: Mon, 19 Aug 2019 17:00:54 +0530 Subject: [PATCH 01/78] Create plangrid.rb --- custom_connectors/oauth2/plangrid.rb | 2767 ++++++++++++++++++++++++++ 1 file changed, 2767 insertions(+) create mode 100644 custom_connectors/oauth2/plangrid.rb diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb new file mode 100644 index 00000000..f218284f --- /dev/null +++ b/custom_connectors/oauth2/plangrid.rb @@ -0,0 +1,2767 @@ +{ + title: 'Plangrid', + 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' + } + ], + authorization: { + type: 'oauth2', + authorization_url: lambda do |connection| + 'https://io.plangrid.com/oauth/authorize?response_type=' \ + "code&client_id=#{connection['client_id']}&" \ + 'scope=write:projects%20read:profile' + end, + acquire: lambda do |connection, auth_code, redirect_uri| + response = post('https://io.plangrid.com/oauth/token'). + 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| + post('https://io.plangrid.com/oauth/token'). + payload(grant_type: 'refresh_token', + refresh_token: refresh_token). + request_format_www_form_urlencoded + end, + apply: lambda do |_connection, access_token| + if current_url.include?('https://io.plangrid.com') + headers(Authorization: "Bearer #{access_token}", + Accept: 'application/vnd.plangrid+json; version=1') + end + end + }, + base_uri: lambda do |_connection| + 'https://io.plangrid.com' + end + }, + test: ->(_connection) { get('/me') }, + object_definitions: { + project: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'name', label: 'Project name', sticky: true }, + { name: 'custom_id', label: 'Project code', sticky: true }, + { name: 'organization_id' }, + { name: 'type', control_type: 'select', + label: 'Project type', sticky: true, + pick_list: 'project_types', + toggle_hint: 'Select project type', + toggle_field: { + name: 'type', + label: 'Project type', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Project type with possible values of general,' \ + ' manufacturing, power, water-sewer-waste, industrial-' \ + 'petroleum, transportation, hazardous-waste, telecom, ' \ + 'education-k-12, education-higher, gov-federal, ' \ + 'gov-state-local, or other' + } }, + { name: 'status', label: 'Project status', sticky: true }, + { name: 'owner', sticky: true, label: 'Project owner' }, + { name: 'start_date', type: 'date', + sticky: true, + render_input: 'date_conversion', + parse_output: 'date_conversion', + label: 'Project start date', + hint: 'Project start date. ISO-8601 date format (YYYY-MM-DD).' }, + { name: 'end_date', type: 'date', + sticky: true, + render_input: 'date_conversion', + parse_output: 'date_conversion', + label: 'Project end date', + hint: 'Project end date. ISO-8601 date format (YYYY-MM-DD).' }, + { name: 'street_1', sticky: true, + label: 'Street line 1' }, + { name: 'street_2', sticky: true, label: 'Street line 2' }, + { name: 'city', sticky: true, label: 'Town or city' }, + { name: 'region', sticky: true, label: 'State, province, or region' }, + { name: 'postal_code', sticky: true, label: 'Zip or postal code' }, + { name: 'country', + sticky: true, + hint: 'Project address country in 2-letter ISO 3166 code.' }, + { name: 'latitude' }, + { name: 'longitude' }, + { name: 'updated_at', type: 'date_time', + render_input: 'date_time_conversion', + parse_output: 'date_time_conversion', + label: 'Updated at' } + ] + end + }, + document: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', label: 'Document ID' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'name', label: 'Document name' }, + { name: 'folder' }, + { name: 'url' }, + { name: 'created_at', type: 'date_time', + render_input: 'parse_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' }, + { name: 'email' } + ] }, + { name: 'deleted', type: 'boolean' }, + { name: 'updated_at', type: 'date_time', + render_input: 'parse_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' } + ] + end + }, + task: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', label: 'Task ID' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'assignees', type: 'array', of: 'object', properties: [ + { name: 'assignee' } + ] }, + { name: 'closed_at', type: 'date_time', + render_input: 'date_time_conversion', + parse_output: 'date_time_conversion' }, + { name: 'created_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' }, + { name: 'email' } + ] }, + { name: 'comments', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] }, + { name: 'cost_impact', type: 'number' }, + { name: 'has_cost_impact', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'cost_impact', + label: 'Cost impact', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } }, + { name: 'currency_code', + hint: 'The ISO-4217 currency code of the cost_impact,' \ + ' Currently only supports USD. maybe null if cost_impact is ' \ + 'not specified' }, + { name: 'current_annotation', type: 'object', properties: [ + { name: 'uid' }, + { name: 'color' }, + { name: 'stamp' }, + { name: 'visibility' }, + { name: 'deleted', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'deleted', + label: 'Deleted', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } }, + { name: 'sheet', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' } + ] } + ] }, + { name: 'deleted', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'deleted', + label: 'Deleted', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } }, + { name: 'description' }, + { name: 'due_at', type: 'date_time', + render_input: 'date_time_conversion', + parse_output: 'date_time_conversion' }, + { name: 'followers', type: 'array', of: 'object', properties: [ + { name: 'type' }, + { name: 'uid' } + ] }, + { name: 'issue_list', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' } + ] }, + { name: 'number', type: 'number' }, + { name: 'photos', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] }, + { name: 'room' }, + { name: 'schedule_impact', type: 'integer' }, + { name: 'has_schedule_impact', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'has_schedule_impact', + label: 'Has schedule impact', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } }, + { name: 'start_date', + type: 'date_time', + render_input: 'date_conversion', + parse_output: 'date_conversion' }, + { name: 'status', control_type: 'select', pick_list: + %w[open in_review pending closed].select { |op| [op.labelize, op] }, + 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", "in_review", "pending",' \ + ' "closed".' + } }, + { name: 'string', + hint: 'One to two character stamp associated with task.' }, + { name: 'title' }, + { name: 'type', control_type: 'select', + pick_list: [ + %w[issue issue], + %w[Planned\ work planned_work], + %w[other other] + ], + toggle_hint: 'Select type', + toggle_field: { + name: 'type', + label: 'Type', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: "issue", "planned_work",' \ + ' "other".' + } }, + { name: 'updated_at', + render_input: 'date_time_conversion', + parse_output: 'date_time_conversion', + type: 'date_time' }, + { name: 'updated_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' }, + { name: 'email' } + ] } + + ] + end + }, + file_upload: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid' }, + { name: 'aws_post_form_arguments', type: 'object', + properties: [ + { name: 'action' }, + { name: 'fields', type: 'array', of: 'object', properties: [ + { name: 'name' }, + { name: 'value' } + ] } + ] }, + { name: 'webhook_url' } + ] + end + }, + annotation: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', label: 'Unique Identifier' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'color' }, + { name: 'stamp' }, + { name: 'visibility' }, + { name: 'deleted', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'deleted', + label: 'Deleted', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } }, + { name: 'sheet', type: 'object', properties: [ + { name: 'uid' }, + { name: 'label' }, + { name: 'color' } + ] } + ] + end + }, + snapshot: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', label: 'Snapshot ID' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'title' }, + { name: 'url' }, + { name: 'created_at', type: 'date_time', + render_input: 'parse_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' }, + { name: 'email' } + ] }, + { name: 'sheet', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' } + ] }, + { name: 'deleted', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'deleted', + label: 'Deleted', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } } + ] + end + }, + photo: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', label: 'Photo ID' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'title' }, + { name: 'url' }, + { name: 'created_at', type: 'date_time', + render_input: 'parse_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' }, + { name: 'email' } + ] }, + { name: 'deleted', type: 'boolean', control_type: 'checkbox', + toggle_field: { + name: 'deleted', + label: 'Deleted', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } } + ] + end + }, + field_report: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', label: 'File report ID' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'title' }, + { name: 'description' }, + { name: 'report_date', type: 'date_time', + render_input: 'parse_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'field_report_type', type: 'object', properties: [ + { name: 'name' }, + { name: 'project_uid' }, + { name: 'status' }, + { name: 'uid' } + ] }, + { name: 'pdf_url' }, + { name: 'pdf_form_values', type: 'array', of: 'object', + properties: [ + { name: 'name' }, + { name: 'value' } + ] }, + { name: 'pg_form_values', type: 'array', of: 'object', properties: [ + { name: 'pg_equipment_entries', type: 'array', of: 'object', + properties: [ + { name: 'uid' }, + { name: 'timespan' }, + { name: 'quantity', type: 'integer' }, + { name: 'item' }, + { name: 'description' }, + { name: 'deleted', type: 'boolean', + control_type: 'checkbox', + toggle_hint: 'Select from options list', + toggle_field: { + name: 'deleted', + label: 'Deleted', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } } + ] }, + { name: 'pg_materials_entries', type: 'array', of: 'object', + properties: [ + { name: 'uid' }, + { name: 'unit', type: 'integer' }, + { name: 'quantity', type: 'integer' }, + { name: 'item' }, + { name: 'description' }, + { name: 'deleted' } + ] }, + { name: 'pg_worklog_entries', type: 'array', of: 'object', + properties: [ + { name: 'uid' }, + { name: 'trade' }, + { name: 'timespan' }, + { name: 'headcount', type: 'integer' }, + { name: 'description' }, + { name: 'deleted', type: 'boolean', + control_type: 'checkbox', + toggle_hint: 'Select from options list', + toggle_field: { + name: 'deleted', + label: 'Deleted', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } } + ] } + ] }, + { name: 'attachments', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] }, + { name: 'created_by', type: 'object', properties: [ + { name: 'email' }, + { name: 'uid' }, + { name: 'url' } + ] }, + { name: 'photos', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] }, + { name: 'project_uid', label: 'Project ID' }, + { name: 'report_date', type: 'date' }, + { name: 'snapshots', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] }, + { name: 'status' }, + { name: 'updated_at', type: 'date_time', + render_input: 'parse_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'weather', type: 'object', properties: [ + { name: 'humidity', type: 'number' }, + { name: 'precipitation_accumulation', type: 'number' }, + { name: 'precipitation_accumulation_unit' }, + { name: 'speed_unit' }, + { name: 'summary_key' }, + { name: 'temperature_max', type: 'integer' }, + { name: 'temperature_min' }, + { name: 'temperature_unit' }, + { name: 'wind_bearing', type: 'integer' }, + { name: 'wind_gust', type: 'number' }, + { name: 'wind_speed', type: 'number' } + ] } + ] + end + }, + rfi: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', label: 'RFI ID' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'number', type: 'integer' }, + { name: 'status', type: 'object', properties: [ + { name: 'uid' }, + { name: 'label' }, + { name: 'color' } + ] }, + { name: 'locked', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'locked', + label: 'Locked', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } }, + { name: 'title' }, + { name: 'question' }, + { name: 'answer' }, + { name: 'sent_at', type: 'date_time', + render_input: 'parse_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'Date when the RFI was sent. See ' \ + "Timestamps and " \ + 'Timezones for accepted date formats' }, + { name: 'due_at', type: 'date_time', + render_input: 'parse_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'assigned_to_uids', + hint: 'Array of unique identifiers of users who ' \ + 'are RFI assignees.' }, + { name: 'assigned_to', type: 'array', of: 'object', + properties: [ + { name: 'uid' }, + { name: 'url' }, + { name: 'email' } + ] }, + { name: 'updated_at', type: 'date_time', + render_input: 'parse_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'Date when the RFI was sent. See ' \ + "Timestamps and " \ + 'Timezones for accepted date formats' }, + { name: 'updated_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' }, + { name: 'email' } + ] }, + { name: 'created_at', type: 'date_time', + render_input: 'parse_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' }, + { name: 'email' } + ] }, + { name: 'photos', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] }, + { name: 'attachments', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] }, + { name: 'snapshots', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] }, + { name: 'comments', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] } + ] + end + }, + rfi_status: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', label: 'RFI status ID' }, + { name: 'label' }, + { name: 'color' } + ] + end + }, + user: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', label: 'User ID' }, + { name: 'email' }, + { name: 'first_name' }, + { name: 'last_name' }, + { name: 'language' }, + { name: 'role', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' } + ] }, + { name: 'removed' } + ] + end + }, + sheet: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', label: 'Sheet ID' }, + { name: 'name' }, + { name: 'version_name' }, + { name: 'description' }, + { name: 'tags', hint: 'An array of strings representing the' \ + ' tags added to this sheet.' }, + { name: 'published_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' }, + { name: 'email' } + ] }, + { name: 'published_at', type: 'date_time', + render_input: 'parse_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'UTC date and time in ISO-8601 format.' }, + { name: 'deleted', type: 'boolean', + control_type: 'checkbox', + toggle_hint: 'Select from options list', + toggle_field: { + name: 'deleted', + label: 'Deleted', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } }, + { name: 'uploaded_file_name' } + ] + end + }, + sheet_packet: { + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', label: 'Sheet packet ID' }, + { name: 'file_url' }, + { name: 'resource', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' } + ] }, + { name: 'status' } + ] + 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://io.plangrid.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: call('make_schema_builder_fields_sticky', + input_schema) + } + 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 Plangrid", + help: { + body: 'Build your own Plangrid action for any Plangrid ' \ + 'REST endpoint.', + learn_more_url: 'https://developer.plangrid.com/docs/', + learn_more_text: 'The Plangrid 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'] + error("#{verb} not supported") if %w[get post put delete].exclude?(verb) + 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 + }, + create_project: { + title: 'Create project', + description: 'Create project in'\ + ' Plangrid', + help: { + body: 'Create project action uses the' \ + " Create Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/create-project', + learn_more_text: 'Create Project' + }, + input_fields: lambda do |object_definitions| + object_definitions['project']. + ignored('uid', 'updated_at', 'latitude', 'longitude', + 'organization_id'). + required('name') + end, + execute: lambda do |_connection, input| + post('projects').payload(input). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + end, + output_fields: lambda do |object_definitions| + object_definitions['project'] + end, + sample_output: lambda do |_connection, _input| + get('/projects')&.dig('data', 0) || {} + end + }, + update_project: { + title: 'Update project', + description: 'Update project in'\ + ' Plangrid', + help: { + body: 'Update project action uses the' \ + " Update Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/update-project', + learn_more_text: 'Update a Project' + }, + input_fields: lambda do |object_definitions| + object_definitions['project'].required('uid'). + ignored('updated_at', 'latitude', 'longitude', 'organization_id') + end, + execute: lambda do |_connection, input| + patch("/projects/#{input.delete('uid')}").payload(input). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + end, + output_fields: lambda do |object_definitions| + object_definitions['project'] + end, + sample_output: lambda do |_connection, _input| + get('/projects')&.dig('data', 0) || {} + end + }, + get_project_details: { + title: 'Get project info. by ID', + description: 'Get project info.'\ + ' by ID in Plangrid', + help: { + body: 'Get project info. by ID action uses the' \ + " Retrieve a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/retrieve-a-project', + learn_more_text: 'Retrieve a Project' + }, + input_fields: lambda do |object_definitions| + object_definitions['project'].only('uid').required('uid') + end, + execute: lambda do |_connection, input| + get("/projects/#{input['uid']}") + end, + output_fields: lambda do |object_definitions| + object_definitions['project'] + end, + sample_output: lambda do |_connection, _input| + get('/projects')&.dig('data', 0) || {} + end + }, + upload_document: { + title: 'Upload document to a project', + description: 'Upload document to a project'\ + ' in Plangrid', + help: { + body: 'Upload document to a project action uses the' \ + " Upload Document to Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/upload-' \ + 'attachment-to-project', + learn_more_text: 'Upload Document to Project API' + }, + summarize_input: %w[file_content], + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'content_type', + hint: 'Content type of the document\'s file. e.g. for pdf' \ + ' application/pdf', optional: false }, + { name: 'file_content', optional: false }, + { name: 'name', optional: false, + label: 'Document name', + hint: 'Name of the document.' }, + { name: 'folder', label: 'Folder', sticky: true, + control_type: 'select', + pick_list: 'project_folders', + pick_list_params: { project_uid: 'project_uid' }, + toggle_hint: 'Select folder', + hint: 'Folder shows in select options only if at least one file' \ + ' exist in the folder', + toggle_field: { + name: 'folder', + label: 'Project folder', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Folder in project to place the document ' \ + '(case-sensitive). Leave blank to select root folder' + } }, + { name: 'auto_version', type: 'boolean', + control_type: 'checkbox', + toggle_hint: 'Select from options list', + toggle_field: { + name: 'auto_version', + type: 'boolean', + control_type: 'text', + label: 'Auto version', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } } + ] + end, + execute: lambda do |_connection, input| + file_content = input.delete('file_content') + project_uid = input['project_uid'] + file_upload_info = post("/projects/#{project_uid}/" \ + 'attachments/uploads'). + headers('Content-type': 'application/json'). + payload(input) + url = file_upload_info&.dig('aws_post_form_arguments', 'action') + fields = file_upload_info&.dig('aws_post_form_arguments', 'fields') + # webhook_url = file_upload_info. + # dig('aws_post_form_arguments', 'webhook_url') + headers = fields.map { |o| { o['name'] => o['value'] } }.inject(:merge) + status = + post(url). + payload(key: headers['key'], + policy: headers['policy'], + signature: headers['signature'], + AWSAccessKeyId: headers['AWSAccessKeyId'], + 'content-type': headers['Content-Type'], + 'success_action_redirect': headers['success_action_redirect'], + 'x-amz-server-side-encryption': + headers['x-amz-server-side-encryption'], + 'x-amz-storage-class': headers['x-amz-storage-class'], + file: file_content). + request_format_multipart_form. + after_response do |_code, response, _response_headers| + response + end + status.merge('project_uid' => project_uid) + end, + output_fields: lambda do |object_definitions| + object_definitions['document'] + end, + sample_output: lambda do |_connection, _input| + { + uid: '147a420e-a182-4312-8fa5-4d10064d2f1a', + name: 'Bender', + folder: 'Specifications', + url: 'https://attachment-assets.plangrid.com/147a420e-a182-' \ + '4312-8fa5-4d10064d2f1a.pdf', + created_at: '2013-05-17T02:30:22+00:00', + created_by: { + uid: null, + url: null, + email: 'nick@subcontractor.com' + }, + deleted: false + } + end + + }, + create_rfi: { + title: 'Create RFI in a project', + description: 'Create RFI in'\ + ' a Plangrid project ', + help: { + body: 'Create RFI in project action uses the ' \ + "Create RFI in Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/create-rfi-' \ + 'in-a-project', + learn_more_text: 'Create RFI in a Project' + }, + input_fields: lambda do |object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'status', label: 'Status', + hint: 'Use this for create and update rfi status' } + ].concat(object_definitions['rfi']. + only('locked', 'title', 'question', 'answer', 'sent_at', + 'due_at', 'assigned_to_uids'). + required('title')) + end, + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + payload = input&.map do |key, val| + if %w[due_at sent_at].include?(key) + { key => val.to_time.utc.iso8601 } + else + { key => val } + end + end&.inject(:merge) + post("/projects/#{project_uid}/rfis").payload(payload). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end&.merge('project_uid' => project_uid) + end, + output_fields: lambda do |object_definitions| + object_definitions['rfi'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/rfis")&.dig('data', 0) || {} + end + }, + update_rfi: { + title: 'Update RFI in a project', + description: 'Update RFI in'\ + ' a Plangrid project', + help: { + body: 'Update RFI in Project action uses the ' \ + "patchUpdate RFI in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/update-' \ + 'rfi-in-a-project', + learn_more_text: 'Update RFI in a Project' + }, + input_fields: lambda do |object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'status', label: 'Status', + hint: 'Use this for create and update rfi status' } + ].concat(object_definitions['rfi']. + only('uid', 'locked', 'title', 'question', 'answer', 'sent_at', + 'due_at', 'assigned_to_uids'). + required('uid')) + end, + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + rfi_id = input.delete('uid') + payload = input&.map do |key, val| + if %w[due_at sent_at].include?(key) + { key => val.to_time.utc.iso8601 } + else + { key => val } + end + end&.inject(:merge) + patch("/projects/#{project_uid}/rfis/#{rfi_id}").payload(payload). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end&.merge('project_uid' => project_uid) + end, + output_fields: lambda do |object_definitions| + object_definitions['rfi'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/rfis")&.dig('data', 0) || {} + end + }, + get_rfi_in_project: { + title: 'Get RFI in a project', + description: 'Get RFI by ID in'\ + ' Plangrid project', + help: { + body: 'Get RFI by ID in a project action uses the' \ + " Retrieve RFI in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/" \ + "retrieve-rfis-in-a-project', + learn_more_text: 'Retrieve RFI in a Project' + }, + input_fields: lambda do |object_definitions| + object_definitions['rfi'].only('project_uid', 'uid'). + required('project_uid', 'uid') + end, + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + get("/projects/#{project_uid}/rfis/#{input['uid']}")&. + merge('project_uid' => project_uid) + end, + output_fields: lambda do |object_definitions| + object_definitions['rfi'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/rfis")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end + }, + create_task: { + title: 'Create task in a project', + description: 'Create task in'\ + ' Plangrid project', + help: { + body: 'Create task in Project action uses the ' \ + "Create task in Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/create-task-in-' \ + 'a-project', + learn_more_text: 'Create Task in a Project' + }, + input_fields: lambda do |object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } } + ].concat(object_definitions['task']. + only('assigned_to_uids', 'cost_impact', 'description', 'due_at', + 'has_cost_impact', 'has_schedule_impact', + 'issue_list_uid', 'room', 'schedule_impact', 'start_date', + 'status', 'title', 'type')) + end, + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + payload = input&.map do |key, val| + if %w[due_at].include?(key) + { key => val.to_time.utc.iso8601 } + else + { key => val } + end + end&.inject(:merge) + post("/projects/#{project_uid}/issues").payload(payload). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end&.merge('project_uid' => project_uid) + end, + output_fields: lambda do |object_definitions| + object_definitions['task'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/issues")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end + }, + update_task: { + title: 'Update task in a Project', + description: 'Update task in'\ + ' Plangrid project', + help: { + body: 'Update task in Project action uses the ' \ + "Create task in Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/create-project', + learn_more_text: 'Update Task in a Project' + }, + input_fields: lambda do |object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g.' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } } + ].concat(object_definitions['task']. + only('uid', 'assigned_to_uids', 'cost_impact', 'description', + 'due_at', 'has_cost_impact', 'has_schedule_impact', + 'issue_list_uid', 'room', 'schedule_impact', 'start_date', + 'status', 'title', 'type').required('uid')) + end, + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + patch("/projects/#{project_uid}/issues/" \ + "#{input.delete('uid')}").payload(input). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end&.merge('project_uid' => project_uid) + end, + output_fields: lambda do |object_definitions| + object_definitions['task'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/issues")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end + }, + get_task: { + title: 'Get task in a project', + description: 'Get task in'\ + ' in a Plangrid project', + help: { + body: 'Get task in a project action uses the ' \ + "Retrieve Task in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ + 'issues-in-a-project', + learn_more_text: 'Retrieve Task in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'issue_uid', label: 'Issue ID', optional: false } + ] + end, + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + get("/projects/#{project_uid}/issues/" \ + "#{input['issue_uid']}"). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end&.merge('project_uid' => project_uid) + end, + output_fields: lambda do |object_definitions| + object_definitions['task'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/issues")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end + }, + invite_user_to_project: { + title: 'Invite a user to a project', + description: 'Invite user to'\ + ' project team Plangrid', + help: { + body: 'Invite user to a project action uses the ' \ + "Invite user in Project team API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'invite-user-to-project-team', + learn_more_text: 'Invite User to Project Team' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'email', optional: false }, + { name: 'role_uid', label: 'Role ID', + hint: 'Unique identifier of role to assign user on project team' } + ] + end, + execute: lambda do |_connection, input| + post("/projects/#{input.delete('project_uid')}/users/invites"). + payload(input). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + end, + output_fields: lambda do |object_definitions| + object_definitions['user'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/users")&.dig('data', 0) || {} + end + }, + get_user_in_project: { + title: 'Get user in project', + description: 'Get user in'\ + ' Plangrid project', + help: { + body: 'Get user in project action uses the ' \ + "Retrieve User on a Project Team.", + learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ + 'users-on-a-project-team', + learn_more_text: 'Retrieve User on a Project Team' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'user_uid', label: 'User ID', optional: false } + ] + end, + execute: lambda do |_connection, input| + get("/projects/#{input['project_uid']}/users/" \ + "#{input['user_uid']}") + end, + output_fields: lambda do |object_definitions| + object_definitions['user'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/users")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end + }, + get_snapshot_in_project: { + title: 'Get snapshot in a project', + description: 'Get snapshot in'\ + ' a Plangrid project', + help: { + body: 'Get snapshot in a project action uses the ' \ + "Retrieve Snapshot in a Project.", + learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ + 'snapshot-in-a-project', + learn_more_text: 'Retrieve Snapshot in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'snapshot_uid', label: 'Snapshot ID', optional: false } + ] + end, + execute: lambda do |_connection, input| + get("/projects/#{input['project_uid']}/snapshots/" \ + "#{input['snapshot_uid']}") + end, + output_fields: lambda do |object_definitions| + object_definitions['snapshot'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/snapshots")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end + }, + get_rfi_statuses_in_project: { + title: 'Get RFI statuses in project', + description: 'Get rfi statuses in'\ + ' Plangrid project', + help: { + body: 'Get rfi statuses in project action uses the ' \ + "Retrieve RFI Statuses in a Project.", + learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ + 'rfi-statuses-in-a-project', + learn_more_text: 'Retrieve RFI Statuses in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'limit', type: 'integer', + hint: 'Number of RFI statuses to retrieve. Maximum value of 50.' }, + { name: 'skip', type: 'integer', + hint: 'Number of RFI statuses to skip in the set of results.' } + ] + end, + execute: lambda do |_connection, input| + { statuses: + get("/projects/#{input['project_uid']}/rfis/statuses")['data'] } + end, + output_fields: lambda do |object_definitions| + [ + { name: 'statuses', type: 'array', of: 'object', + properties: object_definitions['rfi_status'] } + ] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/rfis/statuses")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end + }, + get_roles_on_project: { + title: 'Get roles on a project', + description: 'Get roles on '\ + ' Plangrid project', + help: { + body: 'Get role on a project action uses the ' \ + "Retrieve Role on a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-role-on-a-project', + learn_more_text: 'Retrieve Role on a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'limit', type: 'integer', + hint: 'Number of roles to retrieve. Maximum value of 50.' }, + { name: 'skip', type: 'integer', + hint: 'Number of roles to skip in the set of results.' } + ] + end, + execute: lambda do |_connection, input| + { roles: get("/projects/#{input.delete('project_uid')}/roles", input) } + end, + output_fields: lambda do |_object_definitions| + [ + { name: 'roles', type: 'array', of: 'object', properties: [ + { name: 'uid' }, + { name: 'label' } + ] }, + { name: 'total_count' }, + { name: 'next_page_url' } + ] + end, + sample_output: lambda do |_connection, _input| + { 'roles' => { 'uid' => '9d139e64-cac9-4f23-b4d5-9fd3688b498e', + 'label' => 'Admin' } } + end + }, + get_sheets_in_project: { + title: 'Get sheets in project', + description: 'Get sheets in'\ + ' Plangrid project', + help: { + body: 'Get sheets in project action uses the ' \ + "Retrieve Sheets in a Project.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-sheets-in-a-project', + learn_more_text: 'Retrieve Sheets in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'limit', type: 'integer', + hint: 'Number of sheets to retrieve. Maximum value of 50.' }, + { name: 'skip', type: 'integer', + hint: 'Number of sheets to skip in the set of results' }, + { name: 'updated_after', type: 'date_time', + hint: 'Only retrieve sheets created/updated after ' \ + 'specified UTC date and time.' } + ] + end, + execute: lambda do |_connection, input| + { sheets: get("/projects/#{input.delete('project_uid')}/sheets", + input)['data'] } + end, + output_fields: lambda do |object_definitions| + [{ name: 'sheets', type: 'array', of: 'object', + properties: object_definitions['sheet'] }] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + { + sheets: get("/projects/#{id}/sheets?limit=1")&.dig('data', 0)&. + merge('project_uid' => id) || {} + } + end + }, + get_sheet_in_project: { + title: 'Get sheet by ID in project', + description: 'Get sheet in'\ + ' Plangrid project', + help: { + body: 'Get project sheet details action uses the ' \ + "Retrieve Sheets in a Project.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-a-sheet', + learn_more_text: 'Retrieve Sheet in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'sheet_uid', type: 'Sheet ID', optional: false } + ] + end, + execute: lambda do |_connection, input| + get("/projects/#{input['project_uid']}/sheets/#{input['sheet_uid']}") + end, + output_fields: lambda do |object_definitions| + object_definitions['sheet'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/sheets?limit=1")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end + }, + get_project_sheet_packet: { + title: 'Get project sheet packet', + description: 'Get project sheet packet in'\ + ' packet in Plangrid', + help: { + body: 'Get project sheet packet action uses the ' \ + "Retrieve Sheet Packet API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-sheet-packet', + learn_more_text: 'Retrieve Sheet Packet' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'packet_uid', type: 'Packet ID' } + ] + end, + execute: lambda do |_connection, input| + get("/projects/#{input['project_uid']}/sheets/packets/" \ + "#{input['packet_uid']}") + end, + output_fields: lambda do |object_definitions| + object_definitions['sheet_packet'] + end + }, + get_field_reports_in_project: { + title: 'Get fields reports in project', + description: 'Get field reports in'\ + ' in Plangrid project', + help: { + body: 'Get fields reports in project action uses the ' \ + "Retrieve Field Reports in a" \ + ' Project API.', + learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ + 'field-reports-in-a-project', + learn_more_text: 'Retrieve Field Reports in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'updated_after', type: 'date_time', + hint: 'Only retrieve field reports created/updated after ' \ + 'specified UTC date and time.' }, + { name: 'report_date_min', type: 'date_time', + label: 'Report start date', + hint: 'Only retrieve field reports between a date range ' \ + 'starting with this date in UTC format.' }, + { name: 'report_date_max', type: 'date_time', + label: 'Report end date', + hint: 'Only retrieve field reports between a date range ' \ + 'starting with this date in UTC format.' }, + { name: 'sort_by', control_type: 'select', + pick_list: + %w[report_date updated_at]&.map { |e| [e.labelize, e] }, + toggle_hint: 'Select sort by column', + toggle_field: { + name: 'sort_by', type: 'string', control_type: 'text', + hint: 'Allowed values report_date or updated_at' + } } + ] + end, + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + query_params = '' + input&.map do |key, val| + if %w[updated_after report_date_min report_date_max].include?(key) + query_params = query_params + "#{key}=#{val.to_time.utc.iso8601}" + else + query_params = query_params + "#{key}=#{val}" + end + end + { field_reports: get("/projects/#{project_uid}/field_reports?" \ + "#{query_params}")['data'] } + end, + output_fields: lambda do |object_definitions| + { name: 'field_reports', type: 'array', of: 'object', + properties: object_definitions['field_report'] } + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + { field_reports: + get("/projects/#{id}/rfis/field_reports")&. + merge('project_uid' => id) || {} } + end + }, + upload_photo: { + title: 'Uplod photo to project', + description: 'Upload photo to '\ + ' project in Plangrid', + help: { + body: 'Upload photo to a project action uses the' \ + " Upload Photo to Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/upload-photo' \ + '-to-project', + learn_more_text: 'Upload Photo to Project' + }, + summarize_input: %w[file_content], + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'content_type', optional: false, + hint: "Content type of the photo's file" }, + { name: 'file_content', optional: false }, + { name: 'title', optional: false, label: 'Photo title' } + ] + end, + execute: lambda do |_connection, input| + file_content = input.delete('file_content') + file_upload_info = post("/projects/#{input.delete('project_uid')}/" \ + 'photos/uploads'). + headers('Content-type': 'application/json'). + payload(input) + url = file_upload_info&.dig('aws_post_form_arguments', 'action') + fields = file_upload_info&.dig('aws_post_form_arguments', 'fields') + # webhook_url = file_upload_info. + # dig('aws_post_form_arguments', 'webhook_url') + headers = fields.map { |o| { o['name'] => o['value'] } }.inject(:merge) + post(url). + payload(key: headers['key'], + policy: headers['policy'], + signature: headers['signature'], + AWSAccessKeyId: headers['AWSAccessKeyId'], + 'content-type': headers['Content-Type'], + 'success_action_redirect': headers['success_action_redirect'], + 'x-amz-server-side-encryption': + headers['x-amz-server-side-encryption'], + 'x-amz-storage-class': headers['x-amz-storage-class'], + file: file_content). + request_format_multipart_form. + after_response do |_code, response, _response_headers| + response + end + end, + output_fields: lambda do |object_definitions| + object_definitions['photo'] + end, + sample_output: lambda do |_connection, _input| + { + uid: '147a420e-a182-4312-8fa5-4d10064d2f1a', + title: 'Bongo Drums', + url: 'https://attachment-assets.plangrid.com/147a420e-a182-' \ + '4312-8fa5-4d10064d2f1a.pdf', + created_at: '2013-05-17T02:30:22+00:00', + created_by: { + uid: null, + url: null, + email: 'nick@subcontractor.com' + }, + deleted: false + } + end + }, + update_photo_metadata: { + title: 'Update photo metadata', + description: 'Update photo metadata to '\ + ' Project in Plangrid', + help: { + body: 'Update photo metadata action uses the' \ + " Update Document to Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/update-photo-' \ + 'in-a-project', + learn_more_text: 'Update photo to Project API' + }, + summarize_input: %w[file_content], + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'photo_uid', type: 'Photo ID', optional: false }, + { name: 'title', label: 'Photo title', + hint: 'New title of the photo' } + ] + end, + execute: lambda do |_connection, input| + patch("/projects/#{input.delete('project_uid')}/photos/" \ + "#{input.delete('photo_uid')}"). + headers('Content-type': 'application/json'). + payload(input). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + end, + output_fields: lambda do |object_definitions| + object_definitions['photo'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/photos")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end + }, + get_photo_details: { + title: 'Get photo by ID', + description: 'Get photo in'\ + ' a Plangrid project', + help: { + body: 'Get photo details action uses the ' \ + "Retrieve Photo in Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-a-sheet', + learn_more_text: 'Retrieve Photo in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'photo_uid', type: 'Photo ID', optional: false } + ] + end, + execute: lambda do |_connection, input| + get("/projects/#{input['project_uid']}/photos/" \ + "#{input['photo_uid']}") + end, + output_fields: lambda do |object_definitions| + object_definitions['photo'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/photos")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end + }, + get_document_details: { + title: 'Get document by ID', + description: 'Get document in'\ + ' in Plangrid project', + help: { + body: 'Get document details action uses the ' \ + "Retrieve Document in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-a-sheet', + learn_more_text: 'Retrieve Document in a Project API' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'attachment_uid', type: 'Document ID', optional: false } + ] + end, + execute: lambda do |_connection, input| + get("/projects/#{input['project_uid']}/attachments/" \ + "#{input['attachment_uid']}") + end, + output_fields: lambda do |object_definitions| + object_definitions['document'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/attachments")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end + } + }, + triggers: { + new_updated_project: { + title: 'New/updated project', + description: 'New/updated project in'\ + ' Plangrid', + help: { + body: 'New/updated project trigger uses the' \ + " List all Projects API.", + learn_more_url: 'https://developer.plangrid.com/docs/list-all-projects', + learn_more_text: 'List All Projects API' + }, + input_fields: lambda do |_object_definitions| + [ + { + 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| + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 20 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get('/projects'). + params(limit: limit, + skip: skip, + updated_after: updated_after) + end + closure = if (next_page_url = response['next_page_url']).present? + { 'skip' => skip + limit, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'updated_after' => now.to_time.utc.iso8601 } + end + { + events: response['data'] || [], + next_poll: closure, + can_poll_more: response['next_page_url'].present? + } + end, + dedup: lambda do |project| + "#{project['uid']}@#{project['updated_at']}" + end, + output_fields: lambda do |object_definitions| + object_definitions['project'] + end, + sample_output: lambda do |_connection, _input| + get('/projects')&.dig('data', 0) || {} + end + }, + new_updated_documents: { + title: 'New/updated documents in a project', + description: 'New/updated document in '\ + 'Project Plangrid', + help: { + body: 'New/updated documents in Project trigger uses the' \ + " Retrieve Documents in a Project" \ + ' API.', + learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ + 'attachments-in-a-project', + learn_more_text: 'Retrieve Documents in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { + 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_uid = closure&.[]('project_uid') || input['project_uid'] + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 5 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get("/projects/#{project_uid}/attachments"). + params(limit: limit, + skip: skip, + updated_after: updated_after) + end + closure = if (next_page_url = response['next_page_url']).present? + { 'skip' => skip + limit, + 'project_uid' => project_uid, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'project_uid' => project_uid, + 'updated_after' => now.to_time.utc.iso8601 } + end + documents = response['data']&. + map { |o| o.merge('project_uid' => project_uid) } + { + events: documents || [], + next_poll: closure, + can_poll_more: response['next_page_url'].present? + } + end, + dedup: lambda do |document| + "#{document['uid']}@#{document['created_at']}" + end, + output_fields: lambda do |object_definitions| + object_definitions['document'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/attachments")&.dig('data', 0) || {} + end + }, + new_updated_task: { + title: 'New/updated task in a Project', + description: 'New/updated task in a '\ + 'Project Plangrid', + help: { + body: 'New/updated task in a Project trigger uses the' \ + " Retrieve Tasks " \ + ' in a Project API.', + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-issues-in-a-project', + learn_more_text: 'Retrieve Tasks in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { + 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_uid = closure&.[]('project_uid') || input['project_uid'] + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 10 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get("/projects/#{input.delete('project_uid')}/" \ + 'issues'). + params(limit: limit, + skip: skip, + include_annotationless: true, + updated_after: updated_after) + end + closure = if (next_page_url = response['next_page_url']).present? + { 'skip' => skip + limit, + 'project_uid' => project_uid, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'project_uid' => project_uid, + 'updated_after' => now.to_time.utc.iso8601 } + end + tasks = response['data']&. + map { |o| o.merge('project_uid' => project_uid) } + { + events: tasks || [], + next_poll: closure, + can_poll_more: response['next_page_url'].present? + } + end, + dedup: lambda do |task| + "#{task['uid']}@#{task['updated_at']}" + end, + output_fields: lambda do |object_definitions| + object_definitions['task'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/issues")&. + dig('data', 0) || {} + end + }, + new_updated_annotations: { + title: 'New/updated annotations in Project', + description: 'New/updated annotations '\ + 'in Project Plangrid', + help: { + body: 'New/updated annotations in Project trigger uses the' \ + " Retrieve " \ + ' annotations in a Project API.', + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-annotations-in-a-project', + learn_more_text: 'Retrieve Annotations in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { + 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_uid = closure&.[]('project_uid') || input['project_uid'] + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 10 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get("/projects/#{input.delete('project_uid')}/" \ + 'annotations'). + params(limit: limit, + skip: skip, + updated_after: updated_after) + end + closure = if (next_page_url = response['next_page_url']).present? + { 'skip' => skip + limit, + 'project_uid' => project_uid, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'project_uid' => project_uid, + 'updated_after' => now.to_time.utc.iso8601 } + end + annotations = response['data']&. + map { |o| o.merge('project_uid' => project_uid) } + { + events: annotations || [], + next_poll: closure, + can_poll_more: response['next_page_url'].present? + } + end, + dedup: lambda do |annotation| + "#{annotation['uid']}@#{annotation['updated_at']}" + end, + output_fields: lambda do |object_definitions| + object_definitions['annotation'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/annotations")&. + dig('data', 0) || {} + end + }, + new_updated_photos: { + title: 'New/updated photos in Project', + description: 'New/updated photos '\ + 'in Plangrid Project', + help: { + body: 'New/updated photos in Project trigger uses the' \ + " Retrieve " \ + ' photos in a Project API.', + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-photos-in-a-project', + learn_more_text: 'Retrieve photos in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { + 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_uid = closure&.[]('project_uid') || input['project_uid'] + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 10 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get("/projects/#{input.delete('project_uid')}/" \ + 'photos'). + params(limit: limit, + skip: skip, + updated_after: updated_after) + end + closure = if (next_page_url = response['next_page_url']).present? + { 'skip' => skip + limit, + 'project_uid' => project_uid, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'project_uid' => project_uid, + 'updated_after' => now.to_time.utc.iso8601 } + end + photos = response['data']&. + map { |o| o.merge('project_uid' => project_uid) } + { + events: photos || [], + next_poll: closure, + can_poll_more: response['next_page_url'].present? + } + end, + dedup: lambda do |photo| + "#{photo['uid']}@#{photo['updated_at']}" + end, + output_fields: lambda do |object_definitions| + object_definitions['photo'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/photos")&. + dig('data', 0) || {} + end + }, + new_updated_snapshot: { + title: 'New/updated snapshot in a Project', + description: 'New/updated snapshot '\ + 'in a Project Plangrid', + help: { + body: 'New/updated snapshot in a Project trigger uses the' \ + " Retrieve " \ + ' Snapshots in a Project API.', + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'remove-snapshot-reference-in-rfi', + learn_more_text: 'Retrieve Snapshots in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { + 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_uid = closure&.[]('project_uid') || input['project_uid'] + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 10 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get("/projects/#{input.delete('project_uid')}/" \ + 'snapshots'). + params(limit: limit, + skip: skip, + updated_after: updated_after) + end + closure = if (next_page_url = response['next_page_url']).present? + { 'skip' => skip + limit, + 'project_uid' => project_uid, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'project_uid' => project_uid, + 'updated_after' => now.to_time.utc.iso8601 } + end + snapshots = response['data']&. + map { |o| o.merge('project_uid' => project_uid) } + { + events: snapshots || [], + next_poll: closure, + can_poll_more: response['next_page_url'].present? + } + end, + dedup: lambda do |annotation| + "#{annotation['uid']}@#{annotation['updated_at']}" + end, + output_fields: lambda do |object_definitions| + object_definitions['snapshot'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/snapshots")&. + dig('data', 0) || {} + end + }, + new_updated_field_report: { + title: 'New/updated field report in a Project', + description: 'New/updated field report '\ + 'in Plangrid Project', + help: { + body: 'New/updated field report in Project trigger uses the' \ + " Retrieve " \ + 'field reports in a Project API.', + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-field-reports-in-a-project', + learn_more_text: 'Retrieve field reports in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { + 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_uid = closure&.[]('project_uid') || input['project_uid'] + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 10 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get("/projects/#{input.delete('project_uid')}/" \ + 'field_reports'). + params(limit: limit, + skip: skip, + updated_after: updated_after, + sort_by: 'updated_at', + sort_order: 'asc') + end + closure = if (next_page_url = response['next_page_url']).present? + { 'skip' => skip + limit, + 'project_uid' => project_uid, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'project_uid' => project_uid, + 'updated_after' => now.to_time.utc.iso8601 } + end + field_reports = response['data']&. + map { |o| o.merge('project_uid' => project_uid) } + { + events: field_reports || [], + next_poll: closure, + can_poll_more: response['next_page_url'].present? + } + end, + dedup: lambda do |field_report| + "#{field_report['uid']}@#{field_report['updated_at']}" + end, + output_fields: lambda do |object_definitions| + object_definitions['field_report'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/field_reports")&. + dig('data', 0) || {} + end + }, + new_updated_rfi: { + title: 'New/updated RFI in a Project', + description: 'New/updated RFI '\ + 'in a Plangrid Project', + help: { + body: 'New/updated RFI in a Project trigger uses the' \ + " Retrieve " \ + ' RFIs in a Project API.', + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-rfis-in-a-project', + learn_more_text: 'Retrieve RFIs in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { + 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_uid = closure&.[]('project_uid') || input['project_uid'] + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 10 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get("/projects/#{input.delete('project_uid')}/" \ + 'rfis'). + params(limit: limit, + skip: skip, + updated_after: updated_after) + end + closure = if (next_page_url = response['next_page_url']).present? + { 'skip' => skip + limit, + 'project_uid' => project_uid, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'project_uid' => project_uid, + 'updated_after' => now.to_time.utc.iso8601 } + end + rfis = response['data']&. + map { |o| o.merge('project_uid' => project_uid) } + { + events: rfis || [], + next_poll: closure, + can_poll_more: response['next_page_url'].present? + } + end, + dedup: lambda do |rfi| + "#{rfi['uid']}@#{rfi['updated_at']}" + end, + output_fields: lambda do |object_definitions| + object_definitions['rfi'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/rfis")&. + dig('data', 0) || {} + end + } + }, + pick_lists: { + project_list: lambda do |_connection| + get('projects')&.[]('data')&.pluck('name', 'uid') + end, + project_types: lambda do |_connection| + ['general', 'manufacturing', 'power', 'water-sewer-waste', + 'industrial-petroleum', 'transportation', 'hazardous-waste', + 'telecom', 'education-k-12', 'education-higher', 'gov-federal', + 'gov-state-local', 'other'].map { |type| [type.labelize, type] } + end, + project_folders: lambda do |_connection, project_uid:| + folders = get("/projects/#{project_uid}/attachments")['data']&. + pluck('folder')&.uniq + if folders.size > 0 + folders&.map { |folder| [folder || 'Root', folder || ''] } + else + [['Root', '']] + end + end + } +} From 73983af64c8cb7282c1c05e1f9f605ad7bf11db5 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Tue, 20 Aug 2019 15:49:53 -0400 Subject: [PATCH 02/78] change title to `PlanGrid` with capital `G` --- custom_connectors/oauth2/plangrid.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index f218284f..c00417a9 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1,5 +1,5 @@ { - title: 'Plangrid', + title: 'PlanGrid', connection: { fields: [ { From 08c66a7f6cfcf09c037bd295293a4bb88ed5b0e7 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 12:57:21 -0400 Subject: [PATCH 03/78] update `document` object definition --- custom_connectors/oauth2/plangrid.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index c00417a9..eda14fb4 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -132,7 +132,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -145,14 +145,14 @@ hint: 'Provide project ID e.g. ' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'name', label: 'Document name' }, + { name: 'name', label: 'Document Name' }, { name: 'folder' }, { name: 'url' }, { name: 'created_at', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'created_by', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, From b864213a1be4762e9d52ab08467255dc6174194d Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 12:57:55 -0400 Subject: [PATCH 04/78] update title and description for `New document...` trigger --- custom_connectors/oauth2/plangrid.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index eda14fb4..48c39b30 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2169,11 +2169,11 @@ end }, new_updated_documents: { - title: 'New/updated documents in a project', - description: 'New/updated document in '\ - 'Project Plangrid', + title: 'New or updated document in a project', + description: 'New or updated document in '\ + 'a PlanGrid project', help: { - body: 'New/updated documents in Project trigger uses the' \ + body: 'New or updated document in a project trigger uses the' \ " Retrieve Documents in a Project" \ ' API.', From 8d30006c5677467f2c023ead279508a391d96691 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 12:58:51 -0400 Subject: [PATCH 05/78] update `Get document...` action, append `project_uid` to result --- custom_connectors/oauth2/plangrid.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 48c39b30..dbb2934f 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2061,11 +2061,11 @@ end }, get_document_details: { - title: 'Get document by ID', - description: 'Get document in'\ - ' in Plangrid project', + title: 'Get document in a project', + description: 'Get document'\ + ' in a PlanGrid project', help: { - body: 'Get document details action uses the ' \ + body: 'Get document in a project action uses the ' \ "Retrieve Document in a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ @@ -2090,12 +2090,12 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'attachment_uid', type: 'Document ID', optional: false } + { name: 'attachment_uid', label: 'Document ID', optional: false } ] end, execute: lambda do |_connection, input| get("/projects/#{input['project_uid']}/attachments/" \ - "#{input['attachment_uid']}") + "#{input['attachment_uid']}")&.merge('project_uid' => input.delete('project_uid')) end, output_fields: lambda do |object_definitions| object_definitions['document'] From 715fdd9a7e9c5a500dbd33cac2f843aadf0e6c76 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 12:59:58 -0400 Subject: [PATCH 06/78] pull down `project_folders` pick list only if UID is present --- custom_connectors/oauth2/plangrid.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index dbb2934f..e6ab64cb 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2755,12 +2755,14 @@ 'gov-state-local', 'other'].map { |type| [type.labelize, type] } end, project_folders: lambda do |_connection, project_uid:| - folders = get("/projects/#{project_uid}/attachments")['data']&. - pluck('folder')&.uniq - if folders.size > 0 - folders&.map { |folder| [folder || 'Root', folder || ''] } - else - [['Root', '']] + if project_uid.length === 36 + folders = get("/projects/#{project_uid}/attachments")['data']&. + pluck('folder')&.uniq + if folders.size > 0 + folders&.map { |folder| [folder || 'Root', folder || ''] } + else + [['Root', '']] + end end end } From cac9cd154735fdf60f6435d02f0cded81343db2a Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 13:07:47 -0400 Subject: [PATCH 07/78] update title and description for `Upload document...` action, fix 400 error due to `project_uid` being included in payload, make `auto_version` sticky --- custom_connectors/oauth2/plangrid.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index e6ab64cb..8ca4c49f 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -996,8 +996,8 @@ }, upload_document: { title: 'Upload document to a project', - description: 'Upload document to a project'\ - ' in Plangrid', + description: 'Upload document to a'\ + ' PlanGrid project', help: { body: 'Upload document to a project action uses the' \ " Date: Thu, 22 Aug 2019 13:08:11 -0400 Subject: [PATCH 08/78] add new `Update document...` action --- custom_connectors/oauth2/plangrid.rb | 54 +++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 8ca4c49f..f6a85186 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1108,7 +1108,59 @@ deleted: false } end - + }, + update_document: { + title: 'Update document in a project', + description: 'Update document in a'\ + ' PlanGrid project', + help: { + body: 'Update document in a project action uses the' \ + " Update Document to Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/update-attachment-' \ + 'in-a-project', + learn_more_text: 'Update Document in a Project API' + }, + summarize_input: %w[file_content], + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'attachment_uid', label: 'Document ID', optional: false }, + { name: 'name', label: 'Document Name', + hint: 'New name of the document', sticky: true }, + { name: 'folder', label: 'Folder', + hint: 'New folder of the document', sticky: true } + ] + end, + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + patch("/projects/#{project_uid}/attachments/" \ + "#{input.delete('attachment_uid')}"). + headers('Content-type': 'application/json'). + payload(input). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end&.merge('project_uid' => project_uid) + end, + output_fields: lambda do |object_definitions| + object_definitions['document'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/attachments")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end }, create_rfi: { title: 'Create RFI in a project', From e8ec1c00f04459ffe027a6391cedeee1e24d83d7 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 17:35:00 -0400 Subject: [PATCH 09/78] update `photo` object definition to resolve issue with output not showing up --- custom_connectors/oauth2/plangrid.rb | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index f6a85186..b116bc7e 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -434,7 +434,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -448,24 +448,16 @@ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, { name: 'title' }, - { name: 'url' }, + { name: 'url', label: 'URL' }, { name: 'created_at', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'created_by', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, - { name: 'deleted', type: 'boolean', control_type: 'checkbox', - toggle_field: { - name: 'deleted', - label: 'Deleted', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } } + { name: 'deleted', type: 'boolean' } ] end }, From 65987ae632f02cc2256adcffcca629f17d4481da Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 17:35:21 -0400 Subject: [PATCH 10/78] update title and description for `New photo...` trigger --- custom_connectors/oauth2/plangrid.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index b116bc7e..579906a4 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2459,17 +2459,17 @@ end }, new_updated_photos: { - title: 'New/updated photos in Project', - description: 'New/updated photos '\ - 'in Plangrid Project', + title: 'New or updated photo in a project', + description: 'New or updated photo '\ + 'in a PlanGrid project', help: { - body: 'New/updated photos in Project trigger uses the' \ + body: 'New or updated photo in a project trigger uses the' \ " Retrieve " \ ' photos in a Project API.', learn_more_url: 'https://developer.plangrid.com/docs/' \ 'retrieve-photos-in-a-project', - learn_more_text: 'Retrieve photos in a Project' + learn_more_text: 'Retrieve Photos in a Project' }, input_fields: lambda do |_object_definitions| [ From 3a19f8a96dd203445c3566855358375ec519be6d Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 17:36:27 -0400 Subject: [PATCH 11/78] update title and description for `Get photo...` action, append `project_uid` to result --- custom_connectors/oauth2/plangrid.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 579906a4..a0f76576 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2060,11 +2060,11 @@ end }, get_photo_details: { - title: 'Get photo by ID', + title: 'Get photo in a project', description: 'Get photo in'\ - ' a Plangrid project', + ' a PlanGrid project', help: { - body: 'Get photo details action uses the ' \ + body: 'Get photo action uses the ' \ "Retrieve Photo in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ @@ -2089,12 +2089,12 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'photo_uid', type: 'Photo ID', optional: false } + { name: 'photo_uid', label: 'Photo ID', optional: false } ] end, execute: lambda do |_connection, input| get("/projects/#{input['project_uid']}/photos/" \ - "#{input['photo_uid']}") + "#{input['photo_uid']}")&.merge('project_uid' => input.delete('project_uid')) end, output_fields: lambda do |object_definitions| object_definitions['photo'] From 407f8eb60b984644a2f3e5914da9ff7cec2f106e Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 17:37:01 -0400 Subject: [PATCH 12/78] update title and description for `Update photo...` action, append `project_uid` to result --- custom_connectors/oauth2/plangrid.rb | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index a0f76576..849f7da5 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2010,16 +2010,16 @@ end }, update_photo_metadata: { - title: 'Update photo metadata', - description: 'Update photo metadata to '\ - ' Project in Plangrid', + title: 'Update photo in a project', + description: 'Update photo in'\ + ' a PlanGrid project', help: { - body: 'Update photo metadata action uses the' \ + body: 'Update photo action uses the' \ " Update Document to Project API.", + "project' target='_blank'>Update Photo in a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/update-photo-' \ 'in-a-project', - learn_more_text: 'Update photo to Project API' + learn_more_text: 'Update Photo in a Project API' }, summarize_input: %w[file_content], input_fields: lambda do |_object_definitions| @@ -2036,19 +2036,20 @@ toggle_hint: 'Use project ID', hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'photo_uid', type: 'Photo ID', optional: false }, + { name: 'photo_uid', label: 'Photo ID', optional: false }, { name: 'title', label: 'Photo title', - hint: 'New title of the photo' } + hint: 'New title of the photo', sticky: true } ] end, execute: lambda do |_connection, input| - patch("/projects/#{input.delete('project_uid')}/photos/" \ + project_uid = input.delete('project_uid') + patch("/projects/#{project_uid}/photos/" \ "#{input.delete('photo_uid')}"). headers('Content-type': 'application/json'). payload(input). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end + end&.merge('project_uid' => project_uid) end, output_fields: lambda do |object_definitions| object_definitions['photo'] From 310b93d4a27a8dc69d851b68aea250d886118489 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 17:42:18 -0400 Subject: [PATCH 13/78] update title and description for `Upload photo..` action, append `project_uid` to result --- custom_connectors/oauth2/plangrid.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 849f7da5..f992bcef 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1931,9 +1931,9 @@ end }, upload_photo: { - title: 'Uplod photo to project', + title: 'Upload photo to a project', description: 'Upload photo to '\ - ' project in Plangrid', + ' a PlanGrid project', help: { body: 'Upload photo to a project action uses the' \ " project_uid) end, output_fields: lambda do |object_definitions| object_definitions['photo'] From 378af15170d287159d44cbc016eee1b576ed54f7 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 18:47:11 -0400 Subject: [PATCH 14/78] update `snapshot` object definition --- custom_connectors/oauth2/plangrid.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index f992bcef..c2662b3d 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -387,7 +387,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -406,12 +406,12 @@ render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'created_by', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, { name: 'sheet', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' } ] }, { name: 'deleted', type: 'boolean', From 0f2695e8fa1563f1969559c9a3e0921ed44519d4 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 18:48:15 -0400 Subject: [PATCH 15/78] update title and description for `Get snapshot..` action, append `project_uid` to result --- custom_connectors/oauth2/plangrid.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index c2662b3d..e34f9442 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1564,7 +1564,7 @@ get_snapshot_in_project: { title: 'Get snapshot in a project', description: 'Get snapshot in'\ - ' a Plangrid project', + ' a PlanGrid project', help: { body: 'Get snapshot in a project action uses the ' \ " input['project_uid']) end, output_fields: lambda do |object_definitions| object_definitions['snapshot'] From 3165ec3fbb1ecab170f0555c1ab078ae0ed07a62 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 18:49:02 -0400 Subject: [PATCH 16/78] update title and description for `New or updated snapshot..` trigger --- custom_connectors/oauth2/plangrid.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index e34f9442..4e415ecf 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2544,16 +2544,16 @@ end }, new_updated_snapshot: { - title: 'New/updated snapshot in a Project', - description: 'New/updated snapshot '\ - 'in a Project Plangrid', + title: 'New or updated snapshot in a project', + description: 'New or updated snapshot '\ + 'in a PlanGrid project', help: { - body: 'New/updated snapshot in a Project trigger uses the' \ + body: 'New or updated snapshot in a project trigger uses the' \ " Retrieve " \ + "retrieve-snapshots-in-a-project' target='_blank'>Retrieve " \ ' Snapshots in a Project API.', learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'remove-snapshot-reference-in-rfi', + 'retrieve-snapshots-in-a-project', learn_more_text: 'Retrieve Snapshots in a Project' }, input_fields: lambda do |_object_definitions| From da6e4bda7ebf809ca40bf71e50f7b80519b294cd Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 22:30:52 -0400 Subject: [PATCH 17/78] update `project` object definition --- custom_connectors/oauth2/plangrid.rb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 4e415ecf..1d99a6e4 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -61,7 +61,7 @@ { name: 'uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -74,11 +74,11 @@ hint: 'Provide project ID e.g. ' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'name', label: 'Project name', sticky: true }, - { name: 'custom_id', label: 'Project code', sticky: true }, - { name: 'organization_id' }, + { name: 'name', label: 'Project Name', sticky: true }, + { name: 'custom_id', label: 'Project Code', sticky: true }, + { name: 'organization_id', label: 'Organization ID' }, { name: 'type', control_type: 'select', - label: 'Project type', sticky: true, + label: 'Project Type', sticky: true, pick_list: 'project_types', toggle_hint: 'Select project type', toggle_field: { @@ -93,26 +93,26 @@ 'education-k-12, education-higher, gov-federal, ' \ 'gov-state-local, or other' } }, - { name: 'status', label: 'Project status', sticky: true }, - { name: 'owner', sticky: true, label: 'Project owner' }, + { name: 'status', label: 'Project Status', sticky: true }, + { name: 'owner', sticky: true, label: 'Project Owner' }, { name: 'start_date', type: 'date', sticky: true, render_input: 'date_conversion', parse_output: 'date_conversion', - label: 'Project start date', + label: 'Project Start Date', hint: 'Project start date. ISO-8601 date format (YYYY-MM-DD).' }, { name: 'end_date', type: 'date', sticky: true, render_input: 'date_conversion', parse_output: 'date_conversion', - label: 'Project end date', + label: 'Project End Date', hint: 'Project end date. ISO-8601 date format (YYYY-MM-DD).' }, { name: 'street_1', sticky: true, - label: 'Street line 1' }, + label: 'Street Line 1' }, { name: 'street_2', sticky: true, label: 'Street line 2' }, - { name: 'city', sticky: true, label: 'Town or city' }, - { name: 'region', sticky: true, label: 'State, province, or region' }, - { name: 'postal_code', sticky: true, label: 'Zip or postal code' }, + { name: 'city', sticky: true, label: 'Town or City' }, + { name: 'region', sticky: true, label: 'State, Province, or Region' }, + { name: 'postal_code', sticky: true, label: 'Zip or Postal Code' }, { name: 'country', sticky: true, hint: 'Project address country in 2-letter ISO 3166 code.' }, From eddb8b4f8520b06af99f24e98b65d5390f8572b7 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 22:31:43 -0400 Subject: [PATCH 18/78] update title and description for `Create project` action, include `add_to_organization` parameter --- custom_connectors/oauth2/plangrid.rb | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 1d99a6e4..e6529695 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -907,7 +907,7 @@ create_project: { title: 'Create project', description: 'Create project in'\ - ' Plangrid', + ' PlanGrid', help: { body: 'Create project action uses the' \ " Date: Thu, 22 Aug 2019 22:32:43 -0400 Subject: [PATCH 19/78] update title and description for `Update project` action, handle empty/nil parameters --- custom_connectors/oauth2/plangrid.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index e6529695..27cb3edb 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -952,20 +952,23 @@ update_project: { title: 'Update project', description: 'Update project in'\ - ' Plangrid', + ' PlanGrid', help: { body: 'Update project action uses the' \ " Update Project API.", learn_more_url: 'https://developer.plangrid.com/docs/update-project', - learn_more_text: 'Update a Project' + learn_more_text: 'Update Project' }, input_fields: lambda do |object_definitions| object_definitions['project'].required('uid'). ignored('updated_at', 'latitude', 'longitude', 'organization_id') end, execute: lambda do |_connection, input| - patch("/projects/#{input.delete('uid')}").payload(input). + payload = input.each do |key, value| + input[key].present? || input[key] = nil + end + patch("/projects/#{input.delete('uid')}").payload(payload.except('uid')). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end From 81560c454368b9114356fe50dd8b8d1a1fce5a64 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 22:33:04 -0400 Subject: [PATCH 20/78] update title and description for `Get project` action --- custom_connectors/oauth2/plangrid.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 27cb3edb..bca6b3a6 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -981,11 +981,11 @@ end }, get_project_details: { - title: 'Get project info. by ID', - description: 'Get project info.'\ - ' by ID in Plangrid', + title: 'Get project', + description: 'Get project'\ + ' in PlanGrid', help: { - body: 'Get project info. by ID action uses the' \ + body: 'Get project action uses the' \ " Retrieve a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/retrieve-a-project', From 9a274a11b36b65449e4181eadf8d9ead7a82a23d Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 22:49:16 -0400 Subject: [PATCH 21/78] update title and description for `New annotation..` --- custom_connectors/oauth2/plangrid.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index bca6b3a6..15e33c0c 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2398,14 +2398,14 @@ end }, new_updated_annotations: { - title: 'New/updated annotations in Project', - description: 'New/updated annotations '\ - 'in Project Plangrid', + title: 'New or updated annotation in a project', + description: 'New or updated annotation '\ + 'in a PlanGrid project', help: { - body: 'New/updated annotations in Project trigger uses the' \ + body: 'New or updated annotation in project trigger uses the' \ " Retrieve " \ - ' annotations in a Project API.', + ' Annotations in a Project API.', learn_more_url: 'https://developer.plangrid.com/docs/' \ 'retrieve-annotations-in-a-project', learn_more_text: 'Retrieve Annotations in a Project' From bd80e21fb6c754fe64ba8a370c572d3cc4551504 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 22:49:37 -0400 Subject: [PATCH 22/78] update `annotation` object definition --- custom_connectors/oauth2/plangrid.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 15e33c0c..bc7ada15 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -342,11 +342,11 @@ annotation: { fields: lambda do |_connection, _config_fields| [ - { name: 'uid', label: 'Unique Identifier' }, + { name: 'uid', label: 'Annotation ID' }, { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -373,9 +373,8 @@ hint: 'Allowed values are: true, false' } }, { name: 'sheet', type: 'object', properties: [ - { name: 'uid' }, - { name: 'label' }, - { name: 'color' } + { name: 'uid', label: 'UID' }, + { name: 'url' } ] } ] end From 1444a9b664dd8649189b47b849313319fdb7757b Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 23:00:41 -0400 Subject: [PATCH 23/78] update `sheet` object definition --- custom_connectors/oauth2/plangrid.rb | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index bc7ada15..4f7875ff 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -711,13 +711,29 @@ fields: lambda do |_connection, _config_fields| [ { name: 'uid', label: 'Sheet ID' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project ID', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, { name: 'name' }, - { name: 'version_name' }, + { name: 'version_name', label: 'Version Name' }, { name: 'description' }, - { name: 'tags', hint: 'An array of strings representing the' \ + { name: 'tags', type: 'array', of: 'string', hint: 'An array of strings representing the' \ ' tags added to this sheet.' }, { name: 'published_by', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, @@ -736,7 +752,7 @@ toggle_hint: 'Use custom value', hint: 'Allowed values are: true, false' } }, - { name: 'uploaded_file_name' } + { name: 'uploaded_file_name', label: 'Uploaded file name' } ] end }, From 9d9913c5c690c8ad06af960a8a7dfb6292e94125 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 23:01:24 -0400 Subject: [PATCH 24/78] update title and description for `Get sheet...` action, append `project_uid` to result --- custom_connectors/oauth2/plangrid.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 4f7875ff..c78e5d90 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1802,13 +1802,13 @@ end }, get_sheet_in_project: { - title: 'Get sheet by ID in project', - description: 'Get sheet in'\ - ' Plangrid project', + title: 'Get sheet in a project', + description: 'Get sheet in '\ + 'a PlanGrid project', help: { - body: 'Get project sheet details action uses the ' \ + body: 'Get sheet in a project action uses the ' \ "Retrieve Sheets in a Project.", + " target='_blank'>Retrieve Sheet in a Project.", learn_more_url: 'https://developer.plangrid.com/docs/' \ 'retrieve-a-sheet', learn_more_text: 'Retrieve Sheet in a Project' @@ -1818,7 +1818,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', optional: false, toggle_hint: 'Select project', toggle_field: { @@ -1831,11 +1831,12 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'sheet_uid', type: 'Sheet ID', optional: false } + { name: 'sheet_uid', label: 'Sheet ID', optional: false } ] end, execute: lambda do |_connection, input| - get("/projects/#{input['project_uid']}/sheets/#{input['sheet_uid']}") + get("/projects/#{input['project_uid']}/sheets/#{input['sheet_uid']}")&. + merge('project_uid' => input['project_uid']) end, output_fields: lambda do |object_definitions| object_definitions['sheet'] From 34ffbdd734cb5e45089ec6f15ed5dbd17124d5fd Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 23:16:13 -0400 Subject: [PATCH 25/78] add `New or updated sheet...` trigger --- custom_connectors/oauth2/plangrid.rb | 80 ++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index c78e5d90..f7fe9efe 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2250,6 +2250,86 @@ get('/projects')&.dig('data', 0) || {} end }, + new_updated_sheets: { + title: 'New or updated sheet in a project', + description: 'New or updated sheet in '\ + 'a PlanGrid project', + help: { + body: 'New or updated sheet in a project trigger uses the' \ + " Retrieve Sheets in a Project" \ + ' API.', + learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ + 'sheets-in-a-project', + learn_more_text: 'Retrieve Sheets in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { + 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_uid = closure&.[]('project_uid') || input['project_uid'] + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 5 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get("/projects/#{project_uid}/sheets"). + params(limit: limit, + skip: skip, + updated_after: updated_after) + end + closure = if (next_page_url = response['next_page_url']).present? + { 'skip' => skip + limit, + 'project_uid' => project_uid, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'project_uid' => project_uid, + 'updated_after' => now.to_time.utc.iso8601 } + end + sheets = response['data']&. + map { |o| o.merge('project_uid' => project_uid) } + { + events: sheets || [], + next_poll: closure, + can_poll_more: response['next_page_url'].present? + } + end, + dedup: lambda do |sheet| + "#{sheet['uid']}@#{sheet['created_at']}" + end, + output_fields: lambda do |object_definitions| + object_definitions['sheet'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/sheets")&.dig('data', 0) || {} + end + }, new_updated_documents: { title: 'New or updated document in a project', description: 'New or updated document in '\ From d56295d6ac12ac2dfb4a3a3b9117bb8aa0c33ab8 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 22 Aug 2019 23:53:46 -0400 Subject: [PATCH 26/78] update title and description for `New project` trigger --- custom_connectors/oauth2/plangrid.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index f7fe9efe..7fa44000 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2191,13 +2191,13 @@ }, triggers: { new_updated_project: { - title: 'New/updated project', - description: 'New/updated project in'\ - ' Plangrid', + title: 'New or updated project', + description: 'New or updated project in'\ + ' PlanGrid', help: { - body: 'New/updated project trigger uses the' \ + body: 'New or updated project trigger uses the' \ " List all Projects API.", + " target='_blank'>List All Projects API.", learn_more_url: 'https://developer.plangrid.com/docs/list-all-projects', learn_more_text: 'List All Projects API' }, From 6b8e05e991eae651582e0b2c97d05e8a6e689380 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 00:33:25 -0400 Subject: [PATCH 27/78] update `rfi` object definition --- custom_connectors/oauth2/plangrid.rb | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 7fa44000..c420f08f 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -592,7 +592,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -607,7 +607,7 @@ } }, { name: 'number', type: 'integer' }, { name: 'status', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'label' }, { name: 'color' } ] }, @@ -634,12 +634,9 @@ { name: 'due_at', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, - { name: 'assigned_to_uids', - hint: 'Array of unique identifiers of users who ' \ - 'are RFI assignees.' }, { name: 'assigned_to', type: 'array', of: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, @@ -651,7 +648,7 @@ "timestamps-and-timezones' target='_blank'>Timestamps and " \ 'Timezones for accepted date formats' }, { name: 'updated_by', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, @@ -659,7 +656,7 @@ render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'created_by', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, From a6e02305430b5b34feddc8fbeafabfbf7f48fe3a Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 00:33:44 -0400 Subject: [PATCH 28/78] update `rfi_status` object definition --- custom_connectors/oauth2/plangrid.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index c420f08f..7c59a10b 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -682,7 +682,7 @@ rfi_status: { fields: lambda do |_connection, _config_fields| [ - { name: 'uid', label: 'RFI status ID' }, + { name: 'uid', label: 'Status ID' }, { name: 'label' }, { name: 'color' } ] From 7aa0f0f58111136276bc2afa6c3bb37262375be0 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 00:34:05 -0400 Subject: [PATCH 29/78] update title and description for `Create RFI...` action --- custom_connectors/oauth2/plangrid.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 7c59a10b..d4bd45fe 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1187,9 +1187,9 @@ create_rfi: { title: 'Create RFI in a project', description: 'Create RFI in'\ - ' a Plangrid project ', + ' a PlanGrid project ', help: { - body: 'Create RFI in project action uses the ' \ + body: 'Create RFI in a project action uses the ' \ "Create RFI in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/create-rfi-' \ From af586b79c34092d574dec56d31643135cf4984e3 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 00:34:44 -0400 Subject: [PATCH 30/78] update title and description for `Update RFI..` action --- custom_connectors/oauth2/plangrid.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index d4bd45fe..e7929e12 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1246,11 +1246,11 @@ update_rfi: { title: 'Update RFI in a project', description: 'Update RFI in'\ - ' a Plangrid project', + ' a PlanGrid project', help: { - body: 'Update RFI in Project action uses the ' \ + body: 'Update RFI in a project action uses the ' \ "patchUpdate RFI in a Project API.", + "project' target='_blank'>Update RFI in a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/update-' \ 'rfi-in-a-project', learn_more_text: 'Update RFI in a Project' @@ -1273,8 +1273,7 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'status', label: 'Status', - hint: 'Use this for create and update rfi status' } + { name: 'status', label: 'Status UID' } ].concat(object_definitions['rfi']. only('uid', 'locked', 'title', 'question', 'answer', 'sent_at', 'due_at', 'assigned_to_uids'). From a5669a4097016efee99674d97ec558ed6f70a259 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 00:35:57 -0400 Subject: [PATCH 31/78] update title and description for `Get RFI..` action, include input fields without using object definition for RFI due to sorting issues (RFI ID came before Project) --- custom_connectors/oauth2/plangrid.rb | 29 ++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index e7929e12..94fd0e16 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1304,10 +1304,10 @@ }, get_rfi_in_project: { title: 'Get RFI in a project', - description: 'Get RFI by ID in'\ - ' Plangrid project', + description: 'Get RFI in '\ + 'a PlanGrid project', help: { - body: 'Get RFI by ID in a project action uses the' \ + body: 'Get RFI in a project action uses the' \ " Retrieve RFI in a Project API.", @@ -1316,12 +1316,29 @@ learn_more_text: 'Retrieve RFI in a Project' }, input_fields: lambda do |object_definitions| - object_definitions['rfi'].only('project_uid', 'uid'). - required('project_uid', 'uid') + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'rfi_uid', label: 'RFI ID', optional: false } + ] end, execute: lambda do |_connection, input| project_uid = input.delete('project_uid') - get("/projects/#{project_uid}/rfis/#{input['uid']}")&. + get("/projects/#{project_uid}/rfis/#{input['rfi_uid']}")&. merge('project_uid' => project_uid) end, output_fields: lambda do |object_definitions| From a057b4c5fd3e53fa473c342ba9c262532b8f6b3a Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 00:36:20 -0400 Subject: [PATCH 32/78] update title and description for `Get RFI statuses...` action --- custom_connectors/oauth2/plangrid.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 94fd0e16..1206943d 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1655,10 +1655,10 @@ }, get_rfi_statuses_in_project: { title: 'Get RFI statuses in project', - description: 'Get rfi statuses in'\ - ' Plangrid project', + description: 'Get RFI statuses in'\ + ' a PlanGrid project', help: { - body: 'Get rfi statuses in project action uses the ' \ + body: 'Get RFI statuses in project action uses the ' \ "Retrieve RFI Statuses in a Project.", learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ From e8e473d38457490ebd7c9a0a8bc260dc3776601f Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 00:36:46 -0400 Subject: [PATCH 33/78] update title and description for `New or updated RFI..` trigger --- custom_connectors/oauth2/plangrid.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 1206943d..7a9bb7cc 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2837,11 +2837,11 @@ end }, new_updated_rfi: { - title: 'New/updated RFI in a Project', - description: 'New/updated RFI '\ - 'in a Plangrid Project', + title: 'New or updated RFI in a project', + description: 'New or updated RFI '\ + 'in a PlanGrid project', help: { - body: 'New/updated RFI in a Project trigger uses the' \ + body: 'New or updated RFI in a project trigger uses the' \ " Retrieve " \ ' RFIs in a Project API.', From 0b134419809028d32696cd70aeedfa2e7b2a2f91 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 10:16:04 -0400 Subject: [PATCH 34/78] update `task` object definition --- custom_connectors/oauth2/plangrid.rb | 155 ++++++++++++++------------- 1 file changed, 78 insertions(+), 77 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 7a9bb7cc..a0b1fff5 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -170,7 +170,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -183,26 +183,64 @@ hint: 'Provide project ID e.g. ' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, + { name: 'number', type: 'number' }, + { name: 'title' }, + { name: 'status', control_type: 'select', pick_list: + %w[open in_review pending closed].select { |op| [op.labelize, op] }, + 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", "in_review", "pending",' \ + ' "closed".' + } }, + { name: 'type', control_type: 'select', + pick_list: [ + %w[issue issue], + %w[Planned\ work planned_work], + %w[other other] + ], + toggle_hint: 'Select type', + toggle_field: { + name: 'type', + label: 'Type', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: "issue", "planned_work",' \ + ' "other".' + } }, { name: 'assignees', type: 'array', of: 'object', properties: [ - { name: 'assignee' } + { name: 'uid', label: 'UID' }, + { name: 'type' } ] }, + { name: 'followers', label: 'Watchers', type: 'array', of: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'type' } + ] }, + { name: 'room', label: 'Location' }, + { name: 'start_date', label: 'Start Date', + type: 'date_time', + render_input: 'date_conversion', + parse_output: 'date_conversion' }, { name: 'closed_at', type: 'date_time', render_input: 'date_time_conversion', parse_output: 'date_time_conversion' }, - { name: 'created_at', type: 'date_time', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'created_by', type: 'object', properties: [ + { name: 'due_at', type: 'date_time', + render_input: 'date_time_conversion', + parse_output: 'date_time_conversion' }, + { name: 'string', label: 'Stamp', + hint: 'One to two character stamp associated with task.' }, + { name: 'issue_list', label: 'Issue List', type: 'object', properties: [ { name: 'uid' }, - { name: 'url' }, - { name: 'email' } - ] }, - { name: 'comments', type: 'object', properties: [ - { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'cost_impact', type: 'number' }, - { name: 'has_cost_impact', type: 'boolean', + { name: 'description' }, + { name: 'cost_impact', label: 'Cost Impact', type: 'number' }, + { name: 'has_cost_impact', label: 'Has Cost Impact?', type: 'boolean', control_type: 'checkbox', toggle_hint: 'Select from options list', toggle_field: { name: 'cost_impact', @@ -212,12 +250,23 @@ toggle_hint: 'Use custom value', hint: 'Allowed values are: true, false' } }, - { name: 'currency_code', + { name: 'currency_code', label: 'Currency Code', hint: 'The ISO-4217 currency code of the cost_impact,' \ ' Currently only supports USD. maybe null if cost_impact is ' \ 'not specified' }, + { name: 'schedule_impact', label: 'Schedule Impact', type: 'integer' }, + { name: 'has_schedule_impact', label: 'Has Schedule Impact?', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'has_schedule_impact', + label: 'Has schedule impact', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } }, { name: 'current_annotation', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'color' }, { name: 'stamp' }, { name: 'visibility' }, @@ -232,84 +281,36 @@ hint: 'Allowed values are: true, false' } }, { name: 'sheet', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' } ] } ] }, - { name: 'deleted', type: 'boolean', - control_type: 'checkbox', toggle_hint: 'Select from options list', - toggle_field: { - name: 'deleted', - label: 'Deleted', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } }, - { name: 'description' }, - { name: 'due_at', type: 'date_time', - render_input: 'date_time_conversion', - parse_output: 'date_time_conversion' }, - { name: 'followers', type: 'array', of: 'object', properties: [ - { name: 'type' }, - { name: 'uid' } - ] }, - { name: 'issue_list', type: 'object', properties: [ - { name: 'uid' }, + { name: 'comments', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'number', type: 'number' }, { name: 'photos', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'room' }, - { name: 'schedule_impact', type: 'integer' }, - { name: 'has_schedule_impact', type: 'boolean', + { name: 'deleted', label: 'Deleted?', type: 'boolean', control_type: 'checkbox', toggle_hint: 'Select from options list', toggle_field: { - name: 'has_schedule_impact', - label: 'Has schedule impact', + name: 'deleted', + label: 'Deleted', type: 'string', control_type: 'text', toggle_hint: 'Use custom value', hint: 'Allowed values are: true, false' } }, - { name: 'start_date', - type: 'date_time', - render_input: 'date_conversion', - parse_output: 'date_conversion' }, - { name: 'status', control_type: 'select', pick_list: - %w[open in_review pending closed].select { |op| [op.labelize, op] }, - 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", "in_review", "pending",' \ - ' "closed".' - } }, - { name: 'string', - hint: 'One to two character stamp associated with task.' }, - { name: 'title' }, - { name: 'type', control_type: 'select', - pick_list: [ - %w[issue issue], - %w[Planned\ work planned_work], - %w[other other] - ], - toggle_hint: 'Select type', - toggle_field: { - name: 'type', - label: 'Type', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: "issue", "planned_work",' \ - ' "other".' - } }, + { name: 'created_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'url' }, + { name: 'email' } + ] }, { name: 'updated_at', render_input: 'date_time_conversion', parse_output: 'date_time_conversion', From 5b3d4211f86c1d28e1a19bb08a06b116471b028c Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 10:16:38 -0400 Subject: [PATCH 35/78] update title and description for `Create task..` action, re-order fields --- custom_connectors/oauth2/plangrid.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index a0b1fff5..db62e901 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1354,11 +1354,11 @@ create_task: { title: 'Create task in a project', description: 'Create task in'\ - ' Plangrid project', + ' a PlanGrid project', help: { - body: 'Create task in Project action uses the ' \ + body: 'Create task in a project action uses the ' \ "Create task in Project API.", + "project' target='_blank'>Create Task in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/create-task-in-' \ 'a-project', learn_more_text: 'Create Task in a Project' @@ -1382,10 +1382,11 @@ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } } ].concat(object_definitions['task']. - only('assigned_to_uids', 'cost_impact', 'description', 'due_at', - 'has_cost_impact', 'has_schedule_impact', - 'issue_list_uid', 'room', 'schedule_impact', 'start_date', - 'status', 'title', 'type')) + only('title', 'status', 'type', 'assigned_to_uids', + 'room', 'start_date', 'due_at', 'issue_list_uid', + 'description', 'has_cost_impact', 'cost_impact', + 'has_schedule_impact', 'schedule_impact' + )) end, execute: lambda do |_connection, input| project_uid = input.delete('project_uid') From ee2d2498d25a9b0b3520a609347580fa4209610c Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 10:17:35 -0400 Subject: [PATCH 36/78] update title and description for `Update task..` action, re-order fields, clear empty objects --- custom_connectors/oauth2/plangrid.rb | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index db62e901..6b679b4a 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1412,13 +1412,13 @@ end }, update_task: { - title: 'Update task in a Project', + title: 'Update task in a project', description: 'Update task in'\ - ' Plangrid project', + ' a PlanGrid project', help: { - body: 'Update task in Project action uses the ' \ + body: 'Update task in a project action uses the ' \ "Create task in Project API.", + "project' target='_blank'>Update Task in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/create-project', learn_more_text: 'Update Task in a Project' }, @@ -1439,17 +1439,22 @@ toggle_hint: 'Use project ID', hint: 'Provide project ID e.g.' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } } + } }, + { name: 'issue_uid', label: 'Task ID', optional: false } ].concat(object_definitions['task']. - only('uid', 'assigned_to_uids', 'cost_impact', 'description', - 'due_at', 'has_cost_impact', 'has_schedule_impact', - 'issue_list_uid', 'room', 'schedule_impact', 'start_date', - 'status', 'title', 'type').required('uid')) + only('title', 'status', 'type', 'assigned_to_uids', + 'room', 'start_date', 'due_at', 'issue_list_uid', + 'description', 'has_cost_impact', 'cost_impact', + 'has_schedule_impact', 'schedule_impact' + )) end, execute: lambda do |_connection, input| project_uid = input.delete('project_uid') + payload = input.each do |key, value| + input[key].present? || input[key] = nil + end patch("/projects/#{project_uid}/issues/" \ - "#{input.delete('uid')}").payload(input). + "#{input.delete('issue_uid')}").payload(payload). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end&.merge('project_uid' => project_uid) From 4812fd3d0a913cce3871c6f423e441018d07a256 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 10:18:07 -0400 Subject: [PATCH 37/78] update title and description for `Get task..` action, change field name to `Task ID` --- custom_connectors/oauth2/plangrid.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 6b679b4a..0c23a1d1 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1471,7 +1471,7 @@ get_task: { title: 'Get task in a project', description: 'Get task in'\ - ' in a Plangrid project', + ' a PlanGrid project', help: { body: 'Get task in a project action uses the ' \ " Date: Fri, 23 Aug 2019 10:18:30 -0400 Subject: [PATCH 38/78] update title and description for `New or updated task..` --- custom_connectors/oauth2/plangrid.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 0c23a1d1..ebb3970c 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2431,11 +2431,11 @@ end }, new_updated_task: { - title: 'New/updated task in a Project', - description: 'New/updated task in a '\ - 'Project Plangrid', + title: 'New or updated task in a project', + description: 'New or updated task in a '\ + ' PlanGrid project', help: { - body: 'New/updated task in a Project trigger uses the' \ + body: 'New or updated task in a project trigger uses the' \ " Retrieve Tasks " \ ' in a Project API.', From db780a79321d7dbecadea9fc1db661d24fece8ea Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 10:59:20 -0400 Subject: [PATCH 39/78] update `field_report` object definition --- custom_connectors/oauth2/plangrid.rb | 50 ++++++++++++---------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index ebb3970c..f282aec1 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -464,11 +464,11 @@ field_report: { fields: lambda do |_connection, _config_fields| [ - { name: 'uid', label: 'File report ID' }, + { name: 'uid', label: 'Field Report ID' }, { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -483,28 +483,27 @@ } }, { name: 'title' }, { name: 'description' }, - { name: 'report_date', type: 'date_time', + { name: 'report_date', label: 'Report Date', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, - { name: 'field_report_type', type: 'object', properties: [ + { name: 'status' }, + { name: 'field_report_type', label: 'Field Report Type', type: 'object', properties: [ { name: 'name' }, - { name: 'project_uid' }, { name: 'status' }, - { name: 'uid' } + { name: 'uid', label: 'UID' } ] }, - { name: 'pdf_url' }, - { name: 'pdf_form_values', type: 'array', of: 'object', + { name: 'pdf_url', label: 'PDF URL' }, + { name: 'pdf_form_values', label: 'PDF Form Values', type: 'array', of: 'object', properties: [ { name: 'name' }, { name: 'value' } ] }, - { name: 'pg_form_values', type: 'array', of: 'object', properties: [ - { name: 'pg_equipment_entries', type: 'array', of: 'object', + { name: 'pg_form_values', label: 'Daily Report Values', type: 'array', of: 'object', properties: [ + { name: 'pg_worklog_entries', label: 'Work Log Entries', type: 'array', of: 'object', properties: [ - { name: 'uid' }, + { name: 'trade' }, { name: 'timespan' }, - { name: 'quantity', type: 'integer' }, - { name: 'item' }, + { name: 'headcount', type: 'integer' }, { name: 'description' }, { name: 'deleted', type: 'boolean', control_type: 'checkbox', @@ -518,21 +517,19 @@ hint: 'Allowed values are: true, false' } } ] }, - { name: 'pg_materials_entries', type: 'array', of: 'object', + { name: 'pg_materials_entries', label: 'Material Entries', type: 'array', of: 'object', properties: [ - { name: 'uid' }, { name: 'unit', type: 'integer' }, { name: 'quantity', type: 'integer' }, { name: 'item' }, { name: 'description' }, { name: 'deleted' } ] }, - { name: 'pg_worklog_entries', type: 'array', of: 'object', + { name: 'pg_equipment_entries', label: 'Equipment Entries', type: 'array', of: 'object', properties: [ - { name: 'uid' }, - { name: 'trade' }, { name: 'timespan' }, - { name: 'headcount', type: 'integer' }, + { name: 'quantity', type: 'integer' }, + { name: 'item' }, { name: 'description' }, { name: 'deleted', type: 'boolean', control_type: 'checkbox', @@ -547,26 +544,23 @@ } } ] } ] }, - { name: 'attachments', type: 'object', properties: [ + { name: 'attachments', label: 'Documents', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'created_by', type: 'object', properties: [ - { name: 'email' }, - { name: 'uid' }, - { name: 'url' } - ] }, { name: 'photos', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'project_uid', label: 'Project ID' }, - { name: 'report_date', type: 'date' }, { name: 'snapshots', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'status' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'email' }, + { name: 'uid', label: 'UID' }, + { name: 'url' } + ] }, { name: 'updated_at', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, From 9d9441964db6af79859adebbbb296abbffdb076c Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 10:59:59 -0400 Subject: [PATCH 40/78] update title and description for `Get field reports...` action, fix query params --- custom_connectors/oauth2/plangrid.rb | 38 +++++++++++++++++----------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index f282aec1..0ee4976a 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1903,11 +1903,11 @@ end }, get_field_reports_in_project: { - title: 'Get fields reports in project', + title: 'Get field reports in a project', description: 'Get field reports in'\ - ' in Plangrid project', + ' a PlanGrid project', help: { - body: 'Get fields reports in project action uses the ' \ + body: 'Get field reports in a project action uses the ' \ "Retrieve Field Reports in a" \ ' Project API.', @@ -1920,7 +1920,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', optional: false, toggle_hint: 'Select project', toggle_field: { @@ -1933,17 +1933,17 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'updated_after', type: 'date_time', - hint: 'Only retrieve field reports created/updated after ' \ - 'specified UTC date and time.' }, - { name: 'report_date_min', type: 'date_time', - label: 'Report start date', + { name: 'report_date_min', type: 'date', + label: 'Report Start Date', hint: 'Only retrieve field reports between a date range ' \ 'starting with this date in UTC format.' }, - { name: 'report_date_max', type: 'date_time', - label: 'Report end date', + { name: 'report_date_max', type: 'date', + label: 'Report End Date', hint: 'Only retrieve field reports between a date range ' \ 'starting with this date in UTC format.' }, + { name: 'updated_after', label: 'Updated After', type: 'date_time', + hint: 'Only retrieve field reports created/updated after ' \ + 'specified UTC date and time.' }, { name: 'sort_by', control_type: 'select', pick_list: %w[report_date updated_at]&.map { |e| [e.labelize, e] }, @@ -1951,6 +1951,14 @@ toggle_field: { name: 'sort_by', type: 'string', control_type: 'text', hint: 'Allowed values report_date or updated_at' + } }, + { name: 'sort_order', control_type: 'select', + pick_list: + %w[asc desc]&.map { |e| [e.labelize, e] }, + toggle_hint: 'Select sort order', + toggle_field: { + name: 'sort_by', type: 'string', control_type: 'text', + hint: 'Allowed values asc or desc' } } ] end, @@ -1958,17 +1966,17 @@ project_uid = input.delete('project_uid') query_params = '' input&.map do |key, val| - if %w[updated_after report_date_min report_date_max].include?(key) - query_params = query_params + "#{key}=#{val.to_time.utc.iso8601}" + if %w[updated_after].include?(key) + query_params = query_params + "&" + "#{key}=#{val.to_time.utc.iso8601}" else - query_params = query_params + "#{key}=#{val}" + query_params = query_params + "&" + "#{key}=#{val}" end end { field_reports: get("/projects/#{project_uid}/field_reports?" \ "#{query_params}")['data'] } end, output_fields: lambda do |object_definitions| - { name: 'field_reports', type: 'array', of: 'object', + { name: 'field_reports', label: 'Field Reports', type: 'array', of: 'object', properties: object_definitions['field_report'] } end, sample_output: lambda do |_connection, _input| From b791115eb1561040393351576a0a0f39c959dd23 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 11:00:24 -0400 Subject: [PATCH 41/78] update title and description for `New or updated field report` trigger --- custom_connectors/oauth2/plangrid.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 0ee4976a..23389ec5 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2762,17 +2762,17 @@ end }, new_updated_field_report: { - title: 'New/updated field report in a Project', - description: 'New/updated field report '\ - 'in Plangrid Project', + title: 'New or updated field report in a project', + description: 'New or updated field report '\ + 'in a PlanGrid project', help: { - body: 'New/updated field report in Project trigger uses the' \ + body: 'New or updated field report in a project trigger uses the' \ " Retrieve " \ - 'field reports in a Project API.', + 'Field Reports in a Project API.', learn_more_url: 'https://developer.plangrid.com/docs/' \ 'retrieve-field-reports-in-a-project', - learn_more_text: 'Retrieve field reports in a Project' + learn_more_text: 'Retrieve Field Reports in a Project' }, input_fields: lambda do |_object_definitions| [ From 59f120510496a84da422319db3ef0eeb86d72363 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 14:22:48 -0400 Subject: [PATCH 42/78] update `user` object definition --- custom_connectors/oauth2/plangrid.rb | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 23389ec5..5c2fc59d 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -687,15 +687,31 @@ fields: lambda do |_connection, _config_fields| [ { name: 'uid', label: 'User ID' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project ID', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, { name: 'email' }, - { name: 'first_name' }, - { name: 'last_name' }, - { name: 'language' }, + { name: 'first_name', label: 'First Name' }, + { name: 'last_name', label: 'Last Name' }, + { name: 'language'}, { name: 'role', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' } ] }, - { name: 'removed' } + { name: 'removed', label: 'Removed?' } ] end }, From c7bbd4dc333565741162b0db3fc3a841689200d0 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 14:23:25 -0400 Subject: [PATCH 43/78] update title and description for `Invite user...` action, append `project_uid` to result --- custom_connectors/oauth2/plangrid.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 5c2fc59d..5c69db6e 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1529,23 +1529,23 @@ end }, invite_user_to_project: { - title: 'Invite a user to a project', + title: 'Invite user to a project', description: 'Invite user to'\ - ' project team Plangrid', + ' a PlanGrid project', help: { body: 'Invite user to a project action uses the ' \ "Invite user in Project team API.", + "project-team' target='_blank'>Invite User in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ 'invite-user-to-project-team', - learn_more_text: 'Invite User to Project Team' + learn_more_text: 'Invite User to Project' }, input_fields: lambda do |_object_definitions| [ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', optional: false, toggle_hint: 'Select project', toggle_field: { @@ -1559,16 +1559,17 @@ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, { name: 'email', optional: false }, - { name: 'role_uid', label: 'Role ID', + { name: 'role_uid', label: 'Role ID', sticky: true, hint: 'Unique identifier of role to assign user on project team' } ] end, execute: lambda do |_connection, input| - post("/projects/#{input.delete('project_uid')}/users/invites"). + project_uid = input.delete('project_uid') + post("/projects/#{project_uid}/users/invites"). payload(input). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end + end&.merge('project_uid' => project_uid) end, output_fields: lambda do |object_definitions| object_definitions['user'] From f27a2dbf96e1e342cd02ee6ec0b546b9dbc1025e Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 14:23:47 -0400 Subject: [PATCH 44/78] update title and description for `Get user...` action --- custom_connectors/oauth2/plangrid.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 5c69db6e..2b9544a6 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1582,14 +1582,14 @@ get_user_in_project: { title: 'Get user in project', description: 'Get user in'\ - ' Plangrid project', + ' a PlanGrid project', help: { - body: 'Get user in project action uses the ' \ + body: 'Get user in a project action uses the ' \ "Retrieve User on a Project Team.", + "project-team' target='_blank'>Retrieve User in a Project.", learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ 'users-on-a-project-team', - learn_more_text: 'Retrieve User on a Project Team' + learn_more_text: 'Retrieve User in a Project' }, input_fields: lambda do |_object_definitions| [ From 295e6f7374d4d90e9c1688d422df059986a24e9d Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 14:24:26 -0400 Subject: [PATCH 45/78] update title and description for `Get roles..` action, remove additional params --- custom_connectors/oauth2/plangrid.rb | 37 ++++++++++++---------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 2b9544a6..419336de 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1724,23 +1724,23 @@ end }, get_roles_on_project: { - title: 'Get roles on a project', - description: 'Get roles on '\ - ' Plangrid project', + title: 'Get roles in a project', + description: 'Get roles in '\ + ' a PlanGrid project', help: { - body: 'Get role on a project action uses the ' \ - "Retrieve Role on a Project API.", + body: 'Get roles in a project action uses the ' \ + "Retrieve Roles on a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-role-on-a-project', - learn_more_text: 'Retrieve Role on a Project' + 'retrieve-roles-on-a-project', + learn_more_text: 'Retrieves Role on a Project' }, input_fields: lambda do |_object_definitions| [ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', optional: false, toggle_hint: 'Select project', toggle_field: { @@ -1752,24 +1752,19 @@ toggle_hint: 'Use project ID', hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'limit', type: 'integer', - hint: 'Number of roles to retrieve. Maximum value of 50.' }, - { name: 'skip', type: 'integer', - hint: 'Number of roles to skip in the set of results.' } + } } ] end, execute: lambda do |_connection, input| - { roles: get("/projects/#{input.delete('project_uid')}/roles", input) } + project_uid = input.delete('project_uid') + { roles: get("/projects/#{project_uid}/roles")['data'] } end, output_fields: lambda do |_object_definitions| [ - { name: 'roles', type: 'array', of: 'object', properties: [ - { name: 'uid' }, - { name: 'label' } - ] }, - { name: 'total_count' }, - { name: 'next_page_url' } + { name: 'roles', label: 'Roles', type: 'array', of: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'label', label: 'Role' } + ] } ] end, sample_output: lambda do |_connection, _input| From 4773c8c41ae1e72aa55ae48a0cd679c053460603 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 15:31:44 -0400 Subject: [PATCH 46/78] remove `Get sheets..` action --- custom_connectors/oauth2/plangrid.rb | 56 +--------------------------- 1 file changed, 1 insertion(+), 55 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 419336de..e8b447d2 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1772,61 +1772,7 @@ 'label' => 'Admin' } } end }, - get_sheets_in_project: { - title: 'Get sheets in project', - description: 'Get sheets in'\ - ' Plangrid project', - help: { - body: 'Get sheets in project action uses the ' \ - "Retrieve Sheets in a Project.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-sheets-in-a-project', - learn_more_text: 'Retrieve Sheets in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'limit', type: 'integer', - hint: 'Number of sheets to retrieve. Maximum value of 50.' }, - { name: 'skip', type: 'integer', - hint: 'Number of sheets to skip in the set of results' }, - { name: 'updated_after', type: 'date_time', - hint: 'Only retrieve sheets created/updated after ' \ - 'specified UTC date and time.' } - ] - end, - execute: lambda do |_connection, input| - { sheets: get("/projects/#{input.delete('project_uid')}/sheets", - input)['data'] } - end, - output_fields: lambda do |object_definitions| - [{ name: 'sheets', type: 'array', of: 'object', - properties: object_definitions['sheet'] }] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - { - sheets: get("/projects/#{id}/sheets?limit=1")&.dig('data', 0)&. - merge('project_uid' => id) || {} - } - end - }, + get_sheet_in_project: { title: 'Get sheet in a project', description: 'Get sheet in '\ From 7076bd0f80213a0e6fdf4b4da934004557e961cb Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 15:32:11 -0400 Subject: [PATCH 47/78] update `sheet_packet` object definition --- custom_connectors/oauth2/plangrid.rb | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index e8b447d2..5e727082 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -767,13 +767,29 @@ sheet_packet: { fields: lambda do |_connection, _config_fields| [ - { name: 'uid', label: 'Sheet packet ID' }, - { name: 'file_url' }, + { name: 'uid', label: 'Sheet Packet ID' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project ID', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'status' }, + { name: 'file_url', label: 'File URL' }, { name: 'resource', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' } - ] }, - { name: 'status' } + ] } ] end }, From 338641a8c1f88a824fa40b7bf6011632a36d0bc0 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 15:32:51 -0400 Subject: [PATCH 48/78] update title and description for `Get sheet packet...` action --- custom_connectors/oauth2/plangrid.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 5e727082..5fd9fc51 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1836,11 +1836,11 @@ end }, get_project_sheet_packet: { - title: 'Get project sheet packet', - description: 'Get project sheet packet in'\ - ' packet in Plangrid', + title: 'Get sheet packet in a project', + description: 'Get sheet packet in'\ + ' a PlanGrid project', help: { - body: 'Get project sheet packet action uses the ' \ + body: 'Get sheet packet in a project action uses the ' \ "Retrieve Sheet Packet API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ @@ -1865,12 +1865,12 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'packet_uid', type: 'Packet ID' } + { name: 'packet_uid', label: 'Sheet Packet ID', optional: false } ] end, execute: lambda do |_connection, input| get("/projects/#{input['project_uid']}/sheets/packets/" \ - "#{input['packet_uid']}") + "#{input['packet_uid']}")&.merge('project_uid' => input['project_uid']) end, output_fields: lambda do |object_definitions| object_definitions['sheet_packet'] From 2067a2ac473f4efb85d6492cbd1c0207cde65af6 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 15:33:24 -0400 Subject: [PATCH 49/78] add `Create sheet packet` action --- custom_connectors/oauth2/plangrid.rb | 71 ++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 5fd9fc51..62d60c1a 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2183,6 +2183,77 @@ get("/projects/#{id}/attachments")&.dig('data', 0)&. merge('project_uid' => id) || {} end + }, + create_sheet_packet: { + title: 'Create sheet packet in a project', + description: 'Create sheet packet in '\ + ' a PlanGrid project', + help: { + body: 'Create sheet packet in a project action uses the' \ + " Create Sheet Packet in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/upload-photo' \ + '-to-project', + learn_more_text: 'Create Sheet Packet in a Project' + }, + input_fields: lambda do |object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'sheet_uids', label: 'Sheet IDs', optional: false, + type: 'string', + hint: 'A comma separated list of sheet IDs.' }, + { name: 'include_annotations', label: 'Include annotations?', type: 'boolean', sticky: true, + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'include_annotations', + label: 'Include annotations?', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } }, + ] + end, + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + payload = { + sheet_uids: input.delete('sheet_uids').split(','), + include_annotations: input.delete('include_annotations') + } + post("/projects/#{project_uid}/sheets/packets").payload(payload). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end&.merge('project_uid' => project_uid) + end, + output_fields: lambda do |object_definitions| + object_definitions['sheet_packet'] + end, + sample_output: lambda do |_connection, _input| + { + uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", + file_url: "https://packet-assets.plangrid.com/92cf7193-af0c-42fc-a3ab-7ef5149da720.pdf", + resource: { + uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", + url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/packets/92cf7193-af0c-42fc-a3ab-7ef5149da720" + }, + status: "incomplete" + } + end } }, triggers: { From ecedf21a6c5e670052cc300c04bf35760034f338 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 17:25:36 -0400 Subject: [PATCH 50/78] update `task` object definition to reference Task List instead of Issue List --- custom_connectors/oauth2/plangrid.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 62d60c1a..0a654086 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -234,8 +234,8 @@ parse_output: 'date_time_conversion' }, { name: 'string', label: 'Stamp', hint: 'One to two character stamp associated with task.' }, - { name: 'issue_list', label: 'Issue List', type: 'object', properties: [ - { name: 'uid' }, + { name: 'issue_list', label: 'Task List', type: 'object', properties: [ + { name: 'uid', label: 'Task List ID' }, { name: 'url' } ] }, { name: 'description' }, From b465e618a9fd792f7119c7f6f6bc78066e1fe9fa Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 17:26:24 -0400 Subject: [PATCH 51/78] add correct `issue_list_uid` field when creating/updating task --- custom_connectors/oauth2/plangrid.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 0a654086..71d61a5e 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1406,10 +1406,12 @@ toggle_hint: 'Use project ID', hint: 'Provide project ID e.g. ' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } } + } + }, + { name: 'issue_list_uid', label: 'Task List ID', sticky: true } ].concat(object_definitions['task']. only('title', 'status', 'type', 'assigned_to_uids', - 'room', 'start_date', 'due_at', 'issue_list_uid', + 'room', 'start_date', 'due_at', 'description', 'has_cost_impact', 'cost_impact', 'has_schedule_impact', 'schedule_impact' )) @@ -1465,11 +1467,13 @@ toggle_hint: 'Use project ID', hint: 'Provide project ID e.g.' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'issue_uid', label: 'Task ID', optional: false } + } + }, + { name: 'issue_uid', label: 'Task ID', optional: false }, + { name: 'issue_list_uid', label: 'Task List ID', sticky: true } ].concat(object_definitions['task']. only('title', 'status', 'type', 'assigned_to_uids', - 'room', 'start_date', 'due_at', 'issue_list_uid', + 'room', 'start_date', 'due_at', 'description', 'has_cost_impact', 'cost_impact', 'has_schedule_impact', 'schedule_impact' )) From f7633838afcf5dea4cfd557cd25a3425e66cca44 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 17:26:49 -0400 Subject: [PATCH 52/78] add `Get task list..`, `Update task list..`, `Create task list..` action --- custom_connectors/oauth2/plangrid.rb | 186 +++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 71d61a5e..e1c3aafc 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2258,6 +2258,192 @@ status: "incomplete" } end + }, + get_task_list: { + title: 'Get task list in a project', + description: 'Get task list'\ + ' in a PlanGrid project', + help: { + body: 'Get task list in a project action uses the ' \ + "Retrieve Task List in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-issue-list', + learn_more_text: 'Retrieve Task List in a Project API' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'issue_list_uid', label: 'Task List ID', optional: false } + ] + end, + execute: lambda do |_connection, input| + get("/projects/#{input['project_uid']}/issue_lists/" \ + "#{input['issue_list_uid']}") + end, + output_fields: lambda do |object_definitions| + [ + { + name: "uid", label: "Task List ID" + }, + { + name: "project_uid", label: "Project ID" + }, + { + name: "name", label: "Name" + }, + { + name: "deleted", label: "Deleted", type: "boolean" + } + ] + end, + sample_output: lambda do |_connection, _input| + { + uid: "31f54967-4eac-4bd7-9b35-57f00a973a1d", + name: "QA/QC", + deleted: false, + project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" + } + end + }, + update_task_list: { + title: 'Update task list in a project', + description: 'Update task list'\ + ' in a PlanGrid project', + help: { + body: 'Update task list in a project action uses the ' \ + "Update Task List in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'update-issue-list', + learn_more_text: 'Update Task List in a Project API' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'issue_list_uid', label: 'Task List ID', optional: false }, + { name: 'name', optional: false } + ] + end, + execute: lambda do |_connection, input| + patch("/projects/#{input['project_uid']}/issue_lists/" \ + "#{input['issue_list_uid']}").payload({name: input.delete('name')}) + end, + output_fields: lambda do |object_definitions| + [ + { + name: "uid", label: "Task List ID" + }, + { + name: "project_uid", label: "Project ID" + }, + { + name: "name", label: "Name" + }, + { + name: "deleted", label: "Deleted", type: "boolean" + } + ] + end, + sample_output: lambda do |_connection, _input| + { + uid: "31f54967-4eac-4bd7-9b35-57f00a973a1d", + name: "QA/QC", + deleted: false, + project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" + } + end + }, + create_task_list: { + title: 'Create task list in a project', + description: 'Create task list'\ + ' in a PlanGrid project', + help: { + body: 'Create task list in a project action uses the ' \ + "Create Task List in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'create-issue-list', + learn_more_text: 'Create Task List in a Project API' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'name', optional: false } + ] + end, + execute: lambda do |_connection, input| + post("/projects/#{input.delete('project_uid')}/issue_lists").payload(input) + end, + output_fields: lambda do |object_definitions| + [ + { + name: "uid", label: "Task List ID" + }, + { + name: "project_uid", label: "Project ID" + }, + { + name: "name", label: "Name" + }, + { + name: "deleted", label: "Deleted", type: "boolean" + } + ] + end, + sample_output: lambda do |_connection, _input| + { + uid: "31f54967-4eac-4bd7-9b35-57f00a973a1d", + name: "QA/QC", + deleted: false, + project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" + } + end } }, triggers: { From c1178ed7a04d9cd2618f7725468d8951ea3c42ee Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 23 Aug 2019 18:11:11 -0400 Subject: [PATCH 53/78] add `Create sheet version upload..`, `Upload file to sheet version..`, `Complete sheet upload..` action --- custom_connectors/oauth2/plangrid.rb | 213 +++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index e1c3aafc..05642dc7 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2444,6 +2444,219 @@ project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" } end + }, + create_sheet_version: { + title: 'Create sheet version upload in a project', + description: 'Create sheet version upload'\ + ' in a PlanGrid project', + help: { + body: 'Create sheet version in a project action uses the ' \ + "Upload Version to a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'upload-version-to-project', + learn_more_text: 'Upload Version to a Project API' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'num_files', label: 'Number of PDFs', type: 'integer', optional: false }, + { name: 'version_name', label: 'Version Name', optional: false } + ] + end, + execute: lambda do |_connection, input| + post("/projects/#{input.delete('project_uid')}/sheets/uploads").payload(input) + end, + output_fields: lambda do |object_definitions| + [ + { + name: 'uid', label: 'Sheet Version Upload ID' + }, + { + name: 'complete_url', label: 'Upload Completion URL' + }, + { + name: 'status', + }, + { + name: 'file_upload_requests', label: 'File Upload Requests', + type: 'array', of: 'object', properties: [ + { + name: 'uid', label: 'File Upload ID' + }, + { + name: 'upload_status', label: 'File Upload Status' + }, + { + name: 'url', label: 'File Upload URL' + } + ] + } + ] + end, + sample_output: lambda do |_connection, _input| + { + uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", + complete_url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720", + status: "incomplete", + file_upload_requests: [ + { + uid: "b278fcba-72f0-4161-bfdc-89d5bde4d5e7", + upload_status: "issued", + url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720/files/b278fcba-72f0-4161-bfdc-89d5bde4d5e7" + }, + { + uid: "727fca7d-385b-4476-b257-4b96c00e879b", + upload_status: "issued", + url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720/files/727fca7d-385b-4476-b257-4b96c00e879b" + } + ] + } + end + }, + upload_file_to_sheet_version: { + title: 'Upload file to sheet version in a project', + description: 'Upload file to sheet version'\ + ' in a PlanGrid project', + help: { + body: 'Upload file to sheet version in a project action uses the ' \ + "Upload File to Version in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'upload-file-to-version', + learn_more_text: 'Upload File to Version in a Project API' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'ver_upload_uid', label: 'Sheet Version Upload ID', optional: false }, + { name: 'file_upload_request_uid', label: 'File Upload ID', optional: false }, + { name: 'file_name', label: 'File Name', optional: false }, + { name: 'file_content', label: 'File Content', optional: false } + ] + end, + execute: lambda do |_connection, input| + file_content = input.delete('file_content') + project_uid = input.delete('project_uid') + file_upload_info = post("/projects/#{project_uid}/sheets/" \ + "uploads/#{input.delete('ver_upload_uid')}/" \ + "files/#{input.delete('file_upload_request_uid')}"). + headers('Content-Type': 'application/json'). + payload({file_name: input.delete('file_name')}) + url = file_upload_info&.dig('aws_post_form_arguments', 'action') + fields = file_upload_info&.dig('aws_post_form_arguments', 'fields') + # webhook_url = file_upload_info. + # dig('aws_post_form_arguments', 'webhook_url') + headers = fields.map { |o| { o['name'] => o['value'] } }.inject(:merge) + status = + post(url). + payload(key: headers['key'], + policy: headers['policy'], + signature: headers['signature'], + AWSAccessKeyId: headers['AWSAccessKeyId'], + 'content-type': headers['Content-Type'], + 'success_action_redirect': headers['success_action_redirect'], + 'x-amz-server-side-encryption': + headers['x-amz-server-side-encryption'], + 'x-amz-storage-class': headers['x-amz-storage-class'], + file: file_content). + request_format_multipart_form. + after_response do |_code, response, _response_headers| + response + end + end, + output_fields: lambda do |object_definitions| + + end, + sample_output: lambda do |_connection, _input| + + end + }, + complete_version_upload: { + title: 'Complete sheet version upload to a project', + description: 'Complete sheet version upload '\ + ' to a PlanGrid project', + help: { + body: 'Complete sheet version upload to a project action uses the ' \ + "Complete Version Upload in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'complete-version-upload-to-project', + learn_more_text: 'Complete Version Upload in a Project API' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'ver_upload_uid', label: 'Sheet Version Upload ID', optional: false } + ] + end, + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + post("/projects/#{project_uid}/sheets/" \ + "uploads/#{input.delete('ver_upload_uid')}/completions")&.merge('project_uid' => project_uid) + end, + output_fields: lambda do |object_definitions| + [ + { + name: 'uid', label: 'Sheet Version ID' + }, + { + name: 'status', label: 'Status' + } + ] + end, + sample_output: lambda do |_connection, _input| + { + uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", + complete_url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720", + status: "complete" + } + end } }, triggers: { From 38bec9422c6977fda5164fb9df21f54629e64a11 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Thu, 29 Aug 2019 09:14:47 -0400 Subject: [PATCH 54/78] updated to meet rubocop guidelines by Chandra --- custom_connectors/oauth2/plangrid.rb | 1665 +++++++++----------------- 1 file changed, 547 insertions(+), 1118 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 05642dc7..5385c9a7 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1,5 +1,5 @@ { - title: 'PlanGrid', + title: 'Plangrid', connection: { fields: [ { @@ -54,6 +54,43 @@ end }, test: ->(_connection) { get('/me') }, + methods: { + format_api_output_field_names: lambda do |input| + if input.is_a?(Array) + input.map do |array_value| + call('format_api_output_field_names', array_value) + end + elsif input.is_a?(Hash) + input.map do |key, value| + value = call('format_api_output_field_names', value) + key = key.gsub(/\W/) { |string| "__#{string.encode_hex}__" } + { key => value } + end.inject(:merge) + else + input + end + end, + + format_schema_field_names: lambda do |input| + input.map do |field| + if field[:properties].present? + field[:properties] = call('format_schema_field_names', + field[:properties]) + elsif field['properties'].present? + field['properties'] = call('format_schema_field_names', + field['properties']) + end + if field[:name].present? + field[:name] = field[:name]. + gsub(/\W/) { |string| "__#{string.encode_hex}__" } + elsif field['name'].present? + field['name'] = field['name']. + gsub(/\W/) { |string| "__#{string.encode_hex}__" } + end + field + end + end + }, object_definitions: { project: { fields: lambda do |_connection, _config_fields| @@ -61,7 +98,7 @@ { name: 'uid', control_type: 'select', pick_list: 'project_list', - label: 'Project ID', + label: 'Project', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -74,11 +111,11 @@ hint: 'Provide project ID e.g. ' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'name', label: 'Project Name', sticky: true }, - { name: 'custom_id', label: 'Project Code', sticky: true }, - { name: 'organization_id', label: 'Organization ID' }, + { name: 'name', label: 'Project name', sticky: true }, + { name: 'custom_id', label: 'Project code', sticky: true }, + { name: 'organization_id' }, { name: 'type', control_type: 'select', - label: 'Project Type', sticky: true, + label: 'Project type', sticky: true, pick_list: 'project_types', toggle_hint: 'Select project type', toggle_field: { @@ -93,26 +130,26 @@ 'education-k-12, education-higher, gov-federal, ' \ 'gov-state-local, or other' } }, - { name: 'status', label: 'Project Status', sticky: true }, - { name: 'owner', sticky: true, label: 'Project Owner' }, + { name: 'status', label: 'Project status', sticky: true }, + { name: 'owner', sticky: true, label: 'Project owner' }, { name: 'start_date', type: 'date', sticky: true, render_input: 'date_conversion', parse_output: 'date_conversion', - label: 'Project Start Date', + label: 'Project start date', hint: 'Project start date. ISO-8601 date format (YYYY-MM-DD).' }, { name: 'end_date', type: 'date', sticky: true, render_input: 'date_conversion', parse_output: 'date_conversion', - label: 'Project End Date', + label: 'Project end date', hint: 'Project end date. ISO-8601 date format (YYYY-MM-DD).' }, { name: 'street_1', sticky: true, - label: 'Street Line 1' }, + label: 'Street line 1' }, { name: 'street_2', sticky: true, label: 'Street line 2' }, - { name: 'city', sticky: true, label: 'Town or City' }, - { name: 'region', sticky: true, label: 'State, Province, or Region' }, - { name: 'postal_code', sticky: true, label: 'Zip or Postal Code' }, + { name: 'city', sticky: true, label: 'Town or city' }, + { name: 'region', sticky: true, label: 'State, province, or region' }, + { name: 'postal_code', sticky: true, label: 'Zip or postal code' }, { name: 'country', sticky: true, hint: 'Project address country in 2-letter ISO 3166 code.' }, @@ -121,7 +158,22 @@ { name: 'updated_at', type: 'date_time', render_input: 'date_time_conversion', parse_output: 'date_time_conversion', - label: 'Updated at' } + label: 'Updated at' }, + { name: 'add_to_organization', type: 'boolean', + control_type: 'checkbox', + hint: 'Boolean indicating whether to add the project to the ' \ + 'organization that the API user belongs to or not. By default ' \ + 'the project is created as a personal project and not as an ' \ + 'organization-linked project.', + toggle_hint: 'Select from options list', + toggle_field: { + name: 'add_to_organization', + label: 'Add to organization', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } } ] end }, @@ -132,7 +184,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project ID', + label: 'Project', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -145,14 +197,14 @@ hint: 'Provide project ID e.g. ' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'name', label: 'Document Name' }, + { name: 'name', label: 'Document name' }, { name: 'folder' }, { name: 'url' }, { name: 'created_at', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'created_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'url' }, { name: 'email' } ] }, @@ -170,7 +222,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project ID', + label: 'Project', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -183,64 +235,26 @@ hint: 'Provide project ID e.g. ' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'number', type: 'number' }, - { name: 'title' }, - { name: 'status', control_type: 'select', pick_list: - %w[open in_review pending closed].select { |op| [op.labelize, op] }, - 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", "in_review", "pending",' \ - ' "closed".' - } }, - { name: 'type', control_type: 'select', - pick_list: [ - %w[issue issue], - %w[Planned\ work planned_work], - %w[other other] - ], - toggle_hint: 'Select type', - toggle_field: { - name: 'type', - label: 'Type', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: "issue", "planned_work",' \ - ' "other".' - } }, { name: 'assignees', type: 'array', of: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'type' } - ] }, - { name: 'followers', label: 'Watchers', type: 'array', of: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'type' } + { name: 'assignee' } ] }, - { name: 'room', label: 'Location' }, - { name: 'start_date', label: 'Start Date', - type: 'date_time', - render_input: 'date_conversion', - parse_output: 'date_conversion' }, { name: 'closed_at', type: 'date_time', render_input: 'date_time_conversion', parse_output: 'date_time_conversion' }, - { name: 'due_at', type: 'date_time', - render_input: 'date_time_conversion', - parse_output: 'date_time_conversion' }, - { name: 'string', label: 'Stamp', - hint: 'One to two character stamp associated with task.' }, - { name: 'issue_list', label: 'Task List', type: 'object', properties: [ - { name: 'uid', label: 'Task List ID' }, + { name: 'created_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' }, + { name: 'email' } + ] }, + { name: 'comments', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'description' }, - { name: 'cost_impact', label: 'Cost Impact', type: 'number' }, - { name: 'has_cost_impact', label: 'Has Cost Impact?', type: 'boolean', + { name: 'cost_impact', type: 'number' }, + { name: 'has_cost_impact', type: 'boolean', control_type: 'checkbox', toggle_hint: 'Select from options list', toggle_field: { name: 'cost_impact', @@ -250,23 +264,12 @@ toggle_hint: 'Use custom value', hint: 'Allowed values are: true, false' } }, - { name: 'currency_code', label: 'Currency Code', + { name: 'currency_code', hint: 'The ISO-4217 currency code of the cost_impact,' \ ' Currently only supports USD. maybe null if cost_impact is ' \ 'not specified' }, - { name: 'schedule_impact', label: 'Schedule Impact', type: 'integer' }, - { name: 'has_schedule_impact', label: 'Has Schedule Impact?', type: 'boolean', - control_type: 'checkbox', toggle_hint: 'Select from options list', - toggle_field: { - name: 'has_schedule_impact', - label: 'Has schedule impact', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } }, { name: 'current_annotation', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'color' }, { name: 'stamp' }, { name: 'visibility' }, @@ -281,36 +284,84 @@ hint: 'Allowed values are: true, false' } }, { name: 'sheet', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'url' } ] } ] }, - { name: 'comments', type: 'object', properties: [ - { name: 'total_count', type: 'integer' }, + { name: 'deleted', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'deleted', + label: 'Deleted', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } }, + { name: 'description' }, + { name: 'due_at', type: 'date_time', + render_input: 'date_time_conversion', + parse_output: 'date_time_conversion' }, + { name: 'followers', type: 'array', of: 'object', properties: [ + { name: 'type' }, + { name: 'uid' } + ] }, + { name: 'issue_list', type: 'object', properties: [ + { name: 'uid' }, { name: 'url' } ] }, + { name: 'number', type: 'number' }, { name: 'photos', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'deleted', label: 'Deleted?', type: 'boolean', + { name: 'room' }, + { name: 'schedule_impact', type: 'integer' }, + { name: 'has_schedule_impact', type: 'boolean', control_type: 'checkbox', toggle_hint: 'Select from options list', toggle_field: { - name: 'deleted', - label: 'Deleted', + name: 'has_schedule_impact', + label: 'Has schedule impact', type: 'string', control_type: 'text', toggle_hint: 'Use custom value', hint: 'Allowed values are: true, false' } }, - { name: 'created_at', type: 'date_time', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'created_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' }, - { name: 'email' } - ] }, + { name: 'start_date', + type: 'date_time', + render_input: 'date_conversion', + parse_output: 'date_conversion' }, + { name: 'status', control_type: 'select', pick_list: + %w[open in_review pending closed].select { |op| [op.labelize, op] }, + 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", "in_review", "pending",' \ + ' "closed".' + } }, + { name: 'string', + hint: 'One to two character stamp associated with task.' }, + { name: 'title' }, + { name: 'type', control_type: 'select', + pick_list: [ + %w[issue issue], + %w[Planned\ work planned_work], + %w[other other] + ], + toggle_hint: 'Select type', + toggle_field: { + name: 'type', + label: 'Type', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: "issue", "planned_work",' \ + ' "other".' + } }, { name: 'updated_at', render_input: 'date_time_conversion', parse_output: 'date_time_conversion', @@ -343,11 +394,11 @@ annotation: { fields: lambda do |_connection, _config_fields| [ - { name: 'uid', label: 'Annotation ID' }, + { name: 'uid', label: 'Unique Identifier' }, { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project ID', + label: 'Project', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -374,8 +425,9 @@ hint: 'Allowed values are: true, false' } }, { name: 'sheet', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' } + { name: 'uid' }, + { name: 'label' }, + { name: 'color' } ] } ] end @@ -387,7 +439,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project ID', + label: 'Project', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -406,12 +458,12 @@ render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'created_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'url' }, { name: 'email' } ] }, { name: 'sheet', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'url' } ] }, { name: 'deleted', type: 'boolean', @@ -434,7 +486,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project ID', + label: 'Project', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -448,27 +500,35 @@ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, { name: 'title' }, - { name: 'url', label: 'URL' }, + { name: 'url' }, { name: 'created_at', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'created_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'url' }, { name: 'email' } ] }, - { name: 'deleted', type: 'boolean' } + { name: 'deleted', type: 'boolean', control_type: 'checkbox', + toggle_field: { + name: 'deleted', + label: 'Deleted', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } } ] end }, field_report: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', label: 'Field Report ID' }, + fields: lambda do |_connection, config_fields| + standard_fields = [ + { name: 'uid', label: 'File report ID' }, { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project ID', + label: 'Project', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -483,27 +543,23 @@ } }, { name: 'title' }, { name: 'description' }, - { name: 'report_date', label: 'Report Date', type: 'date_time', + { name: 'report_date', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, - { name: 'status' }, - { name: 'field_report_type', label: 'Field Report Type', type: 'object', properties: [ + { name: 'field_report_type', type: 'object', properties: [ { name: 'name' }, + { name: 'project_uid' }, { name: 'status' }, - { name: 'uid', label: 'UID' } + { name: 'uid' } ] }, - { name: 'pdf_url', label: 'PDF URL' }, - { name: 'pdf_form_values', label: 'PDF Form Values', type: 'array', of: 'object', - properties: [ - { name: 'name' }, - { name: 'value' } - ] }, - { name: 'pg_form_values', label: 'Daily Report Values', type: 'array', of: 'object', properties: [ - { name: 'pg_worklog_entries', label: 'Work Log Entries', type: 'array', of: 'object', + { name: 'pdf_url' }, + { name: 'pg_form_values', type: 'array', of: 'object', properties: [ + { name: 'pg_equipment_entries', type: 'array', of: 'object', properties: [ - { name: 'trade' }, + { name: 'uid' }, { name: 'timespan' }, - { name: 'headcount', type: 'integer' }, + { name: 'quantity', type: 'integer' }, + { name: 'item' }, { name: 'description' }, { name: 'deleted', type: 'boolean', control_type: 'checkbox', @@ -517,19 +573,21 @@ hint: 'Allowed values are: true, false' } } ] }, - { name: 'pg_materials_entries', label: 'Material Entries', type: 'array', of: 'object', + { name: 'pg_materials_entries', type: 'array', of: 'object', properties: [ + { name: 'uid' }, { name: 'unit', type: 'integer' }, { name: 'quantity', type: 'integer' }, { name: 'item' }, { name: 'description' }, { name: 'deleted' } ] }, - { name: 'pg_equipment_entries', label: 'Equipment Entries', type: 'array', of: 'object', + { name: 'pg_worklog_entries', type: 'array', of: 'object', properties: [ + { name: 'uid' }, + { name: 'trade' }, { name: 'timespan' }, - { name: 'quantity', type: 'integer' }, - { name: 'item' }, + { name: 'headcount', type: 'integer' }, { name: 'description' }, { name: 'deleted', type: 'boolean', control_type: 'checkbox', @@ -544,23 +602,26 @@ } } ] } ] }, - { name: 'attachments', label: 'Documents', type: 'object', properties: [ + { name: 'attachments', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, + { name: 'created_by', type: 'object', properties: [ + { name: 'email' }, + { name: 'uid' }, + { name: 'url' } + ] }, { name: 'photos', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, + { name: 'project_uid', label: 'Project ID' }, + { name: 'report_date', type: 'date' }, { name: 'snapshots', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'created_by', type: 'object', properties: [ - { name: 'email' }, - { name: 'uid', label: 'UID' }, - { name: 'url' } - ] }, + { name: 'status' }, { name: 'updated_at', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, @@ -578,6 +639,13 @@ { name: 'wind_speed', type: 'number' } ] } ] + pdf_form_fileds = get("/projects/#{config_fields['project_uid']}/" \ + 'field_reports').params(limit: 1)&. + map do |key, _value| + { name: key } + end&.inject(:merge) + standard_fields.merge({ 'pdf_form_values' => + call('format_schema_field_names', pdf_form_fileds) }) end }, rfi: { @@ -587,7 +655,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project ID', + label: 'Project', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -602,7 +670,7 @@ } }, { name: 'number', type: 'integer' }, { name: 'status', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'label' }, { name: 'color' } ] }, @@ -629,9 +697,12 @@ { name: 'due_at', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, + { name: 'assigned_to_uids', + hint: 'Array of unique identifiers of users who ' \ + 'are RFI assignees.' }, { name: 'assigned_to', type: 'array', of: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'url' }, { name: 'email' } ] }, @@ -643,7 +714,7 @@ "timestamps-and-timezones' target='_blank'>Timestamps and " \ 'Timezones for accepted date formats' }, { name: 'updated_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'url' }, { name: 'email' } ] }, @@ -651,7 +722,7 @@ render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'created_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'url' }, { name: 'email' } ] }, @@ -677,7 +748,7 @@ rfi_status: { fields: lambda do |_connection, _config_fields| [ - { name: 'uid', label: 'Status ID' }, + { name: 'uid', label: 'RFI status ID' }, { name: 'label' }, { name: 'color' } ] @@ -687,31 +758,15 @@ fields: lambda do |_connection, _config_fields| [ { name: 'uid', label: 'User ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, { name: 'email' }, - { name: 'first_name', label: 'First Name' }, - { name: 'last_name', label: 'Last Name' }, - { name: 'language'}, + { name: 'first_name' }, + { name: 'last_name' }, + { name: 'language' }, { name: 'role', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'url' } ] }, - { name: 'removed', label: 'Removed?' } + { name: 'removed' } ] end }, @@ -719,29 +774,13 @@ fields: lambda do |_connection, _config_fields| [ { name: 'uid', label: 'Sheet ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, { name: 'name' }, - { name: 'version_name', label: 'Version Name' }, + { name: 'version_name' }, { name: 'description' }, - { name: 'tags', type: 'array', of: 'string', hint: 'An array of strings representing the' \ + { name: 'tags', hint: 'An array of strings representing the' \ ' tags added to this sheet.' }, { name: 'published_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'url' }, { name: 'email' } ] }, @@ -760,36 +799,20 @@ toggle_hint: 'Use custom value', hint: 'Allowed values are: true, false' } }, - { name: 'uploaded_file_name', label: 'Uploaded file name' } + { name: 'uploaded_file_name' } ] end }, sheet_packet: { fields: lambda do |_connection, _config_fields| [ - { name: 'uid', label: 'Sheet Packet ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'status' }, - { name: 'file_url', label: 'File URL' }, + { name: 'uid', label: 'Sheet packet ID' }, + { name: 'file_url' }, { name: 'resource', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + { name: 'uid' }, { name: 'url' } - ] } + ] }, + { name: 'status' } ] end }, @@ -946,7 +969,7 @@ create_project: { title: 'Create project', description: 'Create project in'\ - ' PlanGrid', + ' Plangrid', help: { body: 'Create project action uses the' \ " project in'\ - ' PlanGrid', + ' Plangrid', help: { body: 'Update project action uses the' \ " Update Project API.", learn_more_url: 'https://developer.plangrid.com/docs/update-project', - learn_more_text: 'Update Project' + learn_more_text: 'Update a Project' }, input_fields: lambda do |object_definitions| object_definitions['project'].required('uid'). ignored('updated_at', 'latitude', 'longitude', 'organization_id') end, execute: lambda do |_connection, input| - payload = input.each do |key, value| - input[key].present? || input[key] = nil - end - patch("/projects/#{input.delete('uid')}").payload(payload.except('uid')). + patch("/projects/#{input.delete('uid')}").payload(input). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end @@ -1020,11 +1025,11 @@ end }, get_project_details: { - title: 'Get project', - description: 'Get project'\ - ' in PlanGrid', + title: 'Get project info. by ID', + description: 'Get project info.'\ + ' by ID in Plangrid', help: { - body: 'Get project action uses the' \ + body: 'Get project info. by ID action uses the' \ " Retrieve a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/retrieve-a-project', @@ -1045,8 +1050,8 @@ }, upload_document: { title: 'Upload document to a project', - description: 'Upload document to a'\ - ' PlanGrid project', + description: 'Upload document to a project'\ + ' in Plangrid', help: { body: 'Upload document to a project action uses the' \ " document in a'\ - ' PlanGrid project', - help: { - body: 'Update document in a project action uses the' \ - " Update Document to Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/update-attachment-' \ - 'in-a-project', - learn_more_text: 'Update Document in a Project API' - }, - summarize_input: %w[file_content], - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'attachment_uid', label: 'Document ID', optional: false }, - { name: 'name', label: 'Document Name', - hint: 'New name of the document', sticky: true }, - { name: 'folder', label: 'Folder', - hint: 'New folder of the document', sticky: true } - ] - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - patch("/projects/#{project_uid}/attachments/" \ - "#{input.delete('attachment_uid')}"). - headers('Content-type': 'application/json'). - payload(input). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['document'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/attachments")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end + }, create_rfi: { title: 'Create RFI in a project', description: 'Create RFI in'\ - ' a PlanGrid project ', + ' a Plangrid project ', help: { - body: 'Create RFI in a project action uses the ' \ + body: 'Create RFI in project action uses the ' \ "Create RFI in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/create-rfi-' \ @@ -1273,11 +1228,11 @@ update_rfi: { title: 'Update RFI in a project', description: 'Update RFI in'\ - ' a PlanGrid project', + ' a Plangrid project', help: { - body: 'Update RFI in a project action uses the ' \ + body: 'Update RFI in Project action uses the ' \ "Update RFI in a Project API.", + "project' target='_blank'>patchUpdate RFI in a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/update-' \ 'rfi-in-a-project', learn_more_text: 'Update RFI in a Project' @@ -1300,7 +1255,8 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'status', label: 'Status UID' } + { name: 'status', label: 'Status', + hint: 'Use this for create and update rfi status' } ].concat(object_definitions['rfi']. only('uid', 'locked', 'title', 'question', 'answer', 'sent_at', 'due_at', 'assigned_to_uids'). @@ -1331,10 +1287,10 @@ }, get_rfi_in_project: { title: 'Get RFI in a project', - description: 'Get RFI in '\ - 'a PlanGrid project', + description: 'Get RFI by ID in'\ + ' Plangrid project', help: { - body: 'Get RFI in a project action uses the' \ + body: 'Get RFI by ID in a project action uses the' \ " Retrieve RFI in a Project API.", @@ -1343,29 +1299,12 @@ learn_more_text: 'Retrieve RFI in a Project' }, input_fields: lambda do |object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'rfi_uid', label: 'RFI ID', optional: false } - ] + object_definitions['rfi'].only('project_uid', 'uid'). + required('project_uid', 'uid') end, execute: lambda do |_connection, input| project_uid = input.delete('project_uid') - get("/projects/#{project_uid}/rfis/#{input['rfi_uid']}")&. + get("/projects/#{project_uid}/rfis/#{input['uid']}")&. merge('project_uid' => project_uid) end, output_fields: lambda do |object_definitions| @@ -1380,11 +1319,11 @@ create_task: { title: 'Create task in a project', description: 'Create task in'\ - ' a PlanGrid project', + ' Plangrid project', help: { - body: 'Create task in a project action uses the ' \ + body: 'Create task in Project action uses the ' \ "Create Task in Project API.", + "project' target='_blank'>Create task in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/create-task-in-' \ 'a-project', learn_more_text: 'Create Task in a Project' @@ -1406,15 +1345,12 @@ toggle_hint: 'Use project ID', hint: 'Provide project ID e.g. ' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } - }, - { name: 'issue_list_uid', label: 'Task List ID', sticky: true } + } } ].concat(object_definitions['task']. - only('title', 'status', 'type', 'assigned_to_uids', - 'room', 'start_date', 'due_at', - 'description', 'has_cost_impact', 'cost_impact', - 'has_schedule_impact', 'schedule_impact' - )) + only('assigned_to_uids', 'cost_impact', 'description', 'due_at', + 'has_cost_impact', 'has_schedule_impact', + 'issue_list_uid', 'room', 'schedule_impact', 'start_date', + 'status', 'title', 'type')) end, execute: lambda do |_connection, input| project_uid = input.delete('project_uid') @@ -1440,13 +1376,13 @@ end }, update_task: { - title: 'Update task in a project', + title: 'Update task in a Project', description: 'Update task in'\ - ' a PlanGrid project', + ' Plangrid project', help: { - body: 'Update task in a project action uses the ' \ + body: 'Update task in Project action uses the ' \ "Update Task in Project API.", + "project' target='_blank'>Create task in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/create-project', learn_more_text: 'Update Task in a Project' }, @@ -1467,24 +1403,17 @@ toggle_hint: 'Use project ID', hint: 'Provide project ID e.g.' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } - }, - { name: 'issue_uid', label: 'Task ID', optional: false }, - { name: 'issue_list_uid', label: 'Task List ID', sticky: true } + } } ].concat(object_definitions['task']. - only('title', 'status', 'type', 'assigned_to_uids', - 'room', 'start_date', 'due_at', - 'description', 'has_cost_impact', 'cost_impact', - 'has_schedule_impact', 'schedule_impact' - )) + only('uid', 'assigned_to_uids', 'cost_impact', 'description', + 'due_at', 'has_cost_impact', 'has_schedule_impact', + 'issue_list_uid', 'room', 'schedule_impact', 'start_date', + 'status', 'title', 'type').required('uid')) end, execute: lambda do |_connection, input| project_uid = input.delete('project_uid') - payload = input.each do |key, value| - input[key].present? || input[key] = nil - end patch("/projects/#{project_uid}/issues/" \ - "#{input.delete('issue_uid')}").payload(payload). + "#{input.delete('uid')}").payload(input). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end&.merge('project_uid' => project_uid) @@ -1501,7 +1430,7 @@ get_task: { title: 'Get task in a project', description: 'Get task in'\ - ' a PlanGrid project', + ' in a Plangrid project', help: { body: 'Get task in a project action uses the ' \ "user to'\ - ' a PlanGrid project', + ' project team Plangrid', help: { body: 'Invite user to a project action uses the ' \ "Invite User in Project API.", + "project-team' target='_blank'>Invite user in Project team API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ 'invite-user-to-project-team', - learn_more_text: 'Invite User to Project' + learn_more_text: 'Invite User to Project Team' }, input_fields: lambda do |_object_definitions| [ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project ID', + label: 'Project', optional: false, toggle_hint: 'Select project', toggle_field: { @@ -1579,17 +1508,16 @@ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, { name: 'email', optional: false }, - { name: 'role_uid', label: 'Role ID', sticky: true, + { name: 'role_uid', label: 'Role ID', hint: 'Unique identifier of role to assign user on project team' } ] end, execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - post("/projects/#{project_uid}/users/invites"). + post("/projects/#{input.delete('project_uid')}/users/invites"). payload(input). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) + end end, output_fields: lambda do |object_definitions| object_definitions['user'] @@ -1599,17 +1527,17 @@ get("/projects/#{id}/users")&.dig('data', 0) || {} end }, - get_user_in_project: { - title: 'Get user in project', + get_user_by_id: { + title: 'Get user in a project', description: 'Get user in'\ - ' a PlanGrid project', + ' Plangrid project', help: { - body: 'Get user in a project action uses the ' \ + body: 'Get user in project action uses the ' \ "Retrieve User in a Project.", + "project-team' target='_blank'>Retrieve User on a Project Team.", learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ 'users-on-a-project-team', - learn_more_text: 'Retrieve User in a Project' + learn_more_text: 'Retrieve User on a Project Team' }, input_fields: lambda do |_object_definitions| [ @@ -1648,7 +1576,7 @@ get_snapshot_in_project: { title: 'Get snapshot in a project', description: 'Get snapshot in'\ - ' a PlanGrid project', + ' a Plangrid project', help: { body: 'Get snapshot in a project action uses the ' \ " input['project_uid']) + "#{input['snapshot_uid']}") end, output_fields: lambda do |object_definitions| object_definitions['snapshot'] @@ -1693,10 +1621,10 @@ }, get_rfi_statuses_in_project: { title: 'Get RFI statuses in project', - description: 'Get RFI statuses in'\ - ' a PlanGrid project', + description: 'Get rfi statuses in'\ + ' Plangrid project', help: { - body: 'Get RFI statuses in project action uses the ' \ + body: 'Get rfi statuses in project action uses the ' \ "Retrieve RFI Statuses in a Project.", learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ @@ -1744,23 +1672,23 @@ end }, get_roles_on_project: { - title: 'Get roles in a project', - description: 'Get roles in '\ - ' a PlanGrid project', + title: 'Get roles on a project', + description: 'Get roles on '\ + ' Plangrid project', help: { - body: 'Get roles in a project action uses the ' \ - "Retrieve Roles on a Project API.", + body: 'Get role on a project action uses the ' \ + "Retrieve Role on a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-roles-on-a-project', - learn_more_text: 'Retrieves Role on a Project' + 'retrieve-role-on-a-project', + learn_more_text: 'Retrieve Role on a Project' }, input_fields: lambda do |_object_definitions| [ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project ID', + label: 'Project', optional: false, toggle_hint: 'Select project', toggle_field: { @@ -1772,19 +1700,24 @@ toggle_hint: 'Use project ID', hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } } + } }, + { name: 'limit', type: 'integer', + hint: 'Number of roles to retrieve. Maximum value of 50.' }, + { name: 'skip', type: 'integer', + hint: 'Number of roles to skip in the set of results.' } ] end, execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - { roles: get("/projects/#{project_uid}/roles")['data'] } + { roles: get("/projects/#{input.delete('project_uid')}/roles", input) } end, output_fields: lambda do |_object_definitions| [ - { name: 'roles', label: 'Roles', type: 'array', of: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'label', label: 'Role' } - ] } + { name: 'roles', type: 'array', of: 'object', properties: [ + { name: 'uid' }, + { name: 'label' } + ] }, + { name: 'total_count' }, + { name: 'next_page_url' } ] end, sample_output: lambda do |_connection, _input| @@ -1792,15 +1725,69 @@ 'label' => 'Admin' } } end }, - + get_sheets_in_project: { + title: 'Get sheets in a project', + description: 'Get sheets in'\ + ' Plangrid project', + help: { + body: 'Get sheets in project action uses the ' \ + "Retrieve Sheets in a Project.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-sheets-in-a-project', + learn_more_text: 'Retrieve Sheets in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'limit', type: 'integer', + hint: 'Number of sheets to retrieve. Maximum value of 50.' }, + { name: 'skip', type: 'integer', + hint: 'Number of sheets to skip in the set of results' }, + { name: 'updated_after', type: 'date_time', + hint: 'Only retrieve sheets created/updated after ' \ + 'specified UTC date and time.' } + ] + end, + execute: lambda do |_connection, input| + { sheets: get("/projects/#{input.delete('project_uid')}/sheets", + input)['data'] } + end, + output_fields: lambda do |object_definitions| + [{ name: 'sheets', type: 'array', of: 'object', + properties: object_definitions['sheet'] }] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + { + sheets: get("/projects/#{id}/sheets?limit=1")&.dig('data', 0)&. + merge('project_uid' => id) || {} + } + end + }, get_sheet_in_project: { - title: 'Get sheet in a project', - description: 'Get sheet in '\ - 'a PlanGrid project', + title: 'Get sheet by ID in project', + description: 'Get sheet in'\ + ' Plangrid project', help: { - body: 'Get sheet in a project action uses the ' \ + body: 'Get project sheet details action uses the ' \ "Retrieve Sheet in a Project.", + " target='_blank'>Retrieve Sheets in a Project.", learn_more_url: 'https://developer.plangrid.com/docs/' \ 'retrieve-a-sheet', learn_more_text: 'Retrieve Sheet in a Project' @@ -1810,7 +1797,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project ID', + label: 'Project', optional: false, toggle_hint: 'Select project', toggle_field: { @@ -1823,12 +1810,11 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'sheet_uid', label: 'Sheet ID', optional: false } + { name: 'sheet_uid', type: 'Sheet ID', optional: false } ] end, execute: lambda do |_connection, input| - get("/projects/#{input['project_uid']}/sheets/#{input['sheet_uid']}")&. - merge('project_uid' => input['project_uid']) + get("/projects/#{input['project_uid']}/sheets/#{input['sheet_uid']}") end, output_fields: lambda do |object_definitions| object_definitions['sheet'] @@ -1840,11 +1826,11 @@ end }, get_project_sheet_packet: { - title: 'Get sheet packet in a project', - description: 'Get sheet packet in'\ - ' a PlanGrid project', + title: 'Get project sheet packet', + description: 'Get project sheet packet in'\ + ' packet in Plangrid', help: { - body: 'Get sheet packet in a project action uses the ' \ + body: 'Get project sheet packet action uses the ' \ "Retrieve Sheet Packet API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ @@ -1869,23 +1855,23 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'packet_uid', label: 'Sheet Packet ID', optional: false } + { name: 'packet_uid', type: 'Packet ID' } ] end, execute: lambda do |_connection, input| get("/projects/#{input['project_uid']}/sheets/packets/" \ - "#{input['packet_uid']}")&.merge('project_uid' => input['project_uid']) + "#{input['packet_uid']}") end, output_fields: lambda do |object_definitions| object_definitions['sheet_packet'] end }, get_field_reports_in_project: { - title: 'Get field reports in a project', + title: 'Get fields reports in project', description: 'Get field reports in'\ - ' a PlanGrid project', + ' in Plangrid project', help: { - body: 'Get field reports in a project action uses the ' \ + body: 'Get fields reports in project action uses the ' \ "Retrieve Field Reports in a" \ ' Project API.', @@ -1898,7 +1884,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project ID', + label: 'Project', optional: false, toggle_hint: 'Select project', toggle_field: { @@ -1911,17 +1897,17 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'report_date_min', type: 'date', - label: 'Report Start Date', + { name: 'updated_after', type: 'date_time', + hint: 'Only retrieve field reports created/updated after ' \ + 'specified UTC date and time.' }, + { name: 'report_date_min', type: 'date_time', + label: 'Report start date', hint: 'Only retrieve field reports between a date range ' \ 'starting with this date in UTC format.' }, - { name: 'report_date_max', type: 'date', - label: 'Report End Date', + { name: 'report_date_max', type: 'date_time', + label: 'Report end date', hint: 'Only retrieve field reports between a date range ' \ 'starting with this date in UTC format.' }, - { name: 'updated_after', label: 'Updated After', type: 'date_time', - hint: 'Only retrieve field reports created/updated after ' \ - 'specified UTC date and time.' }, { name: 'sort_by', control_type: 'select', pick_list: %w[report_date updated_at]&.map { |e| [e.labelize, e] }, @@ -1929,14 +1915,6 @@ toggle_field: { name: 'sort_by', type: 'string', control_type: 'text', hint: 'Allowed values report_date or updated_at' - } }, - { name: 'sort_order', control_type: 'select', - pick_list: - %w[asc desc]&.map { |e| [e.labelize, e] }, - toggle_hint: 'Select sort order', - toggle_field: { - name: 'sort_by', type: 'string', control_type: 'text', - hint: 'Allowed values asc or desc' } } ] end, @@ -1944,17 +1922,17 @@ project_uid = input.delete('project_uid') query_params = '' input&.map do |key, val| - if %w[updated_after].include?(key) - query_params = query_params + "&" + "#{key}=#{val.to_time.utc.iso8601}" + if %w[updated_after report_date_min report_date_max].include?(key) + query_params = query_params + "#{key}=#{val.to_time.utc.iso8601}" else - query_params = query_params + "&" + "#{key}=#{val}" + query_params = query_params + "#{key}=#{val}" end end { field_reports: get("/projects/#{project_uid}/field_reports?" \ "#{query_params}")['data'] } end, output_fields: lambda do |object_definitions| - { name: 'field_reports', label: 'Field Reports', type: 'array', of: 'object', + { name: 'field_reports', type: 'array', of: 'object', properties: object_definitions['field_report'] } end, sample_output: lambda do |_connection, _input| @@ -1965,9 +1943,9 @@ end }, upload_photo: { - title: 'Upload photo to a project', + title: 'Upload photo to project', description: 'Upload photo to '\ - ' a PlanGrid project', + ' project in Plangrid', help: { body: 'Upload photo to a project action uses the' \ " project_uid) + end end, output_fields: lambda do |object_definitions| object_definitions['photo'] @@ -2046,16 +2022,16 @@ end }, update_photo_metadata: { - title: 'Update photo in a project', - description: 'Update photo in'\ - ' a PlanGrid project', + title: 'Update photo metadata', + description: 'Update photo metadata to '\ + ' Project in Plangrid', help: { - body: 'Update photo action uses the' \ + body: 'Update photo metadata action uses the' \ " Update Photo in a Project API.", + "project' target='_blank'>Update Document to Project API.", learn_more_url: 'https://developer.plangrid.com/docs/update-photo-' \ 'in-a-project', - learn_more_text: 'Update Photo in a Project API' + learn_more_text: 'Update photo to Project API' }, summarize_input: %w[file_content], input_fields: lambda do |_object_definitions| @@ -2072,20 +2048,19 @@ toggle_hint: 'Use project ID', hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'photo_uid', label: 'Photo ID', optional: false }, + { name: 'photo_uid', type: 'Photo ID', optional: false }, { name: 'title', label: 'Photo title', - hint: 'New title of the photo', sticky: true } + hint: 'New title of the photo' } ] end, execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - patch("/projects/#{project_uid}/photos/" \ + patch("/projects/#{input.delete('project_uid')}/photos/" \ "#{input.delete('photo_uid')}"). headers('Content-type': 'application/json'). payload(input). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) + end end, output_fields: lambda do |object_definitions| object_definitions['photo'] @@ -2096,12 +2071,12 @@ merge('project_uid' => id) || {} end }, - get_photo_details: { - title: 'Get photo in a project', + get_photo_by_id: { + title: 'Get photo in a Project', description: 'Get photo in'\ - ' a PlanGrid project', + ' a Plangrid project', help: { - body: 'Get photo action uses the ' \ + body: 'Get photo details action uses the ' \ "Retrieve Photo in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ @@ -2126,12 +2101,12 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'photo_uid', label: 'Photo ID', optional: false } + { name: 'photo_uid', type: 'Photo ID', optional: false } ] end, execute: lambda do |_connection, input| get("/projects/#{input['project_uid']}/photos/" \ - "#{input['photo_uid']}")&.merge('project_uid' => input.delete('project_uid')) + "#{input['photo_uid']}") end, output_fields: lambda do |object_definitions| object_definitions['photo'] @@ -2142,12 +2117,12 @@ merge('project_uid' => id) || {} end }, - get_document_details: { + get_document_by_id: { title: 'Get document in a project', - description: 'Get document'\ - ' in a PlanGrid project', + description: 'Get document in'\ + ' in Plangrid project', help: { - body: 'Get document in a project action uses the ' \ + body: 'Get document details action uses the ' \ "Retrieve Document in a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ @@ -2172,12 +2147,12 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'attachment_uid', label: 'Document ID', optional: false } + { name: 'attachment_uid', type: 'Document ID', optional: false } ] end, execute: lambda do |_connection, input| get("/projects/#{input['project_uid']}/attachments/" \ - "#{input['attachment_uid']}")&.merge('project_uid' => input.delete('project_uid')) + "#{input['attachment_uid']}") end, output_fields: lambda do |object_definitions| object_definitions['document'] @@ -2187,654 +2162,104 @@ get("/projects/#{id}/attachments")&.dig('data', 0)&. merge('project_uid' => id) || {} end - }, - create_sheet_packet: { - title: 'Create sheet packet in a project', - description: 'Create sheet packet in '\ - ' a PlanGrid project', + } + }, + triggers: { + new_updated_project: { + title: 'New/updated project', + description: 'New/updated project in'\ + ' Plangrid', help: { - body: 'Create sheet packet in a project action uses the' \ - " Create Sheet Packet in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/upload-photo' \ - '-to-project', - learn_more_text: 'Create Sheet Packet in a Project' + body: 'New/updated project trigger uses the' \ + " List all Projects API.", + learn_more_url: 'https://developer.plangrid.com/docs/list-all-projects', + learn_more_text: 'List All Projects API' }, - input_fields: lambda do |object_definitions| + input_fields: lambda do |_object_definitions| [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'sheet_uids', label: 'Sheet IDs', optional: false, - type: 'string', - hint: 'A comma separated list of sheet IDs.' }, - { name: 'include_annotations', label: 'Include annotations?', type: 'boolean', sticky: true, - control_type: 'checkbox', toggle_hint: 'Select from options list', - toggle_field: { - name: 'include_annotations', - label: 'Include annotations?', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, 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, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - payload = { - sheet_uids: input.delete('sheet_uids').split(','), - include_annotations: input.delete('include_annotations') + poll: lambda do |_connection, input, closure| + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 20 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get('/projects'). + params(limit: limit, + skip: skip, + updated_after: updated_after) + end + closure = if (next_page_url = response['next_page_url']).present? + { 'skip' => skip + limit, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'updated_after' => now.to_time.utc.iso8601 } + end + { + events: response['data'] || [], + next_poll: closure, + can_poll_more: response['next_page_url'].present? } - post("/projects/#{project_uid}/sheets/packets").payload(payload). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) + end, + dedup: lambda do |project| + "#{project['uid']}@#{project['updated_at']}" end, output_fields: lambda do |object_definitions| - object_definitions['sheet_packet'] + object_definitions['project'] end, sample_output: lambda do |_connection, _input| - { - uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", - file_url: "https://packet-assets.plangrid.com/92cf7193-af0c-42fc-a3ab-7ef5149da720.pdf", - resource: { - uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", - url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/packets/92cf7193-af0c-42fc-a3ab-7ef5149da720" - }, - status: "incomplete" - } + get('/projects')&.dig('data', 0) || {} end }, - get_task_list: { - title: 'Get task list in a project', - description: 'Get task list'\ - ' in a PlanGrid project', + new_updated_documents: { + title: 'New/updated documents in a project', + description: 'New/updated document in '\ + 'Project Plangrid', help: { - body: 'Get task list in a project action uses the ' \ - "Retrieve Task List in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-issue-list', - learn_more_text: 'Retrieve Task List in a Project API' + body: 'New/updated documents in Project trigger uses the' \ + " Retrieve Documents in a Project" \ + ' API.', + learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ + 'attachments-in-a-project', + learn_more_text: 'Retrieve Documents in a Project' }, input_fields: lambda do |_object_definitions| [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', + { name: 'project_uid', optional: false, label: 'Project', - optional: false, + control_type: 'select', pick_list: 'project_list', toggle_hint: 'Select project', toggle_field: { name: 'project_uid', + label: 'Project ID', type: 'string', control_type: 'text', - optional: false, - label: 'Project ID', toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'issue_list_uid', label: 'Task List ID', optional: false } - ] - end, - execute: lambda do |_connection, input| - get("/projects/#{input['project_uid']}/issue_lists/" \ - "#{input['issue_list_uid']}") - end, - output_fields: lambda do |object_definitions| - [ - { - name: "uid", label: "Task List ID" - }, - { - name: "project_uid", label: "Project ID" - }, - { - name: "name", label: "Name" - }, { - name: "deleted", label: "Deleted", type: "boolean" - } - ] - end, - sample_output: lambda do |_connection, _input| - { - uid: "31f54967-4eac-4bd7-9b35-57f00a973a1d", - name: "QA/QC", - deleted: false, - project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" - } - end - }, - update_task_list: { - title: 'Update task list in a project', - description: 'Update task list'\ - ' in a PlanGrid project', - help: { - body: 'Update task list in a project action uses the ' \ - "Update Task List in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'update-issue-list', - learn_more_text: 'Update Task List in a Project API' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'issue_list_uid', label: 'Task List ID', optional: false }, - { name: 'name', optional: false } - ] - end, - execute: lambda do |_connection, input| - patch("/projects/#{input['project_uid']}/issue_lists/" \ - "#{input['issue_list_uid']}").payload({name: input.delete('name')}) - end, - output_fields: lambda do |object_definitions| - [ - { - name: "uid", label: "Task List ID" - }, - { - name: "project_uid", label: "Project ID" - }, - { - name: "name", label: "Name" - }, - { - name: "deleted", label: "Deleted", type: "boolean" - } - ] - end, - sample_output: lambda do |_connection, _input| - { - uid: "31f54967-4eac-4bd7-9b35-57f00a973a1d", - name: "QA/QC", - deleted: false, - project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" - } - end - }, - create_task_list: { - title: 'Create task list in a project', - description: 'Create task list'\ - ' in a PlanGrid project', - help: { - body: 'Create task list in a project action uses the ' \ - "Create Task List in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'create-issue-list', - learn_more_text: 'Create Task List in a Project API' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'name', optional: false } - ] - end, - execute: lambda do |_connection, input| - post("/projects/#{input.delete('project_uid')}/issue_lists").payload(input) - end, - output_fields: lambda do |object_definitions| - [ - { - name: "uid", label: "Task List ID" - }, - { - name: "project_uid", label: "Project ID" - }, - { - name: "name", label: "Name" - }, - { - name: "deleted", label: "Deleted", type: "boolean" - } - ] - end, - sample_output: lambda do |_connection, _input| - { - uid: "31f54967-4eac-4bd7-9b35-57f00a973a1d", - name: "QA/QC", - deleted: false, - project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" - } - end - }, - create_sheet_version: { - title: 'Create sheet version upload in a project', - description: 'Create sheet version upload'\ - ' in a PlanGrid project', - help: { - body: 'Create sheet version in a project action uses the ' \ - "Upload Version to a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'upload-version-to-project', - learn_more_text: 'Upload Version to a Project API' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'num_files', label: 'Number of PDFs', type: 'integer', optional: false }, - { name: 'version_name', label: 'Version Name', optional: false } - ] - end, - execute: lambda do |_connection, input| - post("/projects/#{input.delete('project_uid')}/sheets/uploads").payload(input) - end, - output_fields: lambda do |object_definitions| - [ - { - name: 'uid', label: 'Sheet Version Upload ID' - }, - { - name: 'complete_url', label: 'Upload Completion URL' - }, - { - name: 'status', - }, - { - name: 'file_upload_requests', label: 'File Upload Requests', - type: 'array', of: 'object', properties: [ - { - name: 'uid', label: 'File Upload ID' - }, - { - name: 'upload_status', label: 'File Upload Status' - }, - { - name: 'url', label: 'File Upload URL' - } - ] - } - ] - end, - sample_output: lambda do |_connection, _input| - { - uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", - complete_url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720", - status: "incomplete", - file_upload_requests: [ - { - uid: "b278fcba-72f0-4161-bfdc-89d5bde4d5e7", - upload_status: "issued", - url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720/files/b278fcba-72f0-4161-bfdc-89d5bde4d5e7" - }, - { - uid: "727fca7d-385b-4476-b257-4b96c00e879b", - upload_status: "issued", - url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720/files/727fca7d-385b-4476-b257-4b96c00e879b" - } - ] - } - end - }, - upload_file_to_sheet_version: { - title: 'Upload file to sheet version in a project', - description: 'Upload file to sheet version'\ - ' in a PlanGrid project', - help: { - body: 'Upload file to sheet version in a project action uses the ' \ - "Upload File to Version in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'upload-file-to-version', - learn_more_text: 'Upload File to Version in a Project API' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'ver_upload_uid', label: 'Sheet Version Upload ID', optional: false }, - { name: 'file_upload_request_uid', label: 'File Upload ID', optional: false }, - { name: 'file_name', label: 'File Name', optional: false }, - { name: 'file_content', label: 'File Content', optional: false } - ] - end, - execute: lambda do |_connection, input| - file_content = input.delete('file_content') - project_uid = input.delete('project_uid') - file_upload_info = post("/projects/#{project_uid}/sheets/" \ - "uploads/#{input.delete('ver_upload_uid')}/" \ - "files/#{input.delete('file_upload_request_uid')}"). - headers('Content-Type': 'application/json'). - payload({file_name: input.delete('file_name')}) - url = file_upload_info&.dig('aws_post_form_arguments', 'action') - fields = file_upload_info&.dig('aws_post_form_arguments', 'fields') - # webhook_url = file_upload_info. - # dig('aws_post_form_arguments', 'webhook_url') - headers = fields.map { |o| { o['name'] => o['value'] } }.inject(:merge) - status = - post(url). - payload(key: headers['key'], - policy: headers['policy'], - signature: headers['signature'], - AWSAccessKeyId: headers['AWSAccessKeyId'], - 'content-type': headers['Content-Type'], - 'success_action_redirect': headers['success_action_redirect'], - 'x-amz-server-side-encryption': - headers['x-amz-server-side-encryption'], - 'x-amz-storage-class': headers['x-amz-storage-class'], - file: file_content). - request_format_multipart_form. - after_response do |_code, response, _response_headers| - response - end - end, - output_fields: lambda do |object_definitions| - - end, - sample_output: lambda do |_connection, _input| - - end - }, - complete_version_upload: { - title: 'Complete sheet version upload to a project', - description: 'Complete sheet version upload '\ - ' to a PlanGrid project', - help: { - body: 'Complete sheet version upload to a project action uses the ' \ - "Complete Version Upload in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'complete-version-upload-to-project', - learn_more_text: 'Complete Version Upload in a Project API' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'ver_upload_uid', label: 'Sheet Version Upload ID', optional: false } - ] - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - post("/projects/#{project_uid}/sheets/" \ - "uploads/#{input.delete('ver_upload_uid')}/completions")&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - [ - { - name: 'uid', label: 'Sheet Version ID' - }, - { - name: 'status', label: 'Status' - } - ] - end, - sample_output: lambda do |_connection, _input| - { - uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", - complete_url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720", - status: "complete" - } - end - } - }, - triggers: { - new_updated_project: { - title: 'New or updated project', - description: 'New or updated project in'\ - ' PlanGrid', - help: { - body: 'New or updated project trigger uses the' \ - " List All Projects API.", - learn_more_url: 'https://developer.plangrid.com/docs/list-all-projects', - learn_more_text: 'List All Projects API' - }, - input_fields: lambda do |_object_definitions| - [ - { - 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| - updated_after = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 20 - skip = closure&.[]('skip') || 0 - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) - else - get('/projects'). - params(limit: limit, - skip: skip, - updated_after: updated_after) - end - closure = if (next_page_url = response['next_page_url']).present? - { 'skip' => skip + limit, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'updated_after' => now.to_time.utc.iso8601 } - end - { - events: response['data'] || [], - next_poll: closure, - can_poll_more: response['next_page_url'].present? - } - end, - dedup: lambda do |project| - "#{project['uid']}@#{project['updated_at']}" - end, - output_fields: lambda do |object_definitions| - object_definitions['project'] - end, - sample_output: lambda do |_connection, _input| - get('/projects')&.dig('data', 0) || {} - end - }, - new_updated_sheets: { - title: 'New or updated sheet in a project', - description: 'New or updated sheet in '\ - 'a PlanGrid project', - help: { - body: 'New or updated sheet in a project trigger uses the' \ - " Retrieve Sheets in a Project" \ - ' API.', - learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ - 'sheets-in-a-project', - learn_more_text: 'Retrieve Sheets in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { - 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_uid = closure&.[]('project_uid') || input['project_uid'] - updated_after = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 5 - skip = closure&.[]('skip') || 0 - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) - else - get("/projects/#{project_uid}/sheets"). - params(limit: limit, - skip: skip, - updated_after: updated_after) - end - closure = if (next_page_url = response['next_page_url']).present? - { 'skip' => skip + limit, - 'project_uid' => project_uid, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'project_uid' => project_uid, - 'updated_after' => now.to_time.utc.iso8601 } - end - sheets = response['data']&. - map { |o| o.merge('project_uid' => project_uid) } - { - events: sheets || [], - next_poll: closure, - can_poll_more: response['next_page_url'].present? - } - end, - dedup: lambda do |sheet| - "#{sheet['uid']}@#{sheet['created_at']}" - end, - output_fields: lambda do |object_definitions| - object_definitions['sheet'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/sheets")&.dig('data', 0) || {} - end - }, - new_updated_documents: { - title: 'New or updated document in a project', - description: 'New or updated document in '\ - 'a PlanGrid project', - help: { - body: 'New or updated document in a project trigger uses the' \ - " Retrieve Documents in a Project" \ - ' API.', - learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ - 'attachments-in-a-project', - learn_more_text: 'Retrieve Documents in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { - 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' + 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, @@ -2881,11 +2306,11 @@ end }, new_updated_task: { - title: 'New or updated task in a project', - description: 'New or updated task in a '\ - ' PlanGrid project', + title: 'New/updated task in a Project', + description: 'New/updated task in a '\ + 'Project Plangrid', help: { - body: 'New or updated task in a project trigger uses the' \ + body: 'New/updated task in a Project trigger uses the' \ " Retrieve Tasks " \ ' in a Project API.', @@ -2964,14 +2389,14 @@ end }, new_updated_annotations: { - title: 'New or updated annotation in a project', - description: 'New or updated annotation '\ - 'in a PlanGrid project', + title: 'New/updated annotations in Project', + description: 'New/updated annotations '\ + 'in Project Plangrid', help: { - body: 'New or updated annotation in project trigger uses the' \ + body: 'New/updated annotations in Project trigger uses the' \ " Retrieve " \ - ' Annotations in a Project API.', + ' annotations in a Project API.', learn_more_url: 'https://developer.plangrid.com/docs/' \ 'retrieve-annotations-in-a-project', learn_more_text: 'Retrieve Annotations in a Project' @@ -3046,17 +2471,17 @@ end }, new_updated_photos: { - title: 'New or updated photo in a project', - description: 'New or updated photo '\ - 'in a PlanGrid project', + title: 'New/updated photos in Project', + description: 'New/updated photos '\ + 'in Plangrid Project', help: { - body: 'New or updated photo in a project trigger uses the' \ + body: 'New/updated photos in Project trigger uses the' \ " Retrieve " \ ' photos in a Project API.', learn_more_url: 'https://developer.plangrid.com/docs/' \ 'retrieve-photos-in-a-project', - learn_more_text: 'Retrieve Photos in a Project' + learn_more_text: 'Retrieve photos in a Project' }, input_fields: lambda do |_object_definitions| [ @@ -3128,16 +2553,16 @@ end }, new_updated_snapshot: { - title: 'New or updated snapshot in a project', - description: 'New or updated snapshot '\ - 'in a PlanGrid project', + title: 'New/updated snapshot in a Project', + description: 'New/updated snapshot '\ + 'in a Project Plangrid', help: { - body: 'New or updated snapshot in a project trigger uses the' \ + body: 'New/updated snapshot in a Project trigger uses the' \ " Retrieve " \ + "remove-snapshot-reference-in-rfi' target='_blank'>Retrieve " \ ' Snapshots in a Project API.', learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-snapshots-in-a-project', + 'remove-snapshot-reference-in-rfi', learn_more_text: 'Retrieve Snapshots in a Project' }, input_fields: lambda do |_object_definitions| @@ -3210,17 +2635,17 @@ end }, new_updated_field_report: { - title: 'New or updated field report in a project', - description: 'New or updated field report '\ - 'in a PlanGrid project', + title: 'New/updated field report in a Project', + description: 'New/updated field report '\ + 'in Plangrid Project', help: { - body: 'New or updated field report in a project trigger uses the' \ + body: 'New/updated field report in Project trigger uses the' \ " Retrieve " \ - 'Field Reports in a Project API.', + 'field reports in a Project API.', learn_more_url: 'https://developer.plangrid.com/docs/' \ 'retrieve-field-reports-in-a-project', - learn_more_text: 'Retrieve Field Reports in a Project' + learn_more_text: 'Retrieve field reports in a Project' }, input_fields: lambda do |_object_definitions| [ @@ -3273,8 +2698,14 @@ 'project_uid' => project_uid, 'updated_after' => now.to_time.utc.iso8601 } end - field_reports = response['data']&. - map { |o| o.merge('project_uid' => project_uid) } + results = response['data']&. + map do |field_report| + field_report.merge({ 'pdf_form_fileds' => + field_report.delete('pdf_form_fileds')&. + map { |a| { a[0] => a[1] } }&.inject(:merge) }). + merge('project_uid' => project_uid) + end + field_reports = call('format_api_output_field_names', results) { events: field_reports || [], next_poll: closure, @@ -3294,11 +2725,11 @@ end }, new_updated_rfi: { - title: 'New or updated RFI in a project', - description: 'New or updated RFI '\ - 'in a PlanGrid project', + title: 'New/updated RFI in a Project', + description: 'New/updated RFI '\ + 'in a Plangrid Project', help: { - body: 'New or updated RFI in a project trigger uses the' \ + body: 'New/updated RFI in a Project trigger uses the' \ " Retrieve " \ ' RFIs in a Project API.', @@ -3387,14 +2818,12 @@ 'gov-state-local', 'other'].map { |type| [type.labelize, type] } end, project_folders: lambda do |_connection, project_uid:| - if project_uid.length === 36 - folders = get("/projects/#{project_uid}/attachments")['data']&. - pluck('folder')&.uniq - if folders.size > 0 - folders&.map { |folder| [folder || 'Root', folder || ''] } - else - [['Root', '']] - end + folders = get("/projects/#{project_uid}/attachments")['data']&. + pluck('folder')&.uniq + if folders.size > 0 + folders&.map { |folder| [folder || 'Root', folder || ''] } + else + [['Root', '']] end end } From 396716097b1b392f9d45687d2cdcaac5fef649fc Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 30 Aug 2019 13:06:14 -0400 Subject: [PATCH 55/78] update `new or updated field report..` trigger and `get field report..` action to output `pdf_form_fields` --- custom_connectors/oauth2/plangrid.rb | 1704 +++++++++++++++++--------- 1 file changed, 1144 insertions(+), 560 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 5385c9a7..253c77be 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1,5 +1,5 @@ { - title: 'Plangrid', + title: 'PlanGrid', connection: { fields: [ { @@ -54,43 +54,6 @@ end }, test: ->(_connection) { get('/me') }, - methods: { - format_api_output_field_names: lambda do |input| - if input.is_a?(Array) - input.map do |array_value| - call('format_api_output_field_names', array_value) - end - elsif input.is_a?(Hash) - input.map do |key, value| - value = call('format_api_output_field_names', value) - key = key.gsub(/\W/) { |string| "__#{string.encode_hex}__" } - { key => value } - end.inject(:merge) - else - input - end - end, - - format_schema_field_names: lambda do |input| - input.map do |field| - if field[:properties].present? - field[:properties] = call('format_schema_field_names', - field[:properties]) - elsif field['properties'].present? - field['properties'] = call('format_schema_field_names', - field['properties']) - end - if field[:name].present? - field[:name] = field[:name]. - gsub(/\W/) { |string| "__#{string.encode_hex}__" } - elsif field['name'].present? - field['name'] = field['name']. - gsub(/\W/) { |string| "__#{string.encode_hex}__" } - end - field - end - end - }, object_definitions: { project: { fields: lambda do |_connection, _config_fields| @@ -98,7 +61,7 @@ { name: 'uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -111,11 +74,11 @@ hint: 'Provide project ID e.g. ' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'name', label: 'Project name', sticky: true }, - { name: 'custom_id', label: 'Project code', sticky: true }, - { name: 'organization_id' }, + { name: 'name', label: 'Project Name', sticky: true }, + { name: 'custom_id', label: 'Project Code', sticky: true }, + { name: 'organization_id', label: 'Organization ID' }, { name: 'type', control_type: 'select', - label: 'Project type', sticky: true, + label: 'Project Type', sticky: true, pick_list: 'project_types', toggle_hint: 'Select project type', toggle_field: { @@ -130,26 +93,26 @@ 'education-k-12, education-higher, gov-federal, ' \ 'gov-state-local, or other' } }, - { name: 'status', label: 'Project status', sticky: true }, - { name: 'owner', sticky: true, label: 'Project owner' }, + { name: 'status', label: 'Project Status', sticky: true }, + { name: 'owner', sticky: true, label: 'Project Owner' }, { name: 'start_date', type: 'date', sticky: true, render_input: 'date_conversion', parse_output: 'date_conversion', - label: 'Project start date', + label: 'Project Start Date', hint: 'Project start date. ISO-8601 date format (YYYY-MM-DD).' }, { name: 'end_date', type: 'date', sticky: true, render_input: 'date_conversion', parse_output: 'date_conversion', - label: 'Project end date', + label: 'Project End Date', hint: 'Project end date. ISO-8601 date format (YYYY-MM-DD).' }, { name: 'street_1', sticky: true, - label: 'Street line 1' }, + label: 'Street Line 1' }, { name: 'street_2', sticky: true, label: 'Street line 2' }, - { name: 'city', sticky: true, label: 'Town or city' }, - { name: 'region', sticky: true, label: 'State, province, or region' }, - { name: 'postal_code', sticky: true, label: 'Zip or postal code' }, + { name: 'city', sticky: true, label: 'Town or City' }, + { name: 'region', sticky: true, label: 'State, Province, or Region' }, + { name: 'postal_code', sticky: true, label: 'Zip or Postal Code' }, { name: 'country', sticky: true, hint: 'Project address country in 2-letter ISO 3166 code.' }, @@ -158,22 +121,7 @@ { name: 'updated_at', type: 'date_time', render_input: 'date_time_conversion', parse_output: 'date_time_conversion', - label: 'Updated at' }, - { name: 'add_to_organization', type: 'boolean', - control_type: 'checkbox', - hint: 'Boolean indicating whether to add the project to the ' \ - 'organization that the API user belongs to or not. By default ' \ - 'the project is created as a personal project and not as an ' \ - 'organization-linked project.', - toggle_hint: 'Select from options list', - toggle_field: { - name: 'add_to_organization', - label: 'Add to organization', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } } + label: 'Updated at' } ] end }, @@ -184,7 +132,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -197,14 +145,14 @@ hint: 'Provide project ID e.g. ' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'name', label: 'Document name' }, + { name: 'name', label: 'Document Name' }, { name: 'folder' }, { name: 'url' }, { name: 'created_at', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'created_by', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, @@ -222,7 +170,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -235,26 +183,64 @@ hint: 'Provide project ID e.g. ' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, + { name: 'number', type: 'number' }, + { name: 'title' }, + { name: 'status', control_type: 'select', pick_list: + %w[open in_review pending closed].select { |op| [op.labelize, op] }, + 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", "in_review", "pending",' \ + ' "closed".' + } }, + { name: 'type', control_type: 'select', + pick_list: [ + %w[issue issue], + %w[Planned\ work planned_work], + %w[other other] + ], + toggle_hint: 'Select type', + toggle_field: { + name: 'type', + label: 'Type', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: "issue", "planned_work",' \ + ' "other".' + } }, { name: 'assignees', type: 'array', of: 'object', properties: [ - { name: 'assignee' } + { name: 'uid', label: 'UID' }, + { name: 'type' } + ] }, + { name: 'followers', label: 'Watchers', type: 'array', of: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'type' } ] }, + { name: 'room', label: 'Location' }, + { name: 'start_date', label: 'Start Date', + type: 'date_time', + render_input: 'date_conversion', + parse_output: 'date_conversion' }, { name: 'closed_at', type: 'date_time', render_input: 'date_time_conversion', parse_output: 'date_time_conversion' }, - { name: 'created_at', type: 'date_time', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'created_by', type: 'object', properties: [ - { name: 'uid' }, - { name: 'url' }, - { name: 'email' } - ] }, - { name: 'comments', type: 'object', properties: [ - { name: 'total_count', type: 'integer' }, + { name: 'due_at', type: 'date_time', + render_input: 'date_time_conversion', + parse_output: 'date_time_conversion' }, + { name: 'string', label: 'Stamp', + hint: 'One to two character stamp associated with task.' }, + { name: 'issue_list', label: 'Task List', type: 'object', properties: [ + { name: 'uid', label: 'Task List ID' }, { name: 'url' } ] }, - { name: 'cost_impact', type: 'number' }, - { name: 'has_cost_impact', type: 'boolean', + { name: 'description' }, + { name: 'cost_impact', label: 'Cost Impact', type: 'number' }, + { name: 'has_cost_impact', label: 'Has Cost Impact?', type: 'boolean', control_type: 'checkbox', toggle_hint: 'Select from options list', toggle_field: { name: 'cost_impact', @@ -264,12 +250,23 @@ toggle_hint: 'Use custom value', hint: 'Allowed values are: true, false' } }, - { name: 'currency_code', + { name: 'currency_code', label: 'Currency Code', hint: 'The ISO-4217 currency code of the cost_impact,' \ ' Currently only supports USD. maybe null if cost_impact is ' \ 'not specified' }, + { name: 'schedule_impact', label: 'Schedule Impact', type: 'integer' }, + { name: 'has_schedule_impact', label: 'Has Schedule Impact?', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'has_schedule_impact', + label: 'Has schedule impact', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } }, { name: 'current_annotation', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'color' }, { name: 'stamp' }, { name: 'visibility' }, @@ -284,84 +281,36 @@ hint: 'Allowed values are: true, false' } }, { name: 'sheet', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' } ] } ] }, - { name: 'deleted', type: 'boolean', - control_type: 'checkbox', toggle_hint: 'Select from options list', - toggle_field: { - name: 'deleted', - label: 'Deleted', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } }, - { name: 'description' }, - { name: 'due_at', type: 'date_time', - render_input: 'date_time_conversion', - parse_output: 'date_time_conversion' }, - { name: 'followers', type: 'array', of: 'object', properties: [ - { name: 'type' }, - { name: 'uid' } - ] }, - { name: 'issue_list', type: 'object', properties: [ - { name: 'uid' }, + { name: 'comments', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'number', type: 'number' }, { name: 'photos', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'room' }, - { name: 'schedule_impact', type: 'integer' }, - { name: 'has_schedule_impact', type: 'boolean', + { name: 'deleted', label: 'Deleted?', type: 'boolean', control_type: 'checkbox', toggle_hint: 'Select from options list', toggle_field: { - name: 'has_schedule_impact', - label: 'Has schedule impact', + name: 'deleted', + label: 'Deleted', type: 'string', control_type: 'text', toggle_hint: 'Use custom value', hint: 'Allowed values are: true, false' } }, - { name: 'start_date', - type: 'date_time', - render_input: 'date_conversion', - parse_output: 'date_conversion' }, - { name: 'status', control_type: 'select', pick_list: - %w[open in_review pending closed].select { |op| [op.labelize, op] }, - 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", "in_review", "pending",' \ - ' "closed".' - } }, - { name: 'string', - hint: 'One to two character stamp associated with task.' }, - { name: 'title' }, - { name: 'type', control_type: 'select', - pick_list: [ - %w[issue issue], - %w[Planned\ work planned_work], - %w[other other] - ], - toggle_hint: 'Select type', - toggle_field: { - name: 'type', - label: 'Type', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: "issue", "planned_work",' \ - ' "other".' - } }, + { name: 'created_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'url' }, + { name: 'email' } + ] }, { name: 'updated_at', render_input: 'date_time_conversion', parse_output: 'date_time_conversion', @@ -394,11 +343,11 @@ annotation: { fields: lambda do |_connection, _config_fields| [ - { name: 'uid', label: 'Unique Identifier' }, + { name: 'uid', label: 'Annotation ID' }, { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -425,9 +374,8 @@ hint: 'Allowed values are: true, false' } }, { name: 'sheet', type: 'object', properties: [ - { name: 'uid' }, - { name: 'label' }, - { name: 'color' } + { name: 'uid', label: 'UID' }, + { name: 'url' } ] } ] end @@ -439,7 +387,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -458,12 +406,12 @@ render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'created_by', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, { name: 'sheet', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' } ] }, { name: 'deleted', type: 'boolean', @@ -486,7 +434,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -500,35 +448,27 @@ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, { name: 'title' }, - { name: 'url' }, + { name: 'url', label: 'URL' }, { name: 'created_at', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'created_by', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, - { name: 'deleted', type: 'boolean', control_type: 'checkbox', - toggle_field: { - name: 'deleted', - label: 'Deleted', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } } + { name: 'deleted', type: 'boolean' } ] end }, field_report: { - fields: lambda do |_connection, config_fields| - standard_fields = [ - { name: 'uid', label: 'File report ID' }, + fields: lambda do |_connection, _config_fields| + [ + { name: 'uid', label: 'Field Report ID' }, { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -543,23 +483,27 @@ } }, { name: 'title' }, { name: 'description' }, - { name: 'report_date', type: 'date_time', + { name: 'report_date', label: 'Report Date', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, - { name: 'field_report_type', type: 'object', properties: [ + { name: 'status' }, + { name: 'field_report_type', label: 'Field Report Type', type: 'object', properties: [ { name: 'name' }, - { name: 'project_uid' }, { name: 'status' }, - { name: 'uid' } + { name: 'uid', label: 'UID' } ] }, - { name: 'pdf_url' }, - { name: 'pg_form_values', type: 'array', of: 'object', properties: [ - { name: 'pg_equipment_entries', type: 'array', of: 'object', + { name: 'pdf_url', label: 'PDF URL' }, + { name: 'pdf_form_values', label: 'PDF Form Values', type: 'array', of: 'object', properties: [ + { name: 'name', label: 'Field Name' }, + { name: 'value', label: 'Field Value' } + ]}, + { name: 'pdf_form_fields', label: 'PDF Field Values', type: 'object' }, + { name: 'pg_form_values', label: 'Daily Report Values', type: 'array', of: 'object', properties: [ + { name: 'pg_worklog_entries', label: 'Work Log Entries', type: 'array', of: 'object', properties: [ - { name: 'uid' }, + { name: 'trade' }, { name: 'timespan' }, - { name: 'quantity', type: 'integer' }, - { name: 'item' }, + { name: 'headcount', type: 'integer' }, { name: 'description' }, { name: 'deleted', type: 'boolean', control_type: 'checkbox', @@ -573,21 +517,19 @@ hint: 'Allowed values are: true, false' } } ] }, - { name: 'pg_materials_entries', type: 'array', of: 'object', + { name: 'pg_materials_entries', label: 'Material Entries', type: 'array', of: 'object', properties: [ - { name: 'uid' }, { name: 'unit', type: 'integer' }, { name: 'quantity', type: 'integer' }, { name: 'item' }, { name: 'description' }, { name: 'deleted' } ] }, - { name: 'pg_worklog_entries', type: 'array', of: 'object', + { name: 'pg_equipment_entries', label: 'Equipment Entries', type: 'array', of: 'object', properties: [ - { name: 'uid' }, - { name: 'trade' }, { name: 'timespan' }, - { name: 'headcount', type: 'integer' }, + { name: 'quantity', type: 'integer' }, + { name: 'item' }, { name: 'description' }, { name: 'deleted', type: 'boolean', control_type: 'checkbox', @@ -602,26 +544,23 @@ } } ] } ] }, - { name: 'attachments', type: 'object', properties: [ + { name: 'attachments', label: 'Documents', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'created_by', type: 'object', properties: [ - { name: 'email' }, - { name: 'uid' }, - { name: 'url' } - ] }, { name: 'photos', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'project_uid', label: 'Project ID' }, - { name: 'report_date', type: 'date' }, { name: 'snapshots', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, { name: 'url' } ] }, - { name: 'status' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'email' }, + { name: 'uid', label: 'UID' }, + { name: 'url' } + ] }, { name: 'updated_at', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, @@ -639,13 +578,6 @@ { name: 'wind_speed', type: 'number' } ] } ] - pdf_form_fileds = get("/projects/#{config_fields['project_uid']}/" \ - 'field_reports').params(limit: 1)&. - map do |key, _value| - { name: key } - end&.inject(:merge) - standard_fields.merge({ 'pdf_form_values' => - call('format_schema_field_names', pdf_form_fileds) }) end }, rfi: { @@ -655,7 +587,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', sticky: true, toggle_hint: 'Select project', toggle_field: { @@ -670,7 +602,7 @@ } }, { name: 'number', type: 'integer' }, { name: 'status', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'label' }, { name: 'color' } ] }, @@ -697,12 +629,9 @@ { name: 'due_at', type: 'date_time', render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, - { name: 'assigned_to_uids', - hint: 'Array of unique identifiers of users who ' \ - 'are RFI assignees.' }, { name: 'assigned_to', type: 'array', of: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, @@ -714,7 +643,7 @@ "timestamps-and-timezones' target='_blank'>Timestamps and " \ 'Timezones for accepted date formats' }, { name: 'updated_by', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, @@ -722,7 +651,7 @@ render_input: 'parse_iso8601_timestamp', parse_output: 'parse_iso8601_timestamp' }, { name: 'created_by', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, @@ -748,7 +677,7 @@ rfi_status: { fields: lambda do |_connection, _config_fields| [ - { name: 'uid', label: 'RFI status ID' }, + { name: 'uid', label: 'Status ID' }, { name: 'label' }, { name: 'color' } ] @@ -758,15 +687,31 @@ fields: lambda do |_connection, _config_fields| [ { name: 'uid', label: 'User ID' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project ID', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, { name: 'email' }, - { name: 'first_name' }, - { name: 'last_name' }, - { name: 'language' }, + { name: 'first_name', label: 'First Name' }, + { name: 'last_name', label: 'Last Name' }, + { name: 'language'}, { name: 'role', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' } ] }, - { name: 'removed' } + { name: 'removed', label: 'Removed?' } ] end }, @@ -774,13 +719,29 @@ fields: lambda do |_connection, _config_fields| [ { name: 'uid', label: 'Sheet ID' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project ID', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, { name: 'name' }, - { name: 'version_name' }, + { name: 'version_name', label: 'Version Name' }, { name: 'description' }, - { name: 'tags', hint: 'An array of strings representing the' \ + { name: 'tags', type: 'array', of: 'string', hint: 'An array of strings representing the' \ ' tags added to this sheet.' }, { name: 'published_by', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' }, { name: 'email' } ] }, @@ -799,20 +760,36 @@ toggle_hint: 'Use custom value', hint: 'Allowed values are: true, false' } }, - { name: 'uploaded_file_name' } + { name: 'uploaded_file_name', label: 'Uploaded file name' } ] end }, sheet_packet: { fields: lambda do |_connection, _config_fields| [ - { name: 'uid', label: 'Sheet packet ID' }, - { name: 'file_url' }, + { name: 'uid', label: 'Sheet Packet ID' }, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project ID', + sticky: true, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'status' }, + { name: 'file_url', label: 'File URL' }, { name: 'resource', type: 'object', properties: [ - { name: 'uid' }, + { name: 'uid', label: 'UID' }, { name: 'url' } - ] }, - { name: 'status' } + ] } ] end }, @@ -969,7 +946,7 @@ create_project: { title: 'Create project', description: 'Create project in'\ - ' Plangrid', + ' PlanGrid', help: { body: 'Create project action uses the' \ " project in'\ - ' Plangrid', + ' PlanGrid', help: { body: 'Update project action uses the' \ " Update Project API.", learn_more_url: 'https://developer.plangrid.com/docs/update-project', - learn_more_text: 'Update a Project' + learn_more_text: 'Update Project' }, input_fields: lambda do |object_definitions| object_definitions['project'].required('uid'). ignored('updated_at', 'latitude', 'longitude', 'organization_id') end, execute: lambda do |_connection, input| - patch("/projects/#{input.delete('uid')}").payload(input). + payload = input.each do |key, value| + input[key].present? || input[key] = nil + end + patch("/projects/#{input.delete('uid')}").payload(payload.except('uid')). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end @@ -1025,11 +1020,11 @@ end }, get_project_details: { - title: 'Get project info. by ID', - description: 'Get project info.'\ - ' by ID in Plangrid', + title: 'Get project', + description: 'Get project'\ + ' in PlanGrid', help: { - body: 'Get project info. by ID action uses the' \ + body: 'Get project action uses the' \ " Retrieve a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/retrieve-a-project', @@ -1050,8 +1045,8 @@ }, upload_document: { title: 'Upload document to a project', - description: 'Upload document to a project'\ - ' in Plangrid', + description: 'Upload document to a'\ + ' PlanGrid project', help: { body: 'Upload document to a project action uses the' \ " document in a'\ + ' PlanGrid project', + help: { + body: 'Update document in a project action uses the' \ + " Update Document to Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/update-attachment-' \ + 'in-a-project', + learn_more_text: 'Update Document in a Project API' + }, + summarize_input: %w[file_content], + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'attachment_uid', label: 'Document ID', optional: false }, + { name: 'name', label: 'Document Name', + hint: 'New name of the document', sticky: true }, + { name: 'folder', label: 'Folder', + hint: 'New folder of the document', sticky: true } + ] + end, + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + patch("/projects/#{project_uid}/attachments/" \ + "#{input.delete('attachment_uid')}"). + headers('Content-type': 'application/json'). + payload(input). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end&.merge('project_uid' => project_uid) + end, + output_fields: lambda do |object_definitions| + object_definitions['document'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/attachments")&.dig('data', 0)&. + merge('project_uid' => id) || {} + end }, create_rfi: { title: 'Create RFI in a project', description: 'Create RFI in'\ - ' a Plangrid project ', + ' a PlanGrid project ', help: { - body: 'Create RFI in project action uses the ' \ + body: 'Create RFI in a project action uses the ' \ "Create RFI in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/create-rfi-' \ @@ -1228,11 +1273,11 @@ update_rfi: { title: 'Update RFI in a project', description: 'Update RFI in'\ - ' a Plangrid project', + ' a PlanGrid project', help: { - body: 'Update RFI in Project action uses the ' \ + body: 'Update RFI in a project action uses the ' \ "patchUpdate RFI in a Project API.", + "project' target='_blank'>Update RFI in a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/update-' \ 'rfi-in-a-project', learn_more_text: 'Update RFI in a Project' @@ -1255,8 +1300,7 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'status', label: 'Status', - hint: 'Use this for create and update rfi status' } + { name: 'status', label: 'Status UID' } ].concat(object_definitions['rfi']. only('uid', 'locked', 'title', 'question', 'answer', 'sent_at', 'due_at', 'assigned_to_uids'). @@ -1287,10 +1331,10 @@ }, get_rfi_in_project: { title: 'Get RFI in a project', - description: 'Get RFI by ID in'\ - ' Plangrid project', + description: 'Get RFI in '\ + 'a PlanGrid project', help: { - body: 'Get RFI by ID in a project action uses the' \ + body: 'Get RFI in a project action uses the' \ " Retrieve RFI in a Project API.", @@ -1299,12 +1343,29 @@ learn_more_text: 'Retrieve RFI in a Project' }, input_fields: lambda do |object_definitions| - object_definitions['rfi'].only('project_uid', 'uid'). - required('project_uid', 'uid') + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'rfi_uid', label: 'RFI ID', optional: false } + ] end, execute: lambda do |_connection, input| project_uid = input.delete('project_uid') - get("/projects/#{project_uid}/rfis/#{input['uid']}")&. + get("/projects/#{project_uid}/rfis/#{input['rfi_uid']}")&. merge('project_uid' => project_uid) end, output_fields: lambda do |object_definitions| @@ -1319,11 +1380,11 @@ create_task: { title: 'Create task in a project', description: 'Create task in'\ - ' Plangrid project', + ' a PlanGrid project', help: { - body: 'Create task in Project action uses the ' \ + body: 'Create task in a project action uses the ' \ "Create task in Project API.", + "project' target='_blank'>Create Task in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/create-task-in-' \ 'a-project', learn_more_text: 'Create Task in a Project' @@ -1345,12 +1406,15 @@ toggle_hint: 'Use project ID', hint: 'Provide project ID e.g. ' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } } + } + }, + { name: 'issue_list_uid', label: 'Task List ID', sticky: true } ].concat(object_definitions['task']. - only('assigned_to_uids', 'cost_impact', 'description', 'due_at', - 'has_cost_impact', 'has_schedule_impact', - 'issue_list_uid', 'room', 'schedule_impact', 'start_date', - 'status', 'title', 'type')) + only('title', 'status', 'type', 'assigned_to_uids', + 'room', 'start_date', 'due_at', + 'description', 'has_cost_impact', 'cost_impact', + 'has_schedule_impact', 'schedule_impact' + )) end, execute: lambda do |_connection, input| project_uid = input.delete('project_uid') @@ -1376,13 +1440,13 @@ end }, update_task: { - title: 'Update task in a Project', + title: 'Update task in a project', description: 'Update task in'\ - ' Plangrid project', + ' a PlanGrid project', help: { - body: 'Update task in Project action uses the ' \ + body: 'Update task in a project action uses the ' \ "Create task in Project API.", + "project' target='_blank'>Update Task in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/create-project', learn_more_text: 'Update Task in a Project' }, @@ -1403,17 +1467,24 @@ toggle_hint: 'Use project ID', hint: 'Provide project ID e.g.' \ ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } } + } + }, + { name: 'issue_uid', label: 'Task ID', optional: false }, + { name: 'issue_list_uid', label: 'Task List ID', sticky: true } ].concat(object_definitions['task']. - only('uid', 'assigned_to_uids', 'cost_impact', 'description', - 'due_at', 'has_cost_impact', 'has_schedule_impact', - 'issue_list_uid', 'room', 'schedule_impact', 'start_date', - 'status', 'title', 'type').required('uid')) + only('title', 'status', 'type', 'assigned_to_uids', + 'room', 'start_date', 'due_at', + 'description', 'has_cost_impact', 'cost_impact', + 'has_schedule_impact', 'schedule_impact' + )) end, execute: lambda do |_connection, input| project_uid = input.delete('project_uid') + payload = input.each do |key, value| + input[key].present? || input[key] = nil + end patch("/projects/#{project_uid}/issues/" \ - "#{input.delete('uid')}").payload(input). + "#{input.delete('issue_uid')}").payload(payload). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end&.merge('project_uid' => project_uid) @@ -1430,7 +1501,7 @@ get_task: { title: 'Get task in a project', description: 'Get task in'\ - ' in a Plangrid project', + ' a PlanGrid project', help: { body: 'Get task in a project action uses the ' \ "user to'\ - ' project team Plangrid', + ' a PlanGrid project', help: { body: 'Invite user to a project action uses the ' \ "Invite user in Project team API.", + "project-team' target='_blank'>Invite User in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ 'invite-user-to-project-team', - learn_more_text: 'Invite User to Project Team' + learn_more_text: 'Invite User to Project' }, input_fields: lambda do |_object_definitions| [ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', optional: false, toggle_hint: 'Select project', toggle_field: { @@ -1508,16 +1579,17 @@ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, { name: 'email', optional: false }, - { name: 'role_uid', label: 'Role ID', + { name: 'role_uid', label: 'Role ID', sticky: true, hint: 'Unique identifier of role to assign user on project team' } ] end, execute: lambda do |_connection, input| - post("/projects/#{input.delete('project_uid')}/users/invites"). + project_uid = input.delete('project_uid') + post("/projects/#{project_uid}/users/invites"). payload(input). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end + end&.merge('project_uid' => project_uid) end, output_fields: lambda do |object_definitions| object_definitions['user'] @@ -1527,17 +1599,17 @@ get("/projects/#{id}/users")&.dig('data', 0) || {} end }, - get_user_by_id: { - title: 'Get user in a project', + get_user_in_project: { + title: 'Get user in project', description: 'Get user in'\ - ' Plangrid project', + ' a PlanGrid project', help: { - body: 'Get user in project action uses the ' \ + body: 'Get user in a project action uses the ' \ "Retrieve User on a Project Team.", + "project-team' target='_blank'>Retrieve User in a Project.", learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ 'users-on-a-project-team', - learn_more_text: 'Retrieve User on a Project Team' + learn_more_text: 'Retrieve User in a Project' }, input_fields: lambda do |_object_definitions| [ @@ -1576,7 +1648,7 @@ get_snapshot_in_project: { title: 'Get snapshot in a project', description: 'Get snapshot in'\ - ' a Plangrid project', + ' a PlanGrid project', help: { body: 'Get snapshot in a project action uses the ' \ " input['project_uid']) end, output_fields: lambda do |object_definitions| object_definitions['snapshot'] @@ -1621,10 +1693,10 @@ }, get_rfi_statuses_in_project: { title: 'Get RFI statuses in project', - description: 'Get rfi statuses in'\ - ' Plangrid project', + description: 'Get RFI statuses in'\ + ' a PlanGrid project', help: { - body: 'Get rfi statuses in project action uses the ' \ + body: 'Get RFI statuses in project action uses the ' \ "Retrieve RFI Statuses in a Project.", learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ @@ -1672,23 +1744,23 @@ end }, get_roles_on_project: { - title: 'Get roles on a project', - description: 'Get roles on '\ - ' Plangrid project', + title: 'Get roles in a project', + description: 'Get roles in '\ + ' a PlanGrid project', help: { - body: 'Get role on a project action uses the ' \ - "Retrieve Role on a Project API.", + body: 'Get roles in a project action uses the ' \ + "Retrieve Roles on a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-role-on-a-project', - learn_more_text: 'Retrieve Role on a Project' + 'retrieve-roles-on-a-project', + learn_more_text: 'Retrieves Role on a Project' }, input_fields: lambda do |_object_definitions| [ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', optional: false, toggle_hint: 'Select project', toggle_field: { @@ -1700,24 +1772,19 @@ toggle_hint: 'Use project ID', hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'limit', type: 'integer', - hint: 'Number of roles to retrieve. Maximum value of 50.' }, - { name: 'skip', type: 'integer', - hint: 'Number of roles to skip in the set of results.' } + } } ] end, execute: lambda do |_connection, input| - { roles: get("/projects/#{input.delete('project_uid')}/roles", input) } + project_uid = input.delete('project_uid') + { roles: get("/projects/#{project_uid}/roles")['data'] } end, output_fields: lambda do |_object_definitions| [ - { name: 'roles', type: 'array', of: 'object', properties: [ - { name: 'uid' }, - { name: 'label' } - ] }, - { name: 'total_count' }, - { name: 'next_page_url' } + { name: 'roles', label: 'Roles', type: 'array', of: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'label', label: 'Role' } + ] } ] end, sample_output: lambda do |_connection, _input| @@ -1725,69 +1792,15 @@ 'label' => 'Admin' } } end }, - get_sheets_in_project: { - title: 'Get sheets in a project', - description: 'Get sheets in'\ - ' Plangrid project', - help: { - body: 'Get sheets in project action uses the ' \ - "Retrieve Sheets in a Project.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-sheets-in-a-project', - learn_more_text: 'Retrieve Sheets in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'limit', type: 'integer', - hint: 'Number of sheets to retrieve. Maximum value of 50.' }, - { name: 'skip', type: 'integer', - hint: 'Number of sheets to skip in the set of results' }, - { name: 'updated_after', type: 'date_time', - hint: 'Only retrieve sheets created/updated after ' \ - 'specified UTC date and time.' } - ] - end, - execute: lambda do |_connection, input| - { sheets: get("/projects/#{input.delete('project_uid')}/sheets", - input)['data'] } - end, - output_fields: lambda do |object_definitions| - [{ name: 'sheets', type: 'array', of: 'object', - properties: object_definitions['sheet'] }] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - { - sheets: get("/projects/#{id}/sheets?limit=1")&.dig('data', 0)&. - merge('project_uid' => id) || {} - } - end - }, + get_sheet_in_project: { - title: 'Get sheet by ID in project', - description: 'Get sheet in'\ - ' Plangrid project', + title: 'Get sheet in a project', + description: 'Get sheet in '\ + 'a PlanGrid project', help: { - body: 'Get project sheet details action uses the ' \ + body: 'Get sheet in a project action uses the ' \ "Retrieve Sheets in a Project.", + " target='_blank'>Retrieve Sheet in a Project.", learn_more_url: 'https://developer.plangrid.com/docs/' \ 'retrieve-a-sheet', learn_more_text: 'Retrieve Sheet in a Project' @@ -1797,7 +1810,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', optional: false, toggle_hint: 'Select project', toggle_field: { @@ -1810,11 +1823,12 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'sheet_uid', type: 'Sheet ID', optional: false } + { name: 'sheet_uid', label: 'Sheet ID', optional: false } ] end, execute: lambda do |_connection, input| - get("/projects/#{input['project_uid']}/sheets/#{input['sheet_uid']}") + get("/projects/#{input['project_uid']}/sheets/#{input['sheet_uid']}")&. + merge('project_uid' => input['project_uid']) end, output_fields: lambda do |object_definitions| object_definitions['sheet'] @@ -1826,11 +1840,11 @@ end }, get_project_sheet_packet: { - title: 'Get project sheet packet', - description: 'Get project sheet packet in'\ - ' packet in Plangrid', + title: 'Get sheet packet in a project', + description: 'Get sheet packet in'\ + ' a PlanGrid project', help: { - body: 'Get project sheet packet action uses the ' \ + body: 'Get sheet packet in a project action uses the ' \ "Retrieve Sheet Packet API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ @@ -1855,23 +1869,23 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'packet_uid', type: 'Packet ID' } + { name: 'packet_uid', label: 'Sheet Packet ID', optional: false } ] end, execute: lambda do |_connection, input| get("/projects/#{input['project_uid']}/sheets/packets/" \ - "#{input['packet_uid']}") + "#{input['packet_uid']}")&.merge('project_uid' => input['project_uid']) end, output_fields: lambda do |object_definitions| object_definitions['sheet_packet'] end }, get_field_reports_in_project: { - title: 'Get fields reports in project', + title: 'Get field reports in a project', description: 'Get field reports in'\ - ' in Plangrid project', + ' a PlanGrid project', help: { - body: 'Get fields reports in project action uses the ' \ + body: 'Get field reports in a project action uses the ' \ "Retrieve Field Reports in a" \ ' Project API.', @@ -1884,7 +1898,7 @@ { name: 'project_uid', control_type: 'select', pick_list: 'project_list', - label: 'Project', + label: 'Project ID', optional: false, toggle_hint: 'Select project', toggle_field: { @@ -1897,17 +1911,17 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'updated_after', type: 'date_time', - hint: 'Only retrieve field reports created/updated after ' \ - 'specified UTC date and time.' }, - { name: 'report_date_min', type: 'date_time', - label: 'Report start date', + { name: 'report_date_min', type: 'date', + label: 'Report Start Date', hint: 'Only retrieve field reports between a date range ' \ 'starting with this date in UTC format.' }, - { name: 'report_date_max', type: 'date_time', - label: 'Report end date', + { name: 'report_date_max', type: 'date', + label: 'Report End Date', hint: 'Only retrieve field reports between a date range ' \ 'starting with this date in UTC format.' }, + { name: 'updated_after', label: 'Updated After', type: 'date_time', + hint: 'Only retrieve field reports created/updated after ' \ + 'specified UTC date and time.' }, { name: 'sort_by', control_type: 'select', pick_list: %w[report_date updated_at]&.map { |e| [e.labelize, e] }, @@ -1915,6 +1929,14 @@ toggle_field: { name: 'sort_by', type: 'string', control_type: 'text', hint: 'Allowed values report_date or updated_at' + } }, + { name: 'sort_order', control_type: 'select', + pick_list: + %w[asc desc]&.map { |e| [e.labelize, e] }, + toggle_hint: 'Select sort order', + toggle_field: { + name: 'sort_by', type: 'string', control_type: 'text', + hint: 'Allowed values asc or desc' } } ] end, @@ -1922,17 +1944,26 @@ project_uid = input.delete('project_uid') query_params = '' input&.map do |key, val| - if %w[updated_after report_date_min report_date_max].include?(key) - query_params = query_params + "#{key}=#{val.to_time.utc.iso8601}" + if %w[updated_after].include?(key) + query_params = query_params + "&" + "#{key}=#{val.to_time.utc.iso8601}" else - query_params = query_params + "#{key}=#{val}" + query_params = query_params + "&" + "#{key}=#{val}" end end - { field_reports: get("/projects/#{project_uid}/field_reports?" \ - "#{query_params}")['data'] } + + results = get("/projects/#{project_uid}/field_reports?" \ + "#{query_params}")['data'] + + field_reports = results.map do |field_report| + field_report.merge({ + 'pdf_form_fields' => field_report['pdf_form_values'] + &.map { |a| { a['name'] => a['value'] } }&.inject(:merge) }) + end + { field_reports: field_reports } + end, output_fields: lambda do |object_definitions| - { name: 'field_reports', type: 'array', of: 'object', + { name: 'field_reports', label: 'Field Reports', type: 'array', of: 'object', properties: object_definitions['field_report'] } end, sample_output: lambda do |_connection, _input| @@ -1943,9 +1974,9 @@ end }, upload_photo: { - title: 'Upload photo to project', + title: 'Upload photo to a project', description: 'Upload photo to '\ - ' project in Plangrid', + ' a PlanGrid project', help: { body: 'Upload photo to a project action uses the' \ " project_uid) end, output_fields: lambda do |object_definitions| object_definitions['photo'] @@ -2022,16 +2055,16 @@ end }, update_photo_metadata: { - title: 'Update photo metadata', - description: 'Update photo metadata to '\ - ' Project in Plangrid', + title: 'Update photo in a project', + description: 'Update photo in'\ + ' a PlanGrid project', help: { - body: 'Update photo metadata action uses the' \ + body: 'Update photo action uses the' \ " Update Document to Project API.", + "project' target='_blank'>Update Photo in a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/update-photo-' \ 'in-a-project', - learn_more_text: 'Update photo to Project API' + learn_more_text: 'Update Photo in a Project API' }, summarize_input: %w[file_content], input_fields: lambda do |_object_definitions| @@ -2048,19 +2081,20 @@ toggle_hint: 'Use project ID', hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'photo_uid', type: 'Photo ID', optional: false }, + { name: 'photo_uid', label: 'Photo ID', optional: false }, { name: 'title', label: 'Photo title', - hint: 'New title of the photo' } + hint: 'New title of the photo', sticky: true } ] end, execute: lambda do |_connection, input| - patch("/projects/#{input.delete('project_uid')}/photos/" \ + project_uid = input.delete('project_uid') + patch("/projects/#{project_uid}/photos/" \ "#{input.delete('photo_uid')}"). headers('Content-type': 'application/json'). payload(input). after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") - end + end&.merge('project_uid' => project_uid) end, output_fields: lambda do |object_definitions| object_definitions['photo'] @@ -2071,12 +2105,12 @@ merge('project_uid' => id) || {} end }, - get_photo_by_id: { - title: 'Get photo in a Project', + get_photo_details: { + title: 'Get photo in a project', description: 'Get photo in'\ - ' a Plangrid project', + ' a PlanGrid project', help: { - body: 'Get photo details action uses the ' \ + body: 'Get photo action uses the ' \ "Retrieve Photo in Project API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ @@ -2101,12 +2135,12 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'photo_uid', type: 'Photo ID', optional: false } + { name: 'photo_uid', label: 'Photo ID', optional: false } ] end, execute: lambda do |_connection, input| get("/projects/#{input['project_uid']}/photos/" \ - "#{input['photo_uid']}") + "#{input['photo_uid']}")&.merge('project_uid' => input.delete('project_uid')) end, output_fields: lambda do |object_definitions| object_definitions['photo'] @@ -2117,12 +2151,12 @@ merge('project_uid' => id) || {} end }, - get_document_by_id: { + get_document_details: { title: 'Get document in a project', - description: 'Get document in'\ - ' in Plangrid project', + description: 'Get document'\ + ' in a PlanGrid project', help: { - body: 'Get document details action uses the ' \ + body: 'Get document in a project action uses the ' \ "Retrieve Document in a Project API.", learn_more_url: 'https://developer.plangrid.com/docs/' \ @@ -2147,12 +2181,12 @@ hint: 'Provide project ID e.g. ' \ '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { name: 'attachment_uid', type: 'Document ID', optional: false } + { name: 'attachment_uid', label: 'Document ID', optional: false } ] end, execute: lambda do |_connection, input| get("/projects/#{input['project_uid']}/attachments/" \ - "#{input['attachment_uid']}") + "#{input['attachment_uid']}")&.merge('project_uid' => input.delete('project_uid')) end, output_fields: lambda do |object_definitions| object_definitions['document'] @@ -2162,116 +2196,666 @@ get("/projects/#{id}/attachments")&.dig('data', 0)&. merge('project_uid' => id) || {} end - } - }, - triggers: { - new_updated_project: { - title: 'New/updated project', - description: 'New/updated project in'\ - ' Plangrid', + }, + create_sheet_packet: { + title: 'Create sheet packet in a project', + description: 'Create sheet packet in '\ + ' a PlanGrid project', help: { - body: 'New/updated project trigger uses the' \ - " List all Projects API.", - learn_more_url: 'https://developer.plangrid.com/docs/list-all-projects', - learn_more_text: 'List All Projects API' + body: 'Create sheet packet in a project action uses the' \ + " Create Sheet Packet in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/upload-photo' \ + '-to-project', + learn_more_text: 'Create Sheet Packet in a Project' }, - input_fields: lambda do |_object_definitions| + input_fields: lambda do |object_definitions| [ - { - 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' - } + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'sheet_uids', label: 'Sheet IDs', optional: false, + type: 'string', + hint: 'A comma separated list of sheet IDs.' }, + { name: 'include_annotations', label: 'Include annotations?', type: 'boolean', sticky: true, + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'include_annotations', + label: 'Include annotations?', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } }, ] end, - poll: lambda do |_connection, input, closure| - updated_after = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 20 - skip = closure&.[]('skip') || 0 - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) - else - get('/projects'). - params(limit: limit, - skip: skip, - updated_after: updated_after) - end - closure = if (next_page_url = response['next_page_url']).present? - { 'skip' => skip + limit, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'updated_after' => now.to_time.utc.iso8601 } - end - { - events: response['data'] || [], - next_poll: closure, - can_poll_more: response['next_page_url'].present? + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + payload = { + sheet_uids: input.delete('sheet_uids').split(','), + include_annotations: input.delete('include_annotations') } - end, - dedup: lambda do |project| - "#{project['uid']}@#{project['updated_at']}" + post("/projects/#{project_uid}/sheets/packets").payload(payload). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end&.merge('project_uid' => project_uid) end, output_fields: lambda do |object_definitions| - object_definitions['project'] + object_definitions['sheet_packet'] end, sample_output: lambda do |_connection, _input| - get('/projects')&.dig('data', 0) || {} + { + uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", + file_url: "https://packet-assets.plangrid.com/92cf7193-af0c-42fc-a3ab-7ef5149da720.pdf", + resource: { + uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", + url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/packets/92cf7193-af0c-42fc-a3ab-7ef5149da720" + }, + status: "incomplete" + } end }, - new_updated_documents: { - title: 'New/updated documents in a project', - description: 'New/updated document in '\ - 'Project Plangrid', + get_task_list: { + title: 'Get task list in a project', + description: 'Get task list'\ + ' in a PlanGrid project', help: { - body: 'New/updated documents in Project trigger uses the' \ - " Retrieve Documents in a Project" \ - ' API.', - learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ - 'attachments-in-a-project', - learn_more_text: 'Retrieve Documents in a Project' + body: 'Get task list in a project action uses the ' \ + "Retrieve Task List in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'retrieve-issue-list', + learn_more_text: 'Retrieve Task List in a Project API' }, input_fields: lambda do |_object_definitions| [ - { name: 'project_uid', optional: false, + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', label: 'Project', - control_type: 'select', pick_list: 'project_list', + optional: false, toggle_hint: 'Select project', toggle_field: { name: 'project_uid', - label: 'Project ID', type: 'string', control_type: 'text', + optional: false, + label: 'Project ID', toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' } }, - { - 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' - } + { name: 'issue_list_uid', label: 'Task List ID', optional: false } ] end, - poll: lambda do |_connection, input, closure| - project_uid = closure&.[]('project_uid') || input['project_uid'] - updated_after = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 5 - skip = closure&.[]('skip') || 0 - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) - else + execute: lambda do |_connection, input| + get("/projects/#{input['project_uid']}/issue_lists/" \ + "#{input['issue_list_uid']}") + end, + output_fields: lambda do |object_definitions| + [ + { + name: "uid", label: "Task List ID" + }, + { + name: "project_uid", label: "Project ID" + }, + { + name: "name", label: "Name" + }, + { + name: "deleted", label: "Deleted", type: "boolean" + } + ] + end, + sample_output: lambda do |_connection, _input| + { + uid: "31f54967-4eac-4bd7-9b35-57f00a973a1d", + name: "QA/QC", + deleted: false, + project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" + } + end + }, + update_task_list: { + title: 'Update task list in a project', + description: 'Update task list'\ + ' in a PlanGrid project', + help: { + body: 'Update task list in a project action uses the ' \ + "Update Task List in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'update-issue-list', + learn_more_text: 'Update Task List in a Project API' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'issue_list_uid', label: 'Task List ID', optional: false }, + { name: 'name', optional: false } + ] + end, + execute: lambda do |_connection, input| + patch("/projects/#{input['project_uid']}/issue_lists/" \ + "#{input['issue_list_uid']}").payload({name: input.delete('name')}) + end, + output_fields: lambda do |object_definitions| + [ + { + name: "uid", label: "Task List ID" + }, + { + name: "project_uid", label: "Project ID" + }, + { + name: "name", label: "Name" + }, + { + name: "deleted", label: "Deleted", type: "boolean" + } + ] + end, + sample_output: lambda do |_connection, _input| + { + uid: "31f54967-4eac-4bd7-9b35-57f00a973a1d", + name: "QA/QC", + deleted: false, + project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" + } + end + }, + create_task_list: { + title: 'Create task list in a project', + description: 'Create task list'\ + ' in a PlanGrid project', + help: { + body: 'Create task list in a project action uses the ' \ + "Create Task List in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'create-issue-list', + learn_more_text: 'Create Task List in a Project API' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'name', optional: false } + ] + end, + execute: lambda do |_connection, input| + post("/projects/#{input.delete('project_uid')}/issue_lists").payload(input) + end, + output_fields: lambda do |object_definitions| + [ + { + name: "uid", label: "Task List ID" + }, + { + name: "project_uid", label: "Project ID" + }, + { + name: "name", label: "Name" + }, + { + name: "deleted", label: "Deleted", type: "boolean" + } + ] + end, + sample_output: lambda do |_connection, _input| + { + uid: "31f54967-4eac-4bd7-9b35-57f00a973a1d", + name: "QA/QC", + deleted: false, + project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" + } + end + }, + create_sheet_version: { + title: 'Create sheet version upload in a project', + description: 'Create sheet version upload'\ + ' in a PlanGrid project', + help: { + body: 'Create sheet version in a project action uses the ' \ + "Upload Version to a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'upload-version-to-project', + learn_more_text: 'Upload Version to a Project API' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'num_files', label: 'Number of PDFs', type: 'integer', optional: false }, + { name: 'version_name', label: 'Version Name', optional: false } + ] + end, + execute: lambda do |_connection, input| + post("/projects/#{input.delete('project_uid')}/sheets/uploads").payload(input) + end, + output_fields: lambda do |object_definitions| + [ + { + name: 'uid', label: 'Sheet Version Upload ID' + }, + { + name: 'complete_url', label: 'Upload Completion URL' + }, + { + name: 'status', + }, + { + name: 'file_upload_requests', label: 'File Upload Requests', + type: 'array', of: 'object', properties: [ + { + name: 'uid', label: 'File Upload ID' + }, + { + name: 'upload_status', label: 'File Upload Status' + }, + { + name: 'url', label: 'File Upload URL' + } + ] + } + ] + end, + sample_output: lambda do |_connection, _input| + { + uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", + complete_url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720", + status: "incomplete", + file_upload_requests: [ + { + uid: "b278fcba-72f0-4161-bfdc-89d5bde4d5e7", + upload_status: "issued", + url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720/files/b278fcba-72f0-4161-bfdc-89d5bde4d5e7" + }, + { + uid: "727fca7d-385b-4476-b257-4b96c00e879b", + upload_status: "issued", + url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720/files/727fca7d-385b-4476-b257-4b96c00e879b" + } + ] + } + end + }, + upload_file_to_sheet_version: { + title: 'Upload file to sheet version in a project', + description: 'Upload file to sheet version'\ + ' in a PlanGrid project', + help: { + body: 'Upload file to sheet version in a project action uses the ' \ + "Upload File to Version in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'upload-file-to-version', + learn_more_text: 'Upload File to Version in a Project API' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'ver_upload_uid', label: 'Sheet Version Upload ID', optional: false }, + { name: 'file_upload_request_uid', label: 'File Upload ID', optional: false }, + { name: 'file_name', label: 'File Name', optional: false }, + { name: 'file_content', label: 'File Content', optional: false } + ] + end, + execute: lambda do |_connection, input| + file_content = input.delete('file_content') + project_uid = input.delete('project_uid') + file_upload_info = post("/projects/#{project_uid}/sheets/" \ + "uploads/#{input.delete('ver_upload_uid')}/" \ + "files/#{input.delete('file_upload_request_uid')}"). + headers('Content-Type': 'application/json'). + payload({file_name: input.delete('file_name')}) + url = file_upload_info&.dig('aws_post_form_arguments', 'action') + fields = file_upload_info&.dig('aws_post_form_arguments', 'fields') + # webhook_url = file_upload_info. + # dig('aws_post_form_arguments', 'webhook_url') + headers = fields.map { |o| { o['name'] => o['value'] } }.inject(:merge) + status = + post(url). + payload(key: headers['key'], + policy: headers['policy'], + signature: headers['signature'], + AWSAccessKeyId: headers['AWSAccessKeyId'], + 'content-type': headers['Content-Type'], + 'success_action_redirect': headers['success_action_redirect'], + 'x-amz-server-side-encryption': + headers['x-amz-server-side-encryption'], + 'x-amz-storage-class': headers['x-amz-storage-class'], + file: file_content). + request_format_multipart_form. + after_response do |_code, response, _response_headers| + response + end + end, + output_fields: lambda do |object_definitions| + + end, + sample_output: lambda do |_connection, _input| + + end + }, + complete_version_upload: { + title: 'Complete sheet version upload to a project', + description: 'Complete sheet version upload '\ + ' to a PlanGrid project', + help: { + body: 'Complete sheet version upload to a project action uses the ' \ + "Complete Version Upload in a Project API.", + learn_more_url: 'https://developer.plangrid.com/docs/' \ + 'complete-version-upload-to-project', + learn_more_text: 'Complete Version Upload in a Project API' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Use project ID', + hint: 'Provide project ID e.g. ' \ + '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { name: 'ver_upload_uid', label: 'Sheet Version Upload ID', optional: false } + ] + end, + execute: lambda do |_connection, input| + project_uid = input.delete('project_uid') + post("/projects/#{project_uid}/sheets/" \ + "uploads/#{input.delete('ver_upload_uid')}/completions")&.merge('project_uid' => project_uid) + end, + output_fields: lambda do |object_definitions| + [ + { + name: 'uid', label: 'Sheet Version ID' + }, + { + name: 'status', label: 'Status' + } + ] + end, + sample_output: lambda do |_connection, _input| + { + uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", + complete_url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720", + status: "complete" + } + end + } + }, + triggers: { + new_updated_project: { + title: 'New or updated project', + description: 'New or updated project in'\ + ' PlanGrid', + help: { + body: 'New or updated project trigger uses the' \ + " List All Projects API.", + learn_more_url: 'https://developer.plangrid.com/docs/list-all-projects', + learn_more_text: 'List All Projects API' + }, + input_fields: lambda do |_object_definitions| + [ + { + 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| + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 20 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get('/projects'). + params(limit: limit, + skip: skip, + updated_after: updated_after) + end + closure = if (next_page_url = response['next_page_url']).present? + { 'skip' => skip + limit, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'updated_after' => now.to_time.utc.iso8601 } + end + { + events: response['data'] || [], + next_poll: closure, + can_poll_more: response['next_page_url'].present? + } + end, + dedup: lambda do |project| + "#{project['uid']}@#{project['updated_at']}" + end, + output_fields: lambda do |object_definitions| + object_definitions['project'] + end, + sample_output: lambda do |_connection, _input| + get('/projects')&.dig('data', 0) || {} + end + }, + new_updated_sheets: { + title: 'New or updated sheet in a project', + description: 'New or updated sheet in '\ + 'a PlanGrid project', + help: { + body: 'New or updated sheet in a project trigger uses the' \ + " Retrieve Sheets in a Project" \ + ' API.', + learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ + 'sheets-in-a-project', + learn_more_text: 'Retrieve Sheets in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { + 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_uid = closure&.[]('project_uid') || input['project_uid'] + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 5 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else + get("/projects/#{project_uid}/sheets"). + params(limit: limit, + skip: skip, + updated_after: updated_after) + end + closure = if (next_page_url = response['next_page_url']).present? + { 'skip' => skip + limit, + 'project_uid' => project_uid, + 'next_page_url' => next_page_url } + else + { 'offset' => 0, + 'project_uid' => project_uid, + 'updated_after' => now.to_time.utc.iso8601 } + end + sheets = response['data']&. + map { |o| o.merge('project_uid' => project_uid) } + { + events: sheets || [], + next_poll: closure, + can_poll_more: response['next_page_url'].present? + } + end, + dedup: lambda do |sheet| + "#{sheet['uid']}@#{sheet['created_at']}" + end, + output_fields: lambda do |object_definitions| + object_definitions['sheet'] + end, + sample_output: lambda do |_connection, _input| + id = get('projects')&.[]('data', 0)&.[]('uid') + get("/projects/#{id}/sheets")&.dig('data', 0) || {} + end + }, + new_updated_documents: { + title: 'New or updated document in a project', + description: 'New or updated document in '\ + 'a PlanGrid project', + help: { + body: 'New or updated document in a project trigger uses the' \ + " Retrieve Documents in a Project" \ + ' API.', + learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ + 'attachments-in-a-project', + learn_more_text: 'Retrieve Documents in a Project' + }, + input_fields: lambda do |_object_definitions| + [ + { name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Use project ID', + hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } }, + { + 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_uid = closure&.[]('project_uid') || input['project_uid'] + updated_after = closure&.[]('updated_after') || + (input['since'] || 1.hour.ago).to_time.utc.iso8601 + limit = 5 + skip = closure&.[]('skip') || 0 + response = if (next_page_url = closure&.[]('next_page_url')).present? + get(next_page_url) + else get("/projects/#{project_uid}/attachments"). params(limit: limit, skip: skip, @@ -2306,11 +2890,11 @@ end }, new_updated_task: { - title: 'New/updated task in a Project', - description: 'New/updated task in a '\ - 'Project Plangrid', + title: 'New or updated task in a project', + description: 'New or updated task in a '\ + ' PlanGrid project', help: { - body: 'New/updated task in a Project trigger uses the' \ + body: 'New or updated task in a project trigger uses the' \ " Retrieve Tasks " \ ' in a Project API.', @@ -2389,14 +2973,14 @@ end }, new_updated_annotations: { - title: 'New/updated annotations in Project', - description: 'New/updated annotations '\ - 'in Project Plangrid', + title: 'New or updated annotation in a project', + description: 'New or updated annotation '\ + 'in a PlanGrid project', help: { - body: 'New/updated annotations in Project trigger uses the' \ + body: 'New or updated annotation in project trigger uses the' \ " Retrieve " \ - ' annotations in a Project API.', + ' Annotations in a Project API.', learn_more_url: 'https://developer.plangrid.com/docs/' \ 'retrieve-annotations-in-a-project', learn_more_text: 'Retrieve Annotations in a Project' @@ -2471,17 +3055,17 @@ end }, new_updated_photos: { - title: 'New/updated photos in Project', - description: 'New/updated photos '\ - 'in Plangrid Project', + title: 'New or updated photo in a project', + description: 'New or updated photo '\ + 'in a PlanGrid project', help: { - body: 'New/updated photos in Project trigger uses the' \ + body: 'New or updated photo in a project trigger uses the' \ " Retrieve " \ ' photos in a Project API.', learn_more_url: 'https://developer.plangrid.com/docs/' \ 'retrieve-photos-in-a-project', - learn_more_text: 'Retrieve photos in a Project' + learn_more_text: 'Retrieve Photos in a Project' }, input_fields: lambda do |_object_definitions| [ @@ -2553,16 +3137,16 @@ end }, new_updated_snapshot: { - title: 'New/updated snapshot in a Project', - description: 'New/updated snapshot '\ - 'in a Project Plangrid', + title: 'New or updated snapshot in a project', + description: 'New or updated snapshot '\ + 'in a PlanGrid project', help: { - body: 'New/updated snapshot in a Project trigger uses the' \ + body: 'New or updated snapshot in a project trigger uses the' \ " Retrieve " \ + "retrieve-snapshots-in-a-project' target='_blank'>Retrieve " \ ' Snapshots in a Project API.', learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'remove-snapshot-reference-in-rfi', + 'retrieve-snapshots-in-a-project', learn_more_text: 'Retrieve Snapshots in a Project' }, input_fields: lambda do |_object_definitions| @@ -2635,17 +3219,17 @@ end }, new_updated_field_report: { - title: 'New/updated field report in a Project', - description: 'New/updated field report '\ - 'in Plangrid Project', + title: 'New or updated field report in a project', + description: 'New or updated field report '\ + 'in a PlanGrid project', help: { - body: 'New/updated field report in Project trigger uses the' \ + body: 'New or updated field report in a project trigger uses the' \ " Retrieve " \ - 'field reports in a Project API.', + 'Field Reports in a Project API.', learn_more_url: 'https://developer.plangrid.com/docs/' \ 'retrieve-field-reports-in-a-project', - learn_more_text: 'Retrieve field reports in a Project' + learn_more_text: 'Retrieve Field Reports in a Project' }, input_fields: lambda do |_object_definitions| [ @@ -2698,14 +3282,12 @@ 'project_uid' => project_uid, 'updated_after' => now.to_time.utc.iso8601 } end - results = response['data']&. - map do |field_report| - field_report.merge({ 'pdf_form_fileds' => - field_report.delete('pdf_form_fileds')&. - map { |a| { a[0] => a[1] } }&.inject(:merge) }). - merge('project_uid' => project_uid) - end - field_reports = call('format_api_output_field_names', results) + + field_reports = response['data']&.map do |field_report| + field_report.merge({ + 'pdf_form_fields' => field_report['pdf_form_values'] + &.map { |a| { a['name'] => a['value'] } }&.inject(:merge) }) + end { events: field_reports || [], next_poll: closure, @@ -2725,11 +3307,11 @@ end }, new_updated_rfi: { - title: 'New/updated RFI in a Project', - description: 'New/updated RFI '\ - 'in a Plangrid Project', + title: 'New or updated RFI in a project', + description: 'New or updated RFI '\ + 'in a PlanGrid project', help: { - body: 'New/updated RFI in a Project trigger uses the' \ + body: 'New or updated RFI in a project trigger uses the' \ " Retrieve " \ ' RFIs in a Project API.', @@ -2818,12 +3400,14 @@ 'gov-state-local', 'other'].map { |type| [type.labelize, type] } end, project_folders: lambda do |_connection, project_uid:| - folders = get("/projects/#{project_uid}/attachments")['data']&. - pluck('folder')&.uniq - if folders.size > 0 - folders&.map { |folder| [folder || 'Root', folder || ''] } - else - [['Root', '']] + if project_uid.length === 36 + folders = get("/projects/#{project_uid}/attachments")['data']&. + pluck('folder')&.uniq + if folders.size > 0 + folders&.map { |folder| [folder || 'Root', folder || ''] } + else + [['Root', '']] + end end end } From 7c5ca29e120b27735d48fa412586d18a785642b7 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 6 Sep 2019 09:37:12 -0400 Subject: [PATCH 56/78] fix `project_uid` caching issue in triggers --- custom_connectors/oauth2/plangrid.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 253c77be..8de4fc9d 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2936,7 +2936,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{input.delete('project_uid')}/" \ + get("/projects/#{project_uid}/" \ 'issues'). params(limit: limit, skip: skip, @@ -3019,7 +3019,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{input.delete('project_uid')}/" \ + get("/projects/#{project_uid}/" \ 'annotations'). params(limit: limit, skip: skip, @@ -3101,7 +3101,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{input.delete('project_uid')}/" \ + get("/projects/#{project_uid}/" \ 'photos'). params(limit: limit, skip: skip, @@ -3183,7 +3183,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{input.delete('project_uid')}/" \ + get("/projects/#{project_uid}/" \ 'snapshots'). params(limit: limit, skip: skip, @@ -3265,7 +3265,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{input.delete('project_uid')}/" \ + get("/projects/#{project_uid}/" \ 'field_reports'). params(limit: limit, skip: skip, @@ -3353,7 +3353,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{input.delete('project_uid')}/" \ + get("/projects/#{project_uid}/" \ 'rfis'). params(limit: limit, skip: skip, From 5f0dc44e77aff37d5164d469f2bbe26810c50cca Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 6 Sep 2019 10:31:31 -0400 Subject: [PATCH 57/78] update triggers to pull from input `project_uid` instead of closure value --- custom_connectors/oauth2/plangrid.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 8de4fc9d..86a120f7 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2776,7 +2776,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{project_uid}/sheets"). + get("/projects/#{input['project_uid']}/sheets"). params(limit: limit, skip: skip, updated_after: updated_after) @@ -2856,7 +2856,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{project_uid}/attachments"). + get("/projects/#{input['project_uid']}/attachments"). params(limit: limit, skip: skip, updated_after: updated_after) @@ -2936,7 +2936,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{project_uid}/" \ + get("/projects/#{input['project_uid']}/" \ 'issues'). params(limit: limit, skip: skip, @@ -3019,7 +3019,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{project_uid}/" \ + get("/projects/#{input['project_uid']}/" \ 'annotations'). params(limit: limit, skip: skip, @@ -3101,7 +3101,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{project_uid}/" \ + get("/projects/#{input['project_uid']}/" \ 'photos'). params(limit: limit, skip: skip, @@ -3183,7 +3183,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{project_uid}/" \ + get("/projects/#{input['project_uid']}/" \ 'snapshots'). params(limit: limit, skip: skip, @@ -3265,7 +3265,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{project_uid}/" \ + get("/projects/#{input['project_uid']}/" \ 'field_reports'). params(limit: limit, skip: skip, @@ -3353,7 +3353,7 @@ response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) else - get("/projects/#{project_uid}/" \ + get("/projects/#{input['project_uid']}/" \ 'rfis'). params(limit: limit, skip: skip, From aece557f7ccdd611c6c87cd8d51b017f7445e0ce Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Fri, 6 Sep 2019 11:03:13 -0400 Subject: [PATCH 58/78] output `project_uid` from input instead of closure --- custom_connectors/oauth2/plangrid.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 86a120f7..042fbb94 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2791,7 +2791,7 @@ 'updated_after' => now.to_time.utc.iso8601 } end sheets = response['data']&. - map { |o| o.merge('project_uid' => project_uid) } + map { |o| o.merge('project_uid' => input['project_uid']) } { events: sheets || [], next_poll: closure, @@ -2953,7 +2953,7 @@ 'updated_after' => now.to_time.utc.iso8601 } end tasks = response['data']&. - map { |o| o.merge('project_uid' => project_uid) } + map { |o| o.merge('project_uid' => input['project_uid']) } { events: tasks || [], next_poll: closure, @@ -3035,7 +3035,7 @@ 'updated_after' => now.to_time.utc.iso8601 } end annotations = response['data']&. - map { |o| o.merge('project_uid' => project_uid) } + map { |o| o.merge('project_uid' => input['project_uid']) } { events: annotations || [], next_poll: closure, @@ -3117,7 +3117,7 @@ 'updated_after' => now.to_time.utc.iso8601 } end photos = response['data']&. - map { |o| o.merge('project_uid' => project_uid) } + map { |o| o.merge('project_uid' => input['project_uid']) } { events: photos || [], next_poll: closure, @@ -3199,7 +3199,7 @@ 'updated_after' => now.to_time.utc.iso8601 } end snapshots = response['data']&. - map { |o| o.merge('project_uid' => project_uid) } + map { |o| o.merge('project_uid' => input['project_uid']) } { events: snapshots || [], next_poll: closure, @@ -3369,7 +3369,7 @@ 'updated_after' => now.to_time.utc.iso8601 } end rfis = response['data']&. - map { |o| o.merge('project_uid' => project_uid) } + map { |o| o.merge('project_uid' => input['project_uid']) } { events: rfis || [], next_poll: closure, From 1291ccde5d8bc1b329dc35366e91f7585eeb553a Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Mon, 16 Mar 2020 15:22:39 -0400 Subject: [PATCH 59/78] update connector to code shared on 01.07.2020 --- custom_connectors/oauth2/plangrid.rb | 5021 ++++++++++---------------- 1 file changed, 1843 insertions(+), 3178 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 042fbb94..75e486bd 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -53,3361 +53,2026 @@ 'https://io.plangrid.com' end }, + test: ->(_connection) { get('/me') }, + object_definitions: { - project: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'uid', - type: 'string', - control_type: 'text', - sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'name', label: 'Project Name', sticky: true }, - { name: 'custom_id', label: 'Project Code', sticky: true }, - { name: 'organization_id', label: 'Organization ID' }, - { name: 'type', control_type: 'select', - label: 'Project Type', sticky: true, - pick_list: 'project_types', - toggle_hint: 'Select project type', - toggle_field: { - name: 'type', - label: 'Project type', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Project type with possible values of general,' \ - ' manufacturing, power, water-sewer-waste, industrial-' \ - 'petroleum, transportation, hazardous-waste, telecom, ' \ - 'education-k-12, education-higher, gov-federal, ' \ - 'gov-state-local, or other' - } }, - { name: 'status', label: 'Project Status', sticky: true }, - { name: 'owner', sticky: true, label: 'Project Owner' }, - { name: 'start_date', type: 'date', - sticky: true, - render_input: 'date_conversion', - parse_output: 'date_conversion', - label: 'Project Start Date', - hint: 'Project start date. ISO-8601 date format (YYYY-MM-DD).' }, - { name: 'end_date', type: 'date', - sticky: true, - render_input: 'date_conversion', - parse_output: 'date_conversion', - label: 'Project End Date', - hint: 'Project end date. ISO-8601 date format (YYYY-MM-DD).' }, - { name: 'street_1', sticky: true, - label: 'Street Line 1' }, - { name: 'street_2', sticky: true, label: 'Street line 2' }, - { name: 'city', sticky: true, label: 'Town or City' }, - { name: 'region', sticky: true, label: 'State, Province, or Region' }, - { name: 'postal_code', sticky: true, label: 'Zip or Postal Code' }, - { name: 'country', - sticky: true, - hint: 'Project address country in 2-letter ISO 3166 code.' }, - { name: 'latitude' }, - { name: 'longitude' }, - { name: 'updated_at', type: 'date_time', - render_input: 'date_time_conversion', - parse_output: 'date_time_conversion', - label: 'Updated at' } - ] + get_input_schema: { + fields: lambda do |_connection, config_fields| + case config_fields['object'] + when 'rfi_status' + [ + { name: 'limit', type: 'integer', control_type: 'integer', + hint: 'Number of RFI statuses to retrieve. Maximum value of 50.' }, + { name: 'skip', type: 'integer', control_type: 'integer', + hint: 'Number of RFI statuses to skip in the set of results.' } + ] + when 'field_report' + [ + { name: 'report_date_min', type: 'date', + label: 'Report Start Date', + hint: 'Only retrieve field reports between a date range starting with this date in UTC format.' }, + { name: 'report_date_max', type: 'date', + label: 'Report End Date', + hint: 'Only retrieve field reports between a date range ending with this date in UTC format.' }, + { name: 'updated_after', label: 'Updated After', type: 'date_time', + hint: 'Only retrieve field reports created/updated after specified UTC date and time.' }, + { + name: 'sort_by', label: 'Sort by column', control_type: 'select', + pick_list: + %w[report_date updated_at]&.map { |e| [e.labelize, e] }, + toggle_hint: 'Select column', + toggle_field: { + name: 'sort_by', label: 'Sort by column', type: 'string', control_type: 'text', + toggle_hint: 'Enter column', + hint: 'Allowed values report_date or updated_at.' + } + }, + { + name: 'sort_order', label: 'Sort by order', control_type: 'select', + pick_list: [%w[Ascending asc], %w[Descending desc]], + toggle_hint: 'Select order', + toggle_field: { + name: 'sort_by', label: 'Sort by order', type: 'string', control_type: 'text', + toggle_hint: 'Enter order', + hint: 'Allowed values Ascending or Descending.' + } + }, + { + name: 'output_schema', + control_type: 'schema-designer', + extends_schema: true, + label: 'PDF field values', + hint: 'Manually define the values expected of your PDF field values in the field report.', + optional: true + } + ] + when 'role', 'project' + [] + else + [{ name: "uid", label: "#{config_fields['object'].labelize} ID", optional: false, + hint: 'ID can be found at the end of the url.' }] + end end }, - document: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', label: 'Document ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - sticky: true, + + get_output_schema: { + fields: lambda do |_connection, config_fields| + case config_fields['object'] + when 'project' + [ + { + name: 'uid', + control_type: 'select', + pick_list: 'project_list', label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'name', label: 'Document Name' }, - { name: 'folder' }, - { name: 'url' }, - { name: 'created_at', type: 'date_time', - render_input: 'parse_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'created_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' }, - { name: 'email' } - ] }, - { name: 'deleted', type: 'boolean' }, - { name: 'updated_at', type: 'date_time', - render_input: 'parse_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' } - ] - end - }, - task: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', label: 'Task ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'number', type: 'number' }, - { name: 'title' }, - { name: 'status', control_type: 'select', pick_list: - %w[open in_review pending closed].select { |op| [op.labelize, op] }, - 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", "in_review", "pending",' \ - ' "closed".' - } }, - { name: 'type', control_type: 'select', - pick_list: [ - %w[issue issue], - %w[Planned\ work planned_work], - %w[other other] - ], - toggle_hint: 'Select type', - toggle_field: { - name: 'type', - label: 'Type', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: "issue", "planned_work",' \ - ' "other".' - } }, - { name: 'assignees', type: 'array', of: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'type' } - ] }, - { name: 'followers', label: 'Watchers', type: 'array', of: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'type' } - ] }, - { name: 'room', label: 'Location' }, - { name: 'start_date', label: 'Start Date', - type: 'date_time', - render_input: 'date_conversion', - parse_output: 'date_conversion' }, - { name: 'closed_at', type: 'date_time', - render_input: 'date_time_conversion', - parse_output: 'date_time_conversion' }, - { name: 'due_at', type: 'date_time', - render_input: 'date_time_conversion', - parse_output: 'date_time_conversion' }, - { name: 'string', label: 'Stamp', - hint: 'One to two character stamp associated with task.' }, - { name: 'issue_list', label: 'Task List', type: 'object', properties: [ - { name: 'uid', label: 'Task List ID' }, - { name: 'url' } - ] }, - { name: 'description' }, - { name: 'cost_impact', label: 'Cost Impact', type: 'number' }, - { name: 'has_cost_impact', label: 'Has Cost Impact?', type: 'boolean', - control_type: 'checkbox', toggle_hint: 'Select from options list', - toggle_field: { - name: 'cost_impact', - label: 'Cost impact', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } }, - { name: 'currency_code', label: 'Currency Code', - hint: 'The ISO-4217 currency code of the cost_impact,' \ - ' Currently only supports USD. maybe null if cost_impact is ' \ - 'not specified' }, - { name: 'schedule_impact', label: 'Schedule Impact', type: 'integer' }, - { name: 'has_schedule_impact', label: 'Has Schedule Impact?', type: 'boolean', - control_type: 'checkbox', toggle_hint: 'Select from options list', - toggle_field: { - name: 'has_schedule_impact', - label: 'Has schedule impact', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } }, - { name: 'current_annotation', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'color' }, - { name: 'stamp' }, - { name: 'visibility' }, - { name: 'deleted', type: 'boolean', - control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_hint: 'Select project', + toggle_field: { + name: 'uid', + type: 'string', + control_type: 'text', + sticky: true, + label: 'Project ID', + toggle_hint: 'Enter project ID', + hint: 'Provide project ID. For example, 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } + }, + { name: 'name', label: 'Project Name', sticky: true }, + { name: 'custom_id', label: 'Project Code', sticky: true }, + { name: 'organization_id', label: 'Organization ID' }, + { + name: 'type', control_type: 'select', + label: 'Project Type', sticky: true, + pick_list: 'project_types', + toggle_hint: 'Select project type', toggle_field: { - name: 'deleted', - label: 'Deleted', + name: 'type', + label: 'Project type', type: 'string', control_type: 'text', toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } }, - { name: 'sheet', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' } - ] } - ] }, - { name: 'comments', type: 'object', properties: [ - { name: 'total_count', type: 'integer' }, - { name: 'url' } - ] }, - { name: 'photos', type: 'object', properties: [ - { name: 'total_count', type: 'integer' }, - { name: 'url' } - ] }, - { name: 'deleted', label: 'Deleted?', type: 'boolean', - control_type: 'checkbox', toggle_hint: 'Select from options list', - toggle_field: { - name: 'deleted', - label: 'Deleted', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } }, - { name: 'created_at', type: 'date_time', - render_input: 'render_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'created_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, + hint: 'Project type with possible values of general,' \ + ' manufacturing, power, water-sewer-waste, industrial-' \ + 'petroleum, transportation, hazardous-waste, telecom, ' \ + 'education-k-12, education-higher, gov-federal, ' \ + 'gov-state-local, or other' + } + }, + { name: 'status', label: 'Project Status', sticky: true }, + { name: 'owner', sticky: true, label: 'Project Owner' }, + { name: 'start_date', type: 'date', + sticky: true, + render_input: 'date_conversion', + parse_output: 'date_conversion', + label: 'Project Start Date', + hint: 'Project start date. ISO-8601 date format (YYYY-MM-DD).' }, + { name: 'end_date', type: 'date', + sticky: true, + render_input: 'date_conversion', + parse_output: 'date_conversion', + label: 'Project End Date', + hint: 'Project end date. ISO-8601 date format (YYYY-MM-DD).' }, + { name: 'street_1', sticky: true, + label: 'Street Line 1' }, + { name: 'street_2', sticky: true, label: 'Street line 2' }, + { name: 'city', sticky: true, label: 'Town or City' }, + { name: 'region', sticky: true, label: 'State, Province, or Region' }, + { name: 'postal_code', sticky: true, label: 'Zip or Postal Code' }, + { name: 'country', + sticky: true, + hint: 'Project address country in 2-letter ISO 3166 code.' }, + { name: 'latitude' }, + { name: 'longitude' }, + { name: 'updated_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + label: 'Updated at' } + ] + when 'attachment' + [ + { name: 'uid', label: 'Document ID' }, + { name: "project_uid", label: "Project ID" }, + { name: 'name', label: 'Document Name' }, + { name: 'folder' }, { name: 'url' }, - { name: 'email' } - ] }, - { name: 'updated_at', - render_input: 'date_time_conversion', - parse_output: 'date_time_conversion', - type: 'date_time' }, - { name: 'updated_by', type: 'object', properties: [ + { name: 'created_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { + name: 'created_by', type: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'url' }, + { name: 'email' } + ] + }, + { name: 'deleted', type: 'boolean', control_type: 'checkbox' } + ] + when 'issue' + [ + { name: 'uid', label: 'Task ID' }, + { name: "project_uid", label: "Project ID" }, + { name: 'number', type: 'integer' }, + { name: 'title' }, + { + name: 'status', control_type: 'select', pick_list: + %w[open in_review pending closed].select { |op| [op.labelize, op] }, + 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", "in_review", "pending", "closed".' + } + }, + { + name: 'type', control_type: 'select', + pick_list: [ + %w[issue issue], + %w[Planned\ work planned_work], + %w[other other] + ], + toggle_hint: 'Select type', + toggle_field: { + name: 'type', + label: 'Type', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: "issue", "planned_work", "other".' + } + }, + { + name: 'assignees', type: 'array', of: 'object', properties: [ + { name: 'uid', label: 'Assignee ID' }, + { name: 'type' } + ] + }, + { + name: 'followers', label: 'Watchers', type: 'array', of: 'object', properties: [ + { name: 'uid', label: 'Follower ID' }, + { name: 'type' } + ] + }, + { name: 'room', label: 'Location' }, + { name: 'start_date', label: 'Start Date', + type: 'date_time', + render_input: 'date_conversion', + parse_output: 'date_conversion' }, + { name: 'closed_at', type: 'date_time', + render_input: 'date_time_conversion', + parse_output: 'date_time_conversion' }, + { name: 'due_at', type: 'date_time', + render_input: 'date_time_conversion', + parse_output: 'date_time_conversion' }, + { name: 'string', label: 'Stamp', + hint: 'One to two character stamp associated with task.' }, + { + name: 'issue_list', label: 'Task List', type: 'object', properties: [ + { name: 'uid', label: 'Task List ID' }, + { name: 'url' } + ] + }, + { name: 'description' }, + { name: 'cost_impact', label: 'Cost Impact', type: 'integer' }, + { + name: 'has_cost_impact', label: 'Has Cost Impact?', type: 'boolean', + control_type: 'checkbox' + }, + { name: 'currency_code', label: 'Currency Code', + hint: 'The ISO-4217 currency code of the cost_impact,' \ + ' Currently only supports USD. maybe null if cost_impact is ' \ + 'not specified' }, + { name: 'schedule_impact', label: 'Schedule Impact', type: 'integer' }, + { + name: 'has_schedule_impact', label: 'Has Schedule Impact?', type: 'boolean', + control_type: 'checkbox' + }, + { + name: 'current_annotation', type: 'object', properties: [ + { name: 'uid', label: 'Annotation ID' }, + { name: 'color' }, + { name: 'stamp' }, + { name: 'visibility' }, + { + name: 'deleted', type: 'boolean', + control_type: 'checkbox' + }, + { + name: 'sheet', type: 'object', properties: [ + { name: 'uid', label: 'Sheet ID' }, + { name: 'url' } + ] + } + ] + }, + { + name: 'comments', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] + }, + { + name: 'photos', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] + }, + { + name: 'deleted', type: 'boolean', + control_type: 'checkbox' + }, + { name: 'created_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { + name: 'created_by', type: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'url' }, + { name: 'email' } + ] + }, + { name: 'updated_at', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + type: 'date_time' }, + { + name: 'updated_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' }, + { name: 'email' } + ] + } + ] + when 'file_upload' + [ { name: 'uid' }, + { + name: 'aws_post_form_arguments', type: 'object', + properties: [ + { name: 'action' }, + { name: 'fields', type: 'array', of: 'object', properties: [ + { name: 'name' }, + { name: 'value' } + ] } + ] + }, + { name: "project_uid", label: "Project ID" }, + { name: 'webhook_url' } + ] + when 'annotation' + [ + { name: 'uid', label: 'Annotation ID' }, + { name: "project_uid", label: "Project ID" }, + { name: 'color' }, + { name: 'stamp' }, + { name: 'visibility' }, + { + name: 'deleted', type: 'boolean', + control_type: 'checkbox' + }, + { + name: 'sheet', type: 'object', properties: [ + { name: 'uid', label: 'Sheet ID' }, + { name: 'url' } + ] + } + ] + when 'snapshot' + [ + { name: 'uid', label: 'Snapshot ID' }, + { name: "project_uid", label: "Project ID" }, + { name: 'title' }, { name: 'url' }, - { name: 'email' } - ] } - - ] - end - }, - file_upload: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid' }, - { name: 'aws_post_form_arguments', type: 'object', - properties: [ - { name: 'action' }, - { name: 'fields', type: 'array', of: 'object', properties: [ + { name: 'created_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { + name: 'created_by', type: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'url' }, + { name: 'email' } + ] + }, + { + name: 'sheet', type: 'object', properties: [ + { name: 'uid', label: 'Sheet ID' }, + { name: 'url' } + ] + }, + { + name: 'deleted', type: 'boolean', + control_type: 'checkbox' + } + ] + when 'photo' + [ + { name: 'uid', label: 'Photo ID' }, + { name: "project_uid", label: "Project ID" }, + { name: 'title' }, + { name: 'url', label: 'URL' }, + { name: 'created_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { + name: 'created_by', type: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'url' }, + { name: 'email' } + ] + }, + { name: 'deleted', type: 'boolean' } + ] + when 'field_report' + [ + { name: 'uid', label: 'Field Report ID' }, + { name: "project_uid", label: "Project ID" }, + { name: 'title' }, + { name: 'description' }, + { name: 'report_date', label: 'Report Date', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'status' }, + { + name: 'field_report_type', label: 'Field Report Type', type: 'object', properties: [ + { name: 'name' }, + { name: 'status' }, + { name: 'uid', label: 'Field Report ID' }, + { name: 'project_uid' }, + { name: 'template_type' } + ] + }, + { name: 'pdf_url', label: 'PDF URL' }, + { + name: 'pdf_form_values', label: 'PDF Form Values', type: 'array', of: 'object', + properties: [ { name: 'name' }, { name: 'value' } - ] } - ] }, - { name: 'webhook_url' } - ] + ] + }, + { + name: 'pdf_form_fields', label: 'PDF Field Values', type: 'object' + }, + { + name: 'pg_form_values', type: 'object', properties: [ + { + name: 'pg_worklog_entries', label: 'Work Log Entries', type: 'array', of: 'object', + properties: [ + { name: 'trade' }, + { name: 'timespan' }, + { name: 'headcount', type: 'integer' }, + { name: 'description' }, + { + name: 'deleted', type: 'boolean', + control_type: 'checkbox' + }, + { name: 'uid' } + ] + }, + { + name: 'pg_materials_entries', label: 'Material Entries', type: 'array', of: 'object', + properties: [ + { name: 'unit', type: 'integer' }, + { name: 'quantity', type: 'integer' }, + { name: 'item' }, + { name: 'description' }, + { name: 'deleted', type: "boolean", control_type: 'checkbox' }, + { name: 'uid' } + ] + }, + { + name: 'pg_equipment_entries', label: 'Equipment Entries', type: 'array', of: 'object', + properties: [ + { name: 'timespan' }, + { name: 'quantity', type: 'integer' }, + { name: 'item' }, + { name: 'description' }, + { + name: 'deleted', type: 'boolean', + control_type: 'checkbox' + }, + { name: 'uid' } + ] + } + ] + }, + { + name: 'attachments', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] + }, + { + name: 'photos', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] + }, + { + name: 'snapshots', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] + }, + { + name: 'created_by', type: 'object', properties: [ + { name: 'email' }, + { name: 'uid', label: 'UID' }, + { name: 'url' } + ] + }, + { name: 'updated_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { + name: 'weather', type: 'object', properties: [ + { name: 'humidity', type: 'number' }, + { name: 'precipitation_accumulation', type: 'number' }, + { name: 'precipitation_accumulation_unit' }, + { name: 'speed_unit' }, + { name: 'summary_key' }, + { name: 'temperature_max', type: 'integer' }, + { name: 'temperature_min' }, + { name: 'temperature_unit' }, + { name: 'wind_bearing', type: 'integer' }, + { name: 'wind_gust', type: 'number' }, + { name: 'wind_speed', type: 'number' } + ] + } + ] + when 'rfi' + [ + { name: 'uid', label: 'RFI ID' }, + { name: "project_uid", label: "Project ID" }, + { name: 'number', type: 'integer' }, + { + name: 'status', type: 'object', properties: [ + { name: 'uid', label: 'Status ID' }, + { name: 'label' }, + { name: 'color' } + ] + }, + { + name: 'locked', type: 'boolean', + control_type: 'checkbox' + }, + { name: 'title' }, + { name: 'question' }, + { name: 'answer' }, + { name: 'sent_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'Date when the RFI was sent. See ' \ + "Timestamps and " \ + 'Timezones for accepted date formats' }, + { name: 'due_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { + name: 'assigned_to', type: 'array', of: 'object', + properties: [ + { name: 'uid', label: 'UID' }, + { name: 'url' }, + { name: 'email' } + ] + }, + { name: 'updated_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'Date when the RFI was sent. See ' \ + "Timestamps and " \ + 'Timezones for accepted date formats' }, + { + name: 'updated_by', type: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'url' }, + { name: 'email' } + ] + }, + { name: 'created_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { + name: 'created_by', type: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'url' }, + { name: 'email' } + ] + }, + { + name: 'photos', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] + }, + { + name: 'attachments', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] + }, + { + name: 'snapshots', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] + }, + { + name: 'comments', type: 'object', properties: [ + { name: 'total_count', type: 'integer' }, + { name: 'url' } + ] + } + ] + when 'rfi_status' + [ + { name: 'uid', label: 'RFI status ID' }, + { name: 'label' }, + { name: 'color' }, + { name: "project_uid", label: "Project ID" } + ] + when 'user', 'user_invite' + [ + { name: 'uid', label: 'User ID' }, + { name: "project_uid", label: "Project ID" }, + { name: 'email' }, + { name: 'first_name', label: 'First Name' }, + { name: 'last_name', label: 'Last Name' }, + { name: 'language' }, + { + name: 'role', type: 'object', properties: [ + { name: 'uid', label: 'role ID' }, + { name: 'url' } + ] + }, + { name: 'removed', label: 'Removed?', type: 'boolean' } + ] + when 'sheet' + [ + { name: 'uid', label: 'Sheet ID' }, + { name: "project_uid", label: "Project ID" }, + { name: 'name' }, + { name: 'version_name', label: 'Version Name' }, + { name: 'description' }, + { name: 'tags', type: 'array', of: 'string', hint: 'An array of strings representing the' \ + ' tags added to this sheet.' }, + { + name: 'published_by', type: 'object', properties: [ + { name: 'uid', label: 'UID' }, + { name: 'url' }, + { name: 'email' } + ] + }, + { name: 'published_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'UTC date and time in ISO-8601 format.' }, + { + name: 'deleted', type: 'boolean', + control_type: 'checkbox' + }, + { name: 'uploaded_file_name', label: 'Uploaded file name' }, + { name: 'history_set_uid', label: 'History set ID' } + ] + when 'sheet_packet' + [ + { name: 'uid', label: 'Sheet Packet ID' }, + { name: "project_uid", label: "Project ID" }, + { name: 'status' }, + { name: 'file_url', label: 'File URL' }, + { + name: 'resource', type: 'object', properties: [ + { name: 'uid', label: 'Resource ID' }, + { name: 'url' } + ] + } + ] + when 'issue_list' + [ + { name: "uid", label: "Task List ID" }, + { name: "project_uid", label: "Project ID" }, + { name: "name", label: "Name" }, + { name: "deleted", label: "Deleted", type: "boolean", control_type: 'checkbox' } + ] + when 'role' + [ + { name: 'uid', label: 'Role ID' }, + { name: 'label', label: 'Role' }, + { name: "project_uid", label: "Project ID" } + ] + when 'sheet_upload' + [ + { name: 'uid', label: 'Sheet Version Upload ID' }, + { name: 'complete_url', label: 'Upload Completion URL' }, + { name: 'status' }, + { name: "project_uid", label: "Project ID" }, + { + name: 'file_upload_requests', label: 'File Upload Requests', + type: 'array', of: 'object', properties: [ + { name: 'uid', label: 'File Upload ID' }, + { name: 'upload_status', label: 'File Upload Status' }, + { name: 'url', label: 'File Upload URL' } + ] + } + ] + when 'version_upload' + [ + { name: 'uid', label: 'Sheet Version ID' }, + { name: "project_uid", label: "Project ID" }, + { name: 'status', label: 'Status' } + ] + end end }, - annotation: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', label: 'Annotation ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', + + create_input_schema: { + fields: lambda do |_connection, config_fields| + case config_fields['object'] + when 'project' + [ + { name: 'name', label: 'Project Name', sticky: true, optional: false }, + { name: 'custom_id', label: 'Project Code', sticky: true }, + { + name: 'type', control_type: 'select', + label: 'Project Type', sticky: true, + pick_list: 'project_types', + toggle_hint: 'Select project type', + toggle_field: { + name: 'type', + label: 'Project type', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Project type with possible values of general,' \ + ' manufacturing, power, water-sewer-waste, industrial-' \ + 'petroleum, transportation, hazardous-waste, telecom, ' \ + 'education-k-12, education-higher, gov-federal, ' \ + 'gov-state-local, or other' + } + }, + { name: 'status', label: 'Project Status', sticky: true }, + { name: 'owner', sticky: true, label: 'Project Owner' }, + { name: 'start_date', type: 'date', sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'color' }, - { name: 'stamp' }, - { name: 'visibility' }, - { name: 'deleted', type: 'boolean', - control_type: 'checkbox', toggle_hint: 'Select from options list', - toggle_field: { - name: 'deleted', - label: 'Deleted', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } }, - { name: 'sheet', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' } - ] } - ] - end - }, - snapshot: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', label: 'Snapshot ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'title' }, - { name: 'url' }, - { name: 'created_at', type: 'date_time', - render_input: 'parse_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'created_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' }, - { name: 'email' } - ] }, - { name: 'sheet', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' } - ] }, - { name: 'deleted', type: 'boolean', - control_type: 'checkbox', toggle_hint: 'Select from options list', - toggle_field: { - name: 'deleted', - label: 'Deleted', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } } - ] - end - }, - photo: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', label: 'Photo ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'title' }, - { name: 'url', label: 'URL' }, - { name: 'created_at', type: 'date_time', - render_input: 'parse_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'created_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' }, - { name: 'email' } - ] }, - { name: 'deleted', type: 'boolean' } - ] - end - }, - field_report: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', label: 'Field Report ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'title' }, - { name: 'description' }, - { name: 'report_date', label: 'Report Date', type: 'date_time', - render_input: 'parse_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'status' }, - { name: 'field_report_type', label: 'Field Report Type', type: 'object', properties: [ - { name: 'name' }, - { name: 'status' }, - { name: 'uid', label: 'UID' } - ] }, - { name: 'pdf_url', label: 'PDF URL' }, - { name: 'pdf_form_values', label: 'PDF Form Values', type: 'array', of: 'object', properties: [ - { name: 'name', label: 'Field Name' }, - { name: 'value', label: 'Field Value' } - ]}, - { name: 'pdf_form_fields', label: 'PDF Field Values', type: 'object' }, - { name: 'pg_form_values', label: 'Daily Report Values', type: 'array', of: 'object', properties: [ - { name: 'pg_worklog_entries', label: 'Work Log Entries', type: 'array', of: 'object', - properties: [ - { name: 'trade' }, - { name: 'timespan' }, - { name: 'headcount', type: 'integer' }, - { name: 'description' }, - { name: 'deleted', type: 'boolean', - control_type: 'checkbox', - toggle_hint: 'Select from options list', - toggle_field: { - name: 'deleted', - label: 'Deleted', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } } - ] }, - { name: 'pg_materials_entries', label: 'Material Entries', type: 'array', of: 'object', - properties: [ - { name: 'unit', type: 'integer' }, - { name: 'quantity', type: 'integer' }, - { name: 'item' }, - { name: 'description' }, - { name: 'deleted' } - ] }, - { name: 'pg_equipment_entries', label: 'Equipment Entries', type: 'array', of: 'object', - properties: [ - { name: 'timespan' }, - { name: 'quantity', type: 'integer' }, - { name: 'item' }, - { name: 'description' }, - { name: 'deleted', type: 'boolean', - control_type: 'checkbox', - toggle_hint: 'Select from options list', - toggle_field: { - name: 'deleted', - label: 'Deleted', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } } - ] } - ] }, - { name: 'attachments', label: 'Documents', type: 'object', properties: [ - { name: 'total_count', type: 'integer' }, - { name: 'url' } - ] }, - { name: 'photos', type: 'object', properties: [ - { name: 'total_count', type: 'integer' }, - { name: 'url' } - ] }, - { name: 'snapshots', type: 'object', properties: [ - { name: 'total_count', type: 'integer' }, - { name: 'url' } - ] }, - { name: 'created_by', type: 'object', properties: [ - { name: 'email' }, - { name: 'uid', label: 'UID' }, - { name: 'url' } - ] }, - { name: 'updated_at', type: 'date_time', - render_input: 'parse_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'weather', type: 'object', properties: [ - { name: 'humidity', type: 'number' }, - { name: 'precipitation_accumulation', type: 'number' }, - { name: 'precipitation_accumulation_unit' }, - { name: 'speed_unit' }, - { name: 'summary_key' }, - { name: 'temperature_max', type: 'integer' }, - { name: 'temperature_min' }, - { name: 'temperature_unit' }, - { name: 'wind_bearing', type: 'integer' }, - { name: 'wind_gust', type: 'number' }, - { name: 'wind_speed', type: 'number' } - ] } - ] - end - }, - rfi: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', label: 'RFI ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'number', type: 'integer' }, - { name: 'status', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'label' }, - { name: 'color' } - ] }, - { name: 'locked', type: 'boolean', - control_type: 'checkbox', toggle_hint: 'Select from options list', - toggle_field: { - name: 'locked', - label: 'Locked', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } }, - { name: 'title' }, - { name: 'question' }, - { name: 'answer' }, - { name: 'sent_at', type: 'date_time', - render_input: 'parse_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp', - hint: 'Date when the RFI was sent. See ' \ - "Timestamps and " \ - 'Timezones for accepted date formats' }, - { name: 'due_at', type: 'date_time', - render_input: 'parse_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'assigned_to', type: 'array', of: 'object', - properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' }, - { name: 'email' } - ] }, - { name: 'updated_at', type: 'date_time', - render_input: 'parse_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp', - hint: 'Date when the RFI was sent. See ' \ - "Timestamps and " \ - 'Timezones for accepted date formats' }, - { name: 'updated_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' }, - { name: 'email' } - ] }, - { name: 'created_at', type: 'date_time', - render_input: 'parse_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp' }, - { name: 'created_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' }, - { name: 'email' } - ] }, - { name: 'photos', type: 'object', properties: [ - { name: 'total_count', type: 'integer' }, - { name: 'url' } - ] }, - { name: 'attachments', type: 'object', properties: [ - { name: 'total_count', type: 'integer' }, - { name: 'url' } - ] }, - { name: 'snapshots', type: 'object', properties: [ - { name: 'total_count', type: 'integer' }, - { name: 'url' } - ] }, - { name: 'comments', type: 'object', properties: [ - { name: 'total_count', type: 'integer' }, - { name: 'url' } - ] } - ] - end - }, - rfi_status: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', label: 'Status ID' }, - { name: 'label' }, - { name: 'color' } - ] - end - }, - user: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', label: 'User ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', + render_input: 'date_conversion', + parse_output: 'date_conversion', + label: 'Project Start Date', + hint: 'Project start date. ISO-8601 date format (YYYY-MM-DD).' }, + { name: 'end_date', type: 'date', sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'email' }, - { name: 'first_name', label: 'First Name' }, - { name: 'last_name', label: 'Last Name' }, - { name: 'language'}, - { name: 'role', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' } - ] }, - { name: 'removed', label: 'Removed?' } - ] - end - }, - sheet: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', label: 'Sheet ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', + render_input: 'date_conversion', + parse_output: 'date_conversion', + label: 'Project End Date', + hint: 'Project end date. ISO-8601 date format (YYYY-MM-DD).' }, + { name: 'street_1', sticky: true, + label: 'Street Line 1' }, + { name: 'street_2', sticky: true, label: 'Street line 2' }, + { name: 'city', sticky: true, label: 'Town or City' }, + { name: 'region', sticky: true, label: 'State, Province, or Region' }, + { name: 'postal_code', sticky: true, label: 'Zip or Postal Code' }, + { name: 'country', sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'name' }, - { name: 'version_name', label: 'Version Name' }, - { name: 'description' }, - { name: 'tags', type: 'array', of: 'string', hint: 'An array of strings representing the' \ - ' tags added to this sheet.' }, - { name: 'published_by', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' }, - { name: 'email' } - ] }, - { name: 'published_at', type: 'date_time', - render_input: 'parse_iso8601_timestamp', - parse_output: 'parse_iso8601_timestamp', - hint: 'UTC date and time in ISO-8601 format.' }, - { name: 'deleted', type: 'boolean', - control_type: 'checkbox', - toggle_hint: 'Select from options list', - toggle_field: { - name: 'deleted', - label: 'Deleted', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } }, - { name: 'uploaded_file_name', label: 'Uploaded file name' } - ] - end - }, - sheet_packet: { - fields: lambda do |_connection, _config_fields| - [ - { name: 'uid', label: 'Sheet Packet ID' }, - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - sticky: true, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', + hint: 'Project address country in 2-letter ISO 3166 code.' }, + { + name: 'add_to_organization', type: 'boolean', sticky: true, + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'add_to_organization', + label: 'Add to Organization', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } + } + ] + when 'rfi' + [ + { + name: 'locked', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'locked', + label: 'Locked', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } + }, + { name: 'title', optional: false }, + { name: 'question' }, + { name: 'answer' }, + { name: 'sent_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'Date when the RFI was sent. See ' \ + "Timestamps and " \ + 'Timezones for accepted date formats' }, + { name: 'due_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'assigned_to_uids', hint: "A comma separated list of user IDs." }, + { name: 'status', label: 'Status', + hint: "Uid's of the RFI's initial status. Defaults to the first RFI status in the project" } + ] + when 'issue' + [ + { name: 'title' }, + { + name: 'status', control_type: 'select', pick_list: + %w[open in_review pending closed].select { |op| [op.labelize, op] }, + 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", "in_review", "pending", "closed".' + } + }, + { + name: 'type', control_type: 'select', + pick_list: [ + %w[issue issue], + %w[Planned\ work planned_work], + %w[other other] + ], + toggle_hint: 'Select type', + toggle_field: { + name: 'type', + label: 'Type', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: "issue", "planned_work", "other".' + } + }, + { name: 'room', label: 'Location' }, + { name: 'start_date', label: 'Start Date', + type: 'date_time', + render_input: 'date_conversion', + parse_output: 'date_conversion' }, + { name: 'due_at', type: 'date_time', + render_input: 'date_time_conversion', + parse_output: 'date_time_conversion' }, + { name: 'description' }, + { name: 'cost_impact', label: 'Cost Impact', type: 'number' }, + { + name: 'has_cost_impact', label: 'Has Cost Impact?', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'has_cost_impact', + label: 'Has cost impact?', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } + }, + { name: 'schedule_impact', label: 'Schedule Impact', type: 'integer' }, + { + name: 'has_schedule_impact', label: 'Has Schedule Impact?', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'has_schedule_impact', + label: 'Has schedule impact', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } + }, + { name: 'assigned_to_uids', hint: "A comma separated list of user IDs." }, + { name: 'issue_list_uid', label: 'Task List ID', sticky: true } + ] + when 'sheet_packet' + [ + { name: 'sheet_uids', label: 'Sheet IDs', optional: false, type: 'string', - control_type: 'text', - sticky: true, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'status' }, - { name: 'file_url', label: 'File URL' }, - { name: 'resource', type: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'url' } - ] } - ] - 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://io.plangrid.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 + hint: 'A comma separated list of sheet IDs.' }, + { + name: 'include_annotations', label: 'Include annotations?', type: 'boolean', sticky: true, + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'include_annotations', + label: 'Include annotations?', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' } - else + }, + ] + when 'issue_list' + [ + { name: 'name', optional: false } + ] + when 'sheet_upload' + [ + { name: 'num_files', label: 'Number of PDFs', type: 'integer', optional: false }, + { name: 'version_name', label: 'Version Name', optional: false } + ] + when 'user_invite' + [ + { name: 'email', optional: false }, + { name: 'role_uid', label: 'Role ID', sticky: true, + hint: 'Unique identifier of role to assign user on project team' }, + { name: 'first_name' }, + { name: 'last_name' }, + { name: 'language' } + ] + else + [] + end.concat( + if config_fields['object'] != 'project' + [ { - 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: call('make_schema_builder_fields_sticky', - input_schema) - } - end - ) - ].compact + name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + hint: 'If your project is not in top 50, use project ID toggle', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Enter project ID', + hint: 'Provide project ID. For example, 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } } - end - ), - { - name: 'output', - control_type: 'schema-designer', - sample_data_type: 'json_http', - extends_schema: true, - schema_neutral: true, - sticky: true - } - ] + ] + else + [] + end + ) end }, - custom_action_output: { + + update_input_schema: { fields: lambda do |_connection, config_fields| - parse_json(config_fields['output'] || '[]') - end - } - }, - actions: { - custom_action: { - description: "Custom action " \ - "in Plangrid", - help: { - body: 'Build your own Plangrid action for any Plangrid ' \ - 'REST endpoint.', - learn_more_url: 'https://developer.plangrid.com/docs/', - learn_more_text: 'The Plangrid 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'] - error("#{verb} not supported") if %w[get post put delete].exclude?(verb) - 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 - }, - create_project: { - title: 'Create project', - description: 'Create project in'\ - ' PlanGrid', - help: { - body: 'Create project action uses the' \ - " Create Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/create-project', - learn_more_text: 'Create Project' - }, - input_fields: lambda do |object_definitions| - [ - { name: 'add_to_organization', type: 'boolean', - control_type: 'checkbox', toggle_hint: 'Select from options list', - toggle_field: { - name: 'add_to_organization', - label: 'Add to Organization', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } - } - ].concat(object_definitions['project']. - ignored('uid', 'updated_at', 'latitude', 'longitude', - 'organization_id'). - required('name')) - end, - execute: lambda do |_connection, input| - payload = input.each do |key, value| - input[key].present? || input[key] = nil - end - post('projects').payload(payload). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end - end, - output_fields: lambda do |object_definitions| - object_definitions['project'] - end, - sample_output: lambda do |_connection, _input| - get('/projects')&.dig('data', 0) || {} - end - }, - update_project: { - title: 'Update project', - description: 'Update project in'\ - ' PlanGrid', - help: { - body: 'Update project action uses the' \ - " Update Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/update-project', - learn_more_text: 'Update Project' - }, - input_fields: lambda do |object_definitions| - object_definitions['project'].required('uid'). - ignored('updated_at', 'latitude', 'longitude', 'organization_id') - end, - execute: lambda do |_connection, input| - payload = input.each do |key, value| - input[key].present? || input[key] = nil - end - patch("/projects/#{input.delete('uid')}").payload(payload.except('uid')). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end - end, - output_fields: lambda do |object_definitions| - object_definitions['project'] - end, - sample_output: lambda do |_connection, _input| - get('/projects')&.dig('data', 0) || {} - end - }, - get_project_details: { - title: 'Get project', - description: 'Get project'\ - ' in PlanGrid', - help: { - body: 'Get project action uses the' \ - " Retrieve a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/retrieve-a-project', - learn_more_text: 'Retrieve a Project' - }, - input_fields: lambda do |object_definitions| - object_definitions['project'].only('uid').required('uid') - end, - execute: lambda do |_connection, input| - get("/projects/#{input['uid']}") - end, - output_fields: lambda do |object_definitions| - object_definitions['project'] - end, - sample_output: lambda do |_connection, _input| - get('/projects')&.dig('data', 0) || {} - end - }, - upload_document: { - title: 'Upload document to a project', - description: 'Upload document to a'\ - ' PlanGrid project', - help: { - body: 'Upload document to a project action uses the' \ - " Upload Document to Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/upload-' \ - 'attachment-to-project', - learn_more_text: 'Upload Document to Project API' - }, - summarize_input: %w[file_content], - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'content_type', - hint: 'Content type of the document\'s file. e.g. for pdf' \ - ' application/pdf', optional: false }, - { name: 'file_content', optional: false }, - { name: 'name', optional: false, - label: 'Document name', - hint: 'Name of the document.' }, - { name: 'folder', label: 'Folder', sticky: true, - control_type: 'select', - pick_list: 'project_folders', - pick_list_params: { project_uid: 'project_uid' }, - toggle_hint: 'Select folder', - hint: 'Folder shows in select options only if at least one file' \ - ' exist in the folder', - toggle_field: { - name: 'folder', - label: 'Project folder', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Folder in project to place the document ' \ - '(case-sensitive). Leave blank to select root folder' - } }, - { name: 'auto_version', type: 'boolean', sticky: true, - control_type: 'checkbox', - toggle_hint: 'Select from options list', - toggle_field: { - name: 'auto_version', - type: 'boolean', - control_type: 'text', - label: 'Auto version', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } } - ] - end, - execute: lambda do |_connection, input| - file_content = input.delete('file_content') - project_uid = input['project_uid'] - payload = input.except(:project_uid) - file_upload_info = post("/projects/#{project_uid}/" \ - 'attachments/uploads'). - headers('Content-type': 'application/json'). - payload(payload) - url = file_upload_info&.dig('aws_post_form_arguments', 'action') - fields = file_upload_info&.dig('aws_post_form_arguments', 'fields') - # webhook_url = file_upload_info. - # dig('aws_post_form_arguments', 'webhook_url') - headers = fields.map { |o| { o['name'] => o['value'] } }.inject(:merge) - status = - post(url). - payload(key: headers['key'], - policy: headers['policy'], - signature: headers['signature'], - AWSAccessKeyId: headers['AWSAccessKeyId'], - 'content-type': headers['Content-Type'], - 'success_action_redirect': headers['success_action_redirect'], - 'x-amz-server-side-encryption': - headers['x-amz-server-side-encryption'], - 'x-amz-storage-class': headers['x-amz-storage-class'], - file: file_content). - request_format_multipart_form. - after_response do |_code, response, _response_headers| - response - end - status.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['document'] - end, - sample_output: lambda do |_connection, _input| - { - uid: '147a420e-a182-4312-8fa5-4d10064d2f1a', - name: 'Bender', - folder: 'Specifications', - url: 'https://attachment-assets.plangrid.com/147a420e-a182-' \ - '4312-8fa5-4d10064d2f1a.pdf', - created_at: '2013-05-17T02:30:22+00:00', - created_by: { - uid: null, - url: null, - email: 'nick@subcontractor.com' - }, - deleted: false - } - end - }, - update_document: { - title: 'Update document in a project', - description: 'Update document in a'\ - ' PlanGrid project', - help: { - body: 'Update document in a project action uses the' \ - " Update Document to Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/update-attachment-' \ - 'in-a-project', - learn_more_text: 'Update Document in a Project API' - }, - summarize_input: %w[file_content], - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'attachment_uid', label: 'Document ID', optional: false }, - { name: 'name', label: 'Document Name', - hint: 'New name of the document', sticky: true }, - { name: 'folder', label: 'Folder', - hint: 'New folder of the document', sticky: true } - ] - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - patch("/projects/#{project_uid}/attachments/" \ - "#{input.delete('attachment_uid')}"). - headers('Content-type': 'application/json'). - payload(input). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['document'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/attachments")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end - }, - create_rfi: { - title: 'Create RFI in a project', - description: 'Create RFI in'\ - ' a PlanGrid project ', - help: { - body: 'Create RFI in a project action uses the ' \ - "Create RFI in Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/create-rfi-' \ - 'in-a-project', - learn_more_text: 'Create RFI in a Project' - }, - input_fields: lambda do |object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'status', label: 'Status', - hint: 'Use this for create and update rfi status' } - ].concat(object_definitions['rfi']. - only('locked', 'title', 'question', 'answer', 'sent_at', - 'due_at', 'assigned_to_uids'). - required('title')) - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - payload = input&.map do |key, val| - if %w[due_at sent_at].include?(key) - { key => val.to_time.utc.iso8601 } - else - { key => val } - end - end&.inject(:merge) - post("/projects/#{project_uid}/rfis").payload(payload). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['rfi'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/rfis")&.dig('data', 0) || {} - end - }, - update_rfi: { - title: 'Update RFI in a project', - description: 'Update RFI in'\ - ' a PlanGrid project', - help: { - body: 'Update RFI in a project action uses the ' \ - "Update RFI in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/update-' \ - 'rfi-in-a-project', - learn_more_text: 'Update RFI in a Project' - }, - input_fields: lambda do |object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'status', label: 'Status UID' } - ].concat(object_definitions['rfi']. - only('uid', 'locked', 'title', 'question', 'answer', 'sent_at', - 'due_at', 'assigned_to_uids'). - required('uid')) - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - rfi_id = input.delete('uid') - payload = input&.map do |key, val| - if %w[due_at sent_at].include?(key) - { key => val.to_time.utc.iso8601 } - else - { key => val } - end - end&.inject(:merge) - patch("/projects/#{project_uid}/rfis/#{rfi_id}").payload(payload). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['rfi'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/rfis")&.dig('data', 0) || {} - end - }, - get_rfi_in_project: { - title: 'Get RFI in a project', - description: 'Get RFI in '\ - 'a PlanGrid project', - help: { - body: 'Get RFI in a project action uses the' \ - " Retrieve RFI in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/" \ - "retrieve-rfis-in-a-project', - learn_more_text: 'Retrieve RFI in a Project' - }, - input_fields: lambda do |object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'rfi_uid', label: 'RFI ID', optional: false } - ] - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - get("/projects/#{project_uid}/rfis/#{input['rfi_uid']}")&. - merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['rfi'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/rfis")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end - }, - create_task: { - title: 'Create task in a project', - description: 'Create task in'\ - ' a PlanGrid project', - help: { - body: 'Create task in a project action uses the ' \ - "Create Task in Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/create-task-in-' \ - 'a-project', - learn_more_text: 'Create Task in a Project' - }, - input_fields: lambda do |object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } - }, - { name: 'issue_list_uid', label: 'Task List ID', sticky: true } - ].concat(object_definitions['task']. - only('title', 'status', 'type', 'assigned_to_uids', - 'room', 'start_date', 'due_at', - 'description', 'has_cost_impact', 'cost_impact', - 'has_schedule_impact', 'schedule_impact' - )) - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - payload = input&.map do |key, val| - if %w[due_at].include?(key) - { key => val.to_time.utc.iso8601 } - else - { key => val } - end - end&.inject(:merge) - post("/projects/#{project_uid}/issues").payload(payload). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['task'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/issues")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end - }, - update_task: { - title: 'Update task in a project', - description: 'Update task in'\ - ' a PlanGrid project', - help: { - body: 'Update task in a project action uses the ' \ - "Update Task in Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/create-project', - learn_more_text: 'Update Task in a Project' - }, - input_fields: lambda do |object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g.' \ - ' 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } - }, - { name: 'issue_uid', label: 'Task ID', optional: false }, - { name: 'issue_list_uid', label: 'Task List ID', sticky: true } - ].concat(object_definitions['task']. - only('title', 'status', 'type', 'assigned_to_uids', - 'room', 'start_date', 'due_at', - 'description', 'has_cost_impact', 'cost_impact', - 'has_schedule_impact', 'schedule_impact' - )) - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - payload = input.each do |key, value| - input[key].present? || input[key] = nil - end - patch("/projects/#{project_uid}/issues/" \ - "#{input.delete('issue_uid')}").payload(payload). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['task'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/issues")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end - }, - get_task: { - title: 'Get task in a project', - description: 'Get task in'\ - ' a PlanGrid project', - help: { - body: 'Get task in a project action uses the ' \ - "Retrieve Task in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ - 'issues-in-a-project', - learn_more_text: 'Retrieve Task in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'issue_uid', label: 'Task ID', optional: false } - ] - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - get("/projects/#{project_uid}/issues/" \ - "#{input['issue_uid']}"). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['task'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/issues")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end - }, - invite_user_to_project: { - title: 'Invite user to a project', - description: 'Invite user to'\ - ' a PlanGrid project', - help: { - body: 'Invite user to a project action uses the ' \ - "Invite User in Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'invite-user-to-project-team', - learn_more_text: 'Invite User to Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'email', optional: false }, - { name: 'role_uid', label: 'Role ID', sticky: true, - hint: 'Unique identifier of role to assign user on project team' } - ] - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - post("/projects/#{project_uid}/users/invites"). - payload(input). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['user'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/users")&.dig('data', 0) || {} - end - }, - get_user_in_project: { - title: 'Get user in project', - description: 'Get user in'\ - ' a PlanGrid project', - help: { - body: 'Get user in a project action uses the ' \ - "Retrieve User in a Project.", - learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ - 'users-on-a-project-team', - learn_more_text: 'Retrieve User in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'user_uid', label: 'User ID', optional: false } - ] - end, - execute: lambda do |_connection, input| - get("/projects/#{input['project_uid']}/users/" \ - "#{input['user_uid']}") - end, - output_fields: lambda do |object_definitions| - object_definitions['user'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/users")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end - }, - get_snapshot_in_project: { - title: 'Get snapshot in a project', - description: 'Get snapshot in'\ - ' a PlanGrid project', - help: { - body: 'Get snapshot in a project action uses the ' \ - "Retrieve Snapshot in a Project.", - learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ - 'snapshot-in-a-project', - learn_more_text: 'Retrieve Snapshot in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'snapshot_uid', label: 'Snapshot ID', optional: false } - ] - end, - execute: lambda do |_connection, input| - get("/projects/#{input['project_uid']}/snapshots/" \ - "#{input['snapshot_uid']}")&.merge('project_uid' => input['project_uid']) - end, - output_fields: lambda do |object_definitions| - object_definitions['snapshot'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/snapshots")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end - }, - get_rfi_statuses_in_project: { - title: 'Get RFI statuses in project', - description: 'Get RFI statuses in'\ - ' a PlanGrid project', - help: { - body: 'Get RFI statuses in project action uses the ' \ - "Retrieve RFI Statuses in a Project.", - learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ - 'rfi-statuses-in-a-project', - learn_more_text: 'Retrieve RFI Statuses in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'limit', type: 'integer', - hint: 'Number of RFI statuses to retrieve. Maximum value of 50.' }, - { name: 'skip', type: 'integer', - hint: 'Number of RFI statuses to skip in the set of results.' } - ] - end, - execute: lambda do |_connection, input| - { statuses: - get("/projects/#{input['project_uid']}/rfis/statuses")['data'] } - end, - output_fields: lambda do |object_definitions| - [ - { name: 'statuses', type: 'array', of: 'object', - properties: object_definitions['rfi_status'] } - ] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/rfis/statuses")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end - }, - get_roles_on_project: { - title: 'Get roles in a project', - description: 'Get roles in '\ - ' a PlanGrid project', - help: { - body: 'Get roles in a project action uses the ' \ - "Retrieve Roles on a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-roles-on-a-project', - learn_more_text: 'Retrieves Role on a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } } - ] - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - { roles: get("/projects/#{project_uid}/roles")['data'] } - end, - output_fields: lambda do |_object_definitions| - [ - { name: 'roles', label: 'Roles', type: 'array', of: 'object', properties: [ - { name: 'uid', label: 'UID' }, - { name: 'label', label: 'Role' } - ] } - ] - end, - sample_output: lambda do |_connection, _input| - { 'roles' => { 'uid' => '9d139e64-cac9-4f23-b4d5-9fd3688b498e', - 'label' => 'Admin' } } - end - }, - - get_sheet_in_project: { - title: 'Get sheet in a project', - description: 'Get sheet in '\ - 'a PlanGrid project', - help: { - body: 'Get sheet in a project action uses the ' \ - "Retrieve Sheet in a Project.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-a-sheet', - learn_more_text: 'Retrieve Sheet in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'sheet_uid', label: 'Sheet ID', optional: false } - ] - end, - execute: lambda do |_connection, input| - get("/projects/#{input['project_uid']}/sheets/#{input['sheet_uid']}")&. - merge('project_uid' => input['project_uid']) - end, - output_fields: lambda do |object_definitions| - object_definitions['sheet'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/sheets?limit=1")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end - }, - get_project_sheet_packet: { - title: 'Get sheet packet in a project', - description: 'Get sheet packet in'\ - ' a PlanGrid project', - help: { - body: 'Get sheet packet in a project action uses the ' \ - "Retrieve Sheet Packet API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-sheet-packet', - learn_more_text: 'Retrieve Sheet Packet' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'packet_uid', label: 'Sheet Packet ID', optional: false } - ] - end, - execute: lambda do |_connection, input| - get("/projects/#{input['project_uid']}/sheets/packets/" \ - "#{input['packet_uid']}")&.merge('project_uid' => input['project_uid']) - end, - output_fields: lambda do |object_definitions| - object_definitions['sheet_packet'] - end - }, - get_field_reports_in_project: { - title: 'Get field reports in a project', - description: 'Get field reports in'\ - ' a PlanGrid project', - help: { - body: 'Get field reports in a project action uses the ' \ - "Retrieve Field Reports in a" \ - ' Project API.', - learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ - 'field-reports-in-a-project', - learn_more_text: 'Retrieve Field Reports in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project ID', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'report_date_min', type: 'date', - label: 'Report Start Date', - hint: 'Only retrieve field reports between a date range ' \ - 'starting with this date in UTC format.' }, - { name: 'report_date_max', type: 'date', - label: 'Report End Date', - hint: 'Only retrieve field reports between a date range ' \ - 'starting with this date in UTC format.' }, - { name: 'updated_after', label: 'Updated After', type: 'date_time', - hint: 'Only retrieve field reports created/updated after ' \ - 'specified UTC date and time.' }, - { name: 'sort_by', control_type: 'select', - pick_list: - %w[report_date updated_at]&.map { |e| [e.labelize, e] }, - toggle_hint: 'Select sort by column', - toggle_field: { - name: 'sort_by', type: 'string', control_type: 'text', - hint: 'Allowed values report_date or updated_at' - } }, - { name: 'sort_order', control_type: 'select', - pick_list: - %w[asc desc]&.map { |e| [e.labelize, e] }, - toggle_hint: 'Select sort order', - toggle_field: { - name: 'sort_by', type: 'string', control_type: 'text', - hint: 'Allowed values asc or desc' - } } - ] - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - query_params = '' - input&.map do |key, val| - if %w[updated_after].include?(key) - query_params = query_params + "&" + "#{key}=#{val.to_time.utc.iso8601}" - else - query_params = query_params + "&" + "#{key}=#{val}" - end - end - - results = get("/projects/#{project_uid}/field_reports?" \ - "#{query_params}")['data'] - - field_reports = results.map do |field_report| - field_report.merge({ - 'pdf_form_fields' => field_report['pdf_form_values'] - &.map { |a| { a['name'] => a['value'] } }&.inject(:merge) }) - end - { field_reports: field_reports } - - end, - output_fields: lambda do |object_definitions| - { name: 'field_reports', label: 'Field Reports', type: 'array', of: 'object', - properties: object_definitions['field_report'] } - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - { field_reports: - get("/projects/#{id}/rfis/field_reports")&. - merge('project_uid' => id) || {} } - end - }, - upload_photo: { - title: 'Upload photo to a project', - description: 'Upload photo to '\ - ' a PlanGrid project', - help: { - body: 'Upload photo to a project action uses the' \ - " Upload Photo to Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/upload-photo' \ - '-to-project', - learn_more_text: 'Upload Photo to Project' - }, - summarize_input: %w[file_content], - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'content_type', optional: false, - hint: "Content type of the photo's file" }, - { name: 'file_content', optional: false }, - { name: 'title', optional: false, label: 'Photo title' } - ] - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - file_content = input.delete('file_content') - payload = input.except(:project_uid) - file_upload_info = post("/projects/#{project_uid}/" \ - 'photos/uploads'). - headers('Content-type': 'application/json'). - payload(payload) - url = file_upload_info&.dig('aws_post_form_arguments', 'action') - fields = file_upload_info&.dig('aws_post_form_arguments', 'fields') - # webhook_url = file_upload_info. - # dig('aws_post_form_arguments', 'webhook_url') - headers = fields.map { |o| { o['name'] => o['value'] } }.inject(:merge) - post(url). - payload(key: headers['key'], - policy: headers['policy'], - signature: headers['signature'], - AWSAccessKeyId: headers['AWSAccessKeyId'], - 'content-type': headers['Content-Type'], - 'success_action_redirect': headers['success_action_redirect'], - 'x-amz-server-side-encryption': - headers['x-amz-server-side-encryption'], - 'x-amz-storage-class': headers['x-amz-storage-class'], - file: file_content). - request_format_multipart_form. - after_response do |_code, response, _response_headers| - response - end&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['photo'] - end, - sample_output: lambda do |_connection, _input| - { - uid: '147a420e-a182-4312-8fa5-4d10064d2f1a', - title: 'Bongo Drums', - url: 'https://attachment-assets.plangrid.com/147a420e-a182-' \ - '4312-8fa5-4d10064d2f1a.pdf', - created_at: '2013-05-17T02:30:22+00:00', - created_by: { - uid: null, - url: null, - email: 'nick@subcontractor.com' - }, - deleted: false - } - end - }, - update_photo_metadata: { - title: 'Update photo in a project', - description: 'Update photo in'\ - ' a PlanGrid project', - help: { - body: 'Update photo action uses the' \ - " Update Photo in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/update-photo-' \ - 'in-a-project', - learn_more_text: 'Update Photo in a Project API' - }, - summarize_input: %w[file_content], - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'photo_uid', label: 'Photo ID', optional: false }, - { name: 'title', label: 'Photo title', - hint: 'New title of the photo', sticky: true } - ] - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - patch("/projects/#{project_uid}/photos/" \ - "#{input.delete('photo_uid')}"). - headers('Content-type': 'application/json'). - payload(input). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['photo'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/photos")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end - }, - get_photo_details: { - title: 'Get photo in a project', - description: 'Get photo in'\ - ' a PlanGrid project', - help: { - body: 'Get photo action uses the ' \ - "Retrieve Photo in Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-a-sheet', - learn_more_text: 'Retrieve Photo in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'photo_uid', label: 'Photo ID', optional: false } - ] - end, - execute: lambda do |_connection, input| - get("/projects/#{input['project_uid']}/photos/" \ - "#{input['photo_uid']}")&.merge('project_uid' => input.delete('project_uid')) - end, - output_fields: lambda do |object_definitions| - object_definitions['photo'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/photos")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end - }, - get_document_details: { - title: 'Get document in a project', - description: 'Get document'\ - ' in a PlanGrid project', - help: { - body: 'Get document in a project action uses the ' \ - "Retrieve Document in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-a-sheet', - learn_more_text: 'Retrieve Document in a Project API' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', + case config_fields['object'] + when 'project' + [ + { name: 'name', label: 'Project Name', sticky: true }, + { name: 'custom_id', label: 'Project Code', sticky: true }, + { + name: 'type', control_type: 'select', + label: 'Project Type', sticky: true, + pick_list: 'project_types', + toggle_hint: 'Select project type', + toggle_field: { + name: 'type', + label: 'Project type', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Project type with possible values of general,' \ + ' manufacturing, power, water-sewer-waste, industrial-' \ + 'petroleum, transportation, hazardous-waste, telecom, ' \ + 'education-k-12, education-higher, gov-federal, ' \ + 'gov-state-local, or other' + } + }, + { name: 'status', label: 'Project Status', sticky: true }, + { name: 'owner', sticky: true, label: 'Project Owner' }, + { name: 'start_date', type: 'date', + sticky: true, + render_input: 'date_conversion', + parse_output: 'date_conversion', + label: 'Project Start Date', + hint: 'Project start date. ISO-8601 date format (DD-MM-YYYY).' }, + { name: 'end_date', type: 'date', + sticky: true, + render_input: 'date_conversion', + parse_output: 'date_conversion', + label: 'Project End Date', + hint: 'Project end date. ISO-8601 date format (DD-MM-YYYY).' }, + { name: 'street_1', sticky: true, + label: 'Street Line 1' }, + { name: 'street_2', sticky: true, label: 'Street line 2' }, + { name: 'city', sticky: true, label: 'Town or City' }, + { name: 'region', sticky: true, label: 'State, Province, or Region' }, + { name: 'postal_code', sticky: true, label: 'Zip or Postal Code' }, + { name: 'country', + sticky: true, + hint: 'Project address country in 2-letter ISO 3166 code.' } + ] + when 'rfi' + [ + { + name: 'locked', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'locked', + label: 'Locked', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } + }, + { name: 'title', optional: false }, + { name: 'question' }, + { name: 'answer' }, + { name: 'sent_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp', + hint: 'Date when the RFI was sent. See ' \ + "Timestamps and " \ + 'Timezones for accepted date formats' }, + { name: 'due_at', type: 'date_time', + render_input: 'render_iso8601_timestamp', + parse_output: 'parse_iso8601_timestamp' }, + { name: 'assigned_to_uids', hint: "A comma separated list of user IDs." }, + { name: 'status', label: 'Status', + hint: "Uid's of the RFI's initial status. Defaults to the first RFI status in the project" } + ] + when 'issue' + [ + { name: 'title' }, + { + name: 'status', control_type: 'select', pick_list: + %w[open in_review pending closed].select { |op| [op.labelize, op] }, + 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", "in_review", "pending", "closed".' + } + }, + { + name: 'type', control_type: 'select', + pick_list: [ + %w[issue issue], + %w[Planned\ work planned_work], + %w[other other] + ], + toggle_hint: 'Select type', + toggle_field: { + name: 'type', + label: 'Type', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: "issue", "planned_work", "other".' + } + }, + { name: 'room', label: 'Location' }, + { name: 'start_date', label: 'Start Date', + type: 'date_time', + render_input: 'date_conversion', + parse_output: 'date_conversion' }, + { name: 'due_at', type: 'date_time', + render_input: 'date_time_conversion', + parse_output: 'date_time_conversion' }, + { name: 'description' }, + { name: 'cost_impact', label: 'Cost Impact', type: 'number' }, + { + name: 'has_cost_impact', label: 'Has Cost Impact?', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'has_cost_impact', + label: 'Has cost impact', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } + }, + { name: 'schedule_impact', label: 'Schedule Impact', type: 'integer', + hint: "The task's schedule impact in seconds, if it has one." }, + { + name: 'has_schedule_impact', label: 'Has Schedule Impact?', type: 'boolean', + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'has_schedule_impact', + label: 'Has schedule impact', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } + }, + { name: 'assigned_to_uids', hint: "A comma separated list of user IDs." }, + { name: 'issue_list_uid', label: 'Task List ID', sticky: true } + ] + when 'sheet_packet' + [ + { name: 'sheet_uids', label: 'Sheet IDs', optional: false, type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'attachment_uid', label: 'Document ID', optional: false } - ] - end, - execute: lambda do |_connection, input| - get("/projects/#{input['project_uid']}/attachments/" \ - "#{input['attachment_uid']}")&.merge('project_uid' => input.delete('project_uid')) - end, - output_fields: lambda do |object_definitions| - object_definitions['document'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/attachments")&.dig('data', 0)&. - merge('project_uid' => id) || {} - end - }, - create_sheet_packet: { - title: 'Create sheet packet in a project', - description: 'Create sheet packet in '\ - ' a PlanGrid project', - help: { - body: 'Create sheet packet in a project action uses the' \ - " Create Sheet Packet in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/upload-photo' \ - '-to-project', - learn_more_text: 'Create Sheet Packet in a Project' - }, - input_fields: lambda do |object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { + hint: 'A comma separated list of sheet IDs.' }, + { + name: 'include_annotations', label: 'Include annotations?', type: 'boolean', sticky: true, + control_type: 'checkbox', toggle_hint: 'Select from options list', + toggle_field: { + name: 'include_annotations', + label: 'Include annotations?', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } + }, + ] + when 'issue_list' + [ + { name: 'name', optional: false } + ] + when 'sheet_upload' + [ + { name: 'num_files', label: 'Number of PDFs', type: 'integer', optional: false }, + { name: 'version_name', label: 'Version Name', optional: false } + ] + when 'photo' + [ + { name: 'title', label: 'Photo title', + hint: 'New title of the photo', sticky: true } + ] + else + [] + end.concat( + [ + { name: 'project_uid', - type: 'string', - control_type: 'text', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'sheet_uids', label: 'Sheet IDs', optional: false, - type: 'string', - hint: 'A comma separated list of sheet IDs.' }, - { name: 'include_annotations', label: 'Include annotations?', type: 'boolean', sticky: true, - control_type: 'checkbox', toggle_hint: 'Select from options list', - toggle_field: { - name: 'include_annotations', - label: 'Include annotations?', - type: 'string', - control_type: 'text', - toggle_hint: 'Use custom value', - hint: 'Allowed values are: true, false' - } }, - ] - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - payload = { - sheet_uids: input.delete('sheet_uids').split(','), - include_annotations: input.delete('include_annotations') - } - post("/projects/#{project_uid}/sheets/packets").payload(payload). - after_error_response(/.*/) do |_code, body, _header, message| - error("#{message}: #{body}") - end&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - object_definitions['sheet_packet'] - end, - sample_output: lambda do |_connection, _input| - { - uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", - file_url: "https://packet-assets.plangrid.com/92cf7193-af0c-42fc-a3ab-7ef5149da720.pdf", - resource: { - uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", - url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/packets/92cf7193-af0c-42fc-a3ab-7ef5149da720" - }, - status: "incomplete" - } + hint: 'If your project is not in top 50, use project ID toggle.', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Enter project ID', + hint: 'Provide project ID. For example, 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } + } + ] + ).concat( + if config_fields['object'] != 'project' + [{ name: "uid", label: "#{config_fields['object'].labelize} ID", optional: false }] + else + [] + end + ) end }, - get_task_list: { - title: 'Get task list in a project', - description: 'Get task list'\ - ' in a PlanGrid project', - help: { - body: 'Get task list in a project action uses the ' \ - "Retrieve Task List in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-issue-list', - learn_more_text: 'Retrieve Task List in a Project API' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { + + upload_input_schema: { + fields: lambda do |_connection, config_fields| + case config_fields['object'] + when 'attachment' + [ + { name: 'content_type', + hint: 'Content type of the document\'s file. Example for pdf application/pdf', + optional: false }, + { name: 'file_content', optional: false }, + { name: 'name', optional: false, + label: 'Document name', + hint: 'Name of the document.' }, + { + name: 'folder', label: 'Folder', sticky: true, + control_type: 'select', + pick_list: 'project_folders', + pick_list_params: { project_uid: 'project_uid' }, + toggle_hint: 'Select folder', + hint: 'Folder shows in select options only if at least one file exist in the folder', + toggle_field: { + name: 'folder', + label: 'Project folder', + type: 'string', + control_type: 'text', + toggle_hint: 'Use custom value', + hint: 'Folder in project to place the document ' \ + '(case-sensitive). Leave blank to select root folder' + } + }, + { + name: 'auto_version', type: 'boolean', sticky: true, + control_type: 'checkbox', + toggle_hint: 'Select from options list', + toggle_field: { + name: 'auto_version', + type: 'boolean', + control_type: 'text', + label: 'Auto version', + toggle_hint: 'Use custom value', + hint: 'Allowed values are: true, false' + } + } + ] + when 'photo' + [ + { name: 'content_type', optional: false, + hint: "Content type of the photo's file" }, + { name: 'file_content', optional: false }, + { name: 'title', optional: false, label: 'Photo title' } + ] + when 'file_upload' + [ + { name: 'ver_upload_uid', label: 'Sheet Version Upload ID', optional: false }, + { name: 'file_upload_request_uid', label: 'File Upload ID', optional: false }, + { name: 'file_name', label: 'File Name', optional: false }, + { name: 'file_content', label: 'File Content', optional: false } + ] + when 'version_upload' + [ + { name: 'ver_upload_uid', label: 'Sheet Version Upload ID', optional: false } + ] + else + [] + end.concat( + [ + { name: 'project_uid', - type: 'string', - control_type: 'text', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'issue_list_uid', label: 'Task List ID', optional: false } - ] - end, - execute: lambda do |_connection, input| - get("/projects/#{input['project_uid']}/issue_lists/" \ - "#{input['issue_list_uid']}") - end, - output_fields: lambda do |object_definitions| - [ - { - name: "uid", label: "Task List ID" - }, - { - name: "project_uid", label: "Project ID" - }, - { - name: "name", label: "Name" - }, - { - name: "deleted", label: "Deleted", type: "boolean" - } - ] - end, - sample_output: lambda do |_connection, _input| - { - uid: "31f54967-4eac-4bd7-9b35-57f00a973a1d", - name: "QA/QC", - deleted: false, - project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" - } + hint: 'If your project is not in top 50, use project ID toggle.', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Enter project ID', + hint: 'Provide project ID. For example, 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } + } + ] + ) end }, - update_task_list: { - title: 'Update task list in a project', - description: 'Update task list'\ - ' in a PlanGrid project', - help: { - body: 'Update task list in a project action uses the ' \ - "Update Task List in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'update-issue-list', - learn_more_text: 'Update Task List in a Project API' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'issue_list_uid', label: 'Task List ID', optional: false }, - { name: 'name', optional: false } - ] - end, - execute: lambda do |_connection, input| - patch("/projects/#{input['project_uid']}/issue_lists/" \ - "#{input['issue_list_uid']}").payload({name: input.delete('name')}) - end, - output_fields: lambda do |object_definitions| - [ - { - name: "uid", label: "Task List ID" - }, - { - name: "project_uid", label: "Project ID" - }, - { - name: "name", label: "Name" - }, - { - name: "deleted", label: "Deleted", type: "boolean" - } - ] - end, - sample_output: lambda do |_connection, _input| - { - uid: "31f54967-4eac-4bd7-9b35-57f00a973a1d", - name: "QA/QC", - deleted: false, - project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" - } + + trigger_input: { + fields: lambda do |_connection, config_fields| + if config_fields['object'] != 'project' + [ + { + name: 'project_uid', optional: false, + label: 'Project', + control_type: 'select', pick_list: 'project_list', + hint: 'If your project is not in top 50, use project ID toggle.', + toggle_hint: 'Select project', + toggle_field: { + name: 'project_uid', + label: 'Project ID', + type: 'string', + control_type: 'text', + toggle_hint: 'Enter project ID', + hint: 'Provide project ID. For example, 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } + }, + { + name: 'output_schema', + control_type: 'schema-designer', + ngIf: 'input.object == "field_report"', + extends_schema: true, + label: 'PDF field values', + hint: 'Manually define the values expected of your PDF field values in the field report.', + optional: true + } + ] + else + [] + end end }, - create_task_list: { - title: 'Create task list in a project', - description: 'Create task list'\ - ' in a PlanGrid project', - help: { - body: 'Create task list in a project action uses the ' \ - "Create Task List in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'create-issue-list', - learn_more_text: 'Create Task List in a Project API' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'name', optional: false } - ] - end, - execute: lambda do |_connection, input| - post("/projects/#{input.delete('project_uid')}/issue_lists").payload(input) - end, - output_fields: lambda do |object_definitions| + + custom_action_input: { + fields: lambda do |_connection, config_fields| + input_schema = parse_json(config_fields.dig('input', 'schema') || '[]') + [ { - name: "uid", label: "Task List ID" - }, - { - name: "project_uid", label: "Project ID" - }, - { - name: "name", label: "Name" - }, - { - name: "deleted", label: "Deleted", type: "boolean" - } - ] - end, - sample_output: lambda do |_connection, _input| - { - uid: "31f54967-4eac-4bd7-9b35-57f00a973a1d", - name: "QA/QC", - deleted: false, - project_uid: "11a2b248-fbf5-439e-ab49-34adef8875f8" - } - end - }, - create_sheet_version: { - title: 'Create sheet version upload in a project', - description: 'Create sheet version upload'\ - ' in a PlanGrid project', - help: { - body: 'Create sheet version in a project action uses the ' \ - "Upload Version to a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'upload-version-to-project', - learn_more_text: 'Upload Version to a Project API' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', + name: 'path', optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'num_files', label: 'Number of PDFs', type: 'integer', optional: false }, - { name: 'version_name', label: 'Version Name', optional: false } - ] - end, - execute: lambda do |_connection, input| - post("/projects/#{input.delete('project_uid')}/sheets/uploads").payload(input) - end, - output_fields: lambda do |object_definitions| - [ - { - name: 'uid', label: 'Sheet Version Upload ID' - }, - { - name: 'complete_url', label: 'Upload Completion URL' - }, - { - name: 'status', + hint: 'Base URI is https://io.plangrid.com' \ + ' - path will be appended to this URI. ' \ + 'Use absolute URI to override this base URI.' }, - { - name: 'file_upload_requests', label: 'File Upload Requests', - type: 'array', of: 'object', properties: [ - { - name: 'uid', label: 'File Upload ID' - }, + ( + if %w[get delete].include?(config_fields['verb']) { - name: 'upload_status', label: 'File Upload Status' - }, + 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: 'url', label: 'File Upload URL' + 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: call('make_schema_builder_fields_sticky', + input_schema) + } + end + ) + ].compact } - ] + end + ), + { + name: 'output', + control_type: 'schema-designer', + sample_data_type: 'json_http', + extends_schema: true, + schema_neutral: true, + sticky: true } ] - end, - sample_output: lambda do |_connection, _input| - { - uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", - complete_url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720", - status: "incomplete", - file_upload_requests: [ - { - uid: "b278fcba-72f0-4161-bfdc-89d5bde4d5e7", - upload_status: "issued", - url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720/files/b278fcba-72f0-4161-bfdc-89d5bde4d5e7" - }, - { - uid: "727fca7d-385b-4476-b257-4b96c00e879b", - upload_status: "issued", - url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720/files/727fca7d-385b-4476-b257-4b96c00e879b" - } - ] - } end }, - upload_file_to_sheet_version: { - title: 'Upload file to sheet version in a project', - description: 'Upload file to sheet version'\ - ' in a PlanGrid project', - help: { - body: 'Upload file to sheet version in a project action uses the ' \ - "Upload File to Version in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'upload-file-to-version', - learn_more_text: 'Upload File to Version in a Project API' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'ver_upload_uid', label: 'Sheet Version Upload ID', optional: false }, - { name: 'file_upload_request_uid', label: 'File Upload ID', optional: false }, - { name: 'file_name', label: 'File Name', optional: false }, - { name: 'file_content', label: 'File Content', optional: false } - ] - end, - execute: lambda do |_connection, input| - file_content = input.delete('file_content') - project_uid = input.delete('project_uid') - file_upload_info = post("/projects/#{project_uid}/sheets/" \ - "uploads/#{input.delete('ver_upload_uid')}/" \ - "files/#{input.delete('file_upload_request_uid')}"). - headers('Content-Type': 'application/json'). - payload({file_name: input.delete('file_name')}) - url = file_upload_info&.dig('aws_post_form_arguments', 'action') - fields = file_upload_info&.dig('aws_post_form_arguments', 'fields') - # webhook_url = file_upload_info. - # dig('aws_post_form_arguments', 'webhook_url') - headers = fields.map { |o| { o['name'] => o['value'] } }.inject(:merge) - status = - post(url). - payload(key: headers['key'], - policy: headers['policy'], - signature: headers['signature'], - AWSAccessKeyId: headers['AWSAccessKeyId'], - 'content-type': headers['Content-Type'], - 'success_action_redirect': headers['success_action_redirect'], - 'x-amz-server-side-encryption': - headers['x-amz-server-side-encryption'], - 'x-amz-storage-class': headers['x-amz-storage-class'], - file: file_content). - request_format_multipart_form. - after_response do |_code, response, _response_headers| - response - end - end, - output_fields: lambda do |object_definitions| - - end, - sample_output: lambda do |_connection, _input| - end - }, - complete_version_upload: { - title: 'Complete sheet version upload to a project', - description: 'Complete sheet version upload '\ - ' to a PlanGrid project', - help: { - body: 'Complete sheet version upload to a project action uses the ' \ - "Complete Version Upload in a Project API.", - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'complete-version-upload-to-project', - learn_more_text: 'Complete Version Upload in a Project API' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', - control_type: 'select', - pick_list: 'project_list', - label: 'Project', - optional: false, - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - type: 'string', - control_type: 'text', - optional: false, - label: 'Project ID', - toggle_hint: 'Use project ID', - hint: 'Provide project ID e.g. ' \ - '0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { name: 'ver_upload_uid', label: 'Sheet Version Upload ID', optional: false } - ] - end, - execute: lambda do |_connection, input| - project_uid = input.delete('project_uid') - post("/projects/#{project_uid}/sheets/" \ - "uploads/#{input.delete('ver_upload_uid')}/completions")&.merge('project_uid' => project_uid) - end, - output_fields: lambda do |object_definitions| - [ - { - name: 'uid', label: 'Sheet Version ID' - }, - { - name: 'status', label: 'Status' - } - ] - end, - sample_output: lambda do |_connection, _input| - { - uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", - complete_url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/uploads/92cf7193-af0c-42fc-a3ab-7ef5149da720", - status: "complete" - } + custom_action_output: { + fields: lambda do |_connection, config_fields| + parse_json(config_fields['output'] || '[]') end } }, - triggers: { - new_updated_project: { - title: 'New or updated project', - description: 'New or updated project in'\ - ' PlanGrid', - help: { - body: 'New or updated project trigger uses the' \ - " List All Projects API.", - learn_more_url: 'https://developer.plangrid.com/docs/list-all-projects', - learn_more_text: 'List All Projects API' - }, - input_fields: lambda do |_object_definitions| - [ - { - 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| - updated_after = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 20 - skip = closure&.[]('skip') || 0 - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) - else - get('/projects'). - params(limit: limit, - skip: skip, - updated_after: updated_after) - end - closure = if (next_page_url = response['next_page_url']).present? - { 'skip' => skip + limit, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'updated_after' => now.to_time.utc.iso8601 } - end - { - events: response['data'] || [], - next_poll: closure, - can_poll_more: response['next_page_url'].present? - } - end, - dedup: lambda do |project| - "#{project['uid']}@#{project['updated_at']}" - end, - output_fields: lambda do |object_definitions| - object_definitions['project'] - end, - sample_output: lambda do |_connection, _input| - get('/projects')&.dig('data', 0) || {} - end - }, - new_updated_sheets: { - title: 'New or updated sheet in a project', - description: 'New or updated sheet in '\ - 'a PlanGrid project', + + actions: { + custom_action: { + description: "Custom action in Plangrid", help: { - body: 'New or updated sheet in a project trigger uses the' \ - " Retrieve Sheets in a Project" \ - ' API.', - learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ - 'sheets-in-a-project', - learn_more_text: 'Retrieve Sheets in a Project' + body: 'Build your own Plangrid action for any Plangrid REST endpoint.', + learn_more_url: 'https://developer.plangrid.com/docs/', + learn_more_text: 'The Plangrid API documentation' }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { - 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_uid = closure&.[]('project_uid') || input['project_uid'] - updated_after = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 5 - skip = closure&.[]('skip') || 0 - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) - else - get("/projects/#{input['project_uid']}/sheets"). - params(limit: limit, - skip: skip, - updated_after: updated_after) - end - closure = if (next_page_url = response['next_page_url']).present? - { 'skip' => skip + limit, - 'project_uid' => project_uid, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'project_uid' => project_uid, - 'updated_after' => now.to_time.utc.iso8601 } - end - sheets = response['data']&. - map { |o| o.merge('project_uid' => input['project_uid']) } - { - events: sheets || [], - next_poll: closure, - can_poll_more: response['next_page_url'].present? - } + + 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, - dedup: lambda do |sheet| - "#{sheet['uid']}@#{sheet['created_at']}" + + execute: lambda do |_connection, input| + error("#{input['verb']} not supported") if %w[get post patch delete].exclude?(input['verb']) + data = input.dig('input', 'data').presence || {} + case input['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['sheet'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/sheets")&.dig('data', 0) || {} + object_definitions['custom_action_output'] end }, - new_updated_documents: { - title: 'New or updated document in a project', - description: 'New or updated document in '\ - 'a PlanGrid project', - help: { - body: 'New or updated document in a project trigger uses the' \ - " Retrieve Documents in a Project" \ - ' API.', - learn_more_url: 'https://developer.plangrid.com/docs/retrieve-' \ - 'attachments-in-a-project', - learn_more_text: 'Retrieve Documents in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { - 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' - } - ] + + create_object: { + title: 'Create object', + description: lambda do |_, objects| + "Create #{objects['object']&.downcase || 'object'} in PlanGrid" end, - poll: lambda do |_connection, input, closure| - project_uid = closure&.[]('project_uid') || input['project_uid'] - updated_after = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 5 - skip = closure&.[]('skip') || 0 - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) - else - get("/projects/#{input['project_uid']}/attachments"). - params(limit: limit, - skip: skip, - updated_after: updated_after) - end - closure = if (next_page_url = response['next_page_url']).present? - { 'skip' => skip + limit, - 'project_uid' => project_uid, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'project_uid' => project_uid, - 'updated_after' => now.to_time.utc.iso8601 } - end - documents = response['data']&. - map { |o| o.merge('project_uid' => project_uid) } + help: "Create object in PlanGrid", + + config_fields: [ { - events: documents || [], - next_poll: closure, - can_poll_more: response['next_page_url'].present? + name: 'object', + optional: false, + label: 'Object', + control_type: 'select', + pick_list: 'create_object_list', + hint: 'Select the object from picklist.' } + ], + + input_fields: lambda do |object_definitions| + object_definitions['create_input_schema'] end, - dedup: lambda do |document| - "#{document['uid']}@#{document['created_at']}" + + execute: lambda do |_connection, input| + payload = + input.except('project_uid', 'object').each_with_object({}) do |(key, val), hash| + hash[key] = if %w[due_at sent_at].include?(key) + val.to_time.utc.iso8601 + elsif %w[sheet_uids assigned_to_uids].include?(key) + val.split(",") + else + val + end + end + case input['object'] + when 'project' + post('/projects').payload(payload). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + when 'sheet_packet', 'sheet_upload', 'user_invite' + path = input['object'].split("_") + post("/projects/#{input['project_uid']}/#{path.first.pluralize}/#{path.last.pluralize}").payload(payload). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + else + post("/projects/#{input['project_uid']}/#{input['object'].pluralize}").payload(payload). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + end.merge('project_uid' => input['project_uid']) end, + output_fields: lambda do |object_definitions| - object_definitions['document'] + object_definitions['get_output_schema'] end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/attachments")&.dig('data', 0) || {} + + sample_output: lambda do |_connection, input| + call(:get_sample_output, input['object'], input['project_uid'] || "") end }, - new_updated_task: { - title: 'New or updated task in a project', - description: 'New or updated task in a '\ - ' PlanGrid project', - help: { - body: 'New or updated task in a project trigger uses the' \ - " Retrieve Tasks " \ - ' in a Project API.', - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-issues-in-a-project', - learn_more_text: 'Retrieve Tasks in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { - 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' - } - ] + + update_object: { + title: 'Update object', + description: lambda do |_, objects| + "Update #{objects['object']&.downcase || 'object'} in PlanGrid" end, - poll: lambda do |_connection, input, closure| - project_uid = closure&.[]('project_uid') || input['project_uid'] - updated_after = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 10 - skip = closure&.[]('skip') || 0 - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) - else - get("/projects/#{input['project_uid']}/" \ - 'issues'). - params(limit: limit, - skip: skip, - include_annotationless: true, - updated_after: updated_after) - end - closure = if (next_page_url = response['next_page_url']).present? - { 'skip' => skip + limit, - 'project_uid' => project_uid, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'project_uid' => project_uid, - 'updated_after' => now.to_time.utc.iso8601 } - end - tasks = response['data']&. - map { |o| o.merge('project_uid' => input['project_uid']) } + help: "Update object in PlanGrid", + + config_fields: [ { - events: tasks || [], - next_poll: closure, - can_poll_more: response['next_page_url'].present? + name: 'object', + optional: false, + label: 'Object', + control_type: 'select', + pick_list: 'update_object_list', + hint: 'Select the object from picklist.' } + ], + + input_fields: lambda do |object_definitions| + object_definitions['update_input_schema'] end, - dedup: lambda do |task| - "#{task['uid']}@#{task['updated_at']}" + + execute: lambda do |_connection, input| + payload = + input.except('project_uid', 'uid', 'object').each_with_object({}) do |(key, val), hash| + hash[key] = %w[due_at sent_at].include?(key) ? val.to_time.utc.iso8601 : val + end + if input['object'] == 'project' + patch("/projects/#{input['project_uid']}").payload(payload). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + else + patch("/projects/#{input['project_uid']}/#{input['object'].pluralize}/#{input['uid']}").payload(payload). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + end.merge('project_uid' => input['project_uid']) end, + output_fields: lambda do |object_definitions| - object_definitions['task'] + object_definitions['get_output_schema'] end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/issues")&. - dig('data', 0) || {} + + sample_output: lambda do |_connection, input| + call(:get_sample_output, input['object'], input['project_uid'] || "") end }, - new_updated_annotations: { - title: 'New or updated annotation in a project', - description: 'New or updated annotation '\ - 'in a PlanGrid project', - help: { - body: 'New or updated annotation in project trigger uses the' \ - " Retrieve " \ - ' Annotations in a Project API.', - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-annotations-in-a-project', - learn_more_text: 'Retrieve Annotations in a Project' - }, - input_fields: lambda do |_object_definitions| + + get_object: { + title: 'Get object by ID', + description: lambda do |_, objects| + "Get #{objects['object']&.downcase || 'object'} in PlanGrid" + end, + help: "Get object by ID in PlanGrid", + + config_fields: [ + { + name: 'object', + optional: false, + label: 'Object', + control_type: 'select', + pick_list: 'get_objects', + toggle_hint: 'Select object', + hint: 'Select the object from picklist.' + } + ], + + input_fields: lambda do |object_definitions| [ - { name: 'project_uid', optional: false, + { + name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', label: 'Project', - control_type: 'select', pick_list: 'project_list', + optional: false, toggle_hint: 'Select project', + hint: 'If your project is not in top 50, use project ID toggle.', toggle_field: { name: 'project_uid', - label: 'Project ID', type: 'string', control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { - 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_uid = closure&.[]('project_uid') || input['project_uid'] - updated_after = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 10 - skip = closure&.[]('skip') || 0 - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) - else - get("/projects/#{input['project_uid']}/" \ - 'annotations'). - params(limit: limit, - skip: skip, - updated_after: updated_after) - end - closure = if (next_page_url = response['next_page_url']).present? - { 'skip' => skip + limit, - 'project_uid' => project_uid, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'project_uid' => project_uid, - 'updated_after' => now.to_time.utc.iso8601 } - end - annotations = response['data']&. - map { |o| o.merge('project_uid' => input['project_uid']) } - { - events: annotations || [], - next_poll: closure, - can_poll_more: response['next_page_url'].present? - } + optional: false, + label: 'Project ID', + toggle_hint: 'Enter project ID', + hint: 'Provide project ID. For example, 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } + }, + ].concat(object_definitions['get_input_schema']) end, - dedup: lambda do |annotation| - "#{annotation['uid']}@#{annotation['updated_at']}" + + execute: lambda do |_connection, input| + params = + input.except('project_uid', 'object').each_with_object({}) do |(key, val), hash| + hash[key] = %w[updated_after].include?(key) ? val.to_time.utc.iso8601 : val + end + case input['object'] + when 'project' + get("/projects/#{input['project_uid']}") + when 'sheet_packet' + get("/projects/#{input['project_uid']}/sheets/packets/#{input['uid']}") + else + get("/projects/#{input['project_uid']}/#{input['object'].pluralize}/#{input['uid']}") + end.merge('project_uid' => input['project_uid']) end, + output_fields: lambda do |object_definitions| - object_definitions['annotation'] + object_definitions['get_output_schema'] end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/annotations")&. - dig('data', 0) || {} + + sample_output: lambda do |_connection, input| + call(:get_sample_output, input['object'], input['project_uid'] || "") end }, - new_updated_photos: { - title: 'New or updated photo in a project', - description: 'New or updated photo '\ - 'in a PlanGrid project', - help: { - body: 'New or updated photo in a project trigger uses the' \ - " Retrieve " \ - ' photos in a Project API.', - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-photos-in-a-project', - learn_more_text: 'Retrieve Photos in a Project' - }, - input_fields: lambda do |_object_definitions| + + search_objects: { + title: 'Search objects', + description: lambda do |_, objects| + "Search #{objects['object']&.downcase&.pluralize || 'objects'} in PlanGrid" + end, + help: "Search objects in PlanGrid", + + config_fields: [ + { + name: 'object', + optional: false, + label: 'Object', + control_type: 'select', + pick_list: 'search_objects', + toggle_hint: 'Select object', + hint: 'Select the object from picklist.' + } + ], + + input_fields: lambda do |object_definitions| [ - { name: 'project_uid', optional: false, + { + name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', label: 'Project', - control_type: 'select', pick_list: 'project_list', + optional: false, toggle_hint: 'Select project', + hint: 'If your project is not in top 50, use project ID toggle.', toggle_field: { name: 'project_uid', - label: 'Project ID', type: 'string', control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { - 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' + optional: false, + label: 'Project ID', + toggle_hint: 'Enter project ID', + hint: 'Provide project ID. For example, 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } } - ] - end, - poll: lambda do |_connection, input, closure| - project_uid = closure&.[]('project_uid') || input['project_uid'] - updated_after = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 10 - skip = closure&.[]('skip') || 0 - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) - else - get("/projects/#{input['project_uid']}/" \ - 'photos'). - params(limit: limit, - skip: skip, - updated_after: updated_after) - end - closure = if (next_page_url = response['next_page_url']).present? - { 'skip' => skip + limit, - 'project_uid' => project_uid, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'project_uid' => project_uid, - 'updated_after' => now.to_time.utc.iso8601 } - end - photos = response['data']&. - map { |o| o.merge('project_uid' => input['project_uid']) } - { - events: photos || [], - next_poll: closure, - can_poll_more: response['next_page_url'].present? - } + ].concat(object_definitions['get_input_schema']) end, - dedup: lambda do |photo| - "#{photo['uid']}@#{photo['updated_at']}" + + execute: lambda do |_connection, input| + params = + input.except('project_uid', 'object', 'output_schema').each_with_object({}) do |(key, val), hash| + hash[key] = %w[updated_after].include?(key) ? val.to_time.utc.iso8601 : val + end + case input['object'] + when 'rfi_status' + { data: get("/projects/#{input['project_uid']}/rfis/statuses", params)['data'] } + when 'field_report' + results = get("/projects/#{input['project_uid']}/#{input['object'].pluralize}", params)['data'] + results.map do |field_report| + field_report.merge('pdf_form_fields' => field_report['pdf_form_values']&.map { |a| { a['name'] => a['value'] } }&.inject(:merge)) + end + { data: results } + else + { data: get("/projects/#{input['project_uid']}/#{input['object'].pluralize}", params)['data'] } + end.merge('project_uid' => input['project_uid']) end, + output_fields: lambda do |object_definitions| - object_definitions['photo'] - end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/photos")&. - dig('data', 0) || {} - end - }, - new_updated_snapshot: { - title: 'New or updated snapshot in a project', - description: 'New or updated snapshot '\ - 'in a PlanGrid project', - help: { - body: 'New or updated snapshot in a project trigger uses the' \ - " Retrieve " \ - ' Snapshots in a Project API.', - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-snapshots-in-a-project', - learn_more_text: 'Retrieve Snapshots in a Project' - }, - input_fields: lambda do |_object_definitions| [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, { - 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' + name: 'data', type: 'array', of: 'object', properties: object_definitions['get_output_schema'] } ] end, - poll: lambda do |_connection, input, closure| - project_uid = closure&.[]('project_uid') || input['project_uid'] - updated_after = closure&.[]('updated_after') || - (input['since'] || 1.hour.ago).to_time.utc.iso8601 - limit = 10 - skip = closure&.[]('skip') || 0 - response = if (next_page_url = closure&.[]('next_page_url')).present? - get(next_page_url) - else - get("/projects/#{input['project_uid']}/" \ - 'snapshots'). - params(limit: limit, - skip: skip, - updated_after: updated_after) - end - closure = if (next_page_url = response['next_page_url']).present? - { 'skip' => skip + limit, - 'project_uid' => project_uid, - 'next_page_url' => next_page_url } - else - { 'offset' => 0, - 'project_uid' => project_uid, - 'updated_after' => now.to_time.utc.iso8601 } - end - snapshots = response['data']&. - map { |o| o.merge('project_uid' => input['project_uid']) } + + sample_output: lambda do |_connection, input| + { "data" => Array.wrap(call(:get_sample_output, input['object'], input['project_uid'] || "")) } + end + }, + + upload_object: { + title: 'Upload object', + description: lambda do |_, objects| + "Upload #{objects['object']&.downcase || 'object'} in PlanGrid" + end, + help: "Upload object in PlanGrid", + + config_fields: [ { - events: snapshots || [], - next_poll: closure, - can_poll_more: response['next_page_url'].present? + name: 'object', + optional: false, + label: 'Object', + control_type: 'select', + pick_list: 'upload_object_list', + hint: 'Select the object from picklist.' } + ], + + input_fields: lambda do |object_definitions| + object_definitions['upload_input_schema'] end, - dedup: lambda do |annotation| - "#{annotation['uid']}@#{annotation['updated_at']}" + + execute: lambda do |_connection, input| + case input['object'] + when 'file_upload' + file_upload_info = post("/projects/#{input['project_uid']}/sheets/" \ + "uploads/#{input.delete('ver_upload_uid')}/" \ + "files/#{input.delete('file_upload_request_uid')}"). + headers('Content-Type': 'application/json'). + payload(file_name: input.delete('file_name')) + call(:get_upload_object, file_upload_info, input) + when 'photo', 'attachment' + file_upload_info = post("/projects/#{input['project_uid']}/#{input['object'].pluralize}/uploads"). + headers('Content-type': 'application/json'). + payload(input.except('project_uid', 'file_content', 'object')) + call(:get_upload_object, file_upload_info, input) + else + post("/projects/#{input['project_uid']}/sheets/uploads/#{input['ver_upload_uid']}/completions") + end end, + output_fields: lambda do |object_definitions| - object_definitions['snapshot'] + object_definitions['get_output_schema'] end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/snapshots")&. - dig('data', 0) || {} + + sample_output: lambda do |_connection, input| + call(:get_sample_output, input['object'], input['project_uid'] || "") end }, - new_updated_field_report: { - title: 'New or updated field report in a project', - description: 'New or updated field report '\ - 'in a PlanGrid project', - help: { - body: 'New or updated field report in a project trigger uses the' \ - " Retrieve " \ - 'Field Reports in a Project API.', - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-field-reports-in-a-project', - learn_more_text: 'Retrieve Field Reports in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { - 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' - } - ] + }, + + triggers: { + new_object: { + title: 'New object in PlanGrid', + description: lambda do |_, objects| + "New #{objects['object']&.downcase || 'object'} in PlanGrid" + end, + help: "Triggers when an object is created", + + config_fields: [ + { + name: 'object', + optional: false, + label: 'Object', + control_type: 'select', + pick_list: 'object_list', + hint: 'Select the object from picklist.' + } + ], + + input_fields: lambda do |object_definitions| + object_definitions['trigger_input'].concat( + [ + { + 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_uid = closure&.[]('project_uid') || input['project_uid'] updated_after = closure&.[]('updated_after') || (input['since'] || 1.hour.ago).to_time.utc.iso8601 limit = 10 skip = closure&.[]('skip') || 0 response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) + elsif input['object'] == 'project' + get("/projects").params(limit: limit, skip: skip, updated_after: updated_after) + elsif input['object'] == 'issue' + get("/projects/#{input['project_uid']}/#{input['object'].pluralize}"). + params(limit: limit, skip: skip, updated_after: updated_after, include_annotationless: true) + elsif input['object'] == 'field_report' + get("/projects/#{input['project_uid']}/#{input['object'].pluralize}"). + params(limit: limit, skip: skip, updated_after: updated_after) else - get("/projects/#{input['project_uid']}/" \ - 'field_reports'). - params(limit: limit, - skip: skip, - updated_after: updated_after, - sort_by: 'updated_at', - sort_order: 'asc') + get("/projects/#{input['project_uid']}/#{input['object'].pluralize}"). + params(limit: limit, skip: skip, updated_after: updated_after) end closure = if (next_page_url = response['next_page_url']).present? { 'skip' => skip + limit, - 'project_uid' => project_uid, 'next_page_url' => next_page_url } else - { 'offset' => 0, - 'project_uid' => project_uid, - 'updated_after' => now.to_time.utc.iso8601 } + { 'skip' => 0, + 'updated_after' => response['data']&. + last&.[]('created_at') || response['data']&.last&.[]('published_at') } + end + objects = if input['object'] == 'field_report' + response['data']&.map do |field_report| + field_report.merge('pdf_form_fields' => field_report['pdf_form_values']&.map { |a| { a['name'] => a['value'] } }&.inject(:merge), + 'project_uid' => input['project_uid']) + end + else + response['data']&.map { |o| o.merge('project_uid' => input['project_uid']) } end - - field_reports = response['data']&.map do |field_report| - field_report.merge({ - 'pdf_form_fields' => field_report['pdf_form_values'] - &.map { |a| { a['name'] => a['value'] } }&.inject(:merge) }) - end { - events: field_reports || [], + events: objects || [], next_poll: closure, can_poll_more: response['next_page_url'].present? } end, - dedup: lambda do |field_report| - "#{field_report['uid']}@#{field_report['updated_at']}" + dedup: lambda do |object| + object['uid'] end, output_fields: lambda do |object_definitions| - object_definitions['field_report'] + object_definitions['get_output_schema'] end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/field_reports")&. - dig('data', 0) || {} + sample_output: lambda do |_connection, input| + call(:get_sample_output, input['object'], input['project_uid'] || "") end }, - new_updated_rfi: { - title: 'New or updated RFI in a project', - description: 'New or updated RFI '\ - 'in a PlanGrid project', - help: { - body: 'New or updated RFI in a project trigger uses the' \ - " Retrieve " \ - ' RFIs in a Project API.', - learn_more_url: 'https://developer.plangrid.com/docs/' \ - 'retrieve-rfis-in-a-project', - learn_more_text: 'Retrieve RFIs in a Project' - }, - input_fields: lambda do |_object_definitions| - [ - { name: 'project_uid', optional: false, - label: 'Project', - control_type: 'select', pick_list: 'project_list', - toggle_hint: 'Select project', - toggle_field: { - name: 'project_uid', - label: 'Project ID', - type: 'string', - control_type: 'text', - toggle_hint: 'Use project ID', - hint: 'Use Project ID e.g. 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' - } }, - { - 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' - } - ] + + new_updated_object: { + title: 'New or updated object in PlanGrid', + description: lambda do |_, objects| + "New or updated #{objects['object']&.downcase || 'object'} in PlanGrid" + end, + help: "Triggers when an object is created or updated", + + config_fields: [ + { + name: 'object', + optional: false, + label: 'Object', + control_type: 'select', + pick_list: 'object_list_new', + hint: 'Select the object from picklist.' + } + ], + + input_fields: lambda do |object_definitions| + object_definitions['trigger_input'].concat( + [ + { + 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_uid = closure&.[]('project_uid') || input['project_uid'] updated_after = closure&.[]('updated_after') || (input['since'] || 1.hour.ago).to_time.utc.iso8601 limit = 10 skip = closure&.[]('skip') || 0 + update_time = Time.now.utc.iso8601 response = if (next_page_url = closure&.[]('next_page_url')).present? get(next_page_url) + elsif input['object'] == 'project' + get("/projects").params(limit: limit, skip: skip, updated_after: updated_after) + elsif input['object'] == 'issue' + get("/projects/#{input['project_uid']}/#{input['object'].pluralize}"). + params(limit: limit, skip: skip, updated_after: updated_after, include_annotationless: true) + elsif input['object'] == 'field_report' + get("/projects/#{input['project_uid']}/#{input['object'].pluralize}"). + params(limit: limit, skip: skip, updated_after: updated_after) else - get("/projects/#{input['project_uid']}/" \ - 'rfis'). - params(limit: limit, - skip: skip, - updated_after: updated_after) + get("/projects/#{input['project_uid']}/#{input['object'].pluralize}"). + params(limit: limit, skip: skip, updated_after: updated_after) end + object_update_time = ['annotation', 'sheet', 'attachment'].include? input['object'] closure = if (next_page_url = response['next_page_url']).present? { 'skip' => skip + limit, - 'project_uid' => project_uid, 'next_page_url' => next_page_url } else - { 'offset' => 0, - 'project_uid' => project_uid, - 'updated_after' => now.to_time.utc.iso8601 } + { 'skip' => 0, + 'updated_after' => object_update_time ? update_time : response['data']&.last&.[]('updated_at') } + end + project_hash = { 'project_uid' => input['project_uid'] } + project_hash["updated_after"] = (closure["updated_after"] || updated_after) if ['annotation', 'sheet', 'attachment'].include? input['object'] + objects = if input['object'] == 'field_report' + response['data']&.map do |field_report| + field_report.merge('pdf_form_fields' => field_report['pdf_form_values']&.map { |a| { a['name'] => a['value'] } }&.inject(:merge), + 'project_uid' => input['project_uid']) + end + else + response['data']&.map { |o| o.merge('project_uid' => input['project_uid']) } end - rfis = response['data']&. - map { |o| o.merge('project_uid' => input['project_uid']) } { - events: rfis || [], + events: objects || [], next_poll: closure, can_poll_more: response['next_page_url'].present? } end, - dedup: lambda do |rfi| - "#{rfi['uid']}@#{rfi['updated_at']}" + dedup: lambda do |object| + "#{object['uid']}@#{(object['updated_after'] || object['updated_at'])}" end, output_fields: lambda do |object_definitions| - object_definitions['rfi'] + object_definitions['get_output_schema'] end, - sample_output: lambda do |_connection, _input| - id = get('projects')&.[]('data', 0)&.[]('uid') - get("/projects/#{id}/rfis")&. - dig('data', 0) || {} + sample_output: lambda do |_connection, input| + call(:get_sample_output, input['object'], input['project_uid'] || "") end - } + }, + }, + + methods: { + get_sample_output: lambda do |object, project_uid| + case object + when 'project' + get('/projects')&.dig('data', 0) + when 'field_report' + results = get("/projects/#{project_uid}/field_reports").dig('data', 0)&.merge('project_uid' => project_uid) + when 'rfi_status' + get("/projects/#{project_uid}/rfis/statuses")&.dig('data', 0)&.merge('project_uid' => project_uid) + when 'user_invite' + get("/projects/#{project_uid}/users")&.dig('data', 0)&.merge('project_uid' => project_uid) + when 'sheet_packet' + { + "data" => [ + { + uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", + file_url: "https://packet-assets.plangrid.com/92cf7193-af0c-42fc-a3ab-7ef5149da720.pdf", + resource: { + uid: "92cf7193-af0c-42fc-a3ab-7ef5149da720", + url: "https://io.plangrid.com/projects/da48fcc3-7af1-4fd6-a083-70195468718a/sheets/" \ + "packets/92cf7193-af0c-42fc-a3ab-7ef5149da720" + }, + status: "incomplete" + } + ] + } + when 'sheet_upload' + { + "data" => [ + { + uid: "d050ed4d-425b-4cd2-a46a-1113be6ed37c", + complete_url: "https://io.plangrid.com/projects/5a77d1aa-44ef-4d0f-904a-839015d82dbb/sheets/uploads/d050ed4d-425b-4cd2-a46a-1113be6ed37c/completions", + status: "incomplete", + file_upload_requests: [ + { + uid: "cba96343-bfaf-4f95-805a-dd49169944c0", + upload_status: "issued", + url: "https://io.plangrid.com/projects/5a77d1aa-44ef-4d0f-904a-839015d82dbb/sheets/uploads/d050ed4d-425b-4cd2-a46a-1113be6ed37c/files/cba96343-bfaf-4f95-805a-dd49169944c0" + } + ] + } + ] + } + when 'version_upload' + { + "data" => [ + { + uid: "f23f1677-cb77-425f-bdd5-626a9fba8e83", + complete_url: "https://io.plangrid.com/projects/5a77d1aa-44ef-4d0f-904a-839015d82dbb/sheets/uploads/f23f1677-cb77-425f-bdd5-626a9fba8e83/completions", + status: "complete" + } + ] + } + else + get("/projects/#{project_uid}/#{object.pluralize}")&.dig('data', 0)&.merge('project_uid' => project_uid) + end + end, + + get_upload_object: lambda do |file_upload_info, input| + headers = file_upload_info&.dig('aws_post_form_arguments', 'fields')&. + each_with_object({}) do |obj, hash| + hash[obj['name']] = obj['value'] + end + post(file_upload_info&.dig('aws_post_form_arguments', 'action')). + payload(key: headers['key'], + policy: headers['policy'], + signature: headers['signature'], + AWSAccessKeyId: headers['AWSAccessKeyId'], + 'content-type': headers['Content-Type'], + 'success_action_redirect': headers['success_action_redirect'], + 'x-amz-server-side-encryption': + headers['x-amz-server-side-encryption'], + 'x-amz-storage-class': headers['x-amz-storage-class'], + file: input['file_content']). + request_format_multipart_form. + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + 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 }, + pick_lists: { + create_object_list: lambda do |_connection| + [["Project", "project"], ["Sheet Packet", "sheet_packet"], ["Task List", "issue_list"], ["Task", "issue"], ["RFI", "rfi"], + ["Sheet Version", "sheet_upload"], ["Invite User", "user_invite"]] + end, + + update_object_list: lambda do |_connection| + [["Project", "project"], ["Task List", "issue_list"], ["Task", "issue"], ["RFI", "rfi"], + ["Photo Metadata", "photo"]] + end, + + upload_object_list: lambda do |_connection| + [["Document", "attachment"], ["Photo", "photo"], ["File to sheet version", "file_upload"], + ["Complete version", "version_upload"]] + end, + + get_objects: lambda do |_connection| + [["Project", "project"], ["RFI", "rfi"], ["Task", "issue"], ["User", "user"], + ["Snapshot", "snapshot"], ["Sheet", "sheet"], ["Sheet Packet", "sheet_packet"], + ["Photo", "photo"], ["Document", "attachment"], ["Task_list", "issue_list"]] + end, + + search_objects: lambda do |_connection| + [["RFI Status", "rfi_status"], ["Role", "role"], ["Field Report", "field_report"]] + end, + + object_list: lambda do |_connection| + [["Project", "project"], ["Sheet", "sheet"], ["Document", "attachment"], ["Task", "issue"], ["RFI", "rfi"], + ["Annotation", "annotation"], ["Photo", "photo"], ["Snapshot", "snapshot"], ["Field Report", "field_report"]] + end, + + object_list_new: lambda do |_connection| + [["Project", "project"], ["Task", "issue"], ["RFI", "rfi"], ["Sheet", "sheet"], ["Field Report", "field_report"], + ["Document", "attachment"], ["Annotation", "annotation"]] + end, + project_list: lambda do |_connection| - get('projects')&.[]('data')&.pluck('name', 'uid') + get('/projects')&.[]('data')&.pluck('name', 'uid') end, + project_types: lambda do |_connection| ['general', 'manufacturing', 'power', 'water-sewer-waste', 'industrial-petroleum', 'transportation', 'hazardous-waste', 'telecom', 'education-k-12', 'education-higher', 'gov-federal', 'gov-state-local', 'other'].map { |type| [type.labelize, type] } end, + project_folders: lambda do |_connection, project_uid:| - if project_uid.length === 36 + if project_uid.length == 36 folders = get("/projects/#{project_uid}/attachments")['data']&. pluck('folder')&.uniq - if folders.size > 0 - folders&.map { |folder| [folder || 'Root', folder || ''] } - else - [['Root', '']] - end + folders.size > 0 ? folders&.map { |folder| [folder || 'Root', folder || ''] } : [['Root', '']] end end } From 4ecb5f702657ab8395a9a3c680e70cc14a302d45 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Mon, 16 Mar 2020 17:11:28 -0400 Subject: [PATCH 60/78] add `custom_items` object to field report output --- custom_connectors/oauth2/plangrid.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 75e486bd..5d0aab1c 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -498,6 +498,22 @@ } ] }, + { + name: 'custom_items', label: 'Custom Form Items', type: 'array', + of: 'object', properties: [ + { name: 'section_label', label: 'Section Name' }, + { name: 'item_label', label: 'Item Label' }, + { name: 'value_name', label: 'Value Name' }, + { name: 'notes' }, + { name: 'text_val', label: 'Text Value' }, + { name: 'choice_val', label: 'Choice Value' }, + { name: 'number_val', label: 'Number Value', type: 'number' }, + { name: 'date_val', label: 'Date Value', type: 'date_time' }, + { name: 'array_val', label: 'Array Value', type: 'array', + of: 'string' }, + { name: 'toggle_val', label: 'Toggle Value', type: 'integer' } + ] + }, { name: 'attachments', type: 'object', properties: [ { name: 'total_count', type: 'integer' }, From 0d1da5572a740ce6b0b0e1db85afff3992a2c789 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Tue, 17 Mar 2020 16:43:51 -0400 Subject: [PATCH 61/78] - add `field_report_template` to `search object` action - add `skip` and `limit` parameters for `field_report` input - add `total_count` and `next_page_url` to output for `search object` action --- custom_connectors/oauth2/plangrid.rb | 68 +++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 5d0aab1c..d2adcbef 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -77,6 +77,10 @@ hint: 'Only retrieve field reports between a date range ending with this date in UTC format.' }, { name: 'updated_after', label: 'Updated After', type: 'date_time', hint: 'Only retrieve field reports created/updated after specified UTC date and time.' }, + { name: 'skip', type: 'integer', + hint: 'Number of records to skip.' }, + { name: 'limit', type: 'integer', + hint: 'Number of records to retrieve.' }, { name: 'sort_by', label: 'Sort by column', control_type: 'select', pick_list: @@ -107,6 +111,17 @@ optional: true } ] + when 'field_report_template' + [ + { name: 'updated_after', label: 'Updated After', type: 'date_time', + hint: 'Only retrieve field reports created/updated after specified UTC date and time.' }, + { name: 'updated_before', label: 'Updated Before', type: 'date_time', + hint: 'Only retrieve field reports created/updated before specified UTC date and time.' }, + { name: 'skip', type: 'integer', + hint: 'Number of records to skip.' }, + { name: 'limit', type: 'integer', + hint: 'Number of records to retrieve.' } + ] when 'role', 'project' [] else @@ -558,6 +573,41 @@ ] } ] + when 'field_report_template' + [ + { name: 'uid', label: 'Field Report Template ID' }, + { name: 'name' }, + { name: 'field_reports', label: 'Field Reports', + type: 'object', properties: [ + { name: 'url' } + ] + }, + { name: 'is_pdf', label: 'Is PDF', type: 'boolean' }, + { name: 'pdf_url', label: 'PDF URL' }, + { name: 'template_type', label: 'Template Type' }, + { name: 'status' }, + { name: 'group_permissions', label: 'Group Permissions', + type: 'array', of: 'object', properties: [ + { name: 'permissions', type: 'array', of: 'string' }, + { name: 'role_name', label: 'Role Name' }, + { name: 'role_uid', label: 'Role UID' } + ] + }, + { name: 'user_permissions', label: 'User Permissions', + type: 'array', of: 'object', properties: [ + { name: 'permissions', type: 'array', of:' string' }, + { name: 'user_id', label: 'User UID'} + ] + }, + { name: 'created_by', label: 'Created By', type: 'object', + properties: [ + { name: 'email' }, + { name: 'uid' }, + { name: 'url' } + ] + }, + { name: 'updated_at', label: 'Updated At', type: 'date_time' } + ] when 'rfi' [ { name: 'uid', label: 'RFI ID' }, @@ -1691,15 +1741,18 @@ end case input['object'] when 'rfi_status' - { data: get("/projects/#{input['project_uid']}/rfis/statuses", params)['data'] } + response = get("/projects/#{input['project_uid']}/rfis/statuses", params) + { data: response['data'], total_count: response['total_count'], next_page_url: response['next_page_url'] } when 'field_report' - results = get("/projects/#{input['project_uid']}/#{input['object'].pluralize}", params)['data'] + response = get("/projects/#{input['project_uid']}/#{input['object'].pluralize}", params) + results = response['data'] results.map do |field_report| field_report.merge('pdf_form_fields' => field_report['pdf_form_values']&.map { |a| { a['name'] => a['value'] } }&.inject(:merge)) end - { data: results } + { data: results, total_count: response['total_count'], next_page_url: response['next_page_url'] } else - { data: get("/projects/#{input['project_uid']}/#{input['object'].pluralize}", params)['data'] } + response = get("/projects/#{input['project_uid']}/#{input['object'].pluralize}", params) + { data: response['data'], total_count: response['total_count'], next_page_url: response['next_page_url'] } end.merge('project_uid' => input['project_uid']) end, @@ -1707,7 +1760,9 @@ [ { name: 'data', type: 'array', of: 'object', properties: object_definitions['get_output_schema'] - } + }, + { name: 'total_count', label: 'Total Count', type: 'integer' }, + { name: 'next_page_url', label: 'Next Page URL' } ] end, @@ -2060,7 +2115,8 @@ end, search_objects: lambda do |_connection| - [["RFI Status", "rfi_status"], ["Role", "role"], ["Field Report", "field_report"]] + [["RFI Status", "rfi_status"], ["Role", "role"], ["Field Report", "field_report"], + ["Field Report Template", "field_report_template"]] end, object_list: lambda do |_connection| From 6acefd64699cd69a39873bfd0eb889725de21a75 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Tue, 17 Mar 2020 16:53:18 -0400 Subject: [PATCH 62/78] - add `template_uid` filter parameter when searching for field reports --- custom_connectors/oauth2/plangrid.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index d2adcbef..c0437de8 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -69,6 +69,8 @@ ] when 'field_report' [ + { name: 'template_uid', label: 'Field Report Template ID', + hint: 'Only retrieve field reports for the specified template ID.'}, { name: 'report_date_min', type: 'date', label: 'Report Start Date', hint: 'Only retrieve field reports between a date range starting with this date in UTC format.' }, From 5b94522f98597d899ad4ea06f25e71e282111d48 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 20:59:13 -0400 Subject: [PATCH 63/78] update picklist for `create object` action --- custom_connectors/oauth2/plangrid.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index c0437de8..6fa18f62 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2096,8 +2096,18 @@ pick_lists: { create_object_list: lambda do |_connection| - [["Project", "project"], ["Sheet Packet", "sheet_packet"], ["Task List", "issue_list"], ["Task", "issue"], ["RFI", "rfi"], - ["Sheet Version", "sheet_upload"], ["Invite User", "user_invite"]] + [ + ['Project', 'project'], + ['Field Report Export', 'field_reports/export'], + ['Invite User', 'user_invite'], + ['RFI', 'rfi'], + ['Task List', 'issue_list'], + ['Task', 'issue'], + ['Sheet Packet', 'sheet_packet'], + ['Sheet Version', 'sheet_upload'], + ['Submittal Item', 'submittals/item'], + ['Submittal Package', 'submittals/package'] + ] end, update_object_list: lambda do |_connection| From d7ba2d5b71d19cd5969f43e10c68351a8e48bdf8 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:02:51 -0400 Subject: [PATCH 64/78] add submittals package, submittals item, and field report exports to `create_input_schema` --- custom_connectors/oauth2/plangrid.rb | 123 +++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 6fa18f62..ad039d7f 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -996,6 +996,129 @@ { name: 'last_name' }, { name: 'language' } ] + when 'submittals/package' + [ + { name: 'name', optional: false, + hint: 'The name of the submittal package.' }, + { name: 'custom_id', optional: false, + hint: 'A custom ID for the submittal package.' }, + { name: 'item_uids', optional: false, label: 'Submittal Item IDs', + hint: 'The IDs of the specific submittal items to include in the submittal package. ' \ + 'Separate each item with a comma.' }, + { name: 'ball_in_court_status', + hint: "Reference to the role of the user from whom the next step is expected." \ + " Can be 'manager', 'submitter', or 'reviewer'." }, + { name: 'design_review_due_date', type: 'date', + hint: 'Due date for the design review.' }, + { name: 'file_group_uid', + hint: 'UID of the file group to associate with this submittal package.' }, + { name: 'general_contractor_review_due_date', type: 'date', + hint: "Due date of the general contractor's review." }, + { name: 'lead_time_days', type: 'integer', + hint: 'Number of days of lead time provided for this submittal package.' }, + { name: 'notes' }, + { name: 'required_on_job_date', type: 'date', + hint: 'The date when the submitted material is required on the job.' }, + { name: 'submittal_due_date', type: 'date', + hint: 'Due date for this submittal package.' }, + { name: 'managers', type: 'array', of: 'object', + hint: 'An array of objects describing users assigned the role of manager.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + }, + { name: 'reviewers', type: 'array', of: 'object', + hint: 'An array of objects describing users assigned the role of reviewer.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + }, + { name: 'watchers', type: 'array', of: 'object', + hint: 'An array of objects describing users assigned the role of watcher.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + } + ] + when 'submittals/item' + [ + { name: 'name', optional: false, + hint: 'Name of the submittal item.' }, + { name: 'description', + hint: 'Description of the submittal package.' }, + { name: 'package_uid', + hint: 'ID of the submittal package to which this item should be associated.' }, + { name: 'submittal_due_date', type: 'date', + hint: 'Date when the submittal is due.' }, + { name: 'lead_time_days', type: 'integer', + hint: 'The number of days of lead time provided for this submittal item.' }, + { name: 'required_on_job_date', type: 'date', + hint: 'The date when the submitted material is required on the job.' }, + { name: 'design_review_due_date', type: 'date', + hint: 'The date when the design review is due.' }, + { name: 'general_contractor_review_due_date', type: 'date', + hint: 'The date when the general contractor\'s review is due.' }, + { name: 'managers', type: 'array', of: 'object', + hint: 'An array of objects describing users assigned the role of manager.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + }, + { name: 'reviewers', type: 'array', of: 'object', + hint: 'A list describing users assigned the role of reviewer.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + }, + { name: 'submitters', type: 'array', of: 'object', + hint: 'A list describing users assigned the role of submitter.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + }, + { name: 'watchers', type: 'array', of: 'object', + hint: 'A list describing users assigned the role of watcher.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + } + ] + when 'field_reports/export' + [ + { name: 'field_report_uids', label: 'Field Report IDs', optional: false, + hint: 'A comma separated list of field report IDs.' }, + { + name: 'file_type', + control_type: 'select', + pick_list: 'field_report_export_file_type', + sticky: true, + hint: 'Select the file type of the export', + }, + { + name: 'timezone', + control_type: 'select', + pick_list: 'timezones', + sticky: true, + toggle_hint: 'Select timezone', + toggle_field: { + name: 'timezone', + type: 'string', + label: 'Timezone', + control_type: 'text', + optional: false, + toggle_hint: 'Enter timezone', + hint: 'A valid timezone. See fill list ' \ + 'here.' + } + } + ] else [] end.concat( From fc936a834956de547f7cc1638aa65795dccfa469 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:07:02 -0400 Subject: [PATCH 65/78] add field report export, submittal package, and submittal item to `get_output_schema` --- custom_connectors/oauth2/plangrid.rb | 139 +++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index ad039d7f..4da5d87d 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -610,6 +610,14 @@ }, { name: 'updated_at', label: 'Updated At', type: 'date_time' } ] + when 'field_reports/export' + [ + { name: 'uid', label: 'Export ID' }, + { name: 'project_uid', label: 'Project ID' }, + { name: 'status' }, + { name: 'file_url' }, + { name: 'resource_url' } + ] when 'rfi' [ { name: 'uid', label: 'RFI ID' }, @@ -793,6 +801,137 @@ { name: "project_uid", label: "Project ID" }, { name: 'status', label: 'Status' } ] + when 'submittals/package' + [ + { name: 'uid', label: 'Submittal Package ID' }, + { name: 'project_uid', label: 'Project ID' }, + { name: 'name' }, + { name: 'spec_section' }, + { name: 'spec_section_name' }, + { name: 'custom_id' }, + { name: 'version' }, + { name: 'ball_in_court_status' }, + { name: 'lead_time_days', type: 'integer' }, + { name: 'submittals_due_date', type: 'date_time' }, + { name: 'required_on_job_date', type: 'date_time' }, + { name: 'transmission_status' }, + { name: 'is_voided', type: 'boolean' }, + { name: 'items', type: 'object', properties: [ + { name: 'uids', type: 'array', of: 'string' }, + { name: 'url' }, + { name: 'total_count', type: 'integer'} + ]}, + { name: 'visible_file_group_uid' }, + { name: 'design_review_due_date', type: 'date_time' }, + { name: 'general_contractor_review_due_date', type: 'date_time' }, + { name: 'latest_review', type: 'object', properties: [ + { name: 'uid', label: 'Review ID' }, + { name: 'created_at', type: 'date_time' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'file_group_uid' }, + { name: 'is_official_review' }, + { name: 'package_version' }, + { name: 'review_response_uid' }, + { name: 'reviewed_by', type: 'object', properties: [ + { name: 'type' }, + { name: 'uid' }, + { name: 'url' } + ]} + ]}, + { name: 'latest_review_response_uid' }, + { name: 'received_from_design_at', type: 'date_time' }, + { name: 'sent_to_design_at', type: 'date_time' }, + { name: 'received_from_sub_at', type: 'date_time' }, + { name: 'returned_to_sub_at', type: 'date_time' }, + { name: 'managers', type: 'array', of: 'object', properties: [ + { name: 'type' }, + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'reviewers', type: 'array', of: 'object', properties: [ + { name: 'type' }, + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'submitters', type: 'array', of: 'object', properties: [ + { name: 'type' }, + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'unioned_watchers', type: 'array', of: 'object', properties: [ + { name: 'type' }, + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'watchers', type: 'array', of: 'object', properties: [ + { name: 'type' }, + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'created_at', type: 'date_time' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'published_at', type: 'date_time' }, + { name: 'updated_at', type: 'date_time' }, + { name: 'updated_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' } + ]} + ] + when 'submittals/item' + [ + { name: 'uid', label: 'Submittal Item ID' }, + { name: 'project_uid', label: 'Project ID' }, + { name: 'name' }, + { name: 'description' }, + { name: 'spec_bullet' }, + { name: 'spec_doc' }, + { name: 'spec_heading' }, + { name: 'spec_page' }, + { name: 'spec_section' }, + { name: 'spec_section_name' }, + { name: 'spec_subsection_name' }, + { name: 'lead_time_days', type:'integer' }, + { name: 'required_on_job_date', type: 'date_time' }, + { name: 'submittal_due_date', type: 'date_time' }, + { name: 'submittals_type' }, + { name: 'package', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'design_review_due_date', type: 'date_time' }, + { name: 'general_contractor_review_due_date', type: 'date_time' }, + { name: 'reviewers', type: 'array', of: 'object', properties: [ + { name: 'type' }, + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'managers', type: 'array', of: 'object', properties: [ + { name: 'type' }, + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'submitters', type: 'array', of: 'object', properties: [ + { name: 'type' }, + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'watchers', type: 'array', of: 'object', properties: [ + { name: 'type' }, + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'created_at' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' } + ]} + ] end end }, From d5071ff077455ac91bffc1f8278264e5857b23c6 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:11:19 -0400 Subject: [PATCH 66/78] update `create_object` action to include field report exports, submittal package, and submittal item --- custom_connectors/oauth2/plangrid.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 4da5d87d..947fee53 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1802,6 +1802,14 @@ end, execute: lambda do |_connection, input| + if input['object'] == 'submittals/package' + input['item_uids'] = input['item_uids'].split(',') + end + + if input['object'] == 'field_reports/export' + input['field_report_uids'] = input['field_report_uids'].split(',') + end + payload = input.except('project_uid', 'object').each_with_object({}) do |(key, val), hash| hash[key] = if %w[due_at sent_at].include?(key) @@ -1824,6 +1832,12 @@ after_error_response(/.*/) do |_code, body, _header, message| error("#{message}: #{body}") end + + when 'field_reports/export' + post("/projects/#{input['project_uid']}/field_reports/export").payload(payload). + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end else post("/projects/#{input['project_uid']}/#{input['object'].pluralize}").payload(payload). after_error_response(/.*/) do |_code, body, _header, message| From 77a2c20722c8a668c7fa8acffae58c3b72cf00c8 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:14:24 -0400 Subject: [PATCH 67/78] add `field_report_export_file_type` and `timezones` pick list for field report export --- custom_connectors/oauth2/plangrid.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 947fee53..d99e088c 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2434,6 +2434,24 @@ pluck('folder')&.uniq folders.size > 0 ? folders&.map { |folder| [folder || 'Root', folder || ''] } : [['Root', '']] end + end, + + field_report_export_file_type: lambda do |_connection| + [ + [ 'PDF', 'pdf' ], + [ 'XLSL', 'xlsx' ] + ] + end, + + timezones: lambda do |_connection| + [ + ['America/Los_Angeles','America/Los_Angeles'], + ['America/Denver','America/Denver'], + ['America/Phoenix','America/Phoenix'], + ['America/Chicago','America/Chicago'], + ['America/Mexico_City','America/Mexico_City'], + ['America/New_York','America/New_York'] + ] end } } From 8fee3bb4fe7f8ceb827f6fb9141103f6d79c9d8d Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:19:42 -0400 Subject: [PATCH 68/78] add submittals package and submittals item to `update_object` picklist and `update_object_input` schema --- custom_connectors/oauth2/plangrid.rb | 102 ++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 3 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index d99e088c..58abb1eb 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1473,6 +1473,99 @@ { name: 'title', label: 'Photo title', hint: 'New title of the photo', sticky: true } ] + when 'submittals/package' + [ + { name: 'name', + hint: 'The name of the submittal package.' }, + { name: 'custom_id', + hint: 'A custom ID for the submittal package.' }, + { name: 'item_uids', label: 'Submittal Item IDs', type: 'array', + hint: 'The UIDs of the specific items to include in the submittal package.' }, + { name: 'ball_in_court_status', + hint: 'Reference to the role of the user from whom the next step is expected.' \ + ' Can be \'manager\', \'submitter\', or \'reviewer\'.' }, + { name: 'design_review_due_date', type: 'date', + hint: 'Due date for the design review.' }, + { name: 'file_group_uid', + hint: 'UID of the file group to associate with this submittal package.' }, + { name: 'general_contractor_review_due_date', type: 'date', + hint: 'Due date of the general contractor\'s review.' }, + { name: 'lead_time_days', type: 'integer', + hint: 'Number of days of lead time provided for this submittal package.' }, + { name: 'notes' }, + { name: 'required_on_job_date', type: 'date', + hint: 'The date when the submitted material is required on the job.' }, + { name: 'submittal_due_date', type: 'date', + hint: 'Due date for this submittal package.' }, + { name: 'managers', type: 'array', of: 'object', + hint: 'An array of objects describing users assigned the role of manager.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + }, + { name: 'reviewers', type: 'array', of: 'object', + hint: 'An array of objects describing users assigned the role of reviewer.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + }, + { name: 'watchers', type: 'array', of: 'object', + hint: 'An array of objects describing users assigned the role of watcher.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + } + ] + when 'submittals/item' + [ + { name: 'name', + hint: 'Name of the submittal item.' }, + { name: 'description', + hint: 'Description of the submittal package.' }, + { name: 'package_uid', label: 'Submittal Package ID', + hint: 'ID of the submittal package to which this item should be associated.' }, + { name: 'submittal_due_date', type: 'date', + hint: 'Date when the submittal is due.' }, + { name: 'lead_time_days', type: 'integer', + hint: 'The number of days of lead time provided for this submittal item.' }, + { name: 'required_on_job_date', type: 'date', + hint: 'The date when the submitted material is required on the job.' }, + { name: 'design_review_due_date', type: 'date', + hint: 'The date when the design review is due.' }, + { name: 'general_contractor_review_due_date', type: 'date', + hint: 'The date when the general contractor\'s review is due.' }, + { name: 'managers', type: 'array', of: 'object', + hint: 'An array of objects describing users assigned the role of manager.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + }, + { name: 'reviewers', type: 'array', of: 'object', + hint: 'A list describing users assigned the role of reviewer.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + }, + { name: 'submitters', type: 'array', of: 'object', + hint: 'A list describing users assigned the role of submitter.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + }, + { name: 'watchers', type: 'array', of: 'object', + hint: 'A list describing users assigned the role of watcher.', + properties: [ + { name: 'type', hint: 'Can be `user` or `group`.' }, + { name: 'uid', hint: 'ID of either the user or group' } + ] + } + ] else [] end.concat( @@ -1497,10 +1590,13 @@ } ] ).concat( - if config_fields['object'] != 'project' - [{ name: "uid", label: "#{config_fields['object'].labelize} ID", optional: false }] + case config_fields['object'] + when 'submittals/package' + [{ name: 'uid', label: 'Submittal Package ID', optional: false }] + when 'submittals/item' + [{ name: 'uid', label: 'Submittal Item ID', optional: false }] else - [] + [{ name: 'uid', label: "#{config_fields['object'].labelize} ID", optional: false }] end ) end From f78e88e0491471b8735fbc9172daabab8e37a031 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:25:38 -0400 Subject: [PATCH 69/78] update `get_object` action to include field report exports, submittal item, submittal package, submittal file group, and submittal review status --- custom_connectors/oauth2/plangrid.rb | 72 ++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 58abb1eb..a2f785a7 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -124,8 +124,22 @@ { name: 'limit', type: 'integer', hint: 'Number of records to retrieve.' } ] + when 'field_reports/export' + [{ name: 'uid', label: 'Export ID', optional: false }] when 'role', 'project' [] + when 'submittals/item' + [{ name: 'uids', label: 'Submittal Item ID', optional: false }] + when 'submittals/package' + [{ name: 'uid', label: 'Submittal Package ID', optional: false, + hint: 'ID can be found at the end of the url.' }] + when 'submittals_file_group' + [ + { name: 'uid', label: 'Submittal Package ID', optional: false, + hint: 'ID can be found at the end of the url.' }, + { name: 'created_after', type: 'date_time', + hint: 'Only return file groups created after the specified date.' } + ] else [{ name: "uid", label: "#{config_fields['object'].labelize} ID", optional: false, hint: 'ID can be found at the end of the url.' }] @@ -932,6 +946,51 @@ { name: 'url' } ]} ] + when 'submittals_file_group' + [ + { name: 'package_uid', label: 'Submittal Package ID' }, + { name: 'project_uid', label: 'Project ID' }, + { name: 'data', label: 'File Groups', + type: 'array', of: 'object', properties: [ + { name: 'uid', label: 'File Group ID' }, + { name: 'files', type: 'array', of: 'object', properties: [ + { name: 'document_uid', label: 'Document ID' }, + { name: 'name' }, + { name: 'url' }, + { name: 'created_at', type: 'date_time' }, + { name: 'file_group_uid' } + ]}, + { name: 'package', type: 'object', properties: [ + { name: 'uid' }, + { name: 'url' } + ]}, + { name: 'upload_completed', type: 'boolean'} + ] + }, + { name: 'total_count' }, + { name: 'next_page_url' } + ] + when 'submittals_review_status' + [ + { name: 'package_uid', label: 'Submittal Package ID' }, + { name: 'project_uid', label: 'Project ID' }, + { name: 'data', label: 'Review Status', + type: 'array', of: 'object', properties: [ + { name: 'uid', label: 'Review ID' }, + { name: 'review_response_uid', label: 'Review Response ID' }, + { name: 'is_official_review', type: 'boolean' }, + { name: 'package_version', type: 'integer' }, + { name: 'file_group_uid', label: 'File Group ID' }, + { name: 'created_at' }, + { name: 'created_by', type: 'object', properties: [ + { name: 'uid', label: 'User ID' }, + { name: 'url' } + ]} + ] + }, + { name: 'total_count' }, + { name: 'next_page_url' } + ] end end }, @@ -2050,8 +2109,21 @@ case input['object'] when 'project' get("/projects/#{input['project_uid']}") + when 'field_reports/export' + get("/projects/#{input['project_uid']}/field_reports/export/#{input['uid']}") when 'sheet_packet' get("/projects/#{input['project_uid']}/sheets/packets/#{input['uid']}") + when 'submittals/item' + get("/projects/#{input['project_uid']}/submittals/items?uids=#{input['uids']}").dig('data',0) + when 'submittals_file_group' + get("/projects/#{input['project_uid']}/submittals/packages/#{input['uid']}/file_groups") + .merge('package_uid' => input['uid']) + when 'submittals_history' + get("/projects/#{input['project_uid']}/submittals/packages/#{input['uid']}/history") + .merge('package_uid' => input['uid']) + when 'submittals_review_status' + get("/projects/#{input['project_uid']}/submittals/packages/#{input['uid']}/reviews") + .merge('package_uid' => input['uid']) else get("/projects/#{input['project_uid']}/#{input['object'].pluralize}/#{input['uid']}") end.merge('project_uid' => input['project_uid']) From 1d253bbc16fdf4e7e37deec5003c68c05bf6deeb Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:30:28 -0400 Subject: [PATCH 70/78] add `download object` action for documents, field report exports, and sheet packets --- custom_connectors/oauth2/plangrid.rb | 91 ++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index a2f785a7..015628d6 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -1749,6 +1749,20 @@ end }, + download_input_schema: { + fields: lambda do |_connection, config_fields| + case config_fields['object'] + when 'field_reports/export' + [{ name: 'uid', label: 'Export ID', optional: false }] + when 'sheets/packet' + [{ name: 'uid', label: "Sheet Packet ID", optional: false, + hint: 'Ensure the status of the sheet packet export is `complete` before downloading.' }] + else + [{ name: 'uid', label: "#{config_fields['object'].labelize} ID", optional: false }] + end + end + }, + trigger_input: { fields: lambda do |_connection, config_fields| if config_fields['object'] != 'project' @@ -2266,6 +2280,75 @@ call(:get_sample_output, input['object'], input['project_uid'] || "") end }, + + download_object: { + title: 'Download object', + description: lambda do |_, objects| + "Download #{objects['object']&.downcase || 'object'} in PlanGrid" + end, + help: "Download object in PlanGrid", + + config_fields: [ + { + name: 'object', + optional: false, + label: 'Object', + control_type: 'select', + pick_list: 'download_object_list', + toggle_hint: 'Select object', + hint: 'Select the object from picklist.' + } + ], + + input_fields: lambda do |object_definitions| + [ + { + name: 'project_uid', + control_type: 'select', + pick_list: 'project_list', + label: 'Project', + optional: false, + toggle_hint: 'Select project', + hint: 'If your project is not in top 50, use project ID toggle.', + toggle_field: { + name: 'project_uid', + type: 'string', + control_type: 'text', + optional: false, + label: 'Project ID', + toggle_hint: 'Enter project ID', + hint: 'Provide project ID. For example, 0bbb5bdb-3f87-4b46-9975-90e797ee9ff9' + } + }, + ].concat(object_definitions['download_input_schema']) + end, + + execute: lambda do |_connection, input| + case input['object'] + when 'field_reports/export' + record = get("/projects/#{input['project_uid']}/field_reports/export/#{input['uid']}") + file_content = get(record['url'] || record['file_url']). + response_format_raw. + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + { content: file_content } + else + record = get("/projects/#{input['project_uid']}/#{input['object'].pluralize}/#{input['uid']}") + file_content = get(record['url'] || record['file_url']). + response_format_raw. + after_error_response(/.*/) do |_code, body, _header, message| + error("#{message}: #{body}") + end + { content: file_content } + end + end, + + output_fields: lambda do |object_definitions| + [ + { name: 'content', label: 'File Contents' } + ] + end }, triggers: { @@ -2595,6 +2678,14 @@ 'telecom', 'education-k-12', 'education-higher', 'gov-federal', 'gov-state-local', 'other'].map { |type| [type.labelize, type] } end, + + download_object_list: lambda do |_connection| + [ + ['Document', 'attachment'], + ['Field Report Export', 'field_reports/export'], + ['Sheet Packet', 'sheets/packet'] + ] + end, project_folders: lambda do |_connection, project_uid:| if project_uid.length == 36 From 355a55822a1218998f64636eeea9b784753414a3 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:32:40 -0400 Subject: [PATCH 71/78] update `update_object_list` and `upload_object_list` picklists --- custom_connectors/oauth2/plangrid.rb | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 015628d6..9e99c58b 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2638,13 +2638,24 @@ end, update_object_list: lambda do |_connection| - [["Project", "project"], ["Task List", "issue_list"], ["Task", "issue"], ["RFI", "rfi"], - ["Photo Metadata", "photo"]] + [ + ['Project', 'project'], + ['Photo', 'photo'], + ['RFI', 'rfi'], + ['Task List', 'issue_list'], + ['Task', 'issue'], + ['Submittal Package', 'submittals/package'], + ['Submittal Item', 'submittals/item'] + ] end, upload_object_list: lambda do |_connection| - [["Document", "attachment"], ["Photo", "photo"], ["File to sheet version", "file_upload"], - ["Complete version", "version_upload"]] + [ + ['Document', 'attachment'], + ['Photo', 'photo'], + ['File to Sheet Version', 'file_upload'], + ['Complete Sheet Version', 'version_upload'] + ] end, get_objects: lambda do |_connection| From 152f6665bce86ac423c6e24303066cce9d2c54b0 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:35:26 -0400 Subject: [PATCH 72/78] add field report templates to `search_object` action --- custom_connectors/oauth2/plangrid.rb | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 9e99c58b..12309ae4 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2219,7 +2219,7 @@ output_fields: lambda do |object_definitions| [ { - name: 'data', type: 'array', of: 'object', properties: object_definitions['get_output_schema'] + name: 'data', label: 'Results', type: 'array', of: 'object', properties: object_definitions['get_output_schema'] }, { name: 'total_count', label: 'Total Count', type: 'integer' }, { name: 'next_page_url', label: 'Next Page URL' } @@ -2665,8 +2665,20 @@ end, search_objects: lambda do |_connection| - [["RFI Status", "rfi_status"], ["Role", "role"], ["Field Report", "field_report"], - ["Field Report Template", "field_report_template"]] + [ + ['Field Report', 'field_report'], + ['Field Report Template', 'field_report_template'], + ['RFI Status', 'rfi_status'], + ['Role', 'role'] + ] + end, + + download_object_list: lambda do |_connection| + [ + ['Document', 'attachment'], + ['Field Report Export', 'field_reports/export'], + ['Sheet Packet', 'sheets/packet'] + ] end, object_list: lambda do |_connection| From 1504f03655a70b1ac76c0b928189a7b6052c5a83 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:35:59 -0400 Subject: [PATCH 73/78] add missing closing curly bracket to `download object` action --- custom_connectors/oauth2/plangrid.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 12309ae4..2373dcf2 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2349,6 +2349,7 @@ { name: 'content', label: 'File Contents' } ] end + } }, triggers: { From 36ff76513b0047590ed24491caa5253914b30be2 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:40:03 -0400 Subject: [PATCH 74/78] adjust `new or updated object` trigger for documents to use the `/documents`/ endpoint --- custom_connectors/oauth2/plangrid.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 2373dcf2..5bed6467 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2487,6 +2487,9 @@ elsif input['object'] == 'field_report' get("/projects/#{input['project_uid']}/#{input['object'].pluralize}"). params(limit: limit, skip: skip, updated_after: updated_after) + elsif input['object'] == 'attachment' + get("/projects/#{input['project_uid']}/documents"). + params(limit: limit, skip: skip, updated_after: updated_after) else get("/projects/#{input['project_uid']}/#{input['object'].pluralize}"). params(limit: limit, skip: skip, updated_after: updated_after) @@ -2506,6 +2509,10 @@ field_report.merge('pdf_form_fields' => field_report['pdf_form_values']&.map { |a| { a['name'] => a['value'] } }&.inject(:merge), 'project_uid' => input['project_uid']) end + elsif input['object'] == 'attachment' + response['data'].select { |o| o['type'] == 'file' }&.map do |document| + get("/projects/#{input['project_uid']}/attachments/#{document['uid']}") + end&.map { |o| o.merge('project_uid' => input['project_uid']) } else response['data']&.map { |o| o.merge('project_uid' => input['project_uid']) } end From 71bb491546c0e23637edb6a9fe91e46953ebb880 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:41:28 -0400 Subject: [PATCH 75/78] add `submittal item` to sample output method --- custom_connectors/oauth2/plangrid.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 5bed6467..15eafaaf 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2587,6 +2587,8 @@ } ] } + when 'submittals/items' + get("/projects/#{project_uid}/submittals/items")&.dig('data', 0)&.merge('project_uid' => project_uid) else get("/projects/#{project_uid}/#{object.pluralize}")&.dig('data', 0)&.merge('project_uid' => project_uid) end From c46bf997ca89d8e4bb477165e7fc207e8fc7ebab Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Sat, 9 May 2020 21:43:39 -0400 Subject: [PATCH 76/78] update `field_report_template` output to include project ID and cadence --- custom_connectors/oauth2/plangrid.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 15eafaaf..05b6f73f 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -592,12 +592,14 @@ when 'field_report_template' [ { name: 'uid', label: 'Field Report Template ID' }, + { name: 'project_uid', label: 'Project ID' }, { name: 'name' }, { name: 'field_reports', label: 'Field Reports', type: 'object', properties: [ { name: 'url' } ] }, + { name: 'cadence' }, { name: 'is_pdf', label: 'Is PDF', type: 'boolean' }, { name: 'pdf_url', label: 'PDF URL' }, { name: 'template_type', label: 'Template Type' }, From bc376ebb86ed75fe9a16b89aa7eb89c1706c1668 Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Tue, 12 May 2020 11:55:00 -0400 Subject: [PATCH 77/78] - remove `lead_time_days` from submittal objects - update label for `design_review_due_date` to `Reviewer due date` - update label for `general_contractor_due_date to `Manager due date` --- custom_connectors/oauth2/plangrid.rb | 53 ++++++++++++---------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 05b6f73f..205e842b 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -827,7 +827,6 @@ { name: 'custom_id' }, { name: 'version' }, { name: 'ball_in_court_status' }, - { name: 'lead_time_days', type: 'integer' }, { name: 'submittals_due_date', type: 'date_time' }, { name: 'required_on_job_date', type: 'date_time' }, { name: 'transmission_status' }, @@ -838,8 +837,8 @@ { name: 'total_count', type: 'integer'} ]}, { name: 'visible_file_group_uid' }, - { name: 'design_review_due_date', type: 'date_time' }, - { name: 'general_contractor_review_due_date', type: 'date_time' }, + { name: 'design_review_due_date', type: 'date_time', label: 'Reviewer due date' }, + { name: 'general_contractor_review_due_date', type: 'date_time', label: 'Manager due date' }, { name: 'latest_review', type: 'object', properties: [ { name: 'uid', label: 'Review ID' }, { name: 'created_at', type: 'date_time' }, @@ -858,8 +857,8 @@ ]} ]}, { name: 'latest_review_response_uid' }, - { name: 'received_from_design_at', type: 'date_time' }, - { name: 'sent_to_design_at', type: 'date_time' }, + { name: 'received_from_design_at', type: 'date_time', label: 'Received from reviewer at' }, + { name: 'sent_to_design_at', type: 'date_time', label: 'Sent to reviewer at' }, { name: 'received_from_sub_at', type: 'date_time' }, { name: 'returned_to_sub_at', type: 'date_time' }, { name: 'managers', type: 'array', of: 'object', properties: [ @@ -920,8 +919,8 @@ { name: 'uid' }, { name: 'url' } ]}, - { name: 'design_review_due_date', type: 'date_time' }, - { name: 'general_contractor_review_due_date', type: 'date_time' }, + { name: 'design_review_due_date', type: 'date_time', label: 'Reviewer due date' }, + { name: 'general_contractor_review_due_date', type: 'date_time', label: 'Manager due date' }, { name: 'reviewers', type: 'array', of: 'object', properties: [ { name: 'type' }, { name: 'uid' }, @@ -1208,14 +1207,12 @@ { name: 'ball_in_court_status', hint: "Reference to the role of the user from whom the next step is expected." \ " Can be 'manager', 'submitter', or 'reviewer'." }, - { name: 'design_review_due_date', type: 'date', - hint: 'Due date for the design review.' }, + { name: 'design_review_due_date', type: 'date', label: 'Reviewer due date', + hint: 'The date when the review from reviewers\' is due.' }, { name: 'file_group_uid', hint: 'UID of the file group to associate with this submittal package.' }, - { name: 'general_contractor_review_due_date', type: 'date', - hint: "Due date of the general contractor's review." }, - { name: 'lead_time_days', type: 'integer', - hint: 'Number of days of lead time provided for this submittal package.' }, + { name: 'general_contractor_review_due_date', type: 'date', label: 'Manager due date', + hint: 'The date when the review from manager\'s is due.' }, { name: 'notes' }, { name: 'required_on_job_date', type: 'date', hint: 'The date when the submitted material is required on the job.' }, @@ -1253,14 +1250,12 @@ hint: 'ID of the submittal package to which this item should be associated.' }, { name: 'submittal_due_date', type: 'date', hint: 'Date when the submittal is due.' }, - { name: 'lead_time_days', type: 'integer', - hint: 'The number of days of lead time provided for this submittal item.' }, { name: 'required_on_job_date', type: 'date', hint: 'The date when the submitted material is required on the job.' }, - { name: 'design_review_due_date', type: 'date', - hint: 'The date when the design review is due.' }, - { name: 'general_contractor_review_due_date', type: 'date', - hint: 'The date when the general contractor\'s review is due.' }, + { name: 'design_review_due_date', type: 'date', label: 'Reviewer due date', + hint: 'The date when the review from reviewers\' is due.' }, + { name: 'general_contractor_review_due_date', type: 'date', label: 'Manager due date', + hint: 'The date when the review from manager\'s is due.' }, { name: 'managers', type: 'array', of: 'object', hint: 'An array of objects describing users assigned the role of manager.', properties: [ @@ -1545,14 +1540,12 @@ { name: 'ball_in_court_status', hint: 'Reference to the role of the user from whom the next step is expected.' \ ' Can be \'manager\', \'submitter\', or \'reviewer\'.' }, - { name: 'design_review_due_date', type: 'date', - hint: 'Due date for the design review.' }, + { name: 'design_review_due_date', type: 'date', label: 'Reviewer due date', + hint: 'The date when the review from reviewers\' is due.' }, { name: 'file_group_uid', hint: 'UID of the file group to associate with this submittal package.' }, - { name: 'general_contractor_review_due_date', type: 'date', - hint: 'Due date of the general contractor\'s review.' }, - { name: 'lead_time_days', type: 'integer', - hint: 'Number of days of lead time provided for this submittal package.' }, + { name: 'general_contractor_review_due_date', type: 'date', label: 'Manager review due date', + hint: 'The date when the review from manager\'s is due.' }, { name: 'notes' }, { name: 'required_on_job_date', type: 'date', hint: 'The date when the submitted material is required on the job.' }, @@ -1590,14 +1583,12 @@ hint: 'ID of the submittal package to which this item should be associated.' }, { name: 'submittal_due_date', type: 'date', hint: 'Date when the submittal is due.' }, - { name: 'lead_time_days', type: 'integer', - hint: 'The number of days of lead time provided for this submittal item.' }, { name: 'required_on_job_date', type: 'date', hint: 'The date when the submitted material is required on the job.' }, - { name: 'design_review_due_date', type: 'date', - hint: 'The date when the design review is due.' }, - { name: 'general_contractor_review_due_date', type: 'date', - hint: 'The date when the general contractor\'s review is due.' }, + { name: 'design_review_due_date', type: 'date', label: 'Reviewer due date', + hint: 'The date when the review from reviewers is due.' }, + { name: 'general_contractor_review_due_date', type: 'date', label: 'Manager review due date', + hint: 'The date when the review from manager\'s is due.' }, { name: 'managers', type: 'array', of: 'object', hint: 'An array of objects describing users assigned the role of manager.', properties: [ From 8bc918461b9154a6603a6f22ca3630ff1984caba Mon Sep 17 00:00:00 2001 From: Sophat Sam Date: Tue, 12 May 2020 11:56:52 -0400 Subject: [PATCH 78/78] - update picklist for `get objects` - update picklist for `object_list` (new objects trigger) - update picklist for `object_list_new` (new or updated objects trigger) --- custom_connectors/oauth2/plangrid.rb | 47 +++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/custom_connectors/oauth2/plangrid.rb b/custom_connectors/oauth2/plangrid.rb index 205e842b..c7f67eb1 100644 --- a/custom_connectors/oauth2/plangrid.rb +++ b/custom_connectors/oauth2/plangrid.rb @@ -2662,9 +2662,23 @@ end, get_objects: lambda do |_connection| - [["Project", "project"], ["RFI", "rfi"], ["Task", "issue"], ["User", "user"], - ["Snapshot", "snapshot"], ["Sheet", "sheet"], ["Sheet Packet", "sheet_packet"], - ["Photo", "photo"], ["Document", "attachment"], ["Task_list", "issue_list"]] + [ + ['Project', 'project'], + ['Document', 'attachment'], + ['Field Report Export', 'field_reports/export'], + ['Photo', 'photo'], + ['RFI', 'rfi'], + ['Sheet', 'sheet'], + ['Sheet Packet', 'sheet_packet'], + ['Snapshot', 'snapshot'], + ['Submittal Package', 'submittals/package'], + ['Submittal Item', 'submittals/item'], + ['Submittal Package File Group', 'submittals_file_group'], + ['Submittal Package Review Status', 'submittals_review_status'], + ['Task', 'issue'], + ['Task List', 'issue_list'], + ['User', 'user'] + ] end, search_objects: lambda do |_connection| @@ -2685,13 +2699,32 @@ end, object_list: lambda do |_connection| - [["Project", "project"], ["Sheet", "sheet"], ["Document", "attachment"], ["Task", "issue"], ["RFI", "rfi"], - ["Annotation", "annotation"], ["Photo", "photo"], ["Snapshot", "snapshot"], ["Field Report", "field_report"]] + [ + ['Project', 'project'], + ['Annotation', 'annotation'], + ['Document', 'attachment'], + ['Field Report', 'field_report'], + ['Photo', 'photo'], + ['RFI', 'rfi'], + ['Sheet', 'sheet'], + ['Snapshot', 'snapshot'], + ['Task', 'issue'] + ] end, object_list_new: lambda do |_connection| - [["Project", "project"], ["Task", "issue"], ["RFI", "rfi"], ["Sheet", "sheet"], ["Field Report", "field_report"], - ["Document", "attachment"], ["Annotation", "annotation"]] + [ + ['Project', 'project'], + ['Annotation', 'annotation'], + ['Document', 'attachment'], + ['Field Report', 'field_report'], + ['Field Report Template', 'field_report_template'], + ['RFI', 'rfi'], + ['Sheet', 'sheet'], + ['Submittal Package', 'submittals/package'], + ['Submittal Item', 'submittals/item'], + ['Task', 'issue'] + ] end, project_list: lambda do |_connection|