Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ service.authRefreshMiddleware = async (req, res, next) => {
}

if (expires_at < Date.now()) {
const credentials = await authenticationClient.getRefreshToken(APS_CLIENT_ID, refresh_token, {
const credentials = await authenticationClient.refreshToken(refresh_token, APS_CLIENT_ID, {
clientSecret: APS_CLIENT_SECRET,
scopes: [
Scopes.DataRead,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,36 @@ npm init -y
Next, install all the Node.js dependencies we're going to use. In this case it will be [dotenv](https://www.npmjs.com/package/dotenv)
(utility for initializing environment variables from a file), [Express.js](https://expressjs.com) (web framework),
and [cookie-session](https://www.npmjs.com/package/cookie-session) for handling cookie-based sessions, and finally the necessary APS SDK including:
- [@aps_sdk/autodesk-sdkmanager](https://www.npmjs.com/package/@aps_sdk/autodesk-sdkmanager)
- [@aps_sdk/authentication](https://www.npmjs.com/package/@aps_sdk/authentication)
- [@aps_sdk/data-management](https://www.npmjs.com/package/@aps_sdk/data-management)
- [@aps_sdk/construction-account-admin](https://www.npmjs.com/package/@aps_sdk/construction-account-admin)

```bash
npm install --save dotenv express cookie-session
npm install --save @aps_sdk/autodesk-sdkmanager @aps_sdk/authentication @aps_sdk/data-management @aps_sdk/construction-account-admin
npm install --save @aps_sdk/authentication @aps_sdk/data-management @aps_sdk/construction-account-admin
```

:::note
At the writing of this documentation, the tutorial sample is using the specified version next to the package name.

- [@aps_sdk/authentication v1.0.0 ](https://www.npmjs.com/package/@aps_sdk/authentication/v/1.0.0?activeTab=versions)
- [@aps_sdk/data-management v1.1.2](https://www.npmjs.com/package/@aps_sdk/data-management/v/1.1.2?activeTab=versions)
- [@aps_sdk/construction-account-admin v1.2.1](https://www.npmjs.com/package/@aps_sdk/construction-account-admin/v/1.2.1?activeTab=versions)
:::


The `"dependencies"` in your `package.json` file should now look something like this
(potentially with slightly different version numbers):

```json
// ...
"dependencies": {
"@aps_sdk/authentication": "^1.0.0",
"@aps_sdk/autodesk-sdkmanager": "^1.0.0",
"@aps_sdk/data-management": "^1.0.0",
"@aps_sdk/construction-account-admin": "^1.0.0",
"cookie-session": "^2.1.0",
"dotenv": "^16.4.5",
"express": "^4.19.2"
"@aps_sdk/data-management": "^1.1.2",
"@aps_sdk/construction-account-admin": "^1.2.1",
"cookie-session": "^2.1.1",
"dotenv": "^17.2.3",
"express": "^5.1.0"
},
// ...
```
Expand Down
51 changes: 39 additions & 12 deletions docs/03-tutorials/06-acc-issues/04-issues.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import NodeJsVsCodeEndpoints from './_shared/nodejs-vscode/issue/endpoints.mdx';
import NodeJsVsCodeSDK from './_shared/nodejs-vscode/issue/issue-sdk.mdx';
import NodeJsVsCodeExtractIssues from './_shared/nodejs-vscode/issue/export-issues.mdx';
import NodeJsVsCodeImportIssues from './_shared/nodejs-vscode/issue/import-issues.mdx';

import DotNetEndpoints from './_shared/dotnet/issue/endpoints.mdx';
import DotNetSDK from './_shared/dotnet/issue/issue-sdk.mdx';
import DotNetExtractIssues from './_shared/dotnet/issue/export-issues.mdx';
Expand All @@ -19,12 +19,16 @@ We shall be utilizing ACC Issue SDK in both NodeJs and .NET samples
<EnvTabs NodeJsVsCode={NodeJsVsCodeSDK} DotNetVsCode={DotNetSDK} DotNetVs2022={DotNetSDK} />


:::tip
## Pagination

The 'Issues' collection is managed in the APS cloud database. To ensure optimal performance, the API follows the web standard of **pagination** meaning each HTTP request returns only a portion of the records in the collection.
With current design, ACC Issue API returns 1-100 issues in one call by default. We also have chance to specify the **limit** parameter which indicates how many records in one page. The other parameter **offset** specifies from which index of issue to extract the records.
Check API reference of [GET:Issues](https://aps.autodesk.com/en/docs/acc/v1/reference/http/issues-issues-GET/) for more information.
:::

:::tip
- If the number of issue records is large, the process may take some time. In your production application, consider adding a progress bar that displays the current offset and limit, or use query parameters **filter** to request only specific issues from the API.
- This sample retrieves all issue data. In a real application, you can request only specific fields by using the **fields** query parameter.
:::

## Import Issues
Moving forward, we will add helper functions to create and modify issues. [POST Issues](https://aps.autodesk.com/en/docs/acc/v1/reference/http/issues-issues-POST/) for creating a new issue,
Expand All @@ -35,10 +39,8 @@ To track status, a JSON array is logged on console with the successfully created

<EnvTabs NodeJsVsCode={NodeJsVsCodeImportIssues} DotNetVsCode={DotNetImportIssues} DotNetVs2022={DotNetImportIssues} />


:::info
The issue creation and modification APIs only accept a limited set of fields in the request payload. This sample demonstrates how to just use some required fields from the CSV data.

- title
- description
- issueSubtypeId
Expand All @@ -50,6 +52,7 @@ The issue creation and modification APIs only accept a limited set of fields in
- published
:::



## Server endpoints

Expand All @@ -64,16 +67,40 @@ set of endpoints.

And that's it for the server side. Time to try it out!

- Use same project ID in previous step (remove b.) and try to call the endpoint:
- **GET Issues**: Use same project ID in previous step (remove b.) and try to call the endpoint in the browser:
[http://localhost:8080/api/issues/issues?projectId={your-project-id}](http://localhost:8080/api/issues/issues?projectId={your-project-id}), the server application should
respond with a JSON list of all the issues from this project.

![Issues Response](./_shared/project-issues.webp)

:::info
- It would take a bit long time if the volume of the issue records is large.
This sample extracts raw data of issue.
- Some fields are json object or array object. Their value will be dumped as string in this sample.
- To test creating or modifying issues, use HTTP test tools or commandline scripts to perform the test with access token and request payload.Recommended HTTP test tools: [Postman](https://www.postman.com/downloads/), [Insomnia](https://insomnia.rest/)
:::
- **POST Issues**: Browsers by default do not provide built-in tools to test endpoints that modify data, such as POST, PATCH, DELETE, etc. To test the creation or modification of issues, use other HTTP tools or command-line scripts. Below is a demo using [Postman](https://www.postman.com/downloads/).
- endpoint of this call `POST: http://localhost:8080/api/issues/issues`

- Input headers Content-Type and Cookie. Check [Try it Out of Authentication](/tutorials/acc-issues/auth#try-it-out) to get Cookie value

- Content-Type:application/json
- NodeJS: Cookie:session=< value >;session.sig=< value >
- NET: Cookie:internal_token=< value >;refresh_token=< value >;expires_at=< value>

![Write Test Header](./_shared/write-test-headers.webp)

- Input request payload. If new issue, no **id**. The **issueSubtypeId** can be copied to any of the records of GET Issues. If with **id**, that means to update existing issue.

``` json
{
"projectId":"854c194f-05b3-4117-b926-69fa36c33c0c",
"data":[
{
"title":"create new issue by my application",
"issueSubtypeId":"a1637225-d69c-4afc-ad02-1c73a92ee3c1",
"status":"open"
},
{
"id": "b4f6e2f7-7bda-4e87-b139-7d94bc9c2a8d"
"title":"modify an existing issue by my application",
"status":"close"
}
]
}
```

5 changes: 5 additions & 0 deletions docs/03-tutorials/06-acc-issues/07-ui.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ const TABLE_TABS = {
'REQUEST_URL': '/api/issues/customAttDefs',
'TAB_NAME': 'CUSTOM_ATTRIBUTES_DEFS',
'VISIBILITY': false
},
'ISSUE_USER_PROFILE': {
'REQUEST_URL': '/api/issues/issueUserProfile',
'TAB_NAME': 'USER_PROFILE',
'VISIBILITY': false
}
}

Expand Down
112 changes: 65 additions & 47 deletions docs/03-tutorials/06-acc-issues/08-table.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ Here are the explanation of the main function:
- `resetData`: Fetch and setup the data based on the input accountId, projectId, and tabKey.
- `drawTable`: Draw the bootstrap table with the current data.
- `exportToCSV`: Export the current data into CSV file.
- `importFromCSV`: Import the information into ACC Issue sample from the prepared CSV file.

```js title="wwwroot/table.js"
//////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -64,10 +63,11 @@ class Table {
}

drawTable = () => {
if (this.#dataSet == null || this.#dataSet.length == 0) {
console.warn('DataSet is not ready, please fetch your data first.');
return;
}
// the dataset can be empty or null when
// 1. no records at all
// 2. issue module is not activated with the user
// 3. this user has no access to the data
// 4. exceptions/errors

let columns = [];
for (var key in this.#dataSet[0]) {
Expand All @@ -77,8 +77,8 @@ class Table {
columns.push({
field: key,
title: key,
align: "center",
formatter: function (value) {
align: "left",
formatter: (value) => {
return value.toString();
}
})
Expand All @@ -88,9 +88,15 @@ class Table {
columns.push({
field: key,
title: key,
align: "center",
formatter: function (value) {
return JSON.stringify(value)
align: "left",
formatter: (value) => {

const jsonString = JSON.stringify(value, null, 2);

return `<pre style="max-height: 120px;
max-width: 500px; overflow: auto;
white-space: pre-wrap; margin: 0;word-break: break-word;">
${jsonString}</pre>`;
}
})
} else {
Expand Down Expand Up @@ -125,7 +131,7 @@ class Table {
showToggle: false,
pagination: true,
pageList: [5],
pageSize: 5,
pageSize: 7,
pageNumber: 1,
uniqueId: 'id',
striped: true,
Expand All @@ -134,12 +140,12 @@ class Table {
minimumCountColumns: 2,
smartDisplay: true,
columns: columns,
sortName:'displayId',
sortOrder:'desc'
sortName: 'displayId',
sortOrder: 'desc',
resizable: true
});
}


exportToCSV = () => {
const separatorForColumns = ',';
const headers = Object.keys(this.#dataSet[0]).join(separatorForColumns);
Expand Down Expand Up @@ -172,19 +178,34 @@ class Table {
link.click();
}

formatDate(date, format = 'YYYY-MM-DD') {
const pad = (num) => String(num).padStart(2, '0');

const replacements = {
YYYY: date.getFullYear(),
MM: pad(date.getMonth() + 1),
DD: pad(date.getDate())
};

return format.replace(/YYYY|MM|DD/g, (match) => replacements[match]);
}

// highlight-end
}
```
:::note
- Complex properties (such as JSON objects or arrays) will be displayed in the table but will appear as a note — “Complicated Objects” — when exporting to CSV.
This is because special characters and commas within these objects can distort the CSV format.
If you need to export the actual values, consider parsing each key–value pair and exporting them in an appropriate format.
:::

importFromCSV = async () => {
## Import Issues
Finally, let us implement the feature: batch import projects issues for creating new or modifying existing issue, this is achieved by using a CSV file,
we provided a sample template files for projects issues, you can add/modify your information based on the template,
then import the data from CSV file into ACC account.
- [IssueTemplate.csv](https://github.com/xiaodongliang/aps-acc-issues-tutorial-nodejs/blob/main/template/IssueTemplate.csv)

During import, the code will parse the propery information from a csv file to build request payload.

In `table.js`, add the implementation code into Class `Table`, after the function `exportToCSV`:
- `importFromCSV`: Import the information into ACC Issue sample from the prepared CSV file.

```js title="wwwroot/table.js"
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//Table class wraps the specific data info

// highlight-start

importFromCSV = async () => {
if (TABLE_TABS[this.#tabKey].TAB_NAME != 'ISSUES') {
alert('only issue is supported to be created/modified!Please active ISSUES table firstly!');
return;
Expand Down Expand Up @@ -266,38 +287,35 @@ class Table {
};
input.click();
}
// highlight-end
}
```
:::note

- The complicated properties (json or array) will be in string in the table, but will be a note only: **Complicated Objects**, when exporting to csv
because the special char and comma in the complicated object will distort the csv. If you want to export the value, you may parse each key-value in the comluns.
- During import, the code will parse the propery information from a csv file to build request payload.
:::


## CSV File Prepare
Finally, let us implement the feature: batch import projects issues for creating new or modifying existing issue, this is achieved by using a CSV file,
we provided a sample template files for projects issues, you can add/modify your information based on the template,
then import the data from CSV file into ACC account.

- [IssueTemplate.csv](https://github.com/xiaodongliang/aps-acc-issues-tutorial-nodejs/blob/main/template/IssueTemplate.csv)
formatDate(date, format = 'YYYY-MM-DD') {
const pad = (num) => String(num).padStart(2, '0');
const replacements = {
YYYY: date.getFullYear(),
MM: pad(date.getMonth() + 1),
DD: pad(date.getDate())
};

return format.replace(/YYYY|MM|DD/g, (match) => replacements[match]);
}
// highlight-end

:::caution
- It is strongly recommended to use the same pattern of the csv that is exported in the previous function (Export Issue Records).
```

:::caution CSV File Preparation
- It is strongly recommended to use the same pattern of the csv that is exported in the previous function (exportToCSV).
- To add new issue, leave the column id empty
- To modify the existing issue, keep the column id with the issue id, update other fields with new values.
- A few fields are required when working with creating issues(POST). A few fields are supported when working with modifying issues (PATCH). Please check API references for more details. To make it clearer, this sample only demos some supported fields.
- A few fields are required when working with creating issues(POST). A few fields are supported when working with modifying issues (PATCH). Please check API references for more details.
To make it clearer, this sample only demos some supported fields.
- The row number of the CSV records is not used with API calls, but will be used when tracking the status.
- The status of created/modified/failed are tracked and will be printed out in the browser console after the process.
- The status of created/modified/failed are tracked and will be printed out in the browser console and server log after the process.
- If you open the CSV file with Microsoft Excel, some data type will be automatically changed by the setting, for example, the column of
**startDate** and **duDate** might be changed to the type as **"2012/03/14"**, please make sure to select another type like **"2012-03-14"** without **"/"** as shown in the screenshot,
otherwise the date will not be recognized correctly after exporting to CSV file.
:::
![Excel Data Format](./_shared/excel-data-type.png)


## Try it out

And that's it! Your application is now ready for action. Start it as usual, and when you go to
Expand Down
Loading