Skip to content

Commit

Permalink
prevent unnecessary re-rendering of Firehose by checking if resources…
Browse files Browse the repository at this point in the history
… are loaded when API discovery runs
  • Loading branch information
alecmerdler committed Oct 1, 2018
1 parent bd4de9d commit 993bd2d
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 23 deletions.
2 changes: 2 additions & 0 deletions frontend/public/components/factory/details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export const DetailsPage: React.SFC<DetailsPageProps> = (props) => <Firehose res
kind={props.kind}
breadcrumbsFor={props.breadcrumbsFor} />
<HorizontalNav
// FIXME: Hack because `Firehose` injects props without TypeScript knowing about it
obj={(props as any).obj}
pages={props.pages}
className={`co-m-${_.get(props.kind, 'kind', props.kind)}`}
match={props.match}
Expand Down
4 changes: 2 additions & 2 deletions frontend/public/components/utils/firehose.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ const ConnectToState = connect(({k8s}, {reduxes}) => {
{inject(props.children, _.omit(props, ['children', 'className', 'reduxes']))}
</div>);

const stateToProps = ({k8s}, {resources}) => ({
const stateToProps = ({k8s}, {resources, reduxIDs = []}) => ({
k8sModels: resources.reduce((models, {kind}) => models.set(kind, k8s.getIn(['RESOURCES', 'models', kind])), ImmutableMap()),
inFlight: k8s.getIn(['RESOURCES', 'inFlight']),
inFlight: k8s.getIn(['RESOURCES', 'inFlight']) && reduxIDs.some(id => !k8s.getIn([id, 'loaded'])),
});

export const Firehose = connect(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-disable no-undef, no-unused-vars */

import * as _ from 'lodash-es';
import * as React from 'react';
import * as classNames from 'classnames';
Expand All @@ -7,11 +9,12 @@ import { Route, Switch, Link } from 'react-router-dom';
import { EmptyBox, StatusBox } from '.';
import { PodsPage } from '../pod';
import { AsyncComponent } from './async';
import { K8sResourceKind } from '../../module/k8s';

const editYamlComponent = (props) => <AsyncComponent loader={() => import('../edit-yaml').then(c => c.EditYAML)} obj={props.obj} />;
export const viewYamlComponent = (props) => <AsyncComponent loader={() => import('../edit-yaml').then(c => c.EditYAML)} obj={props.obj} readOnly={true} />;

class PodsComponent extends React.PureComponent {
class PodsComponent extends React.PureComponent<PodsComponentProps> {
render() {
const {metadata: {namespace}, spec: {selector}} = this.props.obj;
if (_.isEmpty(selector)) {
Expand All @@ -25,7 +28,8 @@ class PodsComponent extends React.PureComponent {
}
}

export const navFactory = {
type NavFactory = {[name: string]: (c?: React.ComponentType<any>) => Page};
export const navFactory: NavFactory = {
details: component => ({
href: '',
name: 'Overview',
Expand Down Expand Up @@ -78,8 +82,7 @@ export const navFactory = {
})
};

/** @type {React.SFC<{pages: {href: string, name: string}[], basePath: string}>} */
export const NavBar = ({pages, basePath}) => {
export const NavBar: React.SFC<NavBarProps> = ({pages, basePath}) => {
const divider = <li className="co-m-horizontal-nav__menu-item co-m-horizontal-nav__menu-item--divider" key="_divider" />;
basePath = basePath.replace(/\/$/, '');

Expand All @@ -94,14 +97,26 @@ export const NavBar = ({pages, basePath}) => {
};
NavBar.displayName = 'NavBar';

/** @augments {React.PureComponent<{className?: string, label?: string, pages: {href: string, name: string, component: React.ComponentType}[], match: any, resourceKeys?: string[]}>} */
export class HorizontalNav extends React.PureComponent {
export class HorizontalNav extends React.PureComponent<HorizontalNavProps> {
static propTypes = {
pages: PropTypes.arrayOf(PropTypes.shape({
href: PropTypes.string,
name: PropTypes.string,
component: PropTypes.func,
})),
className: PropTypes.string,
hideNav: PropTypes.bool,
match: PropTypes.shape({
path: PropTypes.string,
}),
};

render () {
const props = this.props;

const componentProps = _.pick(props, ['filters', 'selected', 'match']);
componentProps.obj = props.obj.data;
const extraResources = _.reduce(props.resourceKeys, (acc, key) => ({...acc, [key]: props[key].data}), {});
const componentProps = {..._.pick(props, ['filters', 'selected', 'match']), data: props.obj.data};
// FIXME(alecmerdler): `props.obj === undefined`
const extraResources = _.reduce(props.resourceKeys, (extraObjs, key) => ({...extraObjs, [key]: props[key].data}), {});

const routes = props.pages.map(p => {
const path = `${props.match.url}/${p.href}`;
Expand All @@ -122,15 +137,28 @@ export class HorizontalNav extends React.PureComponent {
}
}

HorizontalNav.propTypes = {
pages: PropTypes.arrayOf(PropTypes.shape({
href: PropTypes.string,
name: PropTypes.string,
component: PropTypes.func,
})),
className: PropTypes.string,
hideNav: PropTypes.bool,
match: PropTypes.shape({
path: PropTypes.string,
}),
type Page = {
href: string;
name: string;
component?: React.ComponentType<any>;
};

export type PodsComponentProps = {
obj: K8sResourceKind;
};

export type NavBarProps = {
pages: Page[];
basePath: string;
};

export type HorizontalNavProps = {
className?: string;
obj: {loaded: boolean, data: K8sResourceKind};
label?: string;
pages: Page[];
match: any;
resourceKeys?: string[];
hideNav?: boolean;
EmptyMsg?: React.ComponentType<any>;
};
2 changes: 1 addition & 1 deletion frontend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"moduleResolution": "node",
"outDir": "./public/dist/build/",
"target": "es5",
"lib": ["dom", "es2015"],
"lib": ["dom", "es2015", "es2016.array.include"],
"jsx": "react",
"allowJs": true,
"downlevelIteration": true,
Expand Down

0 comments on commit 993bd2d

Please sign in to comment.