Skip to content

Commit 9d27eb7

Browse files
Add support for user traits
1 parent ee387c9 commit 9d27eb7

File tree

12 files changed

+7648
-6315
lines changed

12 files changed

+7648
-6315
lines changed

package-lock.json

+7,248-6,314
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@
2222
},
2323
"scripts": {
2424
"build": "npm run clean && ./node_modules/.bin/webpack --env=production --progress --profile --colors --display-optimization-bailout",
25+
"dev": "npm run clean && ./node_modules/.bin/webpack --env=production --progress --profile --colors --watch --display-optimization-bailout",
2526
"clean": "rimraf dist",
2627
"jest": "jest --no-cache --maxWorkers=4 --config config/jest/default.js",
2728
"lint": "npm run lint:js",
2829
"lint:js": "./node_modules/.bin/eslint --ext .js,.jsx .",
2930
"test": "npm run lint && npm run jest"
3031
},
31-
"version": "0.2.0",
32+
"version": "0.2.1",
3233
"dependencies": {
3334
"auth0-js": "^6.8.4",
3435
"isomorphic-fetch": "^2.2.1",
@@ -43,6 +44,7 @@
4344
"redux": "^3.7.2",
4445
"redux-actions": "^2.4.0",
4546
"tc-accounts": "https://github.com/appirio-tech/accounts-app.git#dev",
47+
"to-capital-case": "^1.0.0",
4648
"topcoder-react-utils": "^0.4.3"
4749
},
4850
"devDependencies": {

src/actions/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import memberActions from './members';
1111
import memberTaskActions from './member-tasks';
1212
import reviewOpportunityActions from './reviewOpportunity';
1313
import lookupActions from './lookup';
14+
import uiActions from './ui';
15+
import settingsActions from './settings';
1416

1517
export const actions = {
1618
auth: authActions.auth,
@@ -26,6 +28,8 @@ export const actions = {
2628
memberTasks: memberTaskActions.memberTasks,
2729
reviewOpportunity: reviewOpportunityActions.reviewOpportunity,
2830
lookup: lookupActions.lookup,
31+
ui: uiActions.ui,
32+
settings: settingsActions.settings,
2933
};
3034

3135
export default undefined;

src/actions/settings.js

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* @module "actions.settings"
3+
* @desc Actions related to settings page.
4+
*/
5+
6+
import { createActions } from 'redux-actions';
7+
import { getService } from '../services/user-traits';
8+
9+
/**
10+
* @static
11+
* @desc Creates an action that loads user's all traits.
12+
* @param {String} uuid Operation UUID.
13+
* @param {String} tokenV3 v3 auth token.
14+
* @return {Action}
15+
*/
16+
17+
async function getAllUserTraits(handle, tokenV3) {
18+
const data = await getService(tokenV3).getAllUserTraits(handle);
19+
return { data, handle };
20+
}
21+
22+
/**
23+
* @static
24+
* @desc Creates an action that add trait by trait id.
25+
* @param {String} handle member's handle.
26+
* @param {String} traitId trait id.
27+
* @param {Array} data trait data array.
28+
* @param {String} tokenV3 v3 auth token.
29+
* @return {Action}
30+
*/
31+
async function addUserTrait(handle, traitId, data, tokenV3) {
32+
const result = await getService(tokenV3).addUserTrait(handle, traitId, data);
33+
return { result, handle, traitId };
34+
}
35+
36+
/**
37+
* @static
38+
* @desc Creates an action that update trait by trait id.
39+
* @param {String} handle member's handle.
40+
* @param {String} traitId trait id.
41+
* @param {Array} data trait data array.
42+
* @param {String} tokenV3 v3 auth token.
43+
* @return {Action}
44+
*/
45+
async function updateUserTrait(handle, traitId, data, tokenV3) {
46+
const result = await getService(tokenV3).updateUserTrait(handle, traitId, data);
47+
return { result, handle, traitId };
48+
}
49+
50+
/**
51+
* @static
52+
* @desc Creates an action that delete trait by trait id.
53+
* @param {String} handle member's handle.
54+
* @param {String} traitId trait id.
55+
* @param {String} tokenV3 v3 auth token.
56+
* @return {Action}
57+
*/
58+
async function deleteUserTrait(handle, traitId, tokenV3) {
59+
const data = await getService(tokenV3).deleteUserTrait(handle, traitId);
60+
return { data, handle, traitId };
61+
}
62+
63+
export default createActions({
64+
SETTINGS: {
65+
GET_ALL_USER_TRAITS: getAllUserTraits,
66+
ADD_USER_TRAIT: addUserTrait,
67+
DELETE_USER_TRAIT: deleteUserTrait,
68+
UPDATE_USER_TRAIT: updateUserTrait,
69+
},
70+
});

src/actions/ui/index.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import settingsActions from './settings';
2+
3+
export default {
4+
ui: {
5+
settings: settingsActions.settings,
6+
},
7+
};

src/actions/ui/settings.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Actions for settings page UI.
3+
*/
4+
import _ from 'lodash';
5+
import { createActions } from 'redux-actions';
6+
7+
8+
export default createActions({
9+
SETTINGS: {
10+
PROFILE: {
11+
TOGGLE_TAB: _.identity,
12+
},
13+
TOOLS: {
14+
TOGGLE_TAB: _.identity,
15+
},
16+
},
17+
});

src/reducers/index.js

+8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import reviewOpportunity, { factory as reviewOpportunityFactory }
1818
from './reviewOpportunity';
1919
import mySubmissionsManagement, { factory as mySubmissionsManagementFactory }
2020
from './my-submissions-management';
21+
import ui, { factory as uiFactory }
22+
from './ui';
23+
import settings, { factory as settingsFactory }
24+
from './settings';
2125

2226

2327
export function factory(options) {
@@ -35,6 +39,8 @@ export function factory(options) {
3539
memberTasks: memberTasksFactory(options),
3640
reviewOpportunity: reviewOpportunityFactory(options),
3741
mySubmissionsManagement: mySubmissionsManagementFactory(options),
42+
ui: uiFactory(options),
43+
settings: settingsFactory(options),
3844
});
3945
}
4046

@@ -52,4 +58,6 @@ export default ({
5258
memberTasks,
5359
reviewOpportunity,
5460
mySubmissionsManagement,
61+
ui,
62+
settings,
5563
});

src/reducers/settings.js

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/**
2+
* @module "reducers.settings"
3+
* @desc Reducer for the Redux store segment that holds traits data.
4+
*/
5+
6+
import { handleActions } from 'redux-actions';
7+
import logger from '../utils/logger';
8+
import actions from '../actions/settings';
9+
import { fireErrorMessage } from '../utils/errors';
10+
11+
/**
12+
* Handles SETTINGS/GET_ALL_USER_TRAITS action.
13+
* @param {Object} state
14+
* @param {Object} action
15+
* @return {Object} New state.
16+
*/
17+
function onGetAllUserTraits(state, { error, payload }) {
18+
if (error) {
19+
logger.error('Failed to get all user traits', payload);
20+
return {
21+
...state,
22+
userTraits: [],
23+
};
24+
}
25+
26+
return {
27+
...state,
28+
userTraits: payload.data,
29+
};
30+
}
31+
32+
/**
33+
* Handles SETTINGS/ADD_USER_TRAIT action.
34+
* @param {Object} state
35+
* @param {Object} action
36+
* @return {Object} New state.
37+
*/
38+
function onAddUserTrait(state, { error, payload }) {
39+
if (error) {
40+
logger.error('Failed to add user trait', payload);
41+
fireErrorMessage('Failed to add user trait', '');
42+
return state;
43+
}
44+
const newData = payload.result[0];
45+
return {
46+
...state,
47+
userTraits: [...state.userTraits, newData],
48+
};
49+
}
50+
51+
/**
52+
* Handles SETTINGS/UPDATE_USER_TRAIT action.
53+
* @param {Object} state
54+
* @param {Object} action
55+
* @return {Object} New state.
56+
*/
57+
function onUpdateUserTrait(state, { error, payload }) {
58+
if (error) {
59+
logger.error('Failed to update user trait', payload);
60+
fireErrorMessage('Failed to update user trait', '');
61+
return state;
62+
}
63+
const newData = payload.result[0];
64+
const newUserTraits = state.userTraits.filter(trait => trait.traitId !== payload.traitId);
65+
newUserTraits.push(newData);
66+
67+
return {
68+
...state,
69+
userTraits: newUserTraits,
70+
};
71+
}
72+
73+
/**
74+
* Handles SETTINGS/DELETE_USER_TRAIT action.
75+
* @param {Object} state
76+
* @param {Object} action
77+
* @return {Object} New state.
78+
*/
79+
function onDeleteUserTrait(state, { error, payload }) {
80+
if (error) {
81+
logger.error('Failed to delete user trait', payload);
82+
fireErrorMessage('Failed to delete user trait', '');
83+
return state;
84+
}
85+
const newUserTraits = state.userTraits.filter(trait => trait.traitId !== payload.traitId);
86+
return {
87+
...state,
88+
userTraits: newUserTraits,
89+
};
90+
}
91+
92+
93+
/**
94+
* Creates a new user trait reducer with the specified initial state.
95+
* @param {Object} initialState Optional. Initial state.
96+
* @return {Function} userTraits reducer.
97+
*/
98+
function create(initialState = {
99+
userTraits: [],
100+
}) {
101+
const a = actions.settings;
102+
return handleActions({
103+
[a.getAllUserTraits]: onGetAllUserTraits,
104+
[a.addUserTrait]: onAddUserTrait,
105+
[a.deleteUserTrait]: onDeleteUserTrait,
106+
[a.updateUserTrait]: onUpdateUserTrait,
107+
}, initialState);
108+
}
109+
110+
export function factory() {
111+
return Promise.resolve(create());
112+
}
113+
114+
export default create();

src/reducers/ui/index.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { combineReducers } from 'redux';
2+
3+
import settings from './settings';
4+
5+
export function factory() {
6+
return Promise.resolve(combineReducers({
7+
settings,
8+
}));
9+
}
10+
11+
export default combineReducers({
12+
settings,
13+
});

src/reducers/ui/settings.js

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Reducers for settings page UI.
3+
*/
4+
import _ from 'lodash';
5+
import { handleActions } from 'redux-actions';
6+
7+
import settingsActions from 'actions/ui/settings';
8+
9+
const TABS = {
10+
PROFILE: {
11+
BASIC: 'basic info',
12+
LANGUAGE: 'language',
13+
EDUCATION: 'education',
14+
WORK: 'work',
15+
ORGANIZATION: 'organization',
16+
SKILL: 'skill',
17+
HOBBY: 'hobby',
18+
COMMUNITY: 'community',
19+
},
20+
TOOLS: {
21+
DEVICES: 'device',
22+
SOFTWARE: 'software',
23+
PROVIDERS: 'service provider',
24+
SUBSCRIPTIONS: 'subscription',
25+
},
26+
};
27+
28+
const initState = {
29+
TABS,
30+
};
31+
32+
/**
33+
* Creates a new reducer.
34+
* @param {Object} state Optional. Initial state.
35+
* @return {Function} Reducer.
36+
*/
37+
function create(defaultState = initState) {
38+
const a = settingsActions.settings;
39+
return handleActions({
40+
[a.profile.toggleTab]: (state, { payload }) => ({ ...state, currentProfileTab: payload }),
41+
[a.tools.toggleTab]: (state, { payload }) => ({ ...state, currentToolsTab: payload }),
42+
}, _.defaults(defaultState, {
43+
currentProfileTab: TABS.PROFILE.BASIC,
44+
currentToolsTab: TABS.TOOLS.DEVICES,
45+
}));
46+
}
47+
48+
/**
49+
* Factory which creates a new reducer with its initial state tailored to the
50+
* @return Promise which resolves to the new reducer.
51+
*/
52+
export function factory() {
53+
return Promise.resolve(create());
54+
}
55+
56+
export default create();

src/services/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import * as reviewOpportunities from './reviewOpportunities';
1313
import * as userSetting from './user-settings';
1414
import * as user from './user';
1515
import * as lookup from './lookup';
16+
import * as userTraits from './user-traits';
1617

1718
export const services = {
1819
api,
@@ -27,6 +28,7 @@ export const services = {
2728
userSetting,
2829
reviewOpportunities,
2930
lookup,
31+
userTraits,
3032
};
3133

3234
export default undefined;

0 commit comments

Comments
 (0)