-
Notifications
You must be signed in to change notification settings - Fork 0
AutoTask LCP #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AutoTask LCP #45
Changes from all commits
88c4108
b2687e6
878e49e
dc0265b
46bc12b
eb642ce
15f856f
9722709
a9f1a7b
7f86a27
0fa1dd4
cae7a44
01c069d
aa930bc
c20b366
e4b0b44
ca0bc31
9c26e59
4b7ece8
0325310
ce3ec2a
b73c422
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "steps": [ | ||
| { | ||
| "displayName": "Autotask connection", | ||
| "dataStream": { "name": "companies", "timeframe": "none" }, | ||
| "success": "Successfully connected to Autotask", | ||
| "error": "Cannot connect to Autotask — check your Zone URL, Integration Code, Username and Secret", | ||
| "required": true | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| [ | ||
| { | ||
| "name": "Autotask Company", | ||
| "sourceType": "autotask-company", | ||
| "icon": "building-2", | ||
| "singular": "Company", | ||
| "plural": "Companies" | ||
| }, | ||
| { | ||
| "name": "AutotaskContact", | ||
| "sourceType": "autotask-contact", | ||
| "icon": "user", | ||
| "singular": "Contact", | ||
| "plural": "Contacts" | ||
| }, | ||
| { | ||
| "name": "AutotaskProject", | ||
| "sourceType": "autotask-project", | ||
| "icon": "folder-kanban", | ||
| "singular": "Project", | ||
| "plural": "Projects" | ||
| }, | ||
| { | ||
| "name": "AutotaskResource", | ||
| "sourceType": "autotask-resource", | ||
| "icon": "hard-hat", | ||
| "singular": "Resource", | ||
| "plural": "Resources" | ||
| }, | ||
| { | ||
| "name": "AutotaskContract", | ||
| "sourceType": "autotask-contract", | ||
| "icon": "file-text", | ||
| "singular": "Contract", | ||
| "plural": "Contracts" | ||
| } | ||
| ] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| { | ||
| "name": "companies", | ||
| "displayName": "Companies", | ||
| "description": "All active companies in AutoTask", | ||
| "tags": ["Companies"], | ||
| "baseDataSourceName": "httpRequestUnscoped", | ||
| "timeframes": false, | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "expandInnerObjects": true, | ||
| "endpointPath": "atservicesrest/v1.0/Companies/query?search={\"MaxRecords\":500,\"filter\":[{\"op\":\"exist\",\"field\":\"id\"}]}", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given you have paging added, you could reduce the 500 needed here if you hit size limits - or it could be faster fetching more smaller pages. |
||
| "pathToData": "items", | ||
| "paging": { | ||
| "mode": "nextUrl", | ||
| "pageSize": { "realm": "none" }, | ||
| "in": { | ||
| "realm": "payload", | ||
| "path": "pageDetails.nextPageUrl" | ||
| } | ||
| } | ||
| }, | ||
| "metadata": [ | ||
| { "name": "companyName", "displayName": "Company Name" }, | ||
| { "name": "isActive", "displayName": "Is Active" }, | ||
| { "name": "phone", "displayName": "Phone" }, | ||
| { "name": "address1", "displayName": "Address" }, | ||
| { "name": "city", "displayName": "City" }, | ||
| { "name": "state", "displayName": "State" }, | ||
| { "name": "postalCode", "displayName": "Postal Code" }, | ||
| { "name": "country", "displayName": "Country" }, | ||
| { "name": "createDate", "displayName": "Created Date", "shape": ["date", { "timeZone": "Etc/UTC" }] }, | ||
| { "name": "ownerResourceID", "sourceType": "autotask-resource", "shape": "string", "visible": false }, | ||
| { "name": "ownerResourceName", "displayName": "Owner", "sourceId": "ownerResourceID", "objectPropertyPath": "name" }, | ||
| { "pattern": ".*" } | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| { | ||
| "name": "contacts", | ||
| "displayName": "Contacts", | ||
| "baseDataSourceName": "httpRequestUnscoped", | ||
| "visibility": { "type": "hidden" }, | ||
| "timeframes": false, | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "expandInnerObjects": true, | ||
| "endpointPath": "atservicesrest/v1.0/Contacts/query?search={\"MaxRecords\":500,\"filter\":[{\"op\":\"exist\",\"field\":\"id\"}]}", | ||
| "pathToData": "items", | ||
| "paging": { | ||
| "mode": "nextUrl", | ||
| "pageSize": { "realm": "none" }, | ||
| "in": { | ||
| "realm": "payload", | ||
| "path": "pageDetails.nextPageUrl" | ||
| } | ||
| } | ||
| }, | ||
| "metadata": [ | ||
| { "name": "id", "displayName": "ID", "shape": "string" }, | ||
| { | ||
| "name": "fullName", | ||
| "displayName": "Full Name", | ||
| "computed": true, | ||
| "valueExpression": "{{ $['firstName'] + ' ' + $['lastName'] }}" | ||
| }, | ||
| { "pattern": ".*" } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| { | ||
| "name": "contractStatus", | ||
| "displayName": "Contract Status", | ||
| "description": "Status and key dates for contracts belonging to the selected company", | ||
| "tags": ["Contracts"], | ||
| "baseDataSourceName": "httpRequestScopedSingle", | ||
| "timeframes": false, | ||
| "matches": { | ||
| "sourceType": "autotask-company" | ||
| }, | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "expandInnerObjects": true, | ||
| "endpointPath": "atservicesrest/v1.0/Contracts/query?search={\"MaxRecords\":500,\"filter\":[{\"op\":\"eq\",\"field\":\"companyID\",\"value\":{{objects[0].companyId}}}]}", | ||
| "pathToData": "items", | ||
| "paging": { | ||
| "mode": "nextUrl", | ||
| "pageSize": { "realm": "none" }, | ||
| "in": { | ||
| "realm": "payload", | ||
| "path": "pageDetails.nextPageUrl" | ||
| } | ||
| } | ||
| }, | ||
| "metadata": [ | ||
| { "name": "sourceId", "displayName": "Object ID", "shape": "string", "visible": false }, | ||
| { "name": "id", "displayName": "ID", "sourceType": "autotask-contract", "shape": "string", "visible": false }, | ||
| { "name": "contractName", "displayName": "Contract Name" }, | ||
| { "name": "companyID", "displayName": "Company ID", "sourceType": "autotask-company", "shape": "string", "visible": false }, | ||
| { "name": "companyName", "displayName": "Company", "sourceId": "companyID", "objectPropertyPath": "name" }, | ||
| { | ||
| "name": "contractTypeName", | ||
| "displayName": "Contract Type", | ||
| "computed": true, | ||
| "valueExpression": "{{ $['contractType'] == 1 ? 'Time and Materials' : $['contractType'] == 3 ? 'Fixed Price' : $['contractType'] == 4 ? 'Block Hours' : $['contractType'] == 6 ? 'Retainer' : $['contractType'] == 7 ? 'Recurring Service' : $['contractType'] == 8 ? 'Incident' : 'Unknown' }}" | ||
| }, | ||
| { | ||
| "name": "statusName", | ||
| "displayName": "Status", | ||
| "computed": true, | ||
| "valueExpression": "{{ $['status'] == 1 ? 'Active' : $['status'] == 2 ? 'Upcoming' : $['status'] == 3 ? 'Cancelled' : $['status'] == 4 ? 'Completed' : $['status'] == 6 ? 'Inactive' : 'Unknown' }}", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you using a value expression AND a map here so users can both see our statues like 'success', 'error' as well as nicer raw names like 'Active' and 'Completed'? I think it's OK, just not seen this before. |
||
| "shape": ["state", { | ||
| "map": { | ||
| "success": ["Active", "Completed"], | ||
| "error": ["Cancelled"], | ||
| "warning": ["Upcoming"], | ||
| "unknown": ["Inactive", "Unknown"] | ||
| } | ||
| }] | ||
| }, | ||
| { "name": "startDate", "displayName": "Start Date", "shape": ["date", { "timeZone": "Etc/UTC" }] }, | ||
| { "name": "endDate", "displayName": "End Date", "shape": ["date", { "timeZone": "Etc/UTC" }] }, | ||
| { "pattern": ".*" } | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| { | ||
| "name": "contracts", | ||
| "displayName": "Contracts", | ||
| "baseDataSourceName": "httpRequestUnscoped", | ||
| "visibility": { "type": "hidden" }, | ||
| "timeframes": false, | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "expandInnerObjects": true, | ||
| "endpointPath": "atservicesrest/v1.0/Contracts/query?search={\"MaxRecords\":500,\"filter\":[{\"op\":\"exist\",\"field\":\"id\"}]}", | ||
| "pathToData": "items", | ||
| "paging": { | ||
| "mode": "nextUrl", | ||
| "pageSize": { "realm": "none" }, | ||
| "in": { | ||
| "realm": "payload", | ||
| "path": "pageDetails.nextPageUrl" | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| { | ||
| "name": "financialHealth", | ||
| "displayName": "Financial Health", | ||
| "description": "Estimated revenue, cost, and hours across all contracts", | ||
| "tags": ["Finance"], | ||
| "baseDataSourceName": "httpRequestUnscoped", | ||
| "timeframes": false, | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "expandInnerObjects": true, | ||
| "endpointPath": "atservicesrest/v1.0/Contracts/query?search={\"MaxRecords\":500,\"filter\":[{\"op\":\"exist\",\"field\":\"id\"}]}", | ||
| "pathToData": "items", | ||
| "paging": { | ||
| "mode": "nextUrl", | ||
| "pageSize": { "realm": "none" }, | ||
| "in": { | ||
| "realm": "payload", | ||
| "path": "pageDetails.nextPageUrl" | ||
| } | ||
| } | ||
| }, | ||
| "metadata": [ | ||
| { "name": "id", "displayName": "ID", "visible": false, "shape":"string" }, | ||
| { "name": "contractName", "displayName": "Contract Name" }, | ||
| { | ||
| "name": "contractTypeName", | ||
| "displayName": "Contract Type", | ||
| "computed": true, | ||
| "valueExpression": "{{ $['contractType'] == 1 ? 'Time and Materials' : $['contractType'] == 3 ? 'Fixed Price' : $['contractType'] == 4 ? 'Block Hours' : $['contractType'] == 6 ? 'Retainer' : $['contractType'] == 7 ? 'Recurring Service' : $['contractType'] == 8 ? 'Incident' : 'Unknown' }}" | ||
| }, | ||
| { "name": "estimatedRevenue", "displayName": "Estimated Revenue", "shape": ["number", { "decimalPlaces": 2 }] }, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currency shape better?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can specify the currency dynamically if it's returned in the data / as a column FYI. |
||
| { "name": "estimatedCost", "displayName": "Estimated Cost", "shape": ["number", { "decimalPlaces": 2 }] }, | ||
| { "name": "estimatedHours", "displayName": "Estimated Hours", "shape": ["number", { "decimalPlaces": 2 }] }, | ||
| { | ||
| "name": "statusName", | ||
| "displayName": "Status", | ||
| "computed": true, | ||
| "valueExpression": "{{ $['status'] == 1 ? 'Active' : $['status'] == 2 ? 'Upcoming' : $['status'] == 3 ? 'Cancelled' : $['status'] == 4 ? 'Completed' : $['status'] == 6 ? 'Inactive' : 'Unknown' }}", | ||
| "shape": ["state", { | ||
| "map": { | ||
| "success": ["Active", "Completed"], | ||
| "error": ["Cancelled"], | ||
| "warning": ["Upcoming"], | ||
| "unknown": ["Inactive", "Unknown"] | ||
| } | ||
| }] | ||
| }, | ||
| { "pattern": ".*" } | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| { | ||
| "name": "projectStatus", | ||
| "displayName": "Project Status", | ||
| "description": "Status, progress, and schedule for all projects", | ||
| "tags": ["Projects"], | ||
| "baseDataSourceName": "httpRequestUnscoped", | ||
| "timeframes": false, | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "expandInnerObjects": true, | ||
| "endpointPath": "atservicesrest/v1.0/Projects/query?search={\"MaxRecords\":500,\"filter\":[{\"op\":\"exist\",\"field\":\"id\"}]}", | ||
| "pathToData": "items", | ||
| "paging": { | ||
| "mode": "nextUrl", | ||
| "pageSize": { "realm": "none" }, | ||
| "in": { | ||
| "realm": "payload", | ||
| "path": "pageDetails.nextPageUrl" | ||
| } | ||
| } | ||
| }, | ||
| "metadata": [ | ||
| { "name": "id", "displayName": "ID", "shape": "string" }, | ||
| { "name": "projectName", "displayName": "Project Name" }, | ||
| { "name": "status", "displayName": "Status (Raw)", "shape": ["number", { "decimalPlaces": 0 }], "visible": false }, | ||
| { | ||
| "name": "statusName", | ||
| "displayName": "Status", | ||
| "computed": true, | ||
| "valueExpression": "{{ $['status'] == 1 ? 'Active' : $['status'] == 2 ? 'Inactive' : $['status'] == 3 ? 'Completed' : $['status'] == 5 ? 'On Hold' : 'Unknown' }}", | ||
| "shape": ["state", { | ||
| "map": { | ||
| "success": ["Active", "Completed"], | ||
| "warning": ["On Hold"], | ||
| "unknown": ["Inactive", "Unknown"] | ||
| } | ||
| }] | ||
| }, | ||
| { "name": "completedPercentage", "displayName": "Completed %", "shape": ["number", { "decimalPlaces": 0 }] }, | ||
| { "name": "actualHours", "displayName": "Actual Hours", "shape": ["number", { "decimalPlaces": 2 }] }, | ||
| { "name": "estimatedTime", "displayName": "Estimated Hours", "shape": ["number", { "decimalPlaces": 2 }] }, | ||
| { "name": "startDateTime", "displayName": "Start Date", "shape": ["date", { "timeZone": "Etc/UTC" }] }, | ||
| { "name": "endDateTime", "displayName": "End Date", "shape": ["date", { "timeZone": "Etc/UTC" }] }, | ||
| { "pattern": ".*" } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| { | ||
| "name": "projects", | ||
| "displayName": "Projects", | ||
| "baseDataSourceName": "httpRequestUnscoped", | ||
| "visibility": { "type": "hidden" }, | ||
| "timeframes": false, | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "expandInnerObjects": true, | ||
| "endpointPath": "atservicesrest/v1.0/Projects/query?search={\"MaxRecords\":500,\"filter\":[{\"op\":\"exist\",\"field\":\"id\"}]}", | ||
| "pathToData": "items", | ||
| "paging": { | ||
| "mode": "nextUrl", | ||
| "pageSize": { "realm": "none" }, | ||
| "in": { | ||
| "realm": "payload", | ||
| "path": "pageDetails.nextPageUrl" | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| { | ||
| "name": "resourceUtilisation", | ||
| "displayName": "Resource Utilization", | ||
| "description": "Time entries logged by resources within the selected timeframe", | ||
| "tags": ["Resources"], | ||
| "baseDataSourceName": "httpRequestUnscoped", | ||
| "timeframes": true, | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "expandInnerObjects": true, | ||
| "endpointPath": "atservicesrest/v1.0/TimeEntries/query?search={\"MaxRecords\":500,\"filter\":[{\"op\":\"gte\",\"field\":\"dateWorked\",\"value\":\"{{timeframe.start}}\"},{\"op\":\"lte\",\"field\":\"dateWorked\",\"value\":\"{{timeframe.end}}\"}]}", | ||
| "pathToData": "items", | ||
| "paging": { | ||
| "mode": "nextUrl", | ||
| "pageSize": { "realm": "none" }, | ||
| "in": { | ||
| "realm": "payload", | ||
| "path": "pageDetails.nextPageUrl" | ||
| } | ||
| } | ||
| }, | ||
| "metadata": [ | ||
| { "name": "id", "displayName": "ID", "visible": false,"shape":"string" }, | ||
| { "name": "resourceID", "sourceType": "autotask-resource", "shape": "string", "visible": false }, | ||
| { "name": "resourceName", "displayName": "Resource", "sourceId": "resourceID", "objectPropertyPath": "name" }, | ||
| { "name": "dateWorked", "displayName": "Date Worked", "shape": ["date", { "timeZone": "Etc/UTC" }] }, | ||
| { "name": "hoursWorked", "displayName": "Hours Worked", "shape": ["number", { "decimalPlaces": 2 }] }, | ||
| { "name": "hoursToBill", "displayName": "Hours to Bill", "shape": ["number", { "decimalPlaces": 2 }] }, | ||
| { "name": "billingCodeID", "displayName": "Billing Code ID" }, | ||
| { "name": "ticketID", "displayName": "Ticket ID" }, | ||
| { "pattern": ".*" } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| { | ||
| "name": "resources", | ||
| "displayName": "Resources", | ||
| "baseDataSourceName": "httpRequestUnscoped", | ||
| "visibility": { "type": "hidden" }, | ||
| "timeframes": false, | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "expandInnerObjects": true, | ||
| "endpointPath": "atservicesrest/v1.0/Resources/query?search={\"MaxRecords\":500,\"filter\":[{\"op\":\"exist\",\"field\":\"id\"}]}", | ||
| "pathToData": "items", | ||
| "paging": { | ||
| "mode": "nextUrl", | ||
| "pageSize": { "realm": "none" }, | ||
| "in": { | ||
| "realm": "payload", | ||
| "path": "pageDetails.nextPageUrl" | ||
| } | ||
| } | ||
| }, | ||
| "metadata": [ | ||
| { "name": "id", "displayName": "ID", "shape": "string" }, | ||
| { | ||
| "name": "fullName", | ||
| "displayName": "Full Name", | ||
| "computed": true, | ||
| "valueExpression": "{{ $['firstName'] + ' ' + $['lastName'] }}" | ||
| }, | ||
| { "pattern": ".*" } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| const selectedIds = new Set(context.objects.map(o => String(o.companyId))); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I presume there's not an API parameter to filter by company ID/name? |
||
| result = (data.items ?? []).filter(ticket => selectedIds.has(String(ticket.companyID))); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the name is used for much, but this has a space in while the others do not...