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 @@ -292,6 +292,7 @@ export const sampleKnativeRoutes: FirehoseResult = {
spec: {},
status: {
observedGeneration: 1,
traffic: [{ latestRevision: true, percent: 100, revisionName: 'overlayimage-fdqsf' }],
url: 'http://overlayimage.knativeapps.apps.bpetersen-june-23.devcluster.openshift.com',
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,3 @@
justify-content: space-between;
align-items: center;
}
.odc-revision-deployment-list {
padding: 15px 15px 0px 20px;
&__pod {
width: 25px;
cursor: default;
}
}
Original file line number Diff line number Diff line change
@@ -1,96 +1,25 @@
import * as React from 'react';
import * as _ from 'lodash';
import { Button } from '@patternfly/react-core';
import { PodStatus } from '@console/shared';
import { ChartLabel } from '@patternfly/react-charts';
import { K8sResourceKind, referenceForModel } from '@console/internal/module/k8s';
import {
ResourceLink,
SidebarSectionHeading,
useAccessReview,
} from '@console/internal/components/utils';
import { RevisionModel } from '@console/knative-plugin';
import { K8sResourceKind } from '@console/internal/module/k8s';
import { SidebarSectionHeading, useAccessReview } from '@console/internal/components/utils';
import { setTrafficDistributionModal } from '../modals';
import { ServiceModel } from '../../models';
import RevisionsOverviewListItem from './RevisionsOverviewListItem';
import './RevisionsOverviewList.scss';

export type RevisionsOverviewListProps = {
revisions: K8sResourceKind[];
service: K8sResourceKind;
};

export type RevisionsOverviewListItemProps = {
revision: K8sResourceKind;
service: K8sResourceKind;
};

const RevisionsOverviewListItem: React.FC<RevisionsOverviewListItemProps> = ({
revision,
service,
}) => {
const {
metadata: { name, namespace },
} = revision;
const {
status: { traffic },
} = service;
const getTraffic = (revName: string) => {
if (!traffic || !traffic.length) {
return null;
}
const trafficPercent = _.get(_.find(traffic, { revisionName: revName }), 'percent', null);
return trafficPercent ? `${trafficPercent}%` : null;
};
const deploymentData = _.get(revision, 'resources.current.obj.metadata.ownerReferences[0]', {});
const current = _.get(revision, 'resources.current', null);
const availableReplicas = _.get(revision, 'resources.current.obj.status.availableReplicas', '0');
return (
<li className="list-group-item">
<div className="row">
<div className="col-sm-8 col-xs-9">
<ResourceLink kind={referenceForModel(RevisionModel)} name={name} namespace={namespace} />
</div>
<span className="col-sm-4 col-xs-3 text-right">{getTraffic(name)}</span>
</div>
{deploymentData.name && (
<div className="odc-revision-deployment-list">
<div className="row">
<div className="col-sm-8 col-xs-9">
<ResourceLink
kind={deploymentData.kind}
name={deploymentData.name}
namespace={namespace}
/>
</div>
<div className="col-sm-4 col-xs-3">
<div className="odc-revision-deployment-list__pod">
<PodStatus
standalone
data={current ? current.pods : []}
size={25}
innerRadius={8}
outerRadius={12}
title={availableReplicas}
titleComponent={<ChartLabel style={{ fontSize: '10px' }} />}
showTooltip={false}
/>
</div>
</div>
</div>
</div>
)}
</li>
);
};

const RevisionsOverviewList: React.FC<RevisionsOverviewListProps> = ({ revisions, service }) => {
const canSetTrafficDistribution = useAccessReview({
group: ServiceModel.apiGroup,
resource: ServiceModel.plural,
namespace: service.metadata.namespace,
verb: 'update',
});

return (
<>
<SidebarSectionHeading text="Revisions" className="revision-overview-list">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.odc-revision-deployment-list {
padding: var(--pf-global--spacer--md) var(--pf-global--spacer--lg) var(--pf-global--spacer--sm);
&__pod {
width: var(--pf-global--icon--FontSize--lg);
cursor: default;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use pf variables for padding and width here?

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import * as React from 'react';
import * as _ from 'lodash';
import { PodStatus } from '@console/shared';
import { ChartLabel } from '@patternfly/react-charts';
import { K8sResourceKind, referenceForModel } from '@console/internal/module/k8s';
import { ResourceLink } from '@console/internal/components/utils';
import { RevisionModel } from '@console/knative-plugin';
import './RevisionsOverviewListItem.scss';

export type RevisionsOverviewListItemProps = {
revision: K8sResourceKind;
service: K8sResourceKind;
};

const RevisionsOverviewListItem: React.FC<RevisionsOverviewListItemProps> = ({
revision,
service,
}) => {
const {
metadata: { name, namespace },
} = revision;
const {
status: { traffic },
} = service;
const getTraffic = (revName: string) => {
if (!traffic || !traffic.length) {
return null;
}
const trafficPercent = _.get(_.find(traffic, { revisionName: revName }), 'percent', null);
return trafficPercent ? `${trafficPercent}%` : null;
};
const deploymentData = _.get(revision, 'resources.current.obj.metadata.ownerReferences[0]', {});
const current = _.get(revision, 'resources.current', null);
const availableReplicas = _.get(revision, 'resources.current.obj.status.availableReplicas', '0');
return (
<li className="list-group-item">
<div className="row">
<div className="col-sm-8 col-xs-9">
<ResourceLink kind={referenceForModel(RevisionModel)} name={name} namespace={namespace} />
</div>
<span className="col-sm-4 col-xs-3 text-right">{getTraffic(name)}</span>
</div>
{deploymentData.name && (
<div className="odc-revision-deployment-list">
<div className="row">
<div className="col-sm-8 col-xs-9">
<ResourceLink
kind={deploymentData.kind}
name={deploymentData.name}
namespace={namespace}
/>
</div>
<div className="col-sm-4 col-xs-3">
<div className="odc-revision-deployment-list__pod">
<PodStatus
standalone
data={current ? current.pods : []}
size={25}
innerRadius={8}
outerRadius={12}
title={availableReplicas}
titleComponent={<ChartLabel style={{ fontSize: '10px' }} />}
showTooltip={false}
/>
</div>
</div>
</div>
</div>
)}
</li>
);
};

export default RevisionsOverviewListItem;

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import * as React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import { Button } from '@patternfly/react-core';
import * as utils from '@console/internal/components/utils';
import { MockKnativeResources } from '@console/dev-console/src/components/topology/__tests__/topology-knative-test-data';
import * as modal from '../../modals';
import RevisionsOverviewList, { RevisionsOverviewListProps } from '../RevisionsOverviewList';
import RevisionsOverviewListItem from '../RevisionsOverviewListItem';

describe('RevisionsOverviewList', () => {
let wrapper: ShallowWrapper<RevisionsOverviewListProps>;
beforeEach(() => {
wrapper = shallow(
<RevisionsOverviewList
revisions={MockKnativeResources.revisions.data}
service={MockKnativeResources.ksservices.data[0]}
/>,
);
});

it('should have title Revisions', () => {
expect(wrapper.find(utils.SidebarSectionHeading)).toHaveLength(1);
expect(
wrapper
.find(utils.SidebarSectionHeading)
.at(0)
.props().text,
).toEqual('Revisions');
});

it('should show info if no Revisions present and traffic split sshould button should be disabled', () => {
const spyUseAccessReview = jest.spyOn(utils, 'useAccessReview');
spyUseAccessReview.mockReturnValue(true);
wrapper = shallow(
<RevisionsOverviewList revisions={[]} service={MockKnativeResources.revisions.data[0]} />,
);
expect(wrapper.find('span')).toHaveLength(1);
expect(wrapper.text().includes('No Revisions found for this resource.')).toBe(true);
expect(
wrapper
.find(Button)
.at(0)
.props().isDisabled,
).toBe(true);
});

it('should have button for traffic distribution and enabled', () => {
const spyUseAccessReview = jest.spyOn(utils, 'useAccessReview');
spyUseAccessReview.mockReturnValue(true);
expect(wrapper.find(Button)).toHaveLength(1);
expect(
wrapper
.find(Button)
.at(0)
.props().children,
).toEqual('Set Traffic Distribution');
expect(
wrapper
.find(Button)
.at(0)
.props().isDisabled,
).toBe(false);
});

it('should call setTrafficDistributionModal on click', () => {
const spySetTrafficDistributionModal = jest.spyOn(modal, 'setTrafficDistributionModal');
expect(wrapper.find(Button)).toHaveLength(1);
wrapper.find(Button).simulate('click');
expect(spySetTrafficDistributionModal).toHaveBeenCalled();
});

it('should not show button for traffic distribution if access is not there', () => {
const spyUseAccessReview = jest.spyOn(utils, 'useAccessReview');
spyUseAccessReview.mockReturnValue(false);
wrapper = shallow(
<RevisionsOverviewList
revisions={MockKnativeResources.revisions.data}
service={MockKnativeResources.revisions.data[0]}
/>,
);
expect(wrapper.find(Button).exists()).toBe(false);
});

it('should render RevisionsOverviewListItem', () => {
expect(wrapper.find(RevisionsOverviewListItem)).toHaveLength(1);
});
});
Loading