Lk/update responsive view (#58)
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
.course-card {
|
||||
.card {
|
||||
.pgn__card-wrapper-image-cap.vertical {
|
||||
display: flex;
|
||||
min-height: $card-image-vertical-max-height;
|
||||
}
|
||||
.pgn__card-image-cap {
|
||||
border-bottom-left-radius: 0 !important;
|
||||
}
|
||||
@@ -11,6 +15,9 @@
|
||||
.pgn__card-header-content {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
.pgn__card-footer .pgn__action-row {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.course-card-verify-ribbon-container {
|
||||
width: 100%;
|
||||
|
||||
@@ -50,7 +50,7 @@ export const CertificateBanner = ({ cardId }) => {
|
||||
if (isArchived) {
|
||||
return (
|
||||
<Banner variant="warning">
|
||||
{formatMessage(messages.notEligibleForCert)}.
|
||||
{formatMessage(messages.notEligibleForCert)}
|
||||
{' '}
|
||||
<Hyperlink destination={progressUrl}>{formatMessage(messages.viewGrades)}</Hyperlink>
|
||||
</Banner>
|
||||
|
||||
@@ -101,7 +101,6 @@ exports[`CertificateBanner snapshot not passing and has finished 1`] = `
|
||||
variant="warning"
|
||||
>
|
||||
You are not eligible for a certificate.
|
||||
.
|
||||
|
||||
<Hyperlink
|
||||
destination="progressUrl"
|
||||
|
||||
@@ -22,7 +22,7 @@ export const CourseCardContent = ({ cardId, orientation }) => {
|
||||
const { isVerified } = appHooks.useCardEnrollmentData(cardId);
|
||||
return (
|
||||
<>
|
||||
<a className="pgn__card-wrapper-image-cap horizontal overflow-visible" href={homeUrl}>
|
||||
<a className={`pgn__card-wrapper-image-cap overflow-visible ${orientation}`} href={homeUrl}>
|
||||
<img
|
||||
className="pgn__card-image-cap"
|
||||
src={bannerImgSrc}
|
||||
|
||||
@@ -26,15 +26,14 @@ exports[`CourseCardMenu enrolled, share enabled, email setting enable snapshot 1
|
||||
>
|
||||
Email settings
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item>
|
||||
<TwitterShareButton
|
||||
className="w-100 text-left"
|
||||
title="I'm taking test-course-name online with twitter-social-brand. Check it out!"
|
||||
url="twitter-share-url"
|
||||
>
|
||||
Share to Twitter
|
||||
</TwitterShareButton>
|
||||
</Dropdown.Item>
|
||||
<TwitterShareButton
|
||||
className="pgn__dropdown-item dropdown-item"
|
||||
resetButtonStyle={false}
|
||||
title="I'm taking test-course-name online with twitter-social-brand. Check it out!"
|
||||
url="twitter-share-url"
|
||||
>
|
||||
Share to Twitter
|
||||
</TwitterShareButton>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
<UnenrollConfirmModal
|
||||
@@ -76,15 +75,14 @@ exports[`CourseCardMenu masquerading snapshot 1`] = `
|
||||
>
|
||||
Email settings
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item>
|
||||
<TwitterShareButton
|
||||
className="w-100 text-left"
|
||||
title="I'm taking test-course-name online with twitter-social-brand. Check it out!"
|
||||
url="twitter-share-url"
|
||||
>
|
||||
Share to Twitter
|
||||
</TwitterShareButton>
|
||||
</Dropdown.Item>
|
||||
<TwitterShareButton
|
||||
className="pgn__dropdown-item dropdown-item"
|
||||
resetButtonStyle={false}
|
||||
title="I'm taking test-course-name online with twitter-social-brand. Check it out!"
|
||||
url="twitter-share-url"
|
||||
>
|
||||
Share to Twitter
|
||||
</TwitterShareButton>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
<UnenrollConfirmModal
|
||||
|
||||
@@ -71,18 +71,17 @@ export const CourseCardMenu = ({ cardId }) => {
|
||||
)}
|
||||
*/}
|
||||
{twitter.isEnabled && (
|
||||
<Dropdown.Item>
|
||||
<ReactShare.TwitterShareButton
|
||||
url={twitter.shareUrl}
|
||||
title={formatMessage(messages.shareQuote, {
|
||||
courseName,
|
||||
socialBrand: twitter.socialBrand,
|
||||
})}
|
||||
className="w-100 text-left"
|
||||
>
|
||||
{formatMessage(messages.shareToTwitter)}
|
||||
</ReactShare.TwitterShareButton>
|
||||
</Dropdown.Item>
|
||||
<ReactShare.TwitterShareButton
|
||||
url={twitter.shareUrl}
|
||||
title={formatMessage(messages.shareQuote, {
|
||||
courseName,
|
||||
socialBrand: twitter.socialBrand,
|
||||
})}
|
||||
resetButtonStyle={false}
|
||||
className="pgn__dropdown-item dropdown-item"
|
||||
>
|
||||
{formatMessage(messages.shareToTwitter)}
|
||||
</ReactShare.TwitterShareButton>
|
||||
)}
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
exports[`CourseCardContent snapshot not verified 1`] = `
|
||||
<Fragment>
|
||||
<a
|
||||
className="pgn__card-wrapper-image-cap horizontal overflow-visible"
|
||||
className="pgn__card-wrapper-image-cap overflow-visible vertical"
|
||||
href="test-home-url"
|
||||
>
|
||||
<img
|
||||
@@ -55,7 +55,7 @@ exports[`CourseCardContent snapshot not verified 1`] = `
|
||||
exports[`CourseCardContent snapshot orientation horizontal 1`] = `
|
||||
<Fragment>
|
||||
<a
|
||||
className="pgn__card-wrapper-image-cap horizontal overflow-visible"
|
||||
className="pgn__card-wrapper-image-cap overflow-visible horizontal"
|
||||
href="test-home-url"
|
||||
>
|
||||
<img
|
||||
@@ -125,7 +125,7 @@ exports[`CourseCardContent snapshot orientation horizontal 1`] = `
|
||||
exports[`CourseCardContent snapshot orientation vertical 1`] = `
|
||||
<Fragment>
|
||||
<a
|
||||
className="pgn__card-wrapper-image-cap horizontal overflow-visible"
|
||||
className="pgn__card-wrapper-image-cap overflow-visible vertical"
|
||||
href="test-home-url"
|
||||
>
|
||||
<img
|
||||
|
||||
@@ -1,20 +1,68 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`CourseList snapshots collapsed with multiple courses and pages 1`] = `
|
||||
<div
|
||||
className="course-list-container"
|
||||
>
|
||||
<div
|
||||
className="course-list-heading-container"
|
||||
>
|
||||
<h2
|
||||
className="course-list-title"
|
||||
>
|
||||
My Courses
|
||||
</h2>
|
||||
<div
|
||||
className="course-filter-controls-container"
|
||||
>
|
||||
<CourseFilterControls />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
id="course-list-active-filters-container"
|
||||
>
|
||||
<ActiveCourseFilters />
|
||||
</div>
|
||||
<div
|
||||
className="d-flex flex-column flex-grow-1"
|
||||
>
|
||||
<CourseCard
|
||||
cardId="foo"
|
||||
key="foo"
|
||||
/>
|
||||
<CourseCard
|
||||
cardId="bar"
|
||||
key="bar"
|
||||
/>
|
||||
<CourseCard
|
||||
cardId="baz"
|
||||
key="baz"
|
||||
/>
|
||||
<Pagination
|
||||
className="mx-auto"
|
||||
onPageSelect={[MockFunction setPageNumber]}
|
||||
pageCount={3}
|
||||
paginationLabel="Course List"
|
||||
variant="reduced"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`CourseList snapshots with filters 1`] = `
|
||||
<div
|
||||
className="course-list-container"
|
||||
>
|
||||
<div
|
||||
id="course-list-heading-container"
|
||||
className="course-list-heading-container"
|
||||
>
|
||||
<h2
|
||||
className="mb-4.5"
|
||||
className="course-list-title"
|
||||
>
|
||||
My Courses
|
||||
</h2>
|
||||
<div
|
||||
className="text-right"
|
||||
id="course-filter-controls-container"
|
||||
className="course-filter-controls-container"
|
||||
>
|
||||
<CourseFilterControls
|
||||
abitary="filter"
|
||||
@@ -39,16 +87,15 @@ exports[`CourseList snapshots with multiple courses and pages 1`] = `
|
||||
className="course-list-container"
|
||||
>
|
||||
<div
|
||||
id="course-list-heading-container"
|
||||
className="course-list-heading-container"
|
||||
>
|
||||
<h2
|
||||
className="mb-4.5"
|
||||
className="course-list-title"
|
||||
>
|
||||
My Courses
|
||||
</h2>
|
||||
<div
|
||||
className="text-right"
|
||||
id="course-filter-controls-container"
|
||||
className="course-filter-controls-container"
|
||||
>
|
||||
<CourseFilterControls />
|
||||
</div>
|
||||
@@ -84,16 +131,15 @@ exports[`CourseList snapshots with no filters 1`] = `
|
||||
className="course-list-container"
|
||||
>
|
||||
<div
|
||||
id="course-list-heading-container"
|
||||
className="course-list-heading-container"
|
||||
>
|
||||
<h2
|
||||
className="mb-4.5"
|
||||
className="course-list-title"
|
||||
>
|
||||
My Courses
|
||||
</h2>
|
||||
<div
|
||||
className="text-right"
|
||||
id="course-filter-controls-container"
|
||||
className="course-filter-controls-container"
|
||||
>
|
||||
<CourseFilterControls />
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { useCheckboxSetValues } from '@edx/paragon';
|
||||
import { useCheckboxSetValues, useWindowSize, breakpoints } from '@edx/paragon';
|
||||
|
||||
import { StrictDict } from 'utils';
|
||||
import { actions, hooks as appHooks } from 'data/redux';
|
||||
@@ -9,6 +9,11 @@ import { ListPageSize, SortKeys } from 'data/constants/app';
|
||||
|
||||
import * as module from './hooks';
|
||||
|
||||
export const useIsCollapsed = () => {
|
||||
const { width } = useWindowSize();
|
||||
return width < breakpoints.medium.maxWidth;
|
||||
};
|
||||
|
||||
export const state = StrictDict({
|
||||
sortBy: (val) => React.useState(val), // eslint-disable-line
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
} from 'containers/CourseFilterControls';
|
||||
import CourseCard from 'containers/CourseCard';
|
||||
|
||||
import { useCourseListData } from './hooks';
|
||||
import { useCourseListData, useIsCollapsed } from './hooks';
|
||||
|
||||
import messages from './messages';
|
||||
|
||||
@@ -24,11 +24,12 @@ export const CourseList = () => {
|
||||
showFilters,
|
||||
visibleList,
|
||||
} = useCourseListData();
|
||||
const isCollapsed = useIsCollapsed();
|
||||
return (
|
||||
<div className="course-list-container">
|
||||
<div id="course-list-heading-container">
|
||||
<h2 className="mb-4.5">{formatMessage(messages.myCourses)}</h2>
|
||||
<div id="course-filter-controls-container" className="text-right">
|
||||
<div className="course-list-heading-container">
|
||||
<h2 className="course-list-title">{formatMessage(messages.myCourses)}</h2>
|
||||
<div className="course-filter-controls-container">
|
||||
<CourseFilterControls {...filterOptions} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -43,7 +44,7 @@ export const CourseList = () => {
|
||||
))}
|
||||
{numPages > 1 && (
|
||||
<Pagination
|
||||
variant="secondary"
|
||||
variant={isCollapsed ? 'reduced' : 'secondary'}
|
||||
paginationLabel="Course List"
|
||||
className="mx-auto"
|
||||
pageCount={numPages}
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
#course-list-heading-container {
|
||||
@import "@edx/paragon/scss/core/core";
|
||||
|
||||
.course-list-heading-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.course-list-title {
|
||||
font-size: $h2-font-size;
|
||||
margin: map-get($spacers, 3) 0;
|
||||
}
|
||||
|
||||
.course-list-loading {
|
||||
@@ -8,4 +17,26 @@
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.course-filter-controls-container {
|
||||
text-align: right;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
.course-list-heading-container {
|
||||
flex-direction: column-reverse;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.course-filter-controls-container {
|
||||
text-align: left;
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.course-list-title {
|
||||
font-size: $h3-font-size;
|
||||
margin: map-get($spacers, 2) 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import CourseList from '.';
|
||||
import { useCourseListData } from './hooks';
|
||||
import { useCourseListData, useIsCollapsed } from './hooks';
|
||||
|
||||
jest.mock('./hooks', () => ({
|
||||
useCourseListData: jest.fn(),
|
||||
useIsCollapsed: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('containers/CourseCard', () => 'CourseCard');
|
||||
@@ -21,6 +22,7 @@ describe('CourseList', () => {
|
||||
showFilters: false,
|
||||
visibleList: [],
|
||||
};
|
||||
useIsCollapsed.mockReturnValue(false);
|
||||
const createWrapper = (courseListData) => {
|
||||
useCourseListData.mockReturnValueOnce({
|
||||
...defaultCourseListData,
|
||||
@@ -50,5 +52,14 @@ describe('CourseList', () => {
|
||||
});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
test('collapsed with multiple courses and pages', () => {
|
||||
useIsCollapsed.mockReturnValueOnce(true);
|
||||
const wrapper = createWrapper({
|
||||
visibleList: [{ cardId: 'foo' }, { cardId: 'bar' }, { cardId: 'baz' }],
|
||||
numPages: 3,
|
||||
showFilters: true,
|
||||
});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,13 +7,17 @@ import hooks from './hooks';
|
||||
|
||||
export const columnConfig = {
|
||||
courseList: {
|
||||
xs: { span: 12, offset: 0 },
|
||||
sm: { span: 8, offset: 2 },
|
||||
md: { span: 12, offset: 0 },
|
||||
lg: { span: 10, offset: 1 },
|
||||
sm: { span: 12, offset: 0 },
|
||||
md: { span: 10, offset: 1 },
|
||||
lg: { span: 12, offset: 0 },
|
||||
xl: { span: 8, offset: 0 },
|
||||
},
|
||||
sidebar: { md: 12, xl: 4 },
|
||||
sidebar: {
|
||||
sm: { span: 12, offset: 0 },
|
||||
md: { span: 10, offset: 1 },
|
||||
lg: { span: 12, offset: 0 },
|
||||
xl: { span: 4, offset: 0 },
|
||||
},
|
||||
};
|
||||
|
||||
export const LoadedView = () => {
|
||||
@@ -22,11 +26,11 @@ export const LoadedView = () => {
|
||||
return (
|
||||
<Container fluid size="xl">
|
||||
<Row>
|
||||
<Col {...columnConfig.courseList} className="p-0 px-4">
|
||||
<Col {...columnConfig.courseList} className="course-list-column">
|
||||
<CourseList />
|
||||
</Col>
|
||||
<Col {...columnConfig.sidebar} className="p-0 pr-4 pl-1">
|
||||
{!isCollapsed && (<h2 className="mb-4.5 display-block"> </h2>)}
|
||||
<Col {...columnConfig.sidebar} className="sidebar-column">
|
||||
{!isCollapsed && (<h2 className="course-list-title"> </h2>)}
|
||||
<WidgetSidebar />
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -7,23 +7,23 @@ exports[`LoadedView collapsed snapshot 1`] = `
|
||||
>
|
||||
<Row>
|
||||
<Col
|
||||
className="p-0 px-4"
|
||||
className="course-list-column"
|
||||
lg={
|
||||
Object {
|
||||
"offset": 1,
|
||||
"span": 10,
|
||||
}
|
||||
}
|
||||
md={
|
||||
Object {
|
||||
"offset": 0,
|
||||
"span": 12,
|
||||
}
|
||||
}
|
||||
md={
|
||||
Object {
|
||||
"offset": 1,
|
||||
"span": 10,
|
||||
}
|
||||
}
|
||||
sm={
|
||||
Object {
|
||||
"offset": 2,
|
||||
"span": 8,
|
||||
"offset": 0,
|
||||
"span": 12,
|
||||
}
|
||||
}
|
||||
xl={
|
||||
@@ -32,19 +32,35 @@ exports[`LoadedView collapsed snapshot 1`] = `
|
||||
"span": 8,
|
||||
}
|
||||
}
|
||||
xs={
|
||||
>
|
||||
<CourseList />
|
||||
</Col>
|
||||
<Col
|
||||
className="sidebar-column"
|
||||
lg={
|
||||
Object {
|
||||
"offset": 0,
|
||||
"span": 12,
|
||||
}
|
||||
}
|
||||
>
|
||||
<CourseList />
|
||||
</Col>
|
||||
<Col
|
||||
className="p-0 pr-4 pl-1"
|
||||
md={12}
|
||||
xl={4}
|
||||
md={
|
||||
Object {
|
||||
"offset": 1,
|
||||
"span": 10,
|
||||
}
|
||||
}
|
||||
sm={
|
||||
Object {
|
||||
"offset": 0,
|
||||
"span": 12,
|
||||
}
|
||||
}
|
||||
xl={
|
||||
Object {
|
||||
"offset": 0,
|
||||
"span": 4,
|
||||
}
|
||||
}
|
||||
>
|
||||
<WidgetSidebar />
|
||||
</Col>
|
||||
@@ -59,23 +75,23 @@ exports[`LoadedView not collapsed snapshot 1`] = `
|
||||
>
|
||||
<Row>
|
||||
<Col
|
||||
className="p-0 px-4"
|
||||
className="course-list-column"
|
||||
lg={
|
||||
Object {
|
||||
"offset": 1,
|
||||
"span": 10,
|
||||
}
|
||||
}
|
||||
md={
|
||||
Object {
|
||||
"offset": 0,
|
||||
"span": 12,
|
||||
}
|
||||
}
|
||||
md={
|
||||
Object {
|
||||
"offset": 1,
|
||||
"span": 10,
|
||||
}
|
||||
}
|
||||
sm={
|
||||
Object {
|
||||
"offset": 2,
|
||||
"span": 8,
|
||||
"offset": 0,
|
||||
"span": 12,
|
||||
}
|
||||
}
|
||||
xl={
|
||||
@@ -84,22 +100,38 @@ exports[`LoadedView not collapsed snapshot 1`] = `
|
||||
"span": 8,
|
||||
}
|
||||
}
|
||||
xs={
|
||||
>
|
||||
<CourseList />
|
||||
</Col>
|
||||
<Col
|
||||
className="sidebar-column"
|
||||
lg={
|
||||
Object {
|
||||
"offset": 0,
|
||||
"span": 12,
|
||||
}
|
||||
}
|
||||
>
|
||||
<CourseList />
|
||||
</Col>
|
||||
<Col
|
||||
className="p-0 pr-4 pl-1"
|
||||
md={12}
|
||||
xl={4}
|
||||
md={
|
||||
Object {
|
||||
"offset": 1,
|
||||
"span": 10,
|
||||
}
|
||||
}
|
||||
sm={
|
||||
Object {
|
||||
"offset": 0,
|
||||
"span": 12,
|
||||
}
|
||||
}
|
||||
xl={
|
||||
Object {
|
||||
"offset": 0,
|
||||
"span": 4,
|
||||
}
|
||||
}
|
||||
>
|
||||
<h2
|
||||
className="mb-4.5 display-block"
|
||||
className="course-list-title"
|
||||
>
|
||||
|
||||
</h2>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
@import "@edx/paragon/scss/core/core";
|
||||
|
||||
.course-list-column {
|
||||
padding: 0 map-get($spacers, 4);
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.sidebar-column {
|
||||
padding: 0 map-get($spacers, 3) 0 map-get($spacers, 1);
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(lg) {
|
||||
.sidebar-column {
|
||||
// grid are inheriting dir="ltr" from the body, so we need to override it
|
||||
[dir=ltr] & {
|
||||
padding: 0 map-get($spacers, 3);
|
||||
}
|
||||
[dir=rtl] & {
|
||||
padding: 0 map-get($spacers, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,9 +36,6 @@ exports[`LearnerDashboardHeader snapshots with collapsed 1`] = `
|
||||
</header>
|
||||
</div>
|
||||
<MasqueradeBar />
|
||||
<hr
|
||||
className="mt-0"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
@@ -77,8 +74,5 @@ exports[`LearnerDashboardHeader snapshots without collapsed 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<MasqueradeBar />
|
||||
<hr
|
||||
className="mt-0"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
@@ -53,7 +53,6 @@ export const LearnerDashboardHeader = () => {
|
||||
{!isCollapsed && <GreetingBanner size="large" />}
|
||||
</div>
|
||||
<MasqueradeBar />
|
||||
<hr className="mt-0" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,178 +1,202 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`MasqueradeBar snapshot can masquerade 1`] = `
|
||||
<Form
|
||||
className="masquerade-bar"
|
||||
<div
|
||||
className="w-100 shadow-sm px-2"
|
||||
>
|
||||
<FormLabel
|
||||
className="masquerade-form-label"
|
||||
inline={true}
|
||||
<Form
|
||||
className="masquerade-bar col-sm-12 col-md-10 col-12"
|
||||
>
|
||||
<Icon
|
||||
src={[MockFunction icons.PersonSearch]}
|
||||
/>
|
||||
View as:
|
||||
</FormLabel>
|
||||
<FormGroup
|
||||
className="masquerade-form-input"
|
||||
isInvalid={false}
|
||||
>
|
||||
<FormControl
|
||||
floatingLabel="Student username or email"
|
||||
onChange={[MockFunction handleMasqueradeInputChange]}
|
||||
value=""
|
||||
/>
|
||||
</FormGroup>
|
||||
<StatefulButton
|
||||
disabled={true}
|
||||
labels={
|
||||
Object {
|
||||
"default": "Submit",
|
||||
<FormLabel
|
||||
className="masquerade-form-label"
|
||||
inline={true}
|
||||
>
|
||||
<Icon
|
||||
src={[MockFunction icons.PersonSearch]}
|
||||
/>
|
||||
View as:
|
||||
</FormLabel>
|
||||
<FormGroup
|
||||
className="masquerade-form-input"
|
||||
isInvalid={false}
|
||||
>
|
||||
<FormControl
|
||||
floatingLabel="Username or email"
|
||||
onChange={[MockFunction handleMasqueradeInputChange]}
|
||||
value=""
|
||||
/>
|
||||
</FormGroup>
|
||||
<StatefulButton
|
||||
className="mr-3"
|
||||
disabled={true}
|
||||
labels={
|
||||
Object {
|
||||
"default": "Submit",
|
||||
}
|
||||
}
|
||||
}
|
||||
state="default"
|
||||
type="submit"
|
||||
variant="brand"
|
||||
/>
|
||||
</Form>
|
||||
state="default"
|
||||
type="submit"
|
||||
variant="brand"
|
||||
/>
|
||||
</Form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`MasqueradeBar snapshot can masquerade with input 1`] = `
|
||||
<Form
|
||||
className="masquerade-bar"
|
||||
<div
|
||||
className="w-100 shadow-sm px-2"
|
||||
>
|
||||
<FormLabel
|
||||
className="masquerade-form-label"
|
||||
inline={true}
|
||||
<Form
|
||||
className="masquerade-bar col-sm-12 col-md-10 col-12"
|
||||
>
|
||||
<Icon
|
||||
src={[MockFunction icons.PersonSearch]}
|
||||
/>
|
||||
View as:
|
||||
</FormLabel>
|
||||
<FormGroup
|
||||
className="masquerade-form-input"
|
||||
isInvalid={false}
|
||||
>
|
||||
<FormControl
|
||||
floatingLabel="Student username or email"
|
||||
onChange={[MockFunction handleMasqueradeInputChange]}
|
||||
value="test"
|
||||
/>
|
||||
</FormGroup>
|
||||
<StatefulButton
|
||||
disabled={false}
|
||||
labels={
|
||||
Object {
|
||||
"default": "Submit",
|
||||
<FormLabel
|
||||
className="masquerade-form-label"
|
||||
inline={true}
|
||||
>
|
||||
<Icon
|
||||
src={[MockFunction icons.PersonSearch]}
|
||||
/>
|
||||
View as:
|
||||
</FormLabel>
|
||||
<FormGroup
|
||||
className="masquerade-form-input"
|
||||
isInvalid={false}
|
||||
>
|
||||
<FormControl
|
||||
floatingLabel="Username or email"
|
||||
onChange={[MockFunction handleMasqueradeInputChange]}
|
||||
value="test"
|
||||
/>
|
||||
</FormGroup>
|
||||
<StatefulButton
|
||||
className="mr-3"
|
||||
disabled={false}
|
||||
labels={
|
||||
Object {
|
||||
"default": "Submit",
|
||||
}
|
||||
}
|
||||
}
|
||||
state="default"
|
||||
type="submit"
|
||||
variant="brand"
|
||||
/>
|
||||
</Form>
|
||||
state="default"
|
||||
type="submit"
|
||||
variant="brand"
|
||||
/>
|
||||
</Form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`MasqueradeBar snapshot cannot masquerade 1`] = `""`;
|
||||
|
||||
exports[`MasqueradeBar snapshot is masquerading failed with error 1`] = `
|
||||
<Form
|
||||
className="masquerade-bar"
|
||||
<div
|
||||
className="w-100 shadow-sm px-2"
|
||||
>
|
||||
<FormLabel
|
||||
className="masquerade-form-label"
|
||||
inline={true}
|
||||
<Form
|
||||
className="masquerade-bar col-sm-12 col-md-10 col-12"
|
||||
>
|
||||
<Icon
|
||||
src={[MockFunction icons.PersonSearch]}
|
||||
/>
|
||||
View as:
|
||||
</FormLabel>
|
||||
<FormGroup
|
||||
className="masquerade-form-input"
|
||||
isInvalid={true}
|
||||
>
|
||||
<FormControl
|
||||
floatingLabel="Student username or email"
|
||||
onChange={[MockFunction handleMasqueradeInputChange]}
|
||||
value=""
|
||||
/>
|
||||
<FormControlFeedback
|
||||
hasIcon={false}
|
||||
type="invalid"
|
||||
/>
|
||||
</FormGroup>
|
||||
<StatefulButton
|
||||
disabled={true}
|
||||
labels={
|
||||
Object {
|
||||
"default": "Submit",
|
||||
<FormLabel
|
||||
className="masquerade-form-label"
|
||||
inline={true}
|
||||
>
|
||||
<Icon
|
||||
src={[MockFunction icons.PersonSearch]}
|
||||
/>
|
||||
View as:
|
||||
</FormLabel>
|
||||
<FormGroup
|
||||
className="masquerade-form-input"
|
||||
isInvalid={true}
|
||||
>
|
||||
<FormControl
|
||||
floatingLabel="Username or email"
|
||||
onChange={[MockFunction handleMasqueradeInputChange]}
|
||||
value=""
|
||||
/>
|
||||
<FormControlFeedback
|
||||
hasIcon={false}
|
||||
type="invalid"
|
||||
/>
|
||||
</FormGroup>
|
||||
<StatefulButton
|
||||
className="mr-3"
|
||||
disabled={true}
|
||||
labels={
|
||||
Object {
|
||||
"default": "Submit",
|
||||
}
|
||||
}
|
||||
}
|
||||
state="default"
|
||||
type="submit"
|
||||
variant="brand"
|
||||
/>
|
||||
</Form>
|
||||
state="default"
|
||||
type="submit"
|
||||
variant="brand"
|
||||
/>
|
||||
</Form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`MasqueradeBar snapshot is masquerading pending 1`] = `
|
||||
<Form
|
||||
className="masquerade-bar"
|
||||
<div
|
||||
className="w-100 shadow-sm px-2"
|
||||
>
|
||||
<FormLabel
|
||||
className="masquerade-form-label"
|
||||
inline={true}
|
||||
<Form
|
||||
className="masquerade-bar col-sm-12 col-md-10 col-12"
|
||||
>
|
||||
<Icon
|
||||
src={[MockFunction icons.PersonSearch]}
|
||||
/>
|
||||
View as:
|
||||
</FormLabel>
|
||||
<FormGroup
|
||||
className="masquerade-form-input"
|
||||
isInvalid={false}
|
||||
>
|
||||
<FormControl
|
||||
floatingLabel="Student username or email"
|
||||
onChange={[MockFunction handleMasqueradeInputChange]}
|
||||
value=""
|
||||
/>
|
||||
</FormGroup>
|
||||
<StatefulButton
|
||||
disabled={true}
|
||||
labels={
|
||||
Object {
|
||||
"default": "Submit",
|
||||
<FormLabel
|
||||
className="masquerade-form-label"
|
||||
inline={true}
|
||||
>
|
||||
<Icon
|
||||
src={[MockFunction icons.PersonSearch]}
|
||||
/>
|
||||
View as:
|
||||
</FormLabel>
|
||||
<FormGroup
|
||||
className="masquerade-form-input"
|
||||
isInvalid={false}
|
||||
>
|
||||
<FormControl
|
||||
floatingLabel="Username or email"
|
||||
onChange={[MockFunction handleMasqueradeInputChange]}
|
||||
value=""
|
||||
/>
|
||||
</FormGroup>
|
||||
<StatefulButton
|
||||
className="mr-3"
|
||||
disabled={true}
|
||||
labels={
|
||||
Object {
|
||||
"default": "Submit",
|
||||
}
|
||||
}
|
||||
}
|
||||
state="pending"
|
||||
type="submit"
|
||||
variant="brand"
|
||||
/>
|
||||
</Form>
|
||||
state="pending"
|
||||
type="submit"
|
||||
variant="brand"
|
||||
/>
|
||||
</Form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`MasqueradeBar snapshot is masquerading with input 1`] = `
|
||||
<Form
|
||||
className="masquerade-bar"
|
||||
<div
|
||||
className="w-100 shadow-sm px-2"
|
||||
>
|
||||
<FormLabel
|
||||
className="masquerade-form-label"
|
||||
inline={true}
|
||||
<Form
|
||||
className="masquerade-bar col-sm-12 col-md-10 col-12"
|
||||
>
|
||||
<Icon
|
||||
src={[MockFunction icons.PersonSearch]}
|
||||
/>
|
||||
Viewing as:
|
||||
</FormLabel>
|
||||
<Chip
|
||||
className="masquerade-chip"
|
||||
iconAfter={[MockFunction icons.Close]}
|
||||
onClick={[MockFunction handleClearMasquerade]}
|
||||
>
|
||||
test
|
||||
</Chip>
|
||||
</Form>
|
||||
<FormLabel
|
||||
className="masquerade-form-label"
|
||||
inline={true}
|
||||
>
|
||||
<Icon
|
||||
src={[MockFunction icons.PersonSearch]}
|
||||
/>
|
||||
Viewing as:
|
||||
</FormLabel>
|
||||
<Chip
|
||||
className="masquerade-chip"
|
||||
iconAfter={[MockFunction icons.Close]}
|
||||
onClick={[MockFunction handleClearMasquerade]}
|
||||
>
|
||||
test
|
||||
</Chip>
|
||||
</Form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -36,52 +36,55 @@ export const MasqueradeBar = () => {
|
||||
if (!canMasquerade) { return null; }
|
||||
|
||||
return (
|
||||
<Form className="masquerade-bar">
|
||||
{isMasquerading ? (
|
||||
<>
|
||||
<FormLabel inline className="masquerade-form-label">
|
||||
<Icon src={PersonSearch} />
|
||||
{formatMessage(messages.ViewingAs)}
|
||||
</FormLabel>
|
||||
<Chip
|
||||
className="masquerade-chip"
|
||||
iconAfter={Close}
|
||||
onClick={handleClearMasquerade}
|
||||
>
|
||||
{masqueradeInput}
|
||||
</Chip>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<FormLabel inline className="masquerade-form-label">
|
||||
<Icon src={PersonSearch} />
|
||||
{formatMessage(messages.ViewAs)}
|
||||
</FormLabel>
|
||||
<FormGroup isInvalid={isMasqueradingFailed} className="masquerade-form-input">
|
||||
<FormControl
|
||||
value={masqueradeInput}
|
||||
onChange={handleMasqueradeInputChange}
|
||||
floatingLabel={formatMessage(messages.StudentNameInput)}
|
||||
<div className="w-100 shadow-sm px-2">
|
||||
<Form className="masquerade-bar col-sm-12 col-md-10 col-12">
|
||||
{isMasquerading ? (
|
||||
<>
|
||||
<FormLabel inline className="masquerade-form-label">
|
||||
<Icon src={PersonSearch} />
|
||||
{formatMessage(messages.ViewingAs)}
|
||||
</FormLabel>
|
||||
<Chip
|
||||
className="masquerade-chip"
|
||||
iconAfter={Close}
|
||||
onClick={handleClearMasquerade}
|
||||
>
|
||||
{masqueradeInput}
|
||||
</Chip>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<FormLabel inline className="masquerade-form-label">
|
||||
<Icon src={PersonSearch} />
|
||||
{formatMessage(messages.ViewAs)}
|
||||
</FormLabel>
|
||||
<FormGroup isInvalid={isMasqueradingFailed} className="masquerade-form-input">
|
||||
<FormControl
|
||||
value={masqueradeInput}
|
||||
onChange={handleMasqueradeInputChange}
|
||||
floatingLabel={formatMessage(messages.StudentNameInput)}
|
||||
/>
|
||||
{isMasqueradingFailed && (
|
||||
<FormControlFeedback type="invalid" hasIcon={false}>
|
||||
{formatMessage(masqueradeErrorMessage)}
|
||||
</FormControlFeedback>
|
||||
)}
|
||||
</FormGroup>
|
||||
<StatefulButton
|
||||
disabled={!masqueradeInput.length}
|
||||
variant="brand"
|
||||
onClick={handleMasqueradeSubmit(masqueradeInput)}
|
||||
labels={{
|
||||
default: formatMessage(messages.SubmitButton),
|
||||
}}
|
||||
className="mr-3"
|
||||
state={isMasqueradingPending ? 'pending' : 'default'}
|
||||
type="submit"
|
||||
/>
|
||||
{isMasqueradingFailed && (
|
||||
<FormControlFeedback type="invalid" hasIcon={false}>
|
||||
{formatMessage(masqueradeErrorMessage)}
|
||||
</FormControlFeedback>
|
||||
)}
|
||||
</FormGroup>
|
||||
<StatefulButton
|
||||
disabled={!masqueradeInput.length}
|
||||
variant="brand"
|
||||
onClick={handleMasqueradeSubmit(masqueradeInput)}
|
||||
labels={{
|
||||
default: formatMessage(messages.SubmitButton),
|
||||
}}
|
||||
state={isMasqueradingPending ? 'pending' : 'default'}
|
||||
type="submit"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Form>
|
||||
</>
|
||||
)}
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: map-get($spacers, 3);
|
||||
margin-bottom: map-get($spacers, 2);
|
||||
|
||||
.masquerade-form-label {
|
||||
padding: map-get($spacers, 2) map-get($spacers, 3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0;
|
||||
white-space: nowrap;
|
||||
|
||||
&>.pgn__icon {
|
||||
margin-right: map-get($spacers, 3);
|
||||
@@ -26,4 +28,11 @@
|
||||
padding: map-get($spacers, 2) map-get($spacers, 3);
|
||||
font-size: $font-size-base;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
.masquerade-bar {
|
||||
margin: auto;
|
||||
padding: map-get($spacers, 3) map-get($spacers, 4);
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ const messages = defineMessages({
|
||||
},
|
||||
StudentNameInput: {
|
||||
id: 'MasqueradeBar.StudentNameInput',
|
||||
defaultMessage: 'Student username or email',
|
||||
defaultMessage: 'Username or email',
|
||||
description: 'Label for the Student Name or email input',
|
||||
},
|
||||
NoStudentFound: {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
exports[`WidgetSidebar snapshots default 1`] = `
|
||||
<div
|
||||
className="widget-sidebar px-2"
|
||||
className="widget-sidebar"
|
||||
>
|
||||
<div
|
||||
className="d-flex"
|
||||
|
||||
@@ -3,7 +3,7 @@ import React from 'react';
|
||||
import LookingForChallengeWidget from './widgets/LookingForChallengeWidget';
|
||||
|
||||
export const WidgetSidebar = () => (
|
||||
<div className="widget-sidebar px-2">
|
||||
<div className="widget-sidebar">
|
||||
<div className="d-flex">
|
||||
<LookingForChallengeWidget />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user