diff --git a/__tests__/components/RoutedTabs.test.jsx b/__tests__/components/RoutedTabs.test.jsx
new file mode 100644
index 0000000000..05bc5aeee7
--- /dev/null
+++ b/__tests__/components/RoutedTabs.test.jsx
@@ -0,0 +1,79 @@
+import React from 'react';
+import { mount } from 'enzyme';
+
+import { Router } from 'react-router-dom';
+import { createMemoryHistory } from 'history';
+import { I18nProvider } from '@lingui/react';
+import RoutedTabs from '../../src/components/Tabs/RoutedTabs';
+import { DonateIcon } from '@patternfly/react-icons';
+
+let wrapper;
+
+afterEach(() => {
+ jest.clearAllMocks();
+});
+const tabs = [
+ { name: 'Details', link: 'organizations/19/details', id: 0 },
+ { name: 'Access', link: 'organizations/19/access', id: 1 },
+ { name: 'Teams', link: 'organizations/19/teams', id: 2 }
+];
+
+const history = createMemoryHistory({
+ history: {
+ location: {
+ pathname: '/organizations/19/details'
+ }
+ }
+});
+
+describe('', () => {
+ test('RoutedTabs renders successfully', () => {
+ wrapper = mount(
+
+
+
+
+
+ ).find('RoutedTabs');
+ });
+
+ test('the correct tab is rendered', async () => {
+ const currentTab = 'organizations/1/details';
+ wrapper = mount(
+
+
+
+
+
+ ).find('RoutedTabs');
+ wrapper.find('button').at(2).simulate('click');
+ wrapper.update();
+ expect(history.location.pathname).toEqual('/organizations/19/access');
+ });
+
+ test('Given a URL the correct tab is displayed', async (done) => {
+ const currentTab = createMemoryHistory({
+ initialEntries: ['/organizations/19/teams'],
+ });
+ wrapper = mount(
+
+
+
+
+
+ ).find('RoutedTabs');
+ setImmediate(() => {
+ wrapper.find('Tabs').prop('onSelect')({}, 2);
+ const selectedTab = wrapper.find('li').get(2).props.className;
+ expect(selectedTab).toBe('pf-c-tabs__item pf-m-current');
+ done();
+ });
+ });
+});
diff --git a/__tests__/pages/Organizations/screens/Organization/Organization.test.jsx b/__tests__/pages/Organizations/screens/Organization/Organization.test.jsx
index d7746c5838..a3b59a9e0c 100644
--- a/__tests__/pages/Organizations/screens/Organization/Organization.test.jsx
+++ b/__tests__/pages/Organizations/screens/Organization/Organization.test.jsx
@@ -3,56 +3,19 @@ import { mount } from 'enzyme';
import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
-import Organization, { _Organization } from '../../../../../src/pages/Organizations/screens/Organization/Organization';
+import Organization from '../../../../../src/pages/Organizations/screens/Organization/Organization';
describe('', () => {
test('initially renders succesfully', () => {
- const spy = jest.spyOn(_Organization.prototype, 'checkLocation');
mount(
- <_Organization
+
);
- expect(spy).toHaveBeenCalled();
- });
-
- test('handleTabSelect renders the correct tab', async () => {
- const currentTab = 'organizations/19/access';
- const spy = jest.spyOn(_Organization.prototype, 'handleTabSelect');
- const wrapper = mount(
-
-
-
-
-
- ).find('Organization');
- wrapper.find('button').at(2).simulate('click');
- setImmediate(async () => {
- wrapper.setState({ activeTabKey: 1 });
- });
- wrapper.update();
- expect(spy).toBeCalled();
- expect(wrapper.state('activeTabKey')).toBe(1);
- });
-
- test('checkLocation renders proper state when new tab is selected', async () => {
- const currentTab = 'organizations/19/access';
- const wrapper = mount(
-
-
-
-
-
- ).find('Organization');
- setImmediate(async () => {
- wrapper.setState({ activeTabKey: 1 });
- });
- wrapper.find('button').at(3).simulate('click');
- expect(wrapper.state('activeTabKey')).toBe(2);
});
});
diff --git a/src/components/Tabs/RoutedTabs.jsx b/src/components/Tabs/RoutedTabs.jsx
new file mode 100644
index 0000000000..820eace467
--- /dev/null
+++ b/src/components/Tabs/RoutedTabs.jsx
@@ -0,0 +1,55 @@
+import React from 'react';
+
+import {
+ withRouter
+} from 'react-router-dom';
+
+import {
+ Tab,
+ Tabs
+} from '@patternfly/react-core';
+
+class RoutedTabs extends React.Component {
+ constructor (props) {
+ super(props);
+
+ this.handleTabSelect = this.handleTabSelect.bind(this);
+ }
+
+ getActiveTabId () {
+ const { history, tabsArray } = this.props;
+ const matchTab = tabsArray.find(selectedTab => selectedTab.link === history.location.pathname);
+ return matchTab ? matchTab.id : 0;
+ }
+
+ handleTabSelect (event, eventKey) {
+ const { history, tabsArray } = this.props;
+
+ const tab = tabsArray.find(tabElement => tabElement.id === eventKey);
+ history.push(tab.link);
+ }
+
+ render () {
+ const { tabsArray } = this.props;
+ return (
+
+ {tabsArray.map(tabElement => (
+
+ ))}
+
+ );
+ }
+}
+
+export { RoutedTabs as _RoutedTabs };
+export default withRouter(RoutedTabs);
diff --git a/src/components/Tabs/Tab.jsx b/src/components/Tabs/Tab.jsx
deleted file mode 100644
index 6dd9409391..0000000000
--- a/src/components/Tabs/Tab.jsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { NavLink } from 'react-router-dom';
-import './tabs.scss';
-
-const Tab = ({ children, link, replace }) => (
-
-
- {children}
-
-
-);
-
-Tab.propTypes = {
- children: PropTypes.oneOfType([
- PropTypes.arrayOf(PropTypes.node),
- PropTypes.node
- ]).isRequired,
- link: PropTypes.string,
- replace: PropTypes.bool,
-};
-
-Tab.defaultProps = {
- link: null,
- replace: false,
-};
-
-export default Tab;
diff --git a/src/components/Tabs/Tabs.jsx b/src/components/Tabs/Tabs.jsx
deleted file mode 100644
index abea04f8b8..0000000000
--- a/src/components/Tabs/Tabs.jsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { Link } from 'react-router-dom';
-import { Button, Tooltip } from '@patternfly/react-core';
-import { TimesIcon } from '@patternfly/react-icons';
-import './tabs.scss';
-
-const Tabs = ({ children, labelText, closeButton }) => (
-
-
- {closeButton
- && (
-
-
-
-
-
- )
- }
-
-);
-
-Tabs.propTypes = {
- children: PropTypes.oneOfType([
- PropTypes.arrayOf(PropTypes.node),
- PropTypes.node
- ]).isRequired,
- labelText: PropTypes.string,
- closeButton: PropTypes.shape({
- text: PropTypes.string,
- link: PropTypes.string,
- }),
-};
-
-Tabs.defaultProps = {
- labelText: null,
- closeButton: null,
-};
-
-export default Tabs;
diff --git a/src/components/Tabs/tabs.scss b/src/components/Tabs/tabs.scss
deleted file mode 100644
index 651be6acba..0000000000
--- a/src/components/Tabs/tabs.scss
+++ /dev/null
@@ -1,71 +0,0 @@
-.pf-c-card__header {
- --pf-c-card__header--PaddingBottom: 0;
- --pf-c-card__header--PaddingX: 0;
- --pf-c-card__header--PaddingRight: 0;
- --pf-c-card__header--PaddingLeft: 0;
- --pf-c-card__header--PaddingTop: 0;
-}
-
-.pf-c-tabs {
- --pf-global--link--Color: #484848;
- --pf-global--link--Color--hover: #484848;
- --pf-global--link--TextDecoration--hover: none;
-
- align-items: center;
- flex-direction: row;
- justify-content: space-between;
-
- &:before {
- border-bottom: 1px solid var(--pf-c-tabs__item--BorderColor);
- border-top: 1px solid var(--pf-c-tabs__item--BorderColor);
- bottom: 0;
- content: " ";
- left: 0;
- position: absolute;
- right: 0;
- top: 0;
- }
-
- .pf-c-tabs__button {
- --pf-c-tabs__button--PaddingLeft: 20px;
- --pf-c-tabs__button--PaddingRight: 20px;
- display: block;
- font-weight: 700;
-
- &:after {
- content: '';
- bottom: 0;
- left: 0;
- position: absolute;
- right: 0;
- top: 0;
- }
- }
-
- .pf-c-tabs__item:first-child .pf-c-tabs__button:before {
- border-left: 0;
- }
-
- .pf-c-tabs__item:not(.pf-m-current):hover
- .pf-c-tabs__button::after {
- border-top: none;
- }
-
- .pf-c-tabs__item:hover
- .pf-c-tabs__button:not(.pf-m-current)::after {
- border-bottom: 3px solid var(--pf-global--Color--dark-200);
- border-top: none;
- }
-
- .pf-c-tabs__button.pf-m-current {
- color: var(--pf-c-tabs__item--m-current--Color);
- }
-
- .pf-c-tabs__button.pf-m-current::after {
- content: '';
- border-bottom: 3px solid var(--pf-c-tabs__item--m-current--Color);
- border-top: none;
- margin-left: 1px;
- }
-}
-
diff --git a/src/pages/Organizations/screens/Organization/Organization.jsx b/src/pages/Organizations/screens/Organization/Organization.jsx
index b3a92c77cb..1df548b796 100644
--- a/src/pages/Organizations/screens/Organization/Organization.jsx
+++ b/src/pages/Organizations/screens/Organization/Organization.jsx
@@ -12,8 +12,6 @@ import {
Card,
CardHeader,
PageSection,
- Tab,
- Tabs
} from '@patternfly/react-core';
import {
TimesIcon
@@ -25,6 +23,7 @@ import OrganizationDetail from './OrganizationDetail';
import OrganizationEdit from './OrganizationEdit';
import OrganizationNotifications from './OrganizationNotifications';
import OrganizationTeams from './OrganizationTeams';
+import RoutedTabs from '../../../../components/Tabs/RoutedTabs';
class Organization extends Component {
constructor (props) {
@@ -34,17 +33,9 @@ class Organization extends Component {
organization: null,
error: false,
loading: true,
- tabElements: [
- { name: i18nMark('Details'), link: `${props.match.url}/details`, id: 0 },
- { name: i18nMark('Access'), link: `${props.match.url}/access`, id: 1 },
- { name: i18nMark('Teams'), link: `${props.match.url}/teams`, id: 2 },
- { name: i18nMark('Notifications'), link: `${props.match.url}/notifications`, id: 3 },
- ],
};
this.fetchOrganization = this.fetchOrganization.bind(this);
- this.handleTabSelect = this.handleTabSelect.bind(this);
- this.checkLocation = this.checkLocation.bind(this);
}
componentDidMount () {
@@ -75,28 +66,9 @@ class Organization extends Component {
this.setState({ error: true });
} finally {
this.setState({ loading: false });
- this.checkLocation();
}
}
- checkLocation () {
- const { location } = this.props;
- const { tabElements } = this.state;
- const activeTab = tabElements.filter(tabElement => tabElement.link === location.pathname);
- this.setState({ activeTabKey: activeTab[0].id });
- }
-
- handleTabSelect (event, eventKey) {
- const { history } = this.props;
- const { tabElements } = this.state;
-
- const tab = tabElements.find(tabElement => tabElement.id === eventKey);
- history.push(tab.link);
- const activeTab = tabElements.filter(selectedTab => selectedTab.link === tab.link)
- .map(selectedTab => selectedTab.id);
- this.setState({ activeTabKey: activeTab[0] });
- }
-
render () {
const {
location,
@@ -104,36 +76,25 @@ class Organization extends Component {
history
} = this.props;
const {
- activeTabKey,
organization,
error,
loading,
- tabElements
} = this.state;
let cardHeader = (
{({ i18n }) => (
- <>
-
+ {
- this.handleTabSelect(event, eventKey);
- }}
- >
- {tabElements.map(tabElement => (
-
- ))}
-
+ tabsArray={[
+ { name: i18nMark('Details'), link: `${match.url}/details`, id: 0 },
+ { name: i18nMark('Access'), link: `${match.url}/access`, id: 1 },
+ { name: i18nMark('Teams'), link: `${match.url}/teams`, id: 2 },
+ { name: i18nMark('Notifications'), link: `${match.url}/notifications`, id: 3 },
+ ]}
+ />
- >
+
)}