Skip to content

Commit

Permalink
perf(services): avoid rerenders for service status table column
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Schmidt authored and natmegs committed Apr 9, 2019
1 parent c0b4d7a commit 05c67c3
Show file tree
Hide file tree
Showing 11 changed files with 400 additions and 192 deletions.
123 changes: 88 additions & 35 deletions plugins/services/src/js/columns/ServicesTableStatusColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,103 @@ import Service from "../structs/Service";
import ServiceTree from "../structs/ServiceTree";
import { SortDirection } from "plugins/services/src/js/types/SortDirection";
import ServiceTableUtil from "../utils/ServiceTableUtil";
import { getStatusIconProps } from "../utils/ServiceStatusIconUtil";

const StatusMapping: any = {
Running: "running-state"
};

interface StatusColumnProps {
statusText: string;
instancesCount: number;
runningInstances: number;
timeWaiting: string | null;
timeQueued: number | null;
serviceStatus: object;
isServiceTree: boolean;
isService: boolean;
id: string | number;
displayDeclinedOffers: boolean;
appsWithWarnings: number | null;
unableToLaunch: boolean;
}

const StatusColumn = React.memo(
({
statusText,
instancesCount,
runningInstances,
timeWaiting,
timeQueued,
serviceStatus,
isService,
isServiceTree,
id,
displayDeclinedOffers,
appsWithWarnings,
unableToLaunch
}: StatusColumnProps) => {
const serviceStatusClassSet: string = StatusMapping[statusText] || "";
// L10NTODO: Pluralize
const tooltipContent = (
<Trans render="span">
{runningInstances} {StringUtil.pluralize("instance", runningInstances)}{" "}
running out of {instancesCount}
</Trans>
);
const hasStatusText = statusText !== (ServiceStatus as any).NA.displayName;

return (
<TextCell>
<div className="flex">
<div
className={`${serviceStatusClassSet} service-status-icon-wrapper`}
>
<ServiceStatusIcon
id={id}
isService={isService}
isServiceTree={isServiceTree}
serviceStatus={serviceStatus}
timeWaiting={timeWaiting}
timeQueued={timeQueued}
appsWithWarnings={appsWithWarnings}
displayDeclinedOffers={displayDeclinedOffers}
showTooltip={true}
tooltipContent={tooltipContent}
unableToLaunch={unableToLaunch}
/>
{hasStatusText && (
<Trans
id={statusText}
render="span"
className="status-bar-text"
/>
)}
</div>
<div className="service-status-progressbar-wrapper">
<ServiceStatusProgressBar
instancesCount={instancesCount}
serviceStatus={serviceStatus}
runningInstances={runningInstances}
/>
</div>
</div>
</TextCell>
);
}
);

export function statusRenderer(
service: Service | ServiceTree
): React.ReactNode {
const serviceStatusText: string = service.getStatus();
const serviceStatusClassSet: string = StatusMapping[serviceStatusText] || "";
const instancesCount = service.getInstancesCount() as number;
const runningInstances = service.getRunningInstancesCount() as number;
// L10NTODO: Pluralize
const tooltipContent = (
<Trans render="span">
{runningInstances} {StringUtil.pluralize("instance", runningInstances)}{" "}
running out of {instancesCount}
</Trans>
);
const hasStatusText = serviceStatusText !== ServiceStatus.NA.displayName;
const iconProps = getStatusIconProps(service);

return (
<TextCell>
<div className="flex">
<div className={`${serviceStatusClassSet} service-status-icon-wrapper`}>
<ServiceStatusIcon
service={service}
showTooltip={true}
tooltipContent={tooltipContent}
/>
{hasStatusText && (
<Trans
id={serviceStatusText}
render="span"
className="status-bar-text"
/>
)}
</div>
<div className="service-status-progressbar-wrapper">
<ServiceStatusProgressBar service={service} />
</div>
</div>
</TextCell>
);
const props = {
statusText: service.getStatus(),
instancesCount: service.getInstancesCount(),
runningInstances: service.getRunningInstancesCount()
};
return <StatusColumn {...props} {...iconProps} />;
}

export function statusSorter(
Expand Down
8 changes: 7 additions & 1 deletion plugins/services/src/js/components/ServiceBreadcrumbs.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ class ServiceBreadcrumbs extends React.Component {
let iconDisplay = null;
const instancesCount = service.getInstancesCount();
const runningInstances = service.getRunningInstancesCount();
const serviceStatus = service.getServiceStatus();

const tooltipContent = (
<Plural
Expand All @@ -154,7 +155,12 @@ class ServiceBreadcrumbs extends React.Component {
if (this.props.taskID == null && this.props.params != null) {
progressBar = (
<BreadcrumbSupplementalContent hasProgressBar={true}>
<ServiceStatusProgressBar key="status-bar" service={service} />
<ServiceStatusProgressBar
key="status-bar"
instancesCount={instancesCount}
runningInstances={runningInstances}
serviceStatus={serviceStatus}
/>
</BreadcrumbSupplementalContent>
);
}
Expand Down
4 changes: 3 additions & 1 deletion plugins/services/src/js/components/ServiceList.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import createReactClass from "create-react-class";
import { Link, routerShape } from "react-router";

import ServiceStatusIcon from "./ServiceStatusIcon";
import { getStatusIconProps } from "../utils/ServiceStatusIconUtil";

const ServiceList = createReactClass({
displayName: "ServiceList",
Expand Down Expand Up @@ -50,6 +51,7 @@ const ServiceList = createReactClass({
return services.map(service => {
const instancesCount = service.getInstancesCount();
const runningInstances = service.getRunningInstancesCount();
const iconProps = getStatusIconProps(service);

const tooltipContent = (
<Plural
Expand Down Expand Up @@ -81,9 +83,9 @@ const ServiceList = createReactClass({
content: (
<ServiceStatusIcon
key="icon"
service={service}
showTooltip={true}
tooltipContent={tooltipContent}
{...iconProps}
/>
),
tag: "div"
Expand Down
Loading

0 comments on commit 05c67c3

Please sign in to comment.