cluedin-widget
Version:
This is the project for creating and managing widgets in CluedIn.
465 lines (419 loc) • 19.8 kB
JSX
import React, { Component } from 'react'
import { goToLocation } from '../../core/action/core'
import CluedInProgress from '../../core/components/generics/cluedinprogress.jsx'
import Widget from '../../core/components/generics/widget.jsx'
import registry from '../../core/registry'
import DomainUsers from '../../core/components/users/DomainUsers.jsx'
import config from '../../core/config'
import IntegrationStatus from '../../core/components/providerRelated/integrationStatus.jsx'
import { connect } from 'react-redux'
import { fetchMostConnectedIfNeeded, removeWidget } from '../../core/action/core'
import { fetchActiveProvidersIfNeeded } from '../../core/action/provider'
import { fetchUsersIfNeeded, fetchPotentialUsersIfNeeded } from '../../core/action/user'
import { shouldFetchBoardingIfNeeded, fetchAllInvitations } from '../../core/action/boarding'
import { FormattedMessage, FormattedHTMLMessage } from 'react-intl'
export class OnBoarding extends Component {
componentWillMount() {
const { org } = this.props;
this.props.dispatch( fetchActiveProvidersIfNeeded() );
this.props.dispatch( fetchUsersIfNeeded() );
this.props.dispatch( fetchMostConnectedIfNeeded() );
this.props.dispatch( fetchPotentialUsersIfNeeded() );
this.props.dispatch( shouldFetchBoardingIfNeeded( org ) );
this.props.dispatch( fetchAllInvitations( org ) );
}
inviteUserHandler( email, name ) {
this.props.dispatch( goToLocation( 'goToInviteUser', { email, name } ) );
}
componentDidUpdate() {
if( this.mainContent ) {
setTimeout( function() {
if( this.mainContent.classList.contains( 'cluedIn_hide_slide' ) ) {
this.mainContent.classList.remove( 'cluedIn_hide_slide' );
this.mainContent.classList.add( 'cluedIn_show_slide' );
}
}.bind( this ), 1000 );
}
}
getTitle( step ) {
switch( step ) {
case 1:
return (
<span><FormattedMessage id="OnBoarding.Step1.Title"></FormattedMessage></span>
);
case 2:
return (
<span><FormattedMessage id="OnBoarding.Step2.Title"></FormattedMessage></span>
);
case 3:
return (
<span><FormattedMessage id="OnBoarding.Step3.Title"></FormattedMessage></span>
);
case 4:
return (
<span><FormattedMessage id="OnBoarding.Step4.Title"></FormattedMessage></span>
);
case 5:
return (
<span><FormattedMessage id="OnBoarding.Step5.Title"></FormattedMessage></span>
);
default:
return (
<span><FormattedMessage id="OnBoarding.Step0.Title"></FormattedMessage></span>
);
}
}
getMenu( step ) {
let isActiveStep0 = (step === 0) ? 'active' : '';
let isActiveStep1 = (step === 1) ? 'active' : '';
let isActiveStep2 = (step === 2) ? 'active' : '';
let isActiveStep3 = (step === 3) ? 'active' : '';
let isActiveStep4 = (step === 4) ? 'active' : '';
isActiveStep0 = (step > 0) ? 'done' : isActiveStep0;
isActiveStep1 = (step > 1) ? 'done' : isActiveStep1;
isActiveStep2 = (step > 2) ? 'done' : isActiveStep2;
isActiveStep3 = (step > 3) ? 'done' : isActiveStep3;
isActiveStep4 = (step > 4) ? 'done' : isActiveStep4;
return (
<ul className="cluedIn_progressive_menu cluedIn_m-b cluedIn_m-t">
<li className={isActiveStep0}><a><FormattedMessage id="OnBoarding.Step0.Menu"></FormattedMessage></a>
</li>
<li className={isActiveStep1}><a><FormattedMessage id="OnBoarding.Step1.Menu"></FormattedMessage></a>
</li>
<li className={isActiveStep2}><a><FormattedMessage id="OnBoarding.Step2.Menu"></FormattedMessage></a>
</li>
<li className={isActiveStep3}><a><FormattedMessage id="OnBoarding.Step3.Menu"></FormattedMessage></a>
</li>
<li className={isActiveStep4}><a><FormattedMessage id="OnBoarding.Step4.Menu"></FormattedMessage></a>
</li>
</ul>
)
}
step0Action() {
this.props.dispatch( goToLocation( 'addProvider' ) );
}
step2Action() {
this.props.dispatch( goToLocation( 'addProvider' ) );
}
step1Action( searchTerm ) {
this.props.dispatch( goToLocation( 'goToSearch', searchTerm ) );
}
step3Action( entity ) {
this.props.dispatch( goToLocation( 'entity', entity ) );
}
step4Action() {
this.props.dispatch( goToLocation( 'goToInviteUser' ) );
}
step5Action() {
let { layoutInformation } = this.props;
this.props.dispatch( removeWidget( 'OnBoarding', layoutInformation ) );
}
progress( step ) {
var percentage = ((step / 5) * 100);
var bigNumber = true;
return (<CluedInProgress withBigNumber={bigNumber} percentage={percentage}></CluedInProgress>);
}
content( step ) {
const { connectedData, providers, potentialUsers } = this.props;
switch( step ) {
case 1:
var step1TranslatedValue = {
name: providers[ 0 ].Name,
searchQuery: connectedData[ 0 ].name
};
return (
<div>
<div className="cluedIn_text_zone cluedIn_highlightText">
<FormattedHTMLMessage id="OnBoarding.Step1.Content"
values={step1TranslatedValue}></FormattedHTMLMessage>
<a onClick={this.step1Action.bind(this, connectedData[ 0 ].name)}
className="cluedIn_btn-primary clued_In_btn_big cluedIn_pulse-button cluedIn_btn">
<span className="cluedIn_addon"><i className="fa fa-search"></i></span>
<span>
<FormattedHTMLMessage id="OnBoarding.Step1.ContentAction"
values={step1TranslatedValue}></FormattedHTMLMessage>
</span>
</a>
</div>
</div>
);
case 2:
return (
<div>
<div className="cluedIn_text_zone cluedIn_highlightText">
<FormattedMessage id="OnBoarding.Step2.Content"></FormattedMessage>
</div>
<div className="cluedIn_text_zone cluedIn_highlightText">
In order to benefit from that:
</div>
<div className="cluedIn_text_zone">
<a onClick={this.step2Action.bind(this)}
className="cluedIn_btn-primary clued_In_btn_big cluedIn_pulse-button cluedIn_btn">
<span className="cluedIn_addon">
<i className="fa fa-plug"></i>
</span>
<span>
<FormattedMessage id="OnBoarding.Step2.ContentAction"></FormattedMessage>
</span>
</a>
</div>
</div>
);
case 3:
let step3TranslatedValue = {
name: providers[ 1 ].Name,
connectedData: connectedData[ 0 ].name
};
return (
<div>
<div className="cluedIn_text_zone cluedIn_highlightText">
<FormattedHTMLMessage id="OnBoarding.Step3.Content"
values={step3TranslatedValue}></FormattedHTMLMessage>
</div>
<div className="cluedIn_text_zone cluedIn_highlightText">
<a onClick={this.step3Action.bind(this, connectedData[ 0 ])}
className="cluedIn_btn-primary clued_In_btn_big cluedIn_pulse-button cluedIn_btn">
<FormattedHTMLMessage id="OnBoarding.Step3.ContentAction"
values={step3TranslatedValue}></FormattedHTMLMessage>
</a>
</div>
</div>
);
case 4:
let potentialContent = '';
let invitation = '';
let potentialUsersWithEmail = potentialUsers.filter( ( domainUser ) => {
return domainUser.Properties && domainUser.Properties.MetadataDictionary && domainUser.Properties.MetadataDictionary[ 'property-user.email' ];
} );
if( potentialUsersWithEmail && potentialUsersWithEmail.length > 0 ) {
invitation = (
<span><FormattedMessage id="OnBoarding.Step4.Content2"></FormattedMessage></span>);
potentialContent = (
<div className="cluedIn_line"><DomainUsers inviteClick={this.inviteUserHandler.bind(this)}
potentialUsers={potentialUsersWithEmail}></DomainUsers>
</div>);
}
return (
<div>
<div className="cluedIn_text_zone cluedIn_highlightText">
<FormattedMessage id="OnBoarding.Step4.Content"></FormattedMessage>
<br/><br/>
</div>
<div className="cluedIn_text_zone cluedIn_highlightText">
{invitation}
{potentialContent}
</div>
<div className="cluedIn_text_zone">
<a onClick={this.step4Action.bind(this)}
className="cluedIn_btn-primary clued_In_btn_big cluedIn_pulse-button cluedIn_btn">
<span className="cluedIn_addon">
<i className="fa fa-user-plus"></i>
</span>
<span>
<FormattedMessage id="OnBoarding.Step4.ContentAction"></FormattedMessage>
</span>
</a>
</div>
</div>
);
case 5:
return (
<div className="cluedIn_row">
<div className="cluedIn_col s3">
<img className="cluedIn_img_responsive" src={config.image.party} alt="Congratz!"/>
</div>
<div className="cluedIn_col s9">
<div className="cluedIn_text_zone">
<FormattedHTMLMessage id="OnBoarding.Step5.Content"></FormattedHTMLMessage>
</div>
<div className="cluedIn_text_zone">
<a onClick={this.step5Action.bind(this)}
className="cluedIn_btn-primary clued_In_btn_big cluedIn_pulse-button cluedIn_btn">
<span className="cluedIn_addon">
<i className="fa fa-trash-o "></i>
</span>
<span>
<FormattedMessage
id="OnBoarding.Step5.ContentAction"></FormattedMessage>
</span>
</a>
</div>
</div>
</div>
);
default:
return (
<div>
<div className="cluedIn_text_zone cluedIn_highlightText">
<FormattedMessage id="OnBoarding.Step0.Content"></FormattedMessage>
<br/>
</div>
<div className="cluedIn_text_zone">
<a onClick={this.step0Action.bind(this)}
className="cluedIn_btn-primary clued_In_btn_big cluedIn_pulse-button cluedIn_btn">
<span className="cluedIn_addon">
<i className="fa fa-plug"></i>
</span>
<span>
<FormattedMessage id="OnBoarding.Step0.ContentAction"></FormattedMessage>
</span>
</a>
</div>
</div>
);
}
}
getCrawlingContent() {
const { providers, crawlerStats } = this.props;
let integrationId = crawlerStats.integrationId;
let currentProvider = providers.filter( ( p ) => {
p.Id === integrationId;
} );
return (<div>
<div className="cluedIn_row">
<div className="cluedIn_col s12">
<div className="cluedIn_title">
<div className="textHeading h2">
We are analyzing your data.
</div>
<div ref={(ref) => this.mainContent = ref}
className="cluedIn_hide_slide cluedIn_m-t cluedIn_onBoarding_main">
<p>We are currently analyzing your data. Once we are done, you will receive an email to
inform you.</p>
<IntegrationStatus crawlerStats={crawlerStats}
provider={currentProvider}></IntegrationStatus>
</div>
</div>
</div>
</div>
</div>);
}
step( number ) {
if( number === -1 ) {
return this.getCrawlingContent();
}
var title = this.getTitle( number );
var menu = this.getMenu( number );
var content = this.content( number );
var progress = this.progress( number );
return (
<div>
<div className="cluedIn_row">
<div className="cluedIn_col s12">
<div className="cluedIn_title">
<div className="textHeading h2">
{title}
</div>
</div>
</div>
</div>
<div ref={(ref) => this.mainContent = ref}
className="cluedIn_hide_slide cluedIn_m-t cluedIn_onBoarding_main">
<div className="cluedIn_row">
<div className="cluedIn_col s12">
{menu}
</div>
</div>
<div className="cluedIn_row">
<div className="cluedIn_col s8">
<div className="cluedIn_onBoarding_content">
{content}
</div>
</div>
<div className="cluedIn_col s4">
{progress}
</div>
</div>
</div>
</div>
);
}
isLoading() {
let { isFetchingProvider, isFetchingUsers, isFetchingPotentialUsers, isFetchingBoardingInfo, isFetchingInvitations } = this.props;
return (isFetchingProvider || isFetchingUsers || isFetchingPotentialUsers || isFetchingBoardingInfo || isFetchingInvitations);
}
getStep() {
let { providers, hasSearched, hasVisitConnectedView, users, allInvitations, crawlerStats } = this.props;
let integrationId = crawlerStats.integrationId;
let step = 0;
if( providers && providers.length > 0 ) {
if( hasSearched ) {
if( providers.length > 1 ) {
if( hasVisitConnectedView ) {
if( users && users.length > 1 || allInvitations && allInvitations.length > 0 ) {
step = 5;
} else {
step = 4;
}
} else {
step = 3;
}
} else {
step = 2;
}
} else {
let currentProvider = providers.filter( ( p ) => {
return p.Id === integrationId;
} );
if( currentProvider.length === 0 ) {
step = 1;
} else {
step = -1;
}
}
}
if( step > 5 ) {
step = 0;
}
return step;
}
render() {
let content;
let step = 0;
let isLoading = this.isLoading();
if( !isLoading ) {
step = this.getStep();
content = this.step( step );
} else {
content = (<div>
<div className="cluedIn_row">
<div className="cluedIn_col s12">
<div className="cluedIn_title">
<div className="textHeading">
<div className="bounceball"></div>
<div className="bounceball"></div>
<div className="bounceball"></div>
Loading Configuration Panel
</div>
</div>
</div>
</div>
</div>);
}
let noScroll = true;
return (
<div><Widget noScroll={noScroll}>
{content}
</Widget></div>
);
}
}
function select( state ) {
return {
providers: state.provider.providers,
isFetchingProvider: state.provider.isFetching,
isFetchingUsers: state.user.isFetching,
users: state.user.users,
hasSearched: ( state.boarding.boardingInfo ? state.boarding.boardingInfo.hasSearched : false ),
hasVisitConnectedView: ( state.boarding.boardingInfo ? state.boarding.boardingInfo.hasVisited : false ),
isFetchingBoardingInfo: state.boarding.isFetching,
connectedData: state.core.connectedData,
org: state.core.org,
potentialUsers: state.user.potentialUsers,
isFetchingPotentialUsers: state.user.isFetchingPotentialUsers,
isFetchingInvitations: state.boarding.isFetchingInvitations,
allInvitations: state.boarding.allInvitations,
crawlerStats: state.provider.crawlerStats
};
}
registry.register( 'OnBoarding', connect( select )( OnBoarding ) );