Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle users normalization #1460

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
Applies PR code review feedback
manuelurenah committed Jul 31, 2019
commit a138e895247556a2b7f3af4229cea4b017f5174e
8 changes: 4 additions & 4 deletions lib/drawers/contributors.vue
Original file line number Diff line number Diff line change
@@ -79,9 +79,9 @@
},
computed: {
contributors() {
return _.map(this.users, (user) => {
return this.users.map(user => {
user.formattedTime = formatStatusTime(user.updateTime);

return user;
}).reverse();
}
@@ -92,10 +92,10 @@
};
},
mounted() {
const usersIds = _.uniq(_.map(_.cloneDeep(_.get(this.$store, 'state.page.state.users')), (user) => user.id));
const usersIds = _.uniq(_.map(_.cloneDeep(_.get(this.$store, 'state.page.state.users')), user => user.id));

return getUsersData(usersIds)
.then((usersData) => {
.then(usersData => {
this.users = usersData;
});
},
6 changes: 3 additions & 3 deletions lib/drawers/layout-history.vue
Original file line number Diff line number Diff line change
@@ -126,11 +126,11 @@
return formattedHistory;
}
},
mounted: function () {
const usersIds = _.uniq(_.flatMap(_.map(_.get(this.$store, 'state.page.state.history'), (history) => _.map(history.users, (user) => user.id))));
mounted() {
const usersIds = _.uniq(_.flatMap(_.map(_.get(this.$store, 'state.page.state.history'), history => _.map(history.users, user => user.id))));

return getUsersData(usersIds)
.then((usersData) => {
.then(usersData => {
this.$store.dispatch('saveUsers', usersData);

store.dispatch('fetchLayoutState');
6 changes: 2 additions & 4 deletions lib/drawers/page-history.vue
Original file line number Diff line number Diff line change
@@ -127,8 +127,8 @@
return formattedHistory;
}
},
mounted: function () {
const usersIds = _.uniq(_.flatMap(_.get(this.$store, 'state.page.state.history'), (history) => _.map(history.users, (user) => user.id)));
mounted() {
const usersIds = _.uniq(_.flatMap(_.get(this.$store, 'state.page.state.history'), history => _.map(history.users, user => user.id)));

return getUsersData(usersIds)
.then((usersData) => {
@@ -137,8 +137,6 @@
store.dispatch('getListData', { uri: pageUri() });
});
},
methods: {
},
components: {
UiButton,
avatar
15 changes: 9 additions & 6 deletions lib/nav/mutations.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
import _ from 'lodash';
import _set from 'lodash/set';
import {
CHANGE_FAVORITE_PAGE_CATEGORY,
SHOW_NAV_BACKGROUND,
HIDE_NAV_BACKGROUND,
SAVE_USERS
} from './mutationTypes';

export default {
const mutations = {
[CHANGE_FAVORITE_PAGE_CATEGORY]: (state, id) => {
_.set(state, 'ui.favoritePageCategory', id);
_set(state, 'ui.favoritePageCategory', id);

return state;
},
[SHOW_NAV_BACKGROUND]: (state) => {
_.set(state, 'ui.showNavBackground', true);
_set(state, 'ui.showNavBackground', true);

return state;
},
[HIDE_NAV_BACKGROUND]: (state) => {
_.set(state, 'ui.showNavBackground', false);
_set(state, 'ui.showNavBackground', false);

return state;
},
[SAVE_USERS]: (state, users) => {
_.set(state, 'users', users);
_set(state, 'users', users);

return state;
}
};

export default mutations;
2 changes: 1 addition & 1 deletion lib/nav/page-list-item.vue
Original file line number Diff line number Diff line change
@@ -302,7 +302,7 @@
return this.page.title ? _.truncate(this.page.title, { length: 75 }) : 'No Title';
},
users() {
const pageUsersData = _.flatMap(this.page.users, (user) => _.filter(_.get(this.$store, 'state.users'), (cacheUser) => cacheUser.id === user.id));
const pageUsersData = _.flatMap(this.page.users, user => _.filter(_.get(this.$store, 'state.users'), cacheUser => cacheUser.id === user.id));

return _.take(pageUsersData, 4);
}
15 changes: 5 additions & 10 deletions lib/nav/page-list.vue
Original file line number Diff line number Diff line change
@@ -270,7 +270,7 @@
selectMultipleSites(allSites) {
this.sites = _.map(this.sites, (site) => {
site.selected = allSites;

return site;
});
},
@@ -321,19 +321,14 @@
return postJSON(prefix + searchRoute, query).then((res) => {
const hits = _.get(res, 'hits.hits') || [],
total = _.get(res, 'hits.total'),
pages = _.map(hits, (hit) => Object.assign({}, hit._source, { uri: hit._id })),
usersIds = _.uniq(_.map(_.flatMap(pages, (page) => page.users), (user) => user.id));
pages = _.map(hits, hit => ({ ...hit._source, uri: hit._id })),
usersIds = _.uniq(_.map(_.flatMap(pages, page => page.users), user => user.id));

return getUsersData(usersIds)
.then((usersData) => {
.then(usersData => {
this.$store.dispatch('saveUsers', usersData);

if (offset === 0) {
this.pages = pages;
} else {
this.pages = this.pages.concat(pages);
}

this.pages = offset === 0 ? pages : this.pages.concat(pages);
this.offset = offset + pages.length;
this.total = total; // update the total for this particular query
// (it's used to hide the "load more" button)
51 changes: 32 additions & 19 deletions lib/utils/history.js
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ import isToday from 'date-fns/is_today';
import isTomorrow from 'date-fns/is_tomorrow';
import isValidDate from 'date-fns/is_valid';
import isYesterday from 'date-fns/is_yesterday';
import { generateUserUri } from '../utils/users';
import { generateUserUri } from './users';

function updateUsersList(users, currentUser, updateTime) {
const userIndex = _.findIndex(users, user => user.username === currentUser.username),
@@ -17,8 +17,10 @@ function updateUsersList(users, currentUser, updateTime) {
if (userIndex === -1) { // the user hasn't updated the page before
users.push(user);
} else if (userIndex > -1) {
// if the current user is in the list, but isn't at the end, we should move it to the end
// (if it's already at the end, we just want to update the updateTime for the user)
/*
* if the current user is in the list, but isn't at the end, we should move it to the end
* (if it's already at the end, we just want to update the updateTime for the user)
*/

users.splice(userIndex, 1); // remove user from list
users.push(user); // and add it to the end
@@ -107,23 +109,21 @@ export function formatHistoryToDisplay(history, cacheUsers) {
let formattedHistory = _.map(history, (event) => {
event.formattedTime = formatStatusTime(event.timestamp);
event.formattedAction = addEd(event.action);
event.users = _.compact(_.map(event.users, (user) => _.find(cacheUsers, (cacheUser) => cacheUser.id === user.id)));
event.users = _.compact(_.map(event.users, user => _.find(cacheUsers, cacheUser => cacheUser.id === user.id)));

if (event.users.length > 0) {
event.avatar = {
event.avatar = event.users.length
? {
name: event.users.slice(-1)[0].name || event.users.slice(-1)[0].username,
imageUrl: event.users.slice(-1)[0].imageUrl,
stacked: event.users.length > 1
};
} else {
event.avatar = {};
}
}
: {};

return event;
}).reverse();

// remove unschedule events created by the clay robot
formattedHistory = formattedHistory.filter((event) => !(event.action === 'unschedule' && _.find(event.users, (user) => user.username === 'robot' && user.provider === 'clay')));
formattedHistory = formattedHistory.filter(event => !(event.action === 'unschedule' && _.find(event.users, user => user.username === 'robot' && user.provider === 'clay')));

return formattedHistory;
}
@@ -142,23 +142,36 @@ function formatStatusTime(date) {

if (isToday(date)) {
return distanceInWordsToNow(date, { includeSeconds: false, addSuffix: true });
} else if (isTomorrow(date)) {
}

if (isTomorrow(date)) {
return 'Tomorrow';
} else if (isYesterday(date)) {
}

if (isYesterday(date)) {
return 'Yesterday';
} else if (isThisYear(date)) {
}

if (isThisYear(date)) {
return dateFormat(date, 'M/D');
} else {
return dateFormat(date, 'M/D/YY');
}

return dateFormat(date, 'M/D/YY');
}

/**
* Transforms a word into the past tense.
* @param {string} word
* @returns {string}
*/
function addEd(word) {
if (!word.length) {
return word;
} else if (word[word.length - 1] === 'e') {
}

if (word[word.length - 1] === 'e') {
return `${word}d`;
} else {
return `${word}ed`;
}

return `${word}ed`;
}
2 changes: 1 addition & 1 deletion lib/utils/history.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as lib from './history';
import subMinutes from 'date-fns/sub_minutes';
import differenceInMinutes from 'date-fns/difference_in_minutes';
import * as lib from './history';

describe('history', () => {
describe('updateStateWithAction', () => {
46 changes: 28 additions & 18 deletions lib/utils/users.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import _ from 'lodash';
import store from '../../lib/core-data/store';
import { postJSON, getJSON } from '../../lib/core-data/api';
import { searchRoute, usersRoute } from '../utils/references';
import _get from 'lodash/get';
import store from '../core-data/store';
import { postJSON, getJSON } from '../core-data/api';
import { searchRoute, usersRoute } from './references';

/**
* Makes a query to get the users full data object from Elastic
* @param {string[]} usersIds to stub for testing
* @returns {Promise<Object[]>}
*/
export function getUsersData(usersIds) {
const prefix = _.get(store, 'state.site.prefix'),
function getUsersData(usersIds) {
const prefix = _get(store, 'state.site.prefix'),
usersQuery = {
index: 'users',
body: {
@@ -25,12 +25,10 @@ export function getUsersData(usersIds) {

return postJSON(prefix + searchRoute, usersQuery)
.then((response) => {
const usersDocs = _.get(response, 'hits.hits') || [],
usersData = _.map(usersDocs, (userDoc) => {
const usersDocs = _get(response, 'hits.hits') || [],
usersData = usersDocs.map((userDoc) => {
const id = generateUserUri(userDoc._source);

delete userDoc._ref;

return { id, ...userDoc._source };
});

@@ -43,9 +41,9 @@ export function getUsersData(usersIds) {
* @param {string} userId
* @returns {Object}
*/
export function getSingleUser(userId) {
const prefix = _.get(store, 'state.site.prefix'),
protocol = _.get(store, 'state.site.protocol');
function getSingleUser(userId) {
const prefix = _get(store, 'state.site.prefix'),
protocol = _get(store, 'state.site.protocol');

return getJSON(`${protocol}://${prefix}${usersRoute}${userId}`);
}
@@ -55,15 +53,27 @@ export function getSingleUser(userId) {
* @param {Object} userObject
* @returns {string}
*/
export function generateUserUri(userObject) {
function generateUserUri(userObject) {
return btoa(`${userObject.username}@${userObject.provider}`);
}

export function decodeUserUri(userUri) {
const userData = atob(userUri).split('@');
/**
* Decodes a user uri into username and provider
* @param {string} userUri
* @returns {Object}
*/
function decodeUserUri(userUri) {
const [username, domain, provider] = atob(userUri).split('@');

return {
username: `${userData[0]}@${userData[1]}`,
provider: userData[2]
username: `${username}@${domain}`,
provider
};
}

export {
getUsersData,
getSingleUser,
generateUserUri,
decodeUserUri
};