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

Swik 1827 loading indicator for info panel #754

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7e59b60
Improved the efficiency when loading InfoPanel and InfoPanelView.
Feb 8, 2018
24d0af9
Removed temporary logging for debugging purposes.
Feb 9, 2018
a696627
Merge branch 'master' into swik-1827-loading-indicator-for-info-panel
kadevgraaf Feb 9, 2018
011a371
fix linking errors
kadevgraaf Feb 9, 2018
cd39196
Fixed the code style problem.
Feb 9, 2018
8cecbee
Merge branch 'swik-1827-loading-indicator-for-info-panel' of github.c…
Feb 9, 2018
e3d66ab
Merge branch 'master' into swik-1827-loading-indicator-for-info-panel
kadevgraaf Feb 19, 2018
0ecf5b9
Merge branch 'master' into swik-1827-loading-indicator-for-info-panel
Feb 22, 2018
91c8dba
Added loading indicator on the right side of the slide view.
Feb 23, 2018
dc110f2
Removed unnecessary logging.
Feb 23, 2018
ea22d0c
When removing the loading indicator taken into account if the activit…
Feb 23, 2018
86b7419
Merge branch 'master' into swik-1827-loading-indicator-for-info-panel
kadevgraaf Mar 14, 2018
32a917b
Merge branch 'master' into swik-1827-loading-indicator-for-info-panel
kadevgraaf Apr 23, 2018
06e3372
Merge branch 'master' into swik-1827-loading-indicator-for-info-panel
kadevgraaf Jun 7, 2018
aa0ad36
Merge remote-tracking branch 'origin/master' into swik-1827-loading-i…
Sep 20, 2018
645f55f
Merge remote-tracking branch 'origin/swik-1827-loading-indicator-for-…
Sep 20, 2018
2026f74
Merge branch 'master' into swik-1827-loading-indicator-for-info-panel
abijames Sep 24, 2018
4417aed
Merge branch 'master' into swik-1827-loading-indicator-for-info-panel
vkovtun Oct 23, 2018
71898e1
Fixed merging error.
Oct 23, 2018
9a75ebe
update reveal.js
kadevgraaf Oct 29, 2018
9befdbe
Merge branch 'master' into swik-1827-loading-indicator-for-info-panel
Nov 30, 2018
6aef2be
Fixed not working loading indicator after someone deleted InfoPanel.j…
Nov 30, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ slidewiki
migrate
.idea/
package-lock.json
*.iml
2 changes: 2 additions & 0 deletions actions/loadContributors.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export default function loadContributors(context, payload, done) {
return;
}

context.dispatch('LOAD_CONTRIBUTORS_LOAD', {loadingIndicator: true});

context.service.read('contributors.list', payload, {timeout: 20 * 1000}, (err, res) => {
if (err) {
log.error(context, {filepath: __filename});
Expand Down
38 changes: 37 additions & 1 deletion common.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,41 @@ export default {
isEmailAddress: (email) => {
let re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
},

equals: function(x, y) {
if (x === y) return true;
// if both x and y are null or undefined and exactly the same

if (! (x instanceof Object) || ! (y instanceof Object)) return false;
// if they are not strictly equal, they both need to be Objects

if (x.constructor !== y.constructor) return false;
// they must have the exact same prototype chain, the closest we can do is
// test there constructor.

for (let p in x) {
if (! x.hasOwnProperty(p)) continue;
// other properties were tested using x.constructor === y.constructor

if (! y.hasOwnProperty(p)) return false;
// allows to compare x[p] and y[p] when set to undefined

if (x[p] === y[p]) continue;
// if they have the same strict value or identity then they are equal

if (typeof(x[p]) !== 'object') return false;
// Numbers, Strings, Functions, Booleans must be strictly equal

if (! exports.default.equals(x[p], y[p])) return false;
// Objects and Arrays must be tested recursively
}

for (let p in y) {
if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) return false;
// allows x[p] to be set to undefined
}

return true;
},
};
3 changes: 1 addition & 2 deletions components/Deck/ActivityFeedPanel/ActivityFeedPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ class ActivityFeedPanel extends React.Component {

return (
<div ref="activityFeedPanel">
<h5 className="ui small header" tabIndex="0">Activity Feed
</h5>
<h5 className="ui small header" tabIndex="0">Activity Feed</h5>
<div className="ui basic segment" style={panelDIVStyles}>
{activityDIV}
</div>
Expand Down
2 changes: 2 additions & 0 deletions components/Deck/ActivityFeedPanel/ActivityList.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class ActivityList extends React.Component {
// TODO: same as in the ActivityFeedStore; check if there is more elegant way to tell the component that action loadMoreActivities (in the onScroll function) was executed
if (!nextProps.ActivityFeedStore.wasFetch) return;
this.loading = false;
let activitiesCount = this.props.ActivityFeedStore.activities.length;
console.log('ActivityList.componentWillReceiveProps() [' + 'activitiesCount=' + activitiesCount + ']');
}
render() {
return (
Expand Down
38 changes: 29 additions & 9 deletions components/Deck/InfoPanel/InfoPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,47 @@ import {connectToStores} from 'fluxible-addons-react';
import classNames from 'classnames';
import InfoPanelHeader from './InfoPanelHeader';
import InfoPanelInfoView from './InfoPanelInfoView';

import {equals} from '../../../common.js';
import ContributorsStore from '../../../stores/ContributorsStore';

class InfoPanel extends React.Component {
constructor(props) {
super(props);
this.isLoading = this.isContentUndefined();
}

render() {
const rootNodeStyles = {
fontSize: '1.06em'
};
shouldComponentUpdate(nextProps, nextState) {
let samePropsState = equals(this.props, nextProps);
this.isLoading = this.isContentUndefined();
// Content should be updated only when properties have changed.
return !this.isLoading && !samePropsState;
}

componentWillReceiveProps(nextProps) {
this.isLoading = this.isContentUndefined();
}

componentWillUnmount() {
this.props.ContributorsStore.contributors = [];
this.isLoading = true;
}

return (
<InfoPanelInfoView />
);
isContentUndefined() {
return this.props.ContributorsStore.contributors === undefined
|| this.props.ContributorsStore.contributors === [];
}

render() {
return (<InfoPanelInfoView loadingIndicator={this.props.ContributorsStore.loadingIndicator}/>);
}
}

InfoPanel.contextTypes = {
executeAction: React.PropTypes.func.isRequired
};
InfoPanel = connectToStores(InfoPanel, [], (context, props) => {
InfoPanel = connectToStores(InfoPanel, [ContributorsStore], (context, props) => {
return {
ContributorsStore: context.getStore(ContributorsStore).getState()
};
});

Expand Down
52 changes: 34 additions & 18 deletions components/Deck/InfoPanel/InfoPanelInfoView.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,28 @@ import React from 'react';
import {NavLink} from 'fluxible-router';
import {connectToStores} from 'fluxible-addons-react';
import DeckTreeStore from '../../../stores/DeckTreeStore';
//import ActivityList from '../ActivityFeedPanel/ActivityList';
import ActivityFeedPanel from '../ActivityFeedPanel/ActivityFeedPanel';
import ContributorsPanel from '../ContentModulesPanel/ContributorsPanel/ContributorsPanel';
import cheerio from 'cheerio';
import PresentationPanel from './PresentationsPanel';
import ActivityFeedStore from '../../../stores/ActivityFeedStore';

import {equals} from '../../../common.js';

class InfoPanelInfoView extends React.Component {
constructor(props) {
super(props);
this.isLoading = true;
}

shouldComponentUpdate(nextProps, nextState) {
let samePropsState = equals(this.props, nextProps);
this.isLoading = nextProps.loadingIndicator;
// Content should be updated only when properties have changed.
return !samePropsState;
}

getNameofNodes(tree, selector) {
if(!selector.get('spath')){
if (!selector.get('spath')) {
return 0;
}
let names = [];
Expand All @@ -23,12 +33,13 @@ class InfoPanelInfoView extends React.Component {
nodes.forEach ((node, index) => {
position = node.split(':')[1];
names.push(currentChildren.get(position - 1).get('title'));
if(currentChildren.get(position - 1).get('children')){
if (currentChildren.get(position - 1).get('children')) {
currentChildren = currentChildren.get(position - 1).get('children');
}
});
return names;
}

render() {
let deckTree = this.props.DeckTreeStore.deckTree;
let selector = this.props.DeckTreeStore.selector;
Expand Down Expand Up @@ -71,27 +82,32 @@ class InfoPanelInfoView extends React.Component {
});
title = list; //use title of slide
titlediv =
<div className="ui segment top attached compact">
<h3 className="ui small header">
<i className="grey small file text icon" aria-label="Slide title"></i>
{title}
</h3>
</div>;

<div className="ui segment top attached compact">
<h3 className="ui small header">
<i className="grey small file text icon" aria-label="Slide title"></i>
{title}
</h3>
</div>;
}
else {
//title = rootNode.title;
//title = ''; //use title of deck
titlediv = '';

}

return (
<div className="ui container" ref="infoPanel" role="complementary">
{this.props.DeckTreeStore.revisionId !== this.props.DeckTreeStore.latestRevisionId &&
<div className="ui vertical segment"><NavLink className="" href={'/deck/' + selector.get('id').split('-')[0]}><i className='warning sign icon'></i>
Updated version available</NavLink>
</div>}
{titlediv}
{this.isLoading ? <div className="ui active dimmer"><div className="ui text loader">Loading</div></div> : ''}
{
this.props.DeckTreeStore.revisionId !== this.props.DeckTreeStore.latestRevisionId &&
<div className="ui vertical segment">
<NavLink className="" href={'/deck/' + selector.get('id').split('-')[0]}>
<i className='warning sign icon'></i>
Updated version available
</NavLink>
</div>
}
{titlediv}
<div className="ui attached segment">
<ContributorsPanel />
</div>
Expand Down Expand Up @@ -125,7 +141,7 @@ InfoPanelInfoView.contextTypes = {
InfoPanelInfoView= connectToStores(InfoPanelInfoView, [ActivityFeedStore, DeckTreeStore], (context, props) => {
return {
ActivityFeedStore: context.getStore(ActivityFeedStore).getState(),
DeckTreeStore: context.getStore(DeckTreeStore).getState()
DeckTreeStore: context.getStore(DeckTreeStore).getState(),
};
});
export default InfoPanelInfoView;
13 changes: 11 additions & 2 deletions stores/ContributorsStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@ class ContributorsStore extends BaseStore {
this.translators = [];
this.listName = '';
this.selector = {};
this.loadingIndicator = false;
}
loading(payload){
this.loadingIndicator = payload.loadingIndicator;
this.emitChange();
}
updateContributors(payload) {
this.contributors = this.getContributors(payload.contributors);
this.creator = this.getCreator(payload.contributors);
this.translators = this.getTranslators(payload.contributors);
this.listName = payload.listName;
this.selector = payload.selector;
this.loadingIndicator = false;
this.emitChange();
}

Expand All @@ -24,7 +30,8 @@ class ContributorsStore extends BaseStore {
contributors: this.contributors,
creator: this.creator,
translators: this.translators,
selector: this.selector
selector: this.selector,
loadingIndicator: this.loadingIndicator
};
}
dehydrate() {
Expand All @@ -35,6 +42,7 @@ class ContributorsStore extends BaseStore {
this.creator = state.creator;
this.translators = state.translators;
this.selector = state.selector;
this.loadingIndicator = state.loadingIndicator;
}

getBasedonRole(role, list) {
Expand All @@ -60,7 +68,8 @@ class ContributorsStore extends BaseStore {

ContributorsStore.storeName = 'ContributorsStore';
ContributorsStore.handlers = {
'LOAD_CONTRIBUTORS_SUCCESS': 'updateContributors'
'LOAD_CONTRIBUTORS_SUCCESS': 'updateContributors',
'LOAD_CONTRIBUTORS_LOAD': 'loading'
};

export default ContributorsStore;