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

Ability to "search as client" from their public profile #619

Merged
merged 3 commits into from
Dec 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions src/Components/BidTracker/BidTracker.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { get } from 'lodash';
import SearchAsClientButton from 'Components/BidderPortfolio/SearchAsClientButton/SearchAsClientButton';
import { BID_LIST, NOTIFICATION_LIST, USER_PROFILE } from '../../Constants/PropTypes';
import BidTrackerCardList from './BidTrackerCardList';
import ProfileSectionTitle from '../ProfileSectionTitle';
Expand All @@ -18,6 +19,7 @@ userProfileIsLoading, isPublic, useCDOView }) => {
return (
<div className="usa-grid-full profile-content-inner-container bid-tracker-page">
<BackButton />
{ isPublic && <SearchAsClientButton user={userProfile} /> }
{
!isPublic &&
<NotificationsSection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@ export class SearchAsClientButton extends Component {
super(props);
this.onClick = this.onClick.bind(this);
this.state = {
hasPushed: false,
clicked: false,
};
}

componentWillReceiveProps(nextProps) {
const { hasPushed } = this.state;
const { clicked } = this.state;
const { client, isLoading, hasErrored, history, user } = nextProps;
const { perdet_seq_number: id } = user;
if (client.perdet_seq_number === id && client && client.perdet_seq_number &&
!isLoading && !hasErrored && !hasPushed) {
!isLoading && !hasErrored && clicked) {
const query = genSearchParams(user);
this.setState({ hasPushed: true }, () => {
this.setState({ clicked: false }, () => {
setTimeout(() => {
history.push(`/results?${query}`);
const offset = document.getElementById(ID).offsetTop;
Expand All @@ -58,15 +58,17 @@ export class SearchAsClientButton extends Component {
const { set, user, isLoading } = this.props;
const { perdet_seq_number: id } = user;
if (!isLoading) {
set(id);
this.setState({
clicked: true,
}, () => set(id));
}
}

render() {
const { buttonProps, className } = this.props;
return (
<button
className={`usa-button-primary ${className}`}
className={`usa-button-primary search-as-client-button ${className}`}
onClick={this.onClick}
{...buttonProps}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,19 @@ describe('SearchAsClientButton', () => {
expect(wrapper).toBeDefined();
});

it('sets state and pushes to history when newProps client.id matches id', (done) => {
it('sets pushes to history when newProps client.id matches id', (done) => {
const spy = sinon.spy();
global.document.getElementById = () => ({ offsetTop: '50px' });
const wrapper = shallow(<SearchAsClientButton {...props} />);
wrapper.simulate('click');
wrapper.setProps({
...props,
client: { perdet_seq_number: 1 },
history: { push: spy },
client: { perdet_seq_number: 1 },
isLoading: false,
hasErrored: false,
});
setTimeout(() => {
expect(wrapper.instance().state.hasPushed).toBe(true);
sinon.assert.calledOnce(spy);
done();
}, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

exports[`SearchAsClientButton matches snapshot 1`] = `
<button
className="usa-button-primary "
className="usa-button-primary search-as-client-button "
onClick={[Function]}
>
Search as Client
Expand Down
39 changes: 26 additions & 13 deletions src/Components/ClientHeader/ClientHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@ import { Link } from 'react-router-dom';
import { withRouter } from 'react-router';
import FA from 'react-fontawesome';
import { get } from 'lodash';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { BIDDER_OBJECT } from '../../Constants/PropTypes';
import { unsetClient } from '../../actions/clientView';
import { isCurrentPath } from '../ProfileMenu/navigation';
import { tertiaryCoolBlueLighter, tertiaryCoolBlueLightest } from '../../sass/sass-vars/variables';

export const ID = 'client-header';

const skeletonColors = {
highlightColor: tertiaryCoolBlueLighter,
color: tertiaryCoolBlueLightest,
};

export class ClientHeader extends Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -62,36 +69,42 @@ export class ClientHeader extends Component {
const { client, isLoading, hasErrored, bidderPortfolioSelectedCDO } = this.props;
const name = client && client.name ? client.name : 'Unknown user';

const isSuccess = client && !!client.perdet_seq_number && !isLoading && !hasErrored;
const isSuccess = !!(client && !!client.perdet_seq_number && !isLoading && !hasErrored);

const proxyName = get(bidderPortfolioSelectedCDO, 'name') && !get(bidderPortfolioSelectedCDO, 'isCurrentUser') ?
get(bidderPortfolioSelectedCDO, 'name') : '';

const renderHeader = () => (
<div className="usa-banner client-header">
<div className={`usa-banner client-header ${isLoading ? 'client-header--is-loading' : ''}`}>
<div className="usa-grid usa-banner-inner">
<div className={!showReturnLink ? 'hidden' : ''}>
<Link to={`/profile/public/${client.perdet_seq_number}`}>
<FA name="chevron-left" />
<span>Client Dashboard</span>
</Link>
<SkeletonTheme {...skeletonColors}>
{!isLoading ? <Link to={`/profile/public/${client.perdet_seq_number}`}>
<FA name="chevron-left" />
<span>Client Dashboard</span>
</Link> : <Skeleton width="75%" duration={1.8} />}
</SkeletonTheme>
</div>
<div>
<FA name="clipboard" />
<span id="search-as-name">Position Search for {name}{!!proxyName && ` (Proxying as ${proxyName})`}</span>
<SkeletonTheme {...skeletonColors}>
{!isLoading ? <span><FA name="clipboard" />
<span id="search-as-name">Position Search for {name}{!!proxyName && ` (Proxying as ${proxyName})`}</span></span> : <Skeleton width="75%" duration={1.8} />}
</SkeletonTheme>
</div>
<div>
<button className="unstyled-button" onClick={this.unsetClient}>
<FA name="close" />
<span>Exit client view</span>
</button>
<SkeletonTheme {...skeletonColors}>
{!isLoading ? <button className="unstyled-button" onClick={this.unsetClient}>
<FA name="close" />
<span>Exit client view</span>
</button> : <Skeleton width="75%" duration={1.8} />}
</SkeletonTheme>
</div>
</div>
</div>
);
return (
<div id={ID}>
{isSuccess && renderHeader()}
{isSuccess || isLoading ? renderHeader() : null}
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,66 @@ exports[`ClientHeader matches snapshot 1`] = `
id="client-header"
>
<div
className="usa-banner client-header"
className="usa-banner client-header "
>
<div
className="usa-grid usa-banner-inner"
>
<div
className=""
>
<Link
replace={false}
to="/profile/public/1"
<SkeletonTheme
color="#DCE4EF"
highlightColor="#8BA6CA"
>
<FontAwesome
name="chevron-left"
/>
<span>
Client Dashboard
</span>
</Link>
<Link
replace={false}
to="/profile/public/1"
>
<FontAwesome
name="chevron-left"
/>
<span>
Client Dashboard
</span>
</Link>
</SkeletonTheme>
</div>
<div>
<FontAwesome
name="clipboard"
/>
<span
id="search-as-name"
<SkeletonTheme
color="#DCE4EF"
highlightColor="#8BA6CA"
>
Position Search for
Mary
</span>
<span>
<FontAwesome
name="clipboard"
/>
<span
id="search-as-name"
>
Position Search for
Mary
</span>
</span>
</SkeletonTheme>
</div>
<div>
<button
className="unstyled-button"
onClick={[Function]}
<SkeletonTheme
color="#DCE4EF"
highlightColor="#8BA6CA"
>
<FontAwesome
name="close"
/>
<span>
Exit client view
</span>
</button>
<button
className="unstyled-button"
onClick={[Function]}
>
<FontAwesome
name="close"
/>
<span>
Exit client view
</span>
</button>
</SkeletonTheme>
</div>
</div>
</div>
Expand Down
6 changes: 4 additions & 2 deletions src/Components/ProfileDashboard/ProfileDashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import { Flag } from 'flag';
import { USER_PROFILE, NOTIFICATION_RESULTS, ASSIGNMENT_OBJECT, BID_RESULTS,
FAVORITE_POSITIONS_ARRAY, EMPTY_FUNCTION } from '../../Constants/PropTypes';
FAVORITE_POSITIONS_ARRAY, EMPTY_FUNCTION } from 'Constants/PropTypes';
import PermissionsWrapper from 'Containers/PermissionsWrapper';
import SearchAsClientButton from 'Components/BidderPortfolio/SearchAsClientButton/SearchAsClientButton';
import UserProfile from './UserProfile';
import BidList from './BidList';
import Notifications from './Notifications';
Expand All @@ -13,7 +15,6 @@ import MediaQueryWrapper from '../MediaQuery';
import Favorites from './Favorites';
import Assignments from './Assignments';
import SavedSearches from './SavedSearches/SavedSearchesWrapper';
import PermissionsWrapper from '../../Containers/PermissionsWrapper';
import BackButton from '../BackButton';
import BoxShadow from '../BoxShadow';
import Updates from './Updates';
Expand All @@ -31,6 +32,7 @@ const ProfileDashboard = ({
<div className="usa-grid-full">
<div className="usa-grid-full dashboard-top-section">
{ isPublic ? <BackButton /> : <ProfileSectionTitle title={`Hello, ${userProfile.display_name}`} /> }
{ isPublic && <SearchAsClientButton user={userProfile} /> }
</div>
<MediaQueryWrapper breakpoint="screenLgMin" widthType="max">
{(matches) => {
Expand Down
58 changes: 33 additions & 25 deletions src/Components/ProfileDashboard/ProfileDashboard.test.jsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,63 @@
import React from 'react';
import { shallow } from 'enzyme';
import toJSON from 'enzyme-to-json';
import { toString } from 'lodash';
import ProfileDashboard from './ProfileDashboard';
import { bidderUserObject } from '../../__mocks__/userObject';
import assignmentObject from '../../__mocks__/assignmentObject';
import notificationsObject from '../../__mocks__/notificationsObject';
import bidListObject from '../../__mocks__/bidListObject';

describe('ProfileDashboardComponent', () => {
const props = {
userProfile: bidderUserObject,
assignment: assignmentObject,
isLoading: false,
assignmentIsLoading: false,
notifications: notificationsObject.results,
notificationsIsLoading: false,
bidList: bidListObject.results,
bidListIsLoading: false,
};

it('is defined', () => {
const wrapper = shallow(
<ProfileDashboard
userProfile={bidderUserObject}
assignment={assignmentObject}
isLoading={false}
assignmentIsLoading={false}
notifications={notificationsObject.results}
notificationsIsLoading={false}
bidList={bidListObject.results}
bidListIsLoading={false}
/>);
<ProfileDashboard {...props} />);
expect(wrapper).toBeDefined();
});

it('is defined when isPublic', () => {
const wrapper = shallow(
<ProfileDashboard {...props} isPublic />);
expect(wrapper).toBeDefined();
});

it('displays the Search as Client button when isPublic', () => {
const wrapper = shallow(
<ProfileDashboard {...props} isPublic />);

// Really hacky.
// This did not work: wrapper.find('Connect(withRouter(SearchAsClientButton))').exists()
expect(toString(wrapper.debug())).toMatch(/SearchAsClientButton/);
wrapper.setProps({ ...props, isPublic: false });
wrapper.update();
expect(toString(wrapper.debug())).not.toMatch(/SearchAsClientButton/);
});

it('matches snapshot when loading', () => {
const wrapper = shallow(
<ProfileDashboard
userProfile={bidderUserObject}
assignment={assignmentObject}
{...props}
isLoading
assignmentIsLoading
notifications={notificationsObject.results}
notificationsIsLoading
bidList={bidListObject.results}
bidListIsLoading={false}
/>);
expect(toJSON(wrapper)).toMatchSnapshot();
});

it('matches snapshot when loaded', () => {
const wrapper = shallow(
<ProfileDashboard
userProfile={bidderUserObject}
assignment={assignmentObject}
isLoading={false}
assignmentIsLoading={false}
notifications={notificationsObject.results}
notificationsIsLoading={false}
bidList={bidListObject.results}
bidListIsLoading={false}
/>);
<ProfileDashboard {...props} />);
expect(toJSON(wrapper)).toMatchSnapshot();
});
});
4 changes: 4 additions & 0 deletions src/sass/_bidTracker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ $draft-icon-offset: 120px;
.bid-tracker-page {
position: relative;

.search-as-client-button {
float: right;
}

.bid-tracker-greeting {
margin-bottom: 40px;
}
Expand Down
Loading