+const Tabs = ({ children, labelText, closeButton }) => (
+
+ {closeButton
+ && (
+
+
+
+
+
+
+
+ )
+ }
);
diff --git a/src/components/Tabs/tabs.scss b/src/components/Tabs/tabs.scss
index 421e933063..15c557dea8 100644
--- a/src/components/Tabs/tabs.scss
+++ b/src/components/Tabs/tabs.scss
@@ -1,9 +1,3 @@
-.at-c-orgPane {
- a {
- display: block;
- }
-}
-
.pf-c-card__header {
--pf-c-card__header--PaddingBottom: 0;
--pf-c-card__header--PaddingX: 0;
@@ -29,22 +23,34 @@
.pf-c-tabs__button {
--pf-c-tabs__button--PaddingLeft: 20px;
--pf-c-tabs__button--PaddingRight: 20px;
- }
+ display: block;
- .pf-c-tabs__item.pf-m-current
- .pf-c-tabs__button::after {
- border-bottom: 3px solid var(--pf-c-tabs__item--m-current--Color);
- border-top: none;
+ &:after {
+ content: '';
+ bottom: 0;
+ left: 0;
+ position: absolute;
+ right: 0;
+ top: 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::after {
+ content: '';
+ border-bottom: 3px solid var(--pf-c-tabs__item--m-current--Color);
+ border-top: none;
+ margin-left: 1px;
+ }
}
-.pf-c-breadcrumb__item.heading {
- flex: 100%;
- font-size: 20px;
-}
\ No newline at end of file
diff --git a/src/pages/Organizations/Organizations.jsx b/src/pages/Organizations/Organizations.jsx
index 27f1830cc6..7b5d41377e 100644
--- a/src/pages/Organizations/Organizations.jsx
+++ b/src/pages/Organizations/Organizations.jsx
@@ -1,36 +1,80 @@
-import React from 'react';
+import React, { Component, Fragment } from 'react';
import { Route, Switch } from 'react-router-dom';
+import { i18nMark } from '@lingui/react';
import OrganizationsList from './screens/OrganizationsList';
import OrganizationAdd from './screens/OrganizationAdd';
import Organization from './screens/Organization/Organization';
+import Breadcrumbs from '../../components/Breadcrumbs/Breadcrumbs';
-export default ({ api, match, history }) => (
-
- (
- {
+ if (!organization) {
+ return;
+ }
+
+ const breadcrumbConfig = {
+ '/organizations': i18nMark('Organizations'),
+ '/organizations/add': i18nMark('Create New Organization'),
+ [`/organizations/${organization.id}`]: `${organization.name}`,
+ [`/organizations/${organization.id}/edit`]: i18nMark('Edit Details'),
+ [`/organizations/${organization.id}/details`]: i18nMark('Details'),
+ [`/organizations/${organization.id}/access`]: i18nMark('Access'),
+ [`/organizations/${organization.id}/teams`]: i18nMark('Teams'),
+ [`/organizations/${organization.id}/notifications`]: i18nMark('Notifications'),
+ };
+
+ this.setState({ breadcrumbConfig });
+ }
+
+ render () {
+ const { match, api, history, location } = this.props;
+ const { breadcrumbConfig } = this.state;
+
+ return (
+
+
- )}
- />
- (
-
- )}
- />
- (
-
- )}
- />
-
-);
+
+ (
+
+ )}
+ />
+ (
+
+ )}
+ />
+ (
+
+ )}
+ />
+
+
+ );
+ }
+}
+
+export default Organizations;
diff --git a/src/pages/Organizations/components/OrganizationListItem.jsx b/src/pages/Organizations/components/OrganizationListItem.jsx
index 161b8274a2..74a3699aa1 100644
--- a/src/pages/Organizations/components/OrganizationListItem.jsx
+++ b/src/pages/Organizations/components/OrganizationListItem.jsx
@@ -17,7 +17,6 @@ export default ({
isSelected,
onSelect,
detailUrl,
- parentBreadcrumb
}) => (
@@ -35,17 +34,14 @@ export default ({
{name}
-
+
Users
@@ -53,7 +49,7 @@ export default ({
{userCount}
{' '}
-
+
Teams
diff --git a/src/pages/Organizations/screens/Organization/Organization.jsx b/src/pages/Organizations/screens/Organization/Organization.jsx
index acd0dd407a..83bc7bdd59 100644
--- a/src/pages/Organizations/screens/Organization/Organization.jsx
+++ b/src/pages/Organizations/screens/Organization/Organization.jsx
@@ -1,128 +1,166 @@
-import React, { Component, Fragment } from 'react';
-import { i18nMark } from '@lingui/react';
+import React, { Component } from 'react';
+import { I18n, i18nMark } from '@lingui/react';
+import { Trans, t } from '@lingui/macro';
import {
Switch,
Route,
withRouter,
+ Redirect
} from 'react-router-dom';
import {
+ Card,
+ CardBody,
+ CardHeader,
PageSection
} from '@patternfly/react-core';
-import OrganizationBreadcrumb from '../../components/OrganizationBreadcrumb';
import OrganizationDetail from './OrganizationDetail';
import OrganizationEdit from './OrganizationEdit';
+import OrganizationNotifications from './OrganizationNotifications';
+import Tabs from '../../../../components/Tabs/Tabs';
+import Tab from '../../../../components/Tabs/Tab';
class Organization extends Component {
constructor (props) {
super(props);
- let { breadcrumb: parentBreadcrumbObj, organization } = props.location.state || {};
- if (!parentBreadcrumbObj) {
- parentBreadcrumbObj = 'loading';
- }
- if (!organization) {
- organization = 'loading';
- }
this.state = {
- parentBreadcrumbObj,
- organization,
+ organization: null,
error: false,
- loading: false,
- mounted: false
+ loading: true,
};
this.fetchOrganization = this.fetchOrganization.bind(this);
}
componentDidMount () {
- this.setState({ mounted: true }, () => {
- const { organization } = this.state;
- if (organization === 'loading') {
- this.fetchOrganization();
- }
- });
+ this.fetchOrganization();
}
- componentWillUnmount () {
- this.setState({ mounted: false });
+ async componentDidUpdate (prevProps) {
+ const { location } = this.props;
+ if (location !== prevProps.location) {
+ await this.fetchOrganization();
+ }
}
async fetchOrganization () {
- const { mounted } = this.state;
- const { api } = this.props;
-
- if (mounted) {
- this.setState({ error: false, loading: true });
-
- const { match } = this.props;
- const { parentBreadcrumbObj, organization } = this.state;
- try {
- const { data } = await api.getOrganizationDetails(match.params.id);
- if (organization === 'loading') {
- this.setState({ organization: data });
- }
- const { name } = data;
- if (parentBreadcrumbObj === 'loading') {
- this.setState({ parentBreadcrumbObj: [{ name: i18nMark('Organizations'), url: '/organizations' }, { name, url: match.url }] });
- }
- } catch (err) {
- this.setState({ error: true });
- } finally {
- this.setState({ loading: false });
- }
+ const {
+ api,
+ match,
+ setBreadcrumb
+ } = this.props;
+ try {
+ const { data } = await api.getOrganizationDetails(+match.params.id);
+ this.setState({ organization: data });
+ setBreadcrumb(data);
+ } catch (error) {
+ this.setState({ error: true });
+ } finally {
+ this.setState({ loading: false });
}
}
render () {
- const { location, match, api, history } = this.props;
- const { parentBreadcrumbObj, organization, error, loading } = this.state;
- const params = new URLSearchParams(location.search);
- const currentTab = params.get('tab') || 'details';
+ const {
+ location,
+ match,
+ api,
+ history
+ } = this.props;
+
+ const {
+ organization,
+ error,
+ loading
+ } = this.state;
+
+ const tabElements = [
+ { name: i18nMark('Details'), link: `${match.url}/details` },
+ { name: i18nMark('Access'), link: `${match.url}/access` },
+ { name: i18nMark('Teams'), link: `${match.url}/teams` },
+ { name: i18nMark('Notifications'), link: `${match.url}/notifications` },
+ ];
+
+ let cardHeader = (
+
+
+ {({ i18n }) => (
+
+ {tabElements.map(tabElement => (
+
+ {tabElement.name}
+
+ ))}
+
+ )}
+
+
+ );
+
+ if (location.pathname.endsWith('edit')) {
+ cardHeader = null;
+ }
return (
-
-
-
+
+
+ { cardHeader }
+
(
)}
/>
(
+ )}
+ />
+ Access
}
+ />
+ Teams
}
+ />
+ (
+
)}
/>
{error ? 'error!' : ''}
{loading ? 'loading...' : ''}
-
-
+
+
);
}
}
diff --git a/src/pages/Organizations/screens/Organization/OrganizationDetail.jsx b/src/pages/Organizations/screens/Organization/OrganizationDetail.jsx
index 4c9b4727e7..b7683ec5e1 100644
--- a/src/pages/Organizations/screens/Organization/OrganizationDetail.jsx
+++ b/src/pages/Organizations/screens/Organization/OrganizationDetail.jsx
@@ -1,115 +1,15 @@
-import React, { Fragment } from 'react';
-import { I18n } from '@lingui/react';
-import { Trans, t } from '@lingui/macro';
-import {
- Card,
- CardHeader,
- CardBody,
-} from '@patternfly/react-core';
-import {
- Switch,
- Link,
- Route
-} from 'react-router-dom';
+import React from 'react';
+import { withRouter, Link } from 'react-router-dom';
+import { Trans } from '@lingui/macro';
+import { CardBody } from '@patternfly/react-core';
-import OrganizationNotifications from './OrganizationNotifications';
+const OrganizationDetail = ({ match, organization }) => (
+
+ {`${organization && organization.name} Detail View`}
+
+ Edit Details
+
+
+);
-import Tab from '../../../../components/Tabs/Tab';
-import Tabs from '../../../../components/Tabs/Tabs';
-import getTabName from '../../utils';
-
-const OrganizationDetail = ({
- location,
- match,
- parentBreadcrumbObj,
- organization,
- params,
- currentTab,
- api,
- history
-}) => {
- // TODO: set objectName by param or through grabbing org detail get from api
- const tabList = ['details', 'access', 'teams', 'notifications'];
-
- const deleteResourceView = () => (
-
- {`deleting ${currentTab} association with orgs `}
-
- {`confirm removal of ${currentTab}/cancel and go back to ${currentTab} view.`}
-
-
- );
-
- const addResourceView = () => (
-
- {`adding ${currentTab} `}
-
- {`save/cancel and go back to ${currentTab} view`}
-
-
- );
-
- const resourceView = () => {
- let relatedTemplate;
- switch (currentTab) {
- case 'notifications':
- relatedTemplate = (
-
- );
- break;
- default:
- relatedTemplate = (
-
- {`${currentTab} detail view `}
-
- {`add ${currentTab}`}
-
- {' '}
-
- {`delete ${currentTab}`}
-
-
- );
- }
- return relatedTemplate;
- };
-
- return (
-
-
-
- {({ i18n }) => (
-
- {tabList.map(tab => (
-
- {getTabName(tab)}
-
- ))}
-
- )}
-
-
-
-
- deleteResourceView()} />
- addResourceView()} />
- resourceView(props)} />
-
-
-
- );
-};
-
-export default OrganizationDetail;
+export default withRouter(OrganizationDetail);
diff --git a/src/pages/Organizations/screens/Organization/OrganizationEdit.jsx b/src/pages/Organizations/screens/Organization/OrganizationEdit.jsx
index e72b1eba39..6ef6a469b2 100644
--- a/src/pages/Organizations/screens/Organization/OrganizationEdit.jsx
+++ b/src/pages/Organizations/screens/Organization/OrganizationEdit.jsx
@@ -1,22 +1,17 @@
import React from 'react';
import { Trans } from '@lingui/macro';
-import {
- Card,
- CardBody
-} from '@patternfly/react-core';
import {
Link
} from 'react-router-dom';
+import { CardBody } from '@patternfly/react-core';
-const OrganizationEdit = ({ match, parentBreadcrumbObj, organization }) => (
-
-
- edit view
-
- save/cancel and go back to view
-
-
-
+const OrganizationEdit = ({ match }) => (
+
+ edit view
+
+ save/cancel and go back to view
+
+
);
export default OrganizationEdit;
diff --git a/src/pages/Organizations/screens/OrganizationsList.jsx b/src/pages/Organizations/screens/OrganizationsList.jsx
index 5e3f0bd5d9..2ebb50c33b 100644
--- a/src/pages/Organizations/screens/OrganizationsList.jsx
+++ b/src/pages/Organizations/screens/OrganizationsList.jsx
@@ -6,11 +6,10 @@ import {
withRouter
} from 'react-router-dom';
import { I18n, i18nMark } from '@lingui/react';
-import { Trans, t } from '@lingui/macro';
+import { t } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
- Title,
} from '@patternfly/react-core';
import DataListToolbar from '../../../components/DataListToolbar';
@@ -177,7 +176,6 @@ class OrganizationsList extends Component {
render () {
const {
- light,
medium,
} = PageSectionVariants;
const {
@@ -193,15 +191,9 @@ class OrganizationsList extends Component {
selected,
} = this.state;
const { match } = this.props;
- const parentBreadcrumb = { name: i18nMark('Organizations'), url: match.url };
return (
-
-
- Organizations
-
-
{
- let tabName = '';
- if (tab === 'details') {
- tabName = 'Details';
- } else if (tab === 'access') {
- tabName = 'Access';
- } else if (tab === 'teams') {
- tabName = 'Teams';
- } else if (tab === 'notifications') {
- tabName = 'Notifications';
- }
- return tabName;
-};
-
-export default getTabName;