Skip to content
This repository was archived by the owner on Aug 15, 2023. It is now read-only.

Commit 8d1d5e0

Browse files
Merge pull request #310 from Developer-Autodesk/INVGEN-44551-client-side-cloud-credits
Invgen 44551 client side cloud credits
2 parents 05b415b + c86335e commit 8d1d5e0

36 files changed

+429
-166
lines changed

WebApplication/ClientApp/src/JobManager.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ class JobManager {
3737
if (onStart)
3838
onStart();
3939

40-
connection.on("onComplete", (updatedState/*, stats*/) => {
40+
connection.on("onComplete", (updatedState, stats) => {
4141
// stop connection
4242
connection.stop();
4343

4444
if (onComplete)
45-
onComplete(updatedState);
45+
onComplete(updatedState, stats);
4646
});
4747

4848
connection.on("onError", (jobId, reportUrl) => {
@@ -62,12 +62,12 @@ class JobManager {
6262
if (onStart)
6363
onStart();
6464

65-
connection.on("onComplete", (newProject/*, stats*/) => {
65+
connection.on("onComplete", (newProject, stats) => {
6666
// stop connection
6767
connection.stop();
6868

6969
if (onComplete)
70-
onComplete(newProject);
70+
onComplete(newProject,stats);
7171
});
7272

7373
connection.on("onError", (jobId, reportUrl) => {
@@ -96,7 +96,7 @@ class JobManager {
9696

9797
if (onStart) onStart();
9898

99-
connection.on("onComplete", (downloadUrl/*, stats*/) => {
99+
connection.on("onComplete", (downloadUrl, stats) => {
100100

101101
connection.stop();
102102

@@ -105,7 +105,7 @@ class JobManager {
105105
if (token) {
106106
downloadUrl += "/" + token;
107107
}
108-
onSuccess(downloadUrl);
108+
onSuccess(downloadUrl, stats);
109109
}
110110
});
111111

@@ -124,12 +124,12 @@ class JobManager {
124124
if (onStart)
125125
onStart();
126126

127-
connection.on("onComplete", (drawingUrl/*, stats*/) => {
127+
connection.on("onComplete", (drawingUrl, stats) => {
128128
// stop connection
129129
connection.stop();
130130

131131
if (onComplete) {
132-
onComplete(drawingUrl);
132+
onComplete(drawingUrl, stats);
133133
}
134134
});
135135

WebApplication/ClientApp/src/actions/connectionMock.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ const connectionMock = {
2424
},
2525
invoke: function() {},
2626
stop: function() {},
27-
simulateComplete: function(data) {
28-
this.onHandlers['onComplete'](data);
27+
simulateComplete: function(data, stats) {
28+
this.onHandlers['onComplete'](data, stats);
2929
},
3030
simulateError: function(jobId, link) {
3131
this.onHandlers['onError'](jobId, link);

WebApplication/ClientApp/src/actions/downloadActions.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import { addError, addLog } from './notificationActions';
2020
import { Jobs } from '../JobManager';
21-
import { showDownloadProgress, showDownloadFailed, setDownloadLink, setReportUrlLink } from './uiFlagsActions';
21+
import { showDownloadProgress, showDownloadFailed, setDownloadLink, setReportUrlLink, setStats } from './uiFlagsActions';
2222
import { showDrawingExportProgress, setDrawingPdfUrl } from './uiFlagsActions';
2323

2424
/**
@@ -51,10 +51,11 @@ export const getDownloadLink = (methodName, projectId, hash, dialogTitle) => asy
5151
dispatch(setReportUrlLink(null)); // cleanup url link
5252
},
5353
// onComplete
54-
(downloadUrl) => {
54+
(downloadUrl, stats) => {
5555
dispatch(addLog(`JobManager.doDownloadJob: '${methodName}' completed for project : ${projectId}`));
5656
// set download link, it will show link in UI
5757
dispatch(setDownloadLink(downloadUrl));
58+
dispatch(setStats(stats));
5859
},
5960
// onError
6061
(jobId, reportUrl) => {
@@ -87,15 +88,15 @@ export const fetchDrawing = (project) => async (dispatch) => {
8788
// start job
8889
() => {
8990
dispatch(addLog('JobManager.doDrawingExportJob: HubConnection started for project : ' + project.id));
91+
dispatch(setStats(null));
9092
//dispatch(setReportUrlLink(null)); // cleanup url link
9193
},
9294
// onComplete
93-
(drawingPdfUrl) => {
95+
(drawingPdfUrl, stats) => {
9496
dispatch(addLog('JobManager.doDrawingExportJob: Received onComplete'));
9597
// store drawings link
9698
dispatch(setDrawingPdfUrl(drawingPdfUrl));
97-
// hide progress modal dialog
98-
dispatch(showDrawingExportProgress(false));
99+
dispatch(setStats(stats));
99100
},
100101
// onError
101102
(jobId, reportUrl) => {

WebApplication/ClientApp/src/actions/downloadActions.test.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const fullLink = `${aLink}/${tokenMock}`;
2929
const noTokenLink = `${aLink}`;
3030
const errorReportLink = 'https://error.link';
3131
const jobId = 'job1';
32+
const theStats = { credits: 1 };
3233

3334
// prepare mock for signalR
3435
import connectionMock from './connectionMock';
@@ -71,12 +72,14 @@ describe('downloadActions', () => {
7172
it('check getDownloadLink onComplete action', async () => {
7273
await store.dispatch(downloadActions.getDownloadLink("Method", "ProjectId", "hash", "title"));
7374
// simulate conection.onComplete(rfaLink);
74-
connectionMock.simulateComplete(aLink);
75+
connectionMock.simulateComplete(aLink, theStats);
7576

7677
// check expected store actions
7778
const actions = store.getActions();
7879
const linkAction = actions.find(a => a.type === uiFlagsActionTypes.SET_DOWNLOAD_LINK);
7980
expect(linkAction.url).toEqual(fullLink);
81+
const statsAction = actions.find(a => a.type === uiFlagsActionTypes.SET_STATS);
82+
expect(statsAction.stats).toEqual(theStats);
8083
});
8184

8285
it('check getDownloadLink onError action', async () => {
@@ -94,12 +97,15 @@ describe('downloadActions', () => {
9497
describe('Drawing', () => {
9598
it('check fetchDrawing action', async () => {
9699
await store.dispatch(downloadActions.fetchDrawing({ id: "ProjectId" }));
97-
connectionMock.simulateComplete(aLink);
100+
connectionMock.simulateComplete(aLink, theStats);
98101

99102
// check expected store actions
100103
const actions = store.getActions();
101104
const linkAction = actions.find(a => a.type === uiFlagsActionTypes.SET_DRAWING_URL);
102105
expect(linkAction.url).toEqual(noTokenLink);
106+
// there are two setStats in the flow: clear (null) and set (theStats)
107+
expect(actions.some(a => a.type === uiFlagsActionTypes.SET_STATS && a.stats === null)).toBeTruthy();
108+
expect(actions.some(a => a.type === uiFlagsActionTypes.SET_STATS && a.stats === theStats)).toBeTruthy();
103109
});
104110

105111
it('check fetchDrawing error handling', async () => {

WebApplication/ClientApp/src/actions/parametersActions.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import repo from '../Repository';
2020
import { addError, addLog } from './notificationActions';
2121
import { Jobs } from '../JobManager';
22-
import { showModalProgress, showUpdateFailed, setReportUrlLink } from './uiFlagsActions';
22+
import { showModalProgress, showUpdateFailed, setReportUrlLink, setStats } from './uiFlagsActions';
2323

2424
import { updateProject } from './projectListActions';
2525

@@ -160,12 +160,12 @@ export const updateModelWithParameters = (projectId, data) => async (dispatch) =
160160
() => {
161161
dispatch(addLog('JobManager: HubConnection started for project : ' + projectId));
162162
dispatch(setReportUrlLink(null)); // cleanup url link
163+
dispatch(setStats(null));
163164
},
164165
// onComplete
165-
updatedState => {
166+
(updatedState, stats) => {
166167
dispatch(addLog('JobManager: Received onComplete'));
167-
// hide modal dialog
168-
dispatch(showModalProgress(false));
168+
dispatch(setStats(stats));
169169

170170
// parameters and "base project state" should be handled differently,
171171
// so split the incoming updated state to pieces.
@@ -174,7 +174,6 @@ export const updateModelWithParameters = (projectId, data) => async (dispatch) =
174174
// launch update
175175
const adaptedParams = adaptParameters(parameters);
176176
dispatch(updateParameters(projectId, adaptedParams));
177-
178177
dispatch(updateProject(projectId, baseProjectState));
179178
},
180179
// onError

WebApplication/ClientApp/src/actions/parametersActions.test.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,9 @@ describe('fetchParameters', () => {
267267
parameters: parameters,
268268
...projectData
269269
};
270+
const theStats = { credits: 1 };
270271

271-
connectionMock.simulateComplete(updatedState);
272+
connectionMock.simulateComplete(updatedState, theStats);
272273

273274
// check expected store actions
274275
const actions = store.getActions();
@@ -279,6 +280,9 @@ describe('fetchParameters', () => {
279280
const updateProject = actions.find(a => a.type === projectListActionTypes.UPDATE_PROJECT);
280281
expect(updateProject.activeProjectId).toEqual(projectId);
281282
expect(updateProject.data).toEqual(projectData);
283+
// there are two setStats in the flow: clear (null) and set (theStats)
284+
expect(actions.some(a => a.type === uiFlagsActionTypes.SET_STATS && a.stats === null)).toBeTruthy();
285+
expect(actions.some(a => a.type === uiFlagsActionTypes.SET_STATS && a.stats === theStats)).toBeTruthy();
282286
});
283287

284288
it('check updateModelWithParameters error path', async () => {

WebApplication/ClientApp/src/actions/uiFlagsActions.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ export const actionTypes = {
4141
CLEAR_CHECKED_PROJECTS: 'CLEAR_CHECKED_PROJECTS',
4242
SHOW_DRAWING_PROGRESS: 'SHOW_DRAWING_PROGRESS',
4343
SET_DRAWING_URL: 'SET_DRAWING_URL',
44-
INVALIDATE_DRAWING: 'INVALIDATE_DRAWING'
44+
INVALIDATE_DRAWING: 'INVALIDATE_DRAWING',
45+
SET_STATS: 'SET_STATS'
4546
};
4647

4748
export default actionTypes;
@@ -217,4 +218,11 @@ export const invalidateDrawing = () => {
217218
return {
218219
type: actionTypes.INVALIDATE_DRAWING
219220
};
220-
};
221+
};
222+
223+
export const setStats = (stats) => {
224+
return {
225+
type: actionTypes.SET_STATS,
226+
stats
227+
};
228+
};

WebApplication/ClientApp/src/actions/uploadPackageActions.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import repo from '../Repository';
2020
import { uploadPackageData } from '../reducers/mainReducer';
2121
import { addProject } from './projectListActions';
22-
import { setProjectAlreadyExists, showUploadPackage } from './uiFlagsActions';
22+
import { setProjectAlreadyExists, showUploadPackage, setStats } from './uiFlagsActions';
2323
import { addError, addLog } from './notificationActions';
2424
import { Jobs } from '../JobManager';
2525

@@ -64,9 +64,10 @@ export const uploadPackage = () => async (dispatch, getState) => {
6464
dispatch(addLog('JobManager: HubConnection started for adopt project : ' + uploadResponse));
6565
},
6666
// onComplete
67-
newProject => {
67+
(newProject, stats) => {
6868
dispatch(addLog('JobManager: Received onComplete'));
6969
dispatch(addProject(newProject));
70+
dispatch(setStats(stats));
7071
dispatch(setUploadProgressDone());
7172
},
7273
// onError

WebApplication/ClientApp/src/actions/uploadPackageActions.test.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,18 @@ describe('uploadPackage', () => {
6969
expect(uploadPackageMock).toHaveBeenCalledTimes(1);
7070

7171
const newProject = { name: "newProject" };
72-
connectionMock.simulateComplete(newProject);
72+
const theStats = { credits: 1 };
73+
connectionMock.simulateComplete(newProject, theStats);
7374

7475
const actions = store.getActions();
7576

7677
// check expected actions and their types
7778
expect(actions[0].type).toEqual(uiFlagsActionTypes.SHOW_UPLOAD_PACKAGE);
7879
expect(actions[1].type).toEqual(actionTypes.SET_UPLOAD_PROGRESS_VISIBLE);
7980
// there are some logs in action in between...
80-
expect(actions[actions.length-2].type).toEqual(projectListActions.ADD_PROJECT);
81+
expect(actions[actions.length-3].type).toEqual(projectListActions.ADD_PROJECT);
82+
expect(actions[actions.length-2].type).toEqual(uiFlagsActionTypes.SET_STATS);
83+
expect(actions[actions.length-2].stats).toEqual(theStats);
8184
expect(actions[actions.length-1].type).toEqual(actionTypes.SET_UPLOAD_PROGRESS_DONE);
8285
});
8386

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/////////////////////////////////////////////////////////////////////
2+
// Copyright (c) Autodesk, Inc. All rights reserved
3+
// Written by Forge Design Automation team for Inventor
4+
//
5+
// Permission to use, copy, modify, and distribute this software in
6+
// object code form for any purpose and without fee is hereby granted,
7+
// provided that the above copyright notice appears in all copies and
8+
// that both that copyright notice and the limited warranty and
9+
// restricted rights notice below appear in all supporting
10+
// documentation.
11+
//
12+
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
13+
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
14+
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
15+
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
16+
// UNINTERRUPTED OR ERROR FREE.
17+
/////////////////////////////////////////////////////////////////////
18+
19+
import React, { Component } from 'react';
20+
import { connect } from 'react-redux';
21+
import Spacer from "@hig/spacer";
22+
import Typography from "@hig/typography";
23+
import { getStats } from '../reducers/mainReducer';
24+
import { Cloud16 } from '@hig/icons';
25+
import { significantDigits } from '../utils/conversion';
26+
27+
export class CreditCost extends Component {
28+
render() {
29+
30+
return (
31+
<div>
32+
{this.props.stats?.processing ?
33+
<div>
34+
<Typography><b>Consumed resources:</b></Typography>
35+
<Spacer spacing='s'/>
36+
<Typography>Download: {significantDigits(this.props.stats?.download, 5)}s</Typography>
37+
<Typography>Processing: {significantDigits(this.props.stats?.processing, 5)}s</Typography>
38+
<Typography>Upload: {significantDigits(this.props.stats?.upload, 5)}s</Typography>
39+
<Typography><b>Overall time: {significantDigits(this.props.stats?.total, 5)}s</b></Typography>
40+
<Typography><b>Cloud Credits: {significantDigits(this.props.stats?.credits, 5)}</b> <Cloud16/></Typography>
41+
<Spacer spacing='s'/>
42+
<Typography>Queuing: {significantDigits(this.props.stats?.queueing, 5)}s</Typography>
43+
</div>
44+
:
45+
<div>
46+
<Typography><b>Used cache, Cloud Credits: 0</b> <Cloud16/></Typography>
47+
<Spacer spacing='s'/>
48+
<Typography>The last consumed Cloud Credits: {significantDigits(this.props.stats?.credits, 5)} <Cloud16/></Typography>
49+
</div>
50+
}
51+
<Spacer spacing='m'/>
52+
</div>
53+
);
54+
}
55+
}
56+
57+
/* istanbul ignore next */
58+
export default connect(function (store){
59+
return {
60+
stats: getStats(store)
61+
};
62+
})(CreditCost);

0 commit comments

Comments
 (0)