-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add settings page zero state (#656)
- Loading branch information
Showing
22 changed files
with
648 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
src/components/settings/SettingsAccessTab/SettingsAccessLinkManagement.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import React from 'react'; | ||
import { | ||
DataTable, | ||
StatefulButton, | ||
Button, | ||
} from '@edx/paragon'; | ||
|
||
import { useLinkManagement } from '../data/hooks'; | ||
import SettingsAccessTabSection from './SettingsAccessTabSection'; | ||
|
||
const SettingsAccessLinkManagement = () => { | ||
const { | ||
links, | ||
loadingLinks, | ||
refreshLinks, | ||
} = useLinkManagement(); | ||
|
||
const handleLinkManagementToggleChanged = () => { | ||
// console.log(e.target.checked); | ||
}; | ||
|
||
const handleCopyLink = () => { | ||
// TODO: Handle Copy link to clipboard | ||
// console.log('handleCopyLink', rowData); | ||
}; | ||
|
||
const handleDeactivateLink = () => { | ||
// TODO: Handle deactivate link | ||
// console.log('handleDeactivateLink', rowData); | ||
}; | ||
|
||
/** | ||
* When we successfully create a link we should refresh links | ||
*/ | ||
const handleGenerateLinkSuccess = () => { | ||
refreshLinks(); | ||
}; | ||
|
||
// TODO: consider moving button to separate component | ||
const generateLinkButtonProps = { | ||
labels: { | ||
default: 'Generate Link', | ||
pending: 'Generating Link...', | ||
complete: 'Link Generated', | ||
error: 'Error', | ||
}, | ||
state: 'default', | ||
variant: 'primary', | ||
}; | ||
|
||
// TODO: Make sure our data is being mapped correctly | ||
const data = links; | ||
|
||
return ( | ||
<SettingsAccessTabSection | ||
title="Access via Link" | ||
checked | ||
onChange={handleLinkManagementToggleChanged} | ||
|
||
> | ||
<p>Generate a link to share with your learners.</p> | ||
|
||
<DataTable | ||
data={data} | ||
itemCount={data.length} | ||
// eslint-disable-next-line no-unused-vars | ||
tableActions={(i) => ( | ||
// TODO: Consider making this its own component with logic | ||
<StatefulButton | ||
{...generateLinkButtonProps} | ||
onClick={handleGenerateLinkSuccess} | ||
/> | ||
)} | ||
columns={[ | ||
{ | ||
Header: 'Link', | ||
accessor: 'link', | ||
}, | ||
{ | ||
Header: 'Status', | ||
accessor: 'linkStatus', | ||
}, | ||
{ | ||
Header: 'Date created', | ||
accessor: 'dateCreated', | ||
}, | ||
{ | ||
Header: 'Usage', | ||
accessor: 'usage', | ||
}, | ||
]} | ||
additionalColumns={[ | ||
{ | ||
id: 'action', | ||
Header: '', | ||
/* eslint-disable react/prop-types */ | ||
Cell: ({ row }) => { | ||
if (row.original.linkStatus === 'activated') { | ||
return ( | ||
<div className="d-flex flex-row-reverse"> | ||
<Button onClick={() => handleCopyLink(row)} variant="link">Copy</Button> | ||
<Button onClick={() => handleDeactivateLink(row)} variant="link">Deactivate</Button> | ||
</div> | ||
); | ||
} | ||
return null; | ||
}, | ||
/* eslint-enable */ | ||
}, | ||
]} | ||
> | ||
<DataTable.TableControlBar /> | ||
<DataTable.Table /> | ||
<DataTable.EmptyTable content={loadingLinks ? 'Loading...' : 'No links found'} /> | ||
</DataTable> | ||
</SettingsAccessTabSection> | ||
|
||
); | ||
}; | ||
|
||
export default SettingsAccessLinkManagement; |
23 changes: 23 additions & 0 deletions
23
src/components/settings/SettingsAccessTab/SettingsAccessSSOManagement.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import React from 'react'; | ||
|
||
import SettingsAccessTabSection from './SettingsAccessTabSection'; | ||
|
||
const SettingsAccessSSOManagement = () => { | ||
// TODO: fetch feature setting and handle toggle | ||
const FAKE_SETTING = true; | ||
const handleSSOAccessToggleChanged = () => { | ||
// console.log(e.target.checked); | ||
}; | ||
|
||
return ( | ||
<SettingsAccessTabSection | ||
title="Access via Single Sign-on" | ||
checked={FAKE_SETTING} | ||
onChange={handleSSOAccessToggleChanged} | ||
> | ||
<p>Give learners with Single Sign-On access to the catalog.</p> | ||
</SettingsAccessTabSection> | ||
); | ||
}; | ||
|
||
export default SettingsAccessSSOManagement; |
41 changes: 41 additions & 0 deletions
41
src/components/settings/SettingsAccessTab/SettingsAccessTabSection.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React, { useState } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { | ||
Collapsible, | ||
Form, | ||
} from '@edx/paragon'; | ||
|
||
const SettingsAccessTabSection = ({ | ||
title, | ||
checked, | ||
onChange, | ||
children, | ||
}) => { | ||
const [isExpanded, setExpanded] = useState(true); | ||
return ( | ||
<div className="mb-4"> | ||
<div className="d-flex flex-row-reverse mb-3"> | ||
<Form.Switch onChange={onChange} checked={checked}>Enable</Form.Switch> | ||
</div> | ||
<div> | ||
<Collapsible | ||
open={isExpanded} | ||
onToggle={isOpen => setExpanded(isOpen)} | ||
styling="card" | ||
title={<p><strong>{title}</strong></p>} | ||
> | ||
{children} | ||
</Collapsible> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
SettingsAccessTabSection.propTypes = { | ||
title: PropTypes.string.isRequired, | ||
checked: PropTypes.bool.isRequired, | ||
onChange: PropTypes.func.isRequired, | ||
children: PropTypes.node.isRequired, | ||
}; | ||
|
||
export default SettingsAccessTabSection; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import React from 'react'; | ||
import { | ||
Container, | ||
Col, | ||
Row, | ||
} from '@edx/paragon'; | ||
import { connect } from 'react-redux'; | ||
import PropTypes from 'prop-types'; | ||
|
||
import { features } from '../../../config'; | ||
import ContactCustomerSupportButton from '../../ContactCustomerSupportButton'; | ||
import LinkManagement from './SettingsAccessLinkManagement'; | ||
import SSOManagement from './SettingsAccessSSOManagement'; | ||
|
||
const SettingsAccessTab = ({ learnerPortalEnabled }) => ( | ||
<Container fluid className="pl-0"> | ||
<Row> | ||
<Col> | ||
<h2>Enable browsing on-demand</h2> | ||
</Col> | ||
</Row> | ||
<Row className="mb-4"> | ||
<Col> | ||
<p> | ||
Allow learners without a subsidy to browse the catalog and request enrollment to courses. | ||
Browsing on demand will expire at the end of your latest subscription. | ||
</p> | ||
</Col> | ||
<Col md="auto"> | ||
<ContactCustomerSupportButton variant="outline-primary"> | ||
Contact support | ||
</ContactCustomerSupportButton> | ||
</Col> | ||
</Row> | ||
{features.SETTINGS_UNIVERSAL_LINK && learnerPortalEnabled | ||
&& ( | ||
<div className="mb-4"> | ||
<LinkManagement /> | ||
</div> | ||
)} | ||
<div className="mb-4"> | ||
<SSOManagement /> | ||
</div> | ||
</Container> | ||
); | ||
|
||
const mapStateToProps = state => ({ | ||
learnerPortalEnabled: state.portalConfiguration.enableLearnerPortal, | ||
}); | ||
|
||
SettingsAccessTab.propTypes = { | ||
learnerPortalEnabled: PropTypes.bool.isRequired, | ||
}; | ||
|
||
export default connect(mapStateToProps)(SettingsAccessTab); |
38 changes: 38 additions & 0 deletions
38
src/components/settings/SettingsAccessTab/tests/SettingsAccessTabSection.test.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import React from 'react'; | ||
import { | ||
screen, | ||
render, | ||
cleanup, | ||
act, | ||
waitForElementToBeRemoved, | ||
} from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
|
||
import SettingsAccessTabSection from '../SettingsAccessTabSection'; | ||
|
||
const generateProps = (checked, onChange) => ({ | ||
title: 'toggle me', | ||
children: 'hide me', | ||
checked, | ||
onChange, | ||
}); | ||
|
||
describe('<SettingsAccessTabSection />', () => { | ||
afterEach(() => { | ||
cleanup(); | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('Clicking title ', async () => { | ||
const props = generateProps(true, () => ({})); | ||
render(<SettingsAccessTabSection {...props} />); | ||
// is open by default | ||
expect(screen.queryByText(props.children)).toBeTruthy(); | ||
// click on title | ||
const titleArea = screen.getByText(props.title); | ||
await act(async () => { userEvent.click(titleArea); }); | ||
// wait till its gone and assert | ||
await waitForElementToBeRemoved(() => screen.queryByText(props.children)); | ||
expect(screen.queryByText(props.children)).toBeFalsy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import React from 'react'; | ||
|
||
// TODO: LMS TAB | ||
const SettingsLMSTab = () => (<div>LMS tab belongs here</div>); | ||
|
||
export default SettingsLMSTab; |
Oops, something went wrong.