update Breadcrumb component to ScreenHeader:

- show last breadcrum item as Title on new line
- add activity stream type (to display activity stream icon link in header)
This commit is contained in:
John Mitchell 2021-01-14 09:42:12 -05:00
parent f37471c858
commit 90edb3b551
42 changed files with 302 additions and 136 deletions

View File

@ -1,73 +0,0 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import {
PageSection as PFPageSection,
PageSectionVariants,
Breadcrumb,
BreadcrumbItem,
BreadcrumbHeading,
} from '@patternfly/react-core';
import { Link, Route, useRouteMatch } from 'react-router-dom';
import styled from 'styled-components';
const PageSection = styled(PFPageSection)`
padding-top: 10px;
padding-bottom: 10px;
`;
const Breadcrumbs = ({ breadcrumbConfig }) => {
const { light } = PageSectionVariants;
return (
<PageSection variant={light}>
<Breadcrumb>
<Route path="/:path">
<Crumb breadcrumbConfig={breadcrumbConfig} />
</Route>
</Breadcrumb>
</PageSection>
);
};
const Crumb = ({ breadcrumbConfig, showDivider }) => {
const match = useRouteMatch();
const crumb = breadcrumbConfig[match.url];
let crumbElement = (
<BreadcrumbItem key={match.url} showDivider={showDivider}>
<Link to={match.url}>{crumb}</Link>
</BreadcrumbItem>
);
if (match.isExact) {
crumbElement = (
<BreadcrumbHeading key="breadcrumb-heading" showDivider={showDivider}>
{crumb}
</BreadcrumbHeading>
);
}
if (!crumb) {
crumbElement = null;
}
return (
<Fragment>
{crumbElement}
<Route path={`${match.url}/:path`}>
<Crumb breadcrumbConfig={breadcrumbConfig} showDivider />
</Route>
</Fragment>
);
};
Breadcrumbs.propTypes = {
breadcrumbConfig: PropTypes.objectOf(PropTypes.string).isRequired,
};
Crumb.propTypes = {
breadcrumbConfig: PropTypes.objectOf(PropTypes.string).isRequired,
};
export default Breadcrumbs;

View File

@ -1 +0,0 @@
export { default } from './Breadcrumbs';

View File

@ -0,0 +1,129 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import {
Button,
PageSection,
PageSectionVariants,
Breadcrumb,
BreadcrumbItem,
Title,
Tooltip,
} from '@patternfly/react-core';
import { HistoryIcon } from '@patternfly/react-icons';
import { Link, Route, useRouteMatch } from 'react-router-dom';
const ScreenHeader = ({ breadcrumbConfig, i18n, streamType }) => {
const { light } = PageSectionVariants;
const oneCrumbMatch = useRouteMatch({
path: Object.keys(breadcrumbConfig)[0],
strict: true,
});
const isOnlyOneCrumb = oneCrumbMatch && oneCrumbMatch.isExact;
return (
<PageSection variant={light}>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<div>
{!isOnlyOneCrumb && (
<Breadcrumb>
<Route path="/:path">
<Crumb breadcrumbConfig={breadcrumbConfig} />
</Route>
</Breadcrumb>
)}
<Route path="/:path">
<ActualTitle breadcrumbConfig={breadcrumbConfig} />
</Route>
</div>
{streamType !== 'none' && (
<div>
<Tooltip content={i18n._(t`View activity stream`)} position="top">
<Button
aria-label={i18n._(t`View activity stream`)}
variant="plain"
component={Link}
to={`/activity_stream${
streamType ? `?type=${streamType}` : ''
}`}
>
<HistoryIcon />
</Button>
</Tooltip>
</div>
)}
</div>
</PageSection>
);
};
const ActualTitle = ({ breadcrumbConfig }) => {
const match = useRouteMatch();
const title = breadcrumbConfig[match.url];
let titleElement;
if (match.isExact) {
titleElement = (
<Title size="2xl" headingLevel="h2">
{title}
</Title>
);
}
if (!title) {
titleElement = null;
}
return (
<Fragment>
{titleElement}
<Route path={`${match.url}/:path`}>
<ActualTitle breadcrumbConfig={breadcrumbConfig} />
</Route>
</Fragment>
);
};
const Crumb = ({ breadcrumbConfig, showDivider }) => {
const match = useRouteMatch();
const crumb = breadcrumbConfig[match.url];
let crumbElement = (
<BreadcrumbItem key={match.url} showDivider={showDivider}>
<Link to={match.url}>{crumb}</Link>
</BreadcrumbItem>
);
if (match.isExact) {
crumbElement = null;
}
if (!crumb) {
crumbElement = null;
}
return (
<Fragment>
{crumbElement}
<Route path={`${match.url}/:path`}>
<Crumb breadcrumbConfig={breadcrumbConfig} showDivider />
</Route>
</Fragment>
);
};
ScreenHeader.propTypes = {
breadcrumbConfig: PropTypes.objectOf(PropTypes.string).isRequired,
};
Crumb.propTypes = {
breadcrumbConfig: PropTypes.objectOf(PropTypes.string).isRequired,
};
export default withI18n()(ScreenHeader);

View File

@ -1,9 +1,15 @@
import React from 'react';
import { mount } from 'enzyme';
import { MemoryRouter } from 'react-router-dom';
import Breadcrumbs from './Breadcrumbs';
describe('<Breadcrumb />', () => {
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import ScreenHeader from './ScreenHeader';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<ScreenHeader />', () => {
let breadcrumbWrapper;
let breadcrumb;
let breadcrumbItem;
@ -17,15 +23,15 @@ describe('<Breadcrumb />', () => {
};
const findChildren = () => {
breadcrumb = breadcrumbWrapper.find('Breadcrumb');
breadcrumb = breadcrumbWrapper.find('ScreenHeader');
breadcrumbItem = breadcrumbWrapper.find('BreadcrumbItem');
breadcrumbHeading = breadcrumbWrapper.find('BreadcrumbHeading');
breadcrumbHeading = breadcrumbWrapper.find('Title');
};
test('initially renders succesfully', () => {
breadcrumbWrapper = mount(
breadcrumbWrapper = mountWithContexts(
<MemoryRouter initialEntries={['/foo/1/bar']} initialIndex={0}>
<Breadcrumbs breadcrumbConfig={config} />
<ScreenHeader streamType="all_activity" breadcrumbConfig={config} />
</MemoryRouter>
);
@ -51,9 +57,9 @@ describe('<Breadcrumb />', () => {
];
routes.forEach(([location, crumbLength]) => {
breadcrumbWrapper = mount(
breadcrumbWrapper = mountWithContexts(
<MemoryRouter initialEntries={[location]}>
<Breadcrumbs breadcrumbConfig={config} />
<ScreenHeader streamType="all_activity" breadcrumbConfig={config} />
</MemoryRouter>
);

View File

@ -0,0 +1 @@
export { default } from './ScreenHeader';

View File

@ -12,7 +12,7 @@ import {
import ApplicationsList from './ApplicationsList';
import ApplicationAdd from './ApplicationAdd';
import Application from './Application';
import Breadcrumbs from '../../components/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader';
import { Detail, DetailList } from '../../components/DetailList';
const ApplicationAlert = styled(Alert)`
@ -45,7 +45,10 @@ function Applications({ i18n }) {
return (
<>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader
streamType="o_auth2_application,o_auth2_access_token"
breadcrumbConfig={breadcrumbConfig}
/>
<Switch>
<Route path="/applications/add">
<ApplicationAdd

View File

@ -5,6 +5,10 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import Applications from './Applications';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Applications />', () => {
let wrapper;

View File

@ -3,7 +3,7 @@ import { Route, Switch } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Config } from '../../contexts/Config';
import Breadcrumbs from '../../components/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader';
import Credential from './Credential';
import CredentialAdd from './CredentialAdd';
import { CredentialList } from './CredentialList';
@ -34,7 +34,10 @@ function Credentials({ i18n }) {
return (
<>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader
streamType="credential"
breadcrumbConfig={breadcrumbConfig}
/>
<Switch>
<Route path="/credentials/add">
<Config>{({ me }) => <CredentialAdd me={me || {}} />}</Config>

View File

@ -3,6 +3,10 @@ import { createMemoryHistory } from 'history';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import Credentials from './Credentials';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Credentials />', () => {
let wrapper;
@ -30,8 +34,8 @@ describe('<Credentials />', () => {
},
});
expect(wrapper.find('Crumb').length).toBe(1);
expect(wrapper.find('BreadcrumbHeading').text()).toBe('Credentials');
expect(wrapper.find('Crumb').length).toBe(0);
expect(wrapper.find('Title').text()).toBe('Credentials');
});
test('should display create new credential breadcrumb heading', () => {
@ -51,8 +55,6 @@ describe('<Credentials />', () => {
});
expect(wrapper.find('Crumb').length).toBe(2);
expect(wrapper.find('BreadcrumbHeading').text()).toBe(
'Create New Credential'
);
expect(wrapper.find('Title').text()).toBe('Create New Credential');
});
});

View File

@ -6,7 +6,7 @@ import { Route, Switch } from 'react-router-dom';
import CredentialTypeAdd from './CredentialTypeAdd';
import CredentialTypeList from './CredentialTypeList';
import CredentialType from './CredentialType';
import Breadcrumbs from '../../components/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader';
function CredentialTypes({ i18n }) {
const [breadcrumbConfig, setBreadcrumbConfig] = useState({
@ -33,7 +33,10 @@ function CredentialTypes({ i18n }) {
);
return (
<>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader
streamType="credential_type"
breadcrumbConfig={breadcrumbConfig}
/>
<Switch>
<Route path="/credential_types/add">
<CredentialTypeAdd />

View File

@ -4,6 +4,10 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import CredentialTypes from './CredentialTypes';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<CredentialTypes/>', () => {
let pageWrapper;
let pageSections;

View File

@ -18,7 +18,7 @@ import {
import useRequest from '../../util/useRequest';
import { DashboardAPI } from '../../api';
import Breadcrumbs from '../../components/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader';
import JobList from '../../components/JobList';
import ContentLoading from '../../components/ContentLoading';
import LineChart from './shared/LineChart';
@ -117,7 +117,10 @@ function Dashboard({ i18n }) {
}
return (
<Fragment>
<Breadcrumbs breadcrumbConfig={{ '/home': i18n._(t`Dashboard`) }} />
<ScreenHeader
streamType="all"
breadcrumbConfig={{ '/home': i18n._(t`Dashboard`) }}
/>
<PageSection>
<Counts>
<Count

View File

@ -7,6 +7,9 @@ import { DashboardAPI } from '../../api';
import Dashboard from './Dashboard';
jest.mock('../../api');
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Dashboard />', () => {
let pageWrapper;

View File

@ -4,7 +4,7 @@ import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Config } from '../../contexts/Config';
import Breadcrumbs from '../../components/Breadcrumbs/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader/ScreenHeader';
import HostList from './HostList';
import HostAdd from './HostAdd';
@ -37,7 +37,7 @@ function Hosts({ i18n }) {
return (
<>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader streamType="host" breadcrumbConfig={breadcrumbConfig} />
<Switch>
<Route path="/hosts/add">
<HostAdd />

View File

@ -5,6 +5,10 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import Hosts from './Hosts';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Hosts />', () => {
test('initially renders succesfully', () => {
mountWithContexts(<Hosts />);
@ -27,7 +31,7 @@ describe('<Hosts />', () => {
},
},
});
expect(wrapper.find('BreadcrumbHeading').length).toBe(1);
expect(wrapper.find('Title').length).toBe(1);
wrapper.unmount();
});

View File

@ -9,7 +9,7 @@ import InstanceGroup from './InstanceGroup';
import ContainerGroupAdd from './ContainerGroupAdd';
import ContainerGroup from './ContainerGroup';
import Breadcrumbs from '../../components/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader';
function InstanceGroups({ i18n }) {
const [breadcrumbConfig, setBreadcrumbConfig] = useState({
@ -54,7 +54,10 @@ function InstanceGroups({ i18n }) {
);
return (
<>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader
streamType="instance_group"
breadcrumbConfig={breadcrumbConfig}
/>
<Switch>
<Route path="/instance_groups/container_group/add">
<ContainerGroupAdd />

View File

@ -4,6 +4,10 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import InstanceGroups from './InstanceGroups';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<InstanceGroups/>', () => {
let pageWrapper;
let pageSections;

View File

@ -4,7 +4,7 @@ import { t } from '@lingui/macro';
import { Route, Switch } from 'react-router-dom';
import { Config } from '../../contexts/Config';
import Breadcrumbs from '../../components/Breadcrumbs/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader/ScreenHeader';
import { InventoryList } from './InventoryList';
import Inventory from './Inventory';
import SmartInventory from './SmartInventory';
@ -95,7 +95,10 @@ function Inventories({ i18n }) {
return (
<>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader
streamType="inventory"
breadcrumbConfig={breadcrumbConfig}
/>
<Switch>
<Route path="/inventories/inventory/add">
<InventoryAdd />

View File

@ -4,6 +4,10 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import Inventories from './Inventories';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Inventories />', () => {
let pageWrapper;

View File

@ -4,6 +4,10 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import Job from './Jobs';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Job />', () => {
test('initially renders succesfully', () => {
mountWithContexts(<Job />);

View File

@ -3,7 +3,7 @@ import { Route, Switch, useParams, useRouteMatch } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { PageSection } from '@patternfly/react-core';
import Breadcrumbs from '../../components/Breadcrumbs/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader/ScreenHeader';
import Job from './Job';
import JobTypeRedirect from './JobTypeRedirect';
import JobList from '../../components/JobList';
@ -40,7 +40,7 @@ function Jobs({ i18n }) {
return (
<>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader streamType="job" breadcrumbConfig={breadcrumbConfig} />
<Switch>
<Route exact path={match.path}>
<PageSection>

View File

@ -5,6 +5,10 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import Jobs from './Jobs';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Jobs />', () => {
test('initially renders succesfully', () => {
mountWithContexts(<Jobs />);
@ -27,7 +31,7 @@ describe('<Jobs />', () => {
},
},
});
expect(wrapper.find('BreadcrumbHeading').length).toBe(1);
expect(wrapper.find('Title').length).toBe(1);
wrapper.unmount();
});
});

View File

@ -2,12 +2,13 @@ import React, { Fragment } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import Breadcrumbs from '../../components/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader';
function ManagementJobs({ i18n }) {
return (
<Fragment>
<Breadcrumbs
<ScreenHeader
streamType="none"
breadcrumbConfig={{ '/management_jobs': i18n._(t`Management Jobs`) }}
/>
</Fragment>

View File

@ -4,6 +4,10 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import ManagementJobs from './ManagementJobs';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<ManagementJobs />', () => {
let pageWrapper;
@ -17,6 +21,6 @@ describe('<ManagementJobs />', () => {
test('initially renders without crashing', () => {
expect(pageWrapper.length).toBe(1);
expect(pageWrapper.find('Breadcrumbs').length).toBe(1);
expect(pageWrapper.find('ScreenHeader').length).toBe(1);
});
});

View File

@ -5,7 +5,7 @@ import { t } from '@lingui/macro';
import NotificationTemplateList from './NotificationTemplateList';
import NotificationTemplateAdd from './NotificationTemplateAdd';
import NotificationTemplate from './NotificationTemplate';
import Breadcrumbs from '../../components/Breadcrumbs/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader/ScreenHeader';
function NotificationTemplates({ i18n }) {
const match = useRouteMatch();
@ -32,7 +32,10 @@ function NotificationTemplates({ i18n }) {
return (
<>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader
streamType="notification_template"
breadcrumbConfig={breadcrumbConfig}
/>
<Switch>
<Route path={`${match.url}/add`}>
<NotificationTemplateAdd />

View File

@ -2,6 +2,10 @@ import React from 'react';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import NotificationTemplates from './NotificationTemplates';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<NotificationTemplates />', () => {
let pageWrapper;
let pageSections;

View File

@ -4,7 +4,7 @@ import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Config } from '../../contexts/Config';
import Breadcrumbs from '../../components/Breadcrumbs/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader/ScreenHeader';
import OrganizationsList from './OrganizationList/OrganizationList';
import OrganizationAdd from './OrganizationAdd/OrganizationAdd';
@ -42,7 +42,10 @@ function Organizations({ i18n }) {
return (
<Fragment>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader
streamType="organization"
breadcrumbConfig={breadcrumbConfig}
/>
<Switch>
<Route path={`${match.path}/add`}>
<OrganizationAdd />

View File

@ -5,6 +5,9 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import Organizations from './Organizations';
jest.mock('../../api');
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Organizations />', () => {
test('initially renders succesfully', async () => {

View File

@ -3,7 +3,7 @@ import { Route, withRouter, Switch } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import Breadcrumbs from '../../components/Breadcrumbs/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader/ScreenHeader';
import ProjectsList from './ProjectList/ProjectList';
import ProjectAdd from './ProjectAdd/ProjectAdd';
@ -45,7 +45,7 @@ function Projects({ i18n }) {
return (
<>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader streamType="project" breadcrumbConfig={breadcrumbConfig} />
<Switch>
<Route path="/projects/add">
<ProjectAdd />

View File

@ -5,6 +5,10 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import Projects from './Projects';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Projects />', () => {
test('initially renders succesfully', () => {
mountWithContexts(<Projects />);
@ -27,7 +31,7 @@ describe('<Projects />', () => {
},
},
});
expect(wrapper.find('BreadcrumbHeading').length).toBe(1);
expect(wrapper.find('Title').length).toBe(1);
wrapper.unmount();
});
});

View File

@ -4,7 +4,7 @@ import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { PageSection, Card } from '@patternfly/react-core';
import Breadcrumbs from '../../components/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader';
import { ScheduleList } from '../../components/Schedule';
import { SchedulesAPI } from '../../api';
@ -19,7 +19,8 @@ function AllSchedules({ i18n }) {
return (
<>
<Breadcrumbs
<ScreenHeader
streamType="schedule"
breadcrumbConfig={{
'/schedules': i18n._(t`Schedules`),
}}

View File

@ -3,6 +3,10 @@ import { createMemoryHistory } from 'history';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import AllSchedules from './AllSchedules';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<AllSchedules />', () => {
let wrapper;
@ -30,7 +34,6 @@ describe('<AllSchedules />', () => {
},
});
expect(wrapper.find('Crumb').length).toBe(1);
expect(wrapper.find('BreadcrumbHeading').text()).toBe('Schedules');
expect(wrapper.find('Title').text()).toBe('Schedules');
});
});

View File

@ -5,7 +5,7 @@ import { t } from '@lingui/macro';
import { PageSection, Card } from '@patternfly/react-core';
import ContentError from '../../components/ContentError';
import ContentLoading from '../../components/ContentLoading';
import Breadcrumbs from '../../components/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader';
import ActivityStream from './ActivityStream';
import AzureAD from './AzureAD';
import GitHub from './GitHub';
@ -129,7 +129,7 @@ function Settings({ i18n }) {
return (
<SettingsProvider value={result}>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader streamType="setting" breadcrumbConfig={breadcrumbConfig} />
<Switch>
<Route path="/settings/activity_stream">
<ActivityStream />

View File

@ -13,6 +13,9 @@ jest.mock('../../api/models/Settings');
SettingsAPI.readAllOptions.mockResolvedValue({
data: mockAllOptions,
});
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Settings />', () => {
let wrapper;

View File

@ -4,7 +4,7 @@ import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Config } from '../../contexts/Config';
import Breadcrumbs from '../../components/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader';
import TeamList from './TeamList';
import TeamAdd from './TeamAdd';
import Team from './Team';
@ -36,7 +36,7 @@ function Teams({ i18n }) {
return (
<>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader streamType="team" breadcrumbConfig={breadcrumbConfig} />
<Switch>
<Route path="/teams/add">
<TeamAdd />

View File

@ -3,6 +3,9 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import Teams from './Teams';
jest.mock('../../api');
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Teams />', () => {
test('initially renders succesfully', () => {

View File

@ -4,7 +4,7 @@ import { t } from '@lingui/macro';
import { Route, withRouter, Switch } from 'react-router-dom';
import { PageSection } from '@patternfly/react-core';
import Breadcrumbs from '../../components/Breadcrumbs/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader/ScreenHeader';
import { TemplateList } from './TemplateList';
import Template from './Template';
import WorkflowJobTemplate from './WorkflowJobTemplate';
@ -12,22 +12,24 @@ import JobTemplateAdd from './JobTemplateAdd';
import WorkflowJobTemplateAdd from './WorkflowJobTemplateAdd';
function Templates({ i18n }) {
const initBreadcrumbs = useRef({
const initScreenHeader = useRef({
'/templates': i18n._(t`Templates`),
'/templates/job_template/add': i18n._(t`Create New Job Template`),
'/templates/workflow_job_template/add': i18n._(
t`Create New Workflow Template`
),
});
const [breadcrumbConfig, setBreadcrumbs] = useState(initBreadcrumbs.current);
const [breadcrumbConfig, setScreenHeader] = useState(
initScreenHeader.current
);
const setBreadcrumbConfig = useCallback(
(template, schedule) => {
if (!template) return;
const templatePath = `/templates/${template.type}/${template.id}`;
const schedulesPath = `${templatePath}/schedules`;
const surveyPath = `${templatePath}/survey`;
setBreadcrumbs({
...initBreadcrumbs.current,
setScreenHeader({
...initScreenHeader.current,
[templatePath]: `${template.name}`,
[`${templatePath}/details`]: i18n._(t`Details`),
[`${templatePath}/edit`]: i18n._(t`Edit Details`),
@ -49,7 +51,10 @@ function Templates({ i18n }) {
return (
<>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader
streamType="job_template,workflow_job_template"
breadcrumbConfig={breadcrumbConfig}
/>
<Switch>
<Route path="/templates/job_template/add">
<JobTemplateAdd />

View File

@ -3,6 +3,10 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import Templates from './Templates';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Templates />', () => {
let pageWrapper;

View File

@ -3,7 +3,7 @@ import { Route, useRouteMatch, Switch } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import Breadcrumbs from '../../components/Breadcrumbs/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader/ScreenHeader';
import { Config } from '../../contexts/Config';
import UsersList from './UserList/UserList';
@ -46,7 +46,7 @@ function Users({ i18n }) {
);
return (
<Fragment>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader streamType="user" breadcrumbConfig={breadcrumbConfig} />
<Switch>
<Route path={`${match.path}/add`}>
<UserAdd />

View File

@ -5,6 +5,10 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import Users from './Users';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<Users />', () => {
test('initially renders successfully', () => {
mountWithContexts(<Users />);
@ -27,7 +31,7 @@ describe('<Users />', () => {
},
},
});
expect(wrapper.find('BreadcrumbHeading').length).toBe(1);
expect(wrapper.find('Title').length).toBe(1);
wrapper.unmount();
});
});

View File

@ -4,7 +4,7 @@ import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import WorkflowApprovalList from './WorkflowApprovalList';
import WorkflowApproval from './WorkflowApproval';
import Breadcrumbs from '../../components/Breadcrumbs/Breadcrumbs';
import ScreenHeader from '../../components/ScreenHeader/ScreenHeader';
function WorkflowApprovals({ i18n }) {
const match = useRouteMatch();
@ -26,7 +26,10 @@ function WorkflowApprovals({ i18n }) {
return (
<>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<ScreenHeader
streamType="workflow_approval"
breadcrumbConfig={breadcrumbConfig}
/>
<Switch>
<Route path={`${match.url}/:id`}>
<WorkflowApproval setBreadcrumb={updateBreadcrumbConfig} />

View File

@ -3,6 +3,10 @@ import { createMemoryHistory } from 'history';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import WorkflowApprovals from './WorkflowApprovals';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
}));
describe('<WorkflowApprovals />', () => {
test('initially renders succesfully', () => {
mountWithContexts(<WorkflowApprovals />);
@ -29,7 +33,8 @@ describe('<WorkflowApprovals />', () => {
},
},
});
expect(wrapper.find('BreadcrumbHeading').length).toBe(1);
expect(wrapper.find('Title').length).toBe(1);
wrapper.unmount();
});
});