Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ describe(ClusterServiceVersionResourcesDetailsPage.displayName, () => {

it('passes function to create breadcrumbs for resource to `DetailsPage`', () => {
expect(wrapper.find(DetailsPage).props().breadcrumbsFor(null)).toEqual([
{name: 'Installed Operators', path: `/k8s/ns/default/${ClusterServiceVersionModel.plural}`},
{name: 'etcd', path: `/k8s/ns/default/${ClusterServiceVersionModel.plural}/etcd/etcdclusters`},
{name: `${testResourceInstance.kind} Details`, path: `/k8s/ns/default/${ClusterServiceVersionModel.plural}/etcd/etcdclusters/my-etcd`},
]);
Expand All @@ -227,6 +228,7 @@ describe(ClusterServiceVersionResourcesDetailsPage.displayName, () => {
wrapper.setProps({match});

expect(wrapper.find(DetailsPage).props().breadcrumbsFor(null)).toEqual([
{name: 'Installed Operators', path: `/k8s/ns/example/${ClusterServiceVersionModel.plural}`},
{name: 'example', path: `/k8s/ns/${ClusterServiceVersionModel.plural}/example/example`},
{name: `${testResourceInstance.kind} Details`, path: `/k8s/ns/${ClusterServiceVersionModel.plural}/example/example/example`},
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,16 +238,4 @@ describe(InstallPlanDetailsPage.displayName, () => {
it('renders a `DetailsPage` with correct props', () => {
expect(wrapper.find(DetailsPage).props().pages.map(p => p.name)).toEqual(['Overview', 'YAML', 'Components']);
});

it('passes `breadcrumbsFor` function for rendering a link back to the parent `Subscription` if it has one', () => {
const breadcrumbsFor = wrapper.find(DetailsPage).props().breadcrumbsFor;

expect(breadcrumbsFor(testInstallPlan)).toEqual([{
name: testInstallPlan.metadata.ownerReferences[0].name,
path: `/k8s/ns/default/operators.coreos.com~v1alpha1~Subscription/${testInstallPlan.metadata.ownerReferences[0].name}`,
}, {
name: 'Install Plan Details',
path: match.url,
}]);
});
});
19 changes: 0 additions & 19 deletions frontend/__tests__/components/pod.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { shallow, ShallowWrapper } from 'enzyme';

import { Readiness, PodsDetailsPage } from '../../public/components/pod';
import { DetailsPage } from '../../public/components/factory';
import { K8sResourceKind } from '../../public/module/k8s';
import { ReplicaSetModel } from '../../public/models';

describe('Readiness', () => {
let pod;
Expand Down Expand Up @@ -41,29 +39,12 @@ describe('Readiness', () => {

describe(PodsDetailsPage.displayName, () => {
let wrapper: ShallowWrapper;
let pod: K8sResourceKind;

beforeEach(() => {
pod = {
apiVersion: 'v1',
kind: 'Pod',
metadata: {
name: 'example',
namespace: 'default',
ownerReferences: [{apiVersion: ReplicaSetModel.apiVersion, kind: ReplicaSetModel.kind, name: 'example-rs', uid: '9999'}],
},
};
wrapper = shallow(<PodsDetailsPage match={{url: '/k8s/ns/default/pods/example', path: '/k8s/ns/:ns/:plural/:name', isExact: true, params: {}}} kind="Pod" />);
});

it('renders `DetailsPage` with correct props', () => {
expect(wrapper.find(DetailsPage).exists()).toBe(true);
});

it('passes function to create breadcrumbs for Pod', () => {
expect(wrapper.find(DetailsPage).props().breadcrumbsFor(pod)).toEqual([
{name: pod.metadata.ownerReferences[0].name, path: `/k8s/ns/default/${ReplicaSetModel.plural}/example-rs`},
{name: 'Pod Details', path: '/k8s/ns/default/pods/example'},
]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ describe('Interacting with a `OwnNamespace` install mode Operator (Prometheus)',
});

it('displays YAML editor for creating a new `Alertmanager` instance', async() => {
await $$('.breadcrumb-link').first().click();
await $$('[data-test-id=breadcrumb-link-1]').click();
await crudView.isLoaded();
await element(by.linkText('All Instances')).click();
await browser.wait(until.visibilityOf(element(by.buttonText('Create New'))));
Expand Down Expand Up @@ -227,7 +227,7 @@ describe('Interacting with a `OwnNamespace` install mode Operator (Prometheus)',
});

it('displays YAML editor for creating a new `ServiceMonitor` instance', async() => {
await $$('.breadcrumb-link').first().click();
await $$('[data-test-id=breadcrumb-link-1]').click();
await crudView.isLoaded();
await element(by.linkText('All Instances')).click();
await browser.wait(until.visibilityOf(element(by.buttonText('Create New'))));
Expand Down
3 changes: 0 additions & 3 deletions frontend/public/components/_nav-title.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,4 @@
min-height: 118px; // breadcrumb text + top & bottom padding + h1 text + bottom margin + bottom border + (21 + 25 + 12 + 29 + 30 + 1)
padding-top: 0;
}
&--logo {
padding-top: ($grid-gutter-width / 2);
}
}
5 changes: 0 additions & 5 deletions frontend/public/components/build.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
Timestamp,
} from './utils';
import { BuildPipeline, BuildPipelineLogLink } from './build-pipeline';
import { breadcrumbsForOwnerRefs } from './utils/breadcrumbs';
import { fromNow } from './utils/datetime';
import { BuildLogs } from './build-logs';
import { ResourceEventStream } from './events';
Expand Down Expand Up @@ -239,10 +238,6 @@ const pages = [
export const BuildsDetailsPage: React.SFC<BuildsDetailsPageProps> = props =>
<DetailsPage
{...props}
breadcrumbsFor={obj => breadcrumbsForOwnerRefs(obj).concat({
name: 'Build Details',
path: props.match.url,
})}
kind={BuildsReference}
menuActions={menuActions}
pages={pages} />;
Expand Down
3 changes: 2 additions & 1 deletion frontend/public/components/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,9 @@ export const ContainersDetailsPage: React.FC<ContainerDetailsPageProps> = (props
title={props.match.params.name}
kind="Container"
breadcrumbsFor={() => [
{name: 'Pods', path: `/k8s/ns/${props.match.params.ns}/pods`},
{name: props.match.params.podName, path: resourcePath('Pod', props.match.params.podName, props.match.params.ns)},
{name: 'Container Details', path: `${props.match.url}`},
{name: 'Container Details', path: props.match.url},
]} />
<HorizontalNav hideNav={true} pages={[{name: 'container', href: '', component: ContainerDetails}]} match={props.match} />
</Firehose>
Expand Down
8 changes: 6 additions & 2 deletions frontend/public/components/factory/details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { match } from 'react-router-dom';
import * as _ from 'lodash-es';

import { Firehose, HorizontalNav, PageHeading } from '../utils';
import { K8sResourceKindReference, K8sResourceKind, Selector } from '../../module/k8s';
import { K8sResourceKindReference, K8sResourceKind, K8sKind, Selector } from '../../module/k8s';
import { withFallback } from '../utils/error-boundary';
import { ErrorBoundaryFallback } from '../error';
import { breadcrumbsForDetailsPage } from '../utils/breadcrumbs';

export type FirehoseResource = {
kind: K8sResourceKindReference;
Expand All @@ -18,6 +19,7 @@ export type FirehoseResource = {

export const DetailsPage = withFallback<DetailsPageProps>((props) => <Firehose resources={[{
kind: props.kind,
kindObj: props.kindObj,
name: props.name,
namespace: props.namespace,
isList: false,
Expand All @@ -30,7 +32,8 @@ export const DetailsPage = withFallback<DetailsPageProps>((props) => <Firehose r
menuActions={props.menuActions}
buttonActions={props.buttonActions}
kind={props.kind}
breadcrumbsFor={props.breadcrumbsFor} />
breadcrumbsFor={props.breadcrumbsFor ? props.breadcrumbsFor : breadcrumbsForDetailsPage(props.kindObj, props.match)}
/>
<HorizontalNav
pages={props.pages}
pagesFor={props.pagesFor}
Expand All @@ -55,6 +58,7 @@ export type DetailsPageProps = {
pages?: Page[];
pagesFor?: (obj: K8sResourceKind) => Page[];
kind: K8sResourceKindReference;
kindObj?: K8sKind;
label?: string;
name?: string;
namespace?: string;
Expand Down
7 changes: 4 additions & 3 deletions frontend/public/components/image-stream-tag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,12 @@ export const ImageStreamTagsDetailsPage: React.SFC<ImageStreamTagsDetailsPagePro
{...props}
breadcrumbsFor={obj => {
const imageStreamName = getImageStreamNameForTag(obj);
return [{
return [{name: 'Image Streams', path: `/k8s/ns/${props.match.params.ns}/imagestreams`,
}, {
name: imageStreamName,
path: `/k8s/ns/${obj.metadata.namespace}/imagestreams/${imageStreamName}`,
path: `/k8s/ns/${props.match.params.ns}/imagestreams/${imageStreamName}`,
}, {
name: 'ImageStreamTag Details',
name: 'Image Stream Tag Details',
path: props.match.url,
}];
}}
Expand Down
5 changes: 0 additions & 5 deletions frontend/public/components/machine-set.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import {
resourcePath,
useAccessReview,
} from './utils';
import { breadcrumbsForOwnerRefs } from './utils/breadcrumbs';
import { Tooltip } from './utils/tooltip';

const machineReplicasModal = (resourceKind: K8sKind, resource: MachineSetKind | MachineDeploymentKind) => configureReplicaCountModal({
Expand Down Expand Up @@ -241,10 +240,6 @@ export const MachineSetPage: React.SFC<MachineSetPageProps> = props =>

export const MachineSetDetailsPage: React.SFC<MachineSetDetailsPageProps> = props => <DetailsPage
{...props}
breadcrumbsFor={obj => breadcrumbsForOwnerRefs(obj).concat({
name: 'Machine Set Details',
path: props.match.url,
})}
menuActions={menuActions}
kind={machineSetReference}
pages={[
Expand Down
5 changes: 0 additions & 5 deletions frontend/public/components/machine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
SectionHeading,
navFactory,
} from './utils';
import { breadcrumbsForOwnerRefs } from './utils/breadcrumbs';

const { common } = Kebab.factory;
const menuActions = [...common];
Expand Down Expand Up @@ -147,10 +146,6 @@ export const MachinePage: React.SFC<MachinePageProps> = props =>
export const MachineDetailsPage: React.SFC<MachineDetailsPageProps> = props =>
<DetailsPage
{...props}
breadcrumbsFor={obj => breadcrumbsForOwnerRefs(obj).concat({
name: 'Machine Details',
path: props.match.url,
})}
kind={machineReference}
menuActions={menuActions}
pages={[navFactory.details(MachineDetails), navFactory.editYaml()]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ export const ClusterServiceVersionResourcesDetailsPage: React.SFC<ClusterService
]}
menuActions={actions}
breadcrumbsFor={() => [
{name: 'Installed Operators', path: `/k8s/ns/${props.match.params.ns}/${ClusterServiceVersionModel.plural}`},
{name: props.match.params.appName, path: props.match.url.slice(0, props.match.url.lastIndexOf('/'))},
{name: `${kindForReference(props.kind)} Details`, path: `${props.match.url}`},
]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ export const ClusterServiceVersionsDetailsPage: React.StatelessComponent<Cluster

return <DetailsPage
{...props}
breadcrumbsFor={() => [
{name: 'Installed Operators', path: `/k8s/ns/${props.match.params.ns}/${props.match.params.plural}`},
{name: 'Operator Details', path: props.match.url},
]}
namespace={props.match.params.ns}
kind={referenceForModel(ClusterServiceVersionModel)}
name={props.match.params.name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { SectionHeading, MsgBox, ResourceLink, ResourceKebab, Kebab, ResourceIco
import { InstallPlanKind, InstallPlanApproval, olmNamespace, Step, referenceForStepResource } from './index';
import { K8sResourceKind, referenceForModel, referenceForOwnerRef, k8sUpdate, apiVersionForReference } from '../../module/k8s';
import { SubscriptionModel, ClusterServiceVersionModel, InstallPlanModel, CatalogSourceModel, OperatorGroupModel } from '../../models';
import { breadcrumbsForOwnerRefs } from '../utils/breadcrumbs';
import { requireOperatorGroup } from './operator-group';
import { installPlanPreviewModal } from '../modals';

Expand Down Expand Up @@ -248,10 +247,6 @@ export const InstallPlanDetailsPage: React.SFC<InstallPlanDetailsPageProps> = (p
navFactory.editYaml(),
{href: 'components', name: 'Components', component: InstallPlanPreview},
]}
breadcrumbsFor={(obj) => breadcrumbsForOwnerRefs(obj).concat({
name: 'Install Plan Details',
path: props.match.url,
})}
menuActions={Kebab.factory.common} />;

export type InstallPlansListProps = {
Expand Down
5 changes: 0 additions & 5 deletions frontend/public/components/pod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import {
} from './utils';
import { PodLogs } from './pod-logs';
import { requirePrometheus, Area } from './graphs';
import { breadcrumbsForOwnerRefs } from './utils/breadcrumbs';
import { formatDuration } from './utils/datetime';
import { CamelCaseWrap } from './utils/camel-case-wrap';
import { VolumesTable } from './volumes-table';
Expand Down Expand Up @@ -303,10 +302,6 @@ const PodExecLoader: React.FC<PodExecLoaderProps> = ({obj}) => <div className="c

export const PodsDetailsPage: React.FC<PodDetailsPageProps> = props => <DetailsPage
{...props}
breadcrumbsFor={obj => breadcrumbsForOwnerRefs(obj).concat({
name: 'Pod Details',
path: props.match.url,
})}
menuActions={menuActions}
pages={[
navFactory.details(Details),
Expand Down
5 changes: 0 additions & 5 deletions frontend/public/components/replicaset.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
WorkloadTableHeader,
} from './workload-table';

import { breadcrumbsForOwnerRefs } from './utils/breadcrumbs';
import { ResourceEventStream } from './events';
import { VolumesTable } from './volumes-table';

Expand Down Expand Up @@ -69,10 +68,6 @@ const environmentComponent = (props) => <EnvironmentPage
const {details, editYaml, pods, envEditor, events} = navFactory;
const ReplicaSetsDetailsPage = props => <DetailsPage
{...props}
breadcrumbsFor={obj => breadcrumbsForOwnerRefs(obj).concat({
name: 'ReplicaSet Details',
path: props.match.url,
})}
menuActions={replicaSetMenuActions}
pages={[details(Details), editYaml(), pods(), envEditor(environmentComponent), events(ResourceEventStream)]}
/>;
Expand Down
5 changes: 0 additions & 5 deletions frontend/public/components/replication-controller.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
WorkloadTableHeader,
} from './workload-table';

import { breadcrumbsForOwnerRefs } from './utils/breadcrumbs';
import { VolumesTable } from './volumes-table';

const Details = ({obj: replicationController}) => {
Expand Down Expand Up @@ -64,10 +63,6 @@ const {details, editYaml, pods, envEditor, events} = navFactory;

export const ReplicationControllersDetailsPage = props => <DetailsPage
{...props}
breadcrumbsFor={obj => breadcrumbsForOwnerRefs(obj).concat({
name: 'ReplicationController Details',
path: props.match.url,
})}
menuActions={replicaSetMenuActions}
pages={[details(Details), editYaml(), pods(), envEditor(environmentComponent), events(ResourceEventStream)]}
/>;
Expand Down
2 changes: 1 addition & 1 deletion frontend/public/components/resource-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const ResourceDetailsPage = connectToPlural((props: ResourceDetailsPagePr
<Helmet>
<title>{`${name} · Details`}</title>
</Helmet>
<AsyncComponent loader={componentLoader} match={props.match} namespace={ns} kind={props.modelRef} name={name} />
<AsyncComponent loader={componentLoader} match={props.match} namespace={ns} kind={props.modelRef} kindObj={kindObj} name={name} />
</React.Fragment>;
});

Expand Down
26 changes: 5 additions & 21 deletions frontend/public/components/utils/breadcrumbs.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
import * as _ from 'lodash-es';
import { K8sKind } from '../../module/k8s';

import { modelFor, referenceForOwnerRef, K8sResourceKind } from '../../module/k8s';
import { resourcePathFromModel } from './resource-link';

export const breadcrumbsForOwnerRefs = (obj: K8sResourceKind) => {
const ownerRefs = _.get(obj, 'metadata.ownerReferences');
return _.compact(_.map(ownerRefs, ref => {
const model = modelFor(referenceForOwnerRef(ref));
// ownerReferences might reference resources we don't know about (or even
// ones that don't exist since it's not blocked by the API). Avoid runtime
// errors if we don't have a model for this reference.
if (!model) {
return null;
}

return {
name: ref.name,
path: resourcePathFromModel(model, ref.name, obj.metadata.namespace),
};
}));
};
export const breadcrumbsForDetailsPage = (kindObj: K8sKind, match: any) => () => [
{name: `${kindObj.labelPlural}`, path: match.params.ns ? `/k8s/ns/${match.params.ns}/${match.params.plural}` : `/k8s/cluster/${match.params.plural}`},
{name: `${kindObj.label} Details`, path: `${match.url}`},
];
2 changes: 1 addition & 1 deletion frontend/public/components/utils/headings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const BreadCrumbs: React.SFC<BreadCrumbsProps> = ({breadcrumbs}) => (
{isLast ? (
crumb.name
) : (
<Link className="breadcrumb-link" to={crumb.path}>{crumb.name}</Link>
<Link className="breadcrumb-link" to={crumb.path} data-test-id={`breadcrumb-link-${i}`}>{crumb.name}</Link>
)}
</li>;
}) }
Expand Down