Skip to content

Commit dfd7c74

Browse files
committed
add looker service, action and reducer
1 parent 4dc80a9 commit dfd7c74

File tree

8 files changed

+7323
-6207
lines changed

8 files changed

+7323
-6207
lines changed

package-lock.json

Lines changed: 7138 additions & 6207 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/actions/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import memberTaskActions from './member-tasks';
1212
import reviewOpportunityActions from './reviewOpportunity';
1313
import lookupActions from './lookup';
1414
import settingsActions from './settings';
15+
import lookerActions from './looker';
1516

1617
export const actions = {
1718
auth: authActions.auth,
@@ -28,6 +29,7 @@ export const actions = {
2829
reviewOpportunity: reviewOpportunityActions.reviewOpportunity,
2930
lookup: lookupActions.lookup,
3031
settings: settingsActions.settings,
32+
looker: lookerActions.looker,
3133
};
3234

3335
export default undefined;

src/actions/looker.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @module "actions.looker"
3+
* @desc Actions related to looker data.
4+
*/
5+
6+
import { createActions } from 'redux-actions';
7+
import { getService } from '../services/looker';
8+
9+
/**
10+
* @static
11+
* @desc Creates an action that gets look data by id.
12+
* @return {Action}
13+
*/
14+
async function getLookerDone(lookerId) {
15+
const data = await getService().getLooker(lookerId);
16+
return { data, lookerId };
17+
}
18+
19+
export default createActions({
20+
LOOKER: {
21+
GET_LOOKER_DONE: getLookerDone,
22+
},
23+
});

src/reducers/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import mySubmissionsManagement, { factory as mySubmissionsManagementFactory }
2020
from './my-submissions-management';
2121
import settings, { factory as settingsFactory }
2222
from './settings';
23+
import looker, { factory as lookerFactory }
24+
from './looker';
2325

2426

2527
export function factory(options) {
@@ -38,6 +40,7 @@ export function factory(options) {
3840
reviewOpportunity: reviewOpportunityFactory(options),
3941
mySubmissionsManagement: mySubmissionsManagementFactory(options),
4042
settings: settingsFactory(options),
43+
looker: lookerFactory(options),
4144
});
4245
}
4346

@@ -56,4 +59,5 @@ export default ({
5659
reviewOpportunity,
5760
mySubmissionsManagement,
5861
settings,
62+
looker,
5963
});

src/reducers/looker.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* @module "reducers.looker"
3+
* @desc Reducer for {@link module:actions.looker} actions.
4+
*
5+
* State segment managed by this reducer has the following structure:
6+
* @param {Object} dataSet={}, index by lookerId.
7+
*/
8+
import _ from 'lodash';
9+
import { handleActions } from 'redux-actions';
10+
import actions from '../actions/looker';
11+
12+
/**
13+
* Handles LOOKER/GET_LOOKER_DONE action.
14+
* @param {Object} state
15+
* @param {Object} action Payload will be JSON from api call
16+
* @return {Object} New state
17+
*/
18+
function onGetLookerDone(state, { payload }) {
19+
const {
20+
data: {
21+
res,
22+
error,
23+
},
24+
lookerId,
25+
} = payload;
26+
27+
const newDataSet = {
28+
...state.dataSet,
29+
};
30+
newDataSet[lookerId] = {
31+
lookerData: res,
32+
error,
33+
msg: res.message,
34+
};
35+
return ({
36+
...state,
37+
dataSet: newDataSet,
38+
});
39+
}
40+
41+
/**
42+
* Creates a new Looker reducer with the specified initial state.
43+
* @param {Object} initialState Optional. Initial state.
44+
* @return {Function} Looker reducer.
45+
*/
46+
function create(initialState = {}) {
47+
const a = actions.looker;
48+
return handleActions({
49+
[a.getLookerDone]: onGetLookerDone,
50+
}, _.defaults(initialState, {
51+
dataSet: {},
52+
}));
53+
}
54+
55+
/**
56+
* Factory which creates a new reducer.
57+
* @return {Promise}
58+
* @resolves {Function(state, action): state} New reducer.
59+
*/
60+
export function factory() {
61+
return Promise.resolve(create());
62+
}
63+
64+
/**
65+
* @static
66+
* @member default
67+
* @desc Reducer with default initial state.
68+
*/
69+
export default create();

src/services/api.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { config, isomorphy } from 'topcoder-react-utils';
99
import { delay } from '../utils/time';
1010
import { setErrorIcon, ERROR_ICON_TYPES } from '../utils/errors';
1111

12+
config.API.V4 = 'https://api.topcoder.com/v4';
13+
1214
/* The minimal delay [ms] between API calls. To avoid problems with the requests
1315
* rate limits configured in Topcoder APIs, we throttle requests rate at the
1416
* client side, and at server-side, in dev mode (which is meant to be used for
@@ -265,3 +267,16 @@ export function getApiV3(token) {
265267
}
266268
return lastApiV3;
267269
}
270+
271+
let lastApiV4 = null;
272+
/**
273+
* Returns a new or existing Api object for Topcoder API V4
274+
* @param {String} token Optional. Auth token for Topcoder API V4.
275+
* @return {Api} API V4 service object.
276+
*/
277+
export function getApiV4(token) {
278+
if (!lastApiV4 || lastApiV4.private.token !== token) {
279+
lastApiV4 = new Api(config.API.V4, token);
280+
}
281+
return lastApiV4;
282+
}

src/services/looker.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @module "services.looker"
3+
* @desc This module provides a service to get look data json
4+
* via API V4.
5+
*/
6+
import { getApiResponsePayloadV4 } from '../utils/tc';
7+
import { getApiV4 } from './api';
8+
9+
/**
10+
* Service class.
11+
*/
12+
class LookerService {
13+
/**
14+
* @param {String} tokenV4 Optional. Auth token for Topcoder API v4.
15+
*/
16+
constructor(tokenV4) {
17+
this.private = {
18+
api: getApiV4(tokenV4),
19+
tokenV4,
20+
};
21+
}
22+
23+
/**
24+
* Get json look data by id.
25+
* @param {String} lookerId Look id.
26+
* @return {Promise} Resolves to the json data.
27+
*/
28+
async getLooker(lookerId) {
29+
const res = await this.private.api.get(`/looks/${lookerId}/run/json`);
30+
return getApiResponsePayloadV4(res);
31+
}
32+
}
33+
34+
let lastInstance = null;
35+
/**
36+
* Returns a new or existing looker service.
37+
* @param {String} tokenV4 Optional. Auth token for Topcoder API v4.
38+
* @return {LookerService} looker service object
39+
*/
40+
export function getService(tokenV4) {
41+
if (!lastInstance || tokenV4 !== lastInstance.private.tokenV4) {
42+
lastInstance = new LookerService(tokenV4);
43+
}
44+
return lastInstance;
45+
}
46+
47+
/* Using default export would be confusing in this case. */
48+
export default undefined;

src/utils/tc.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,27 @@ export async function getApiResponsePayloadV3(res) {
3737
if (!x.success) throw new Error(x.content);
3838
return x.content;
3939
}
40+
41+
42+
/**
43+
* Gets payload from a standard success response from TC API v4; or throws
44+
* an error in case of a failure response.
45+
* @param {Object} res
46+
* @return {Promise} Resolves to the payload.
47+
*/
48+
export async function getApiResponsePayloadV4(res) {
49+
const resJson = await res.json();
50+
if (Array.isArray(resJson)) {
51+
return {
52+
res: resJson,
53+
error: false,
54+
};
55+
}
56+
57+
const x = resJson.result;
58+
return {
59+
res: x.content,
60+
error: !x.success,
61+
status: x.status,
62+
};
63+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy