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

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

package.json

Lines changed: 3 additions & 1 deletion
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 70 additions & 0 deletions
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

Lines changed: 7 additions & 0 deletions
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

Lines changed: 17 additions & 0 deletions
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

Lines changed: 8 additions & 0 deletions
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

Lines changed: 114 additions & 0 deletions
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

Lines changed: 13 additions & 0 deletions
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

Lines changed: 56 additions & 0 deletions
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();

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