Skip to content

Commit

Permalink
refactor(core): move app refresher, pager duty buttons to components (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
anotherchrisberry committed Mar 24, 2018
1 parent 1c297b6 commit c128b91
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 55 deletions.
59 changes: 4 additions & 55 deletions app/scripts/modules/core/src/application/ApplicationComponent.tsx
@@ -1,32 +1,26 @@
import { ApplicationRefresher } from 'core/application/nav/ApplicationRefresher';
import * as React from 'react';
import { BindAll } from 'lodash-decorators';
import { Subscription } from 'rxjs';
import { UIView } from '@uirouter/react';

import { Application } from 'core/application';
import { Tooltip } from 'core/presentation';
import { Refresher } from 'core/presentation/refresher/Refresher';
import { NgReact, ReactInjector } from 'core/reactShims';
import { DebugWindow } from 'core/utils/consoleDebug';

import { ApplicationIcon } from './ApplicationIcon';
import './application.less';
import { PagerDutyButton } from './nav/PagerDutyButton';

export interface IApplicationComponentProps {
app: Application;
}

export interface IApplicationComponentState {
compactHeader: boolean;
refreshing: boolean;
lastRefresh: number;
}

@BindAll()
export class ApplicationComponent extends React.Component<IApplicationComponentProps, IApplicationComponentState> {
private activeStateRefreshUnsubscribe: () => void;
private activeStateChangeSubscription: Subscription;
private stopListeningToAppRefresh: Function;

constructor(props: IApplicationComponentProps) {
super(props);
Expand All @@ -39,27 +33,11 @@ export class ApplicationComponent extends React.Component<IApplicationComponentP

DebugWindow.application = app;
app.enableAutoRefresh();
this.activeStateChangeSubscription = app.activeStateChangeStream.subscribe(() => {
this.resetActiveStateRefreshStream(this.props);
this.setState(this.parseState(props));
});
this.stopListeningToAppRefresh = app.onRefresh(null, () => this.setState(this.parseState(props)));
}

private resetActiveStateRefreshStream(props: IApplicationComponentProps): void {
if (this.activeStateRefreshUnsubscribe) { this.activeStateRefreshUnsubscribe(); }
const activeState = props.app.activeState || props.app;
this.activeStateRefreshUnsubscribe = activeState.onRefresh(null, () => {
this.setState(this.parseState(props));
});
}

private parseState(props: IApplicationComponentProps): IApplicationComponentState {
const activeState = props.app.activeState || props.app;
return {
compactHeader: props.app.name.length > 20,
lastRefresh: activeState.lastRefresh,
refreshing: activeState.loading
};
}

Expand All @@ -68,24 +46,12 @@ export class ApplicationComponent extends React.Component<IApplicationComponentP
DebugWindow.application = undefined;
this.props.app.disableAutoRefresh();
}
if (this.activeStateChangeSubscription) {
this.activeStateChangeSubscription.unsubscribe();
}
if (this.stopListeningToAppRefresh) {
this.stopListeningToAppRefresh();
}
}

public pageApplicationOwner(): void {
ReactInjector.pagerDutyWriter.pageApplicationOwnerModal(this.props.app);
}

public handleRefresh(): void {
// Force set refreshing to true since we are forcing the refresh
this.setState({ refreshing: true });
this.props.app.refresh(true);
}

public render() {
const { ApplicationNav, ApplicationNavSecondary } = NgReact;

Expand All @@ -100,27 +66,10 @@ export class ApplicationComponent extends React.Component<IApplicationComponentP
<h2>
<ApplicationIcon app={this.props.app} />
<span className="application-name">{this.props.app.name}</span>
<Refresher
refreshing={this.state.refreshing}
lastRefresh={this.state.lastRefresh}
refresh={this.handleRefresh}
/>
<ApplicationRefresher app={this.props.app}/>
</h2>
) : null;

const PagerDutyButton = this.props.app.attributes.pdApiKey ? (
<div className="page-button">
<Tooltip value="Page application owner">
<button
className="btn btn-xs btn-danger btn-page-owner"
onClick={this.pageApplicationOwner}
>
<i className="fa fa-phone"/>
</button>
</Tooltip>
</div>
) : null;

return (
<div className="application">
<div className={`page-header ${this.state.compactHeader ? 'compact-header' : ''}`}>
Expand All @@ -131,7 +80,7 @@ export class ApplicationComponent extends React.Component<IApplicationComponentP
<ApplicationNav application={this.props.app}/>
<div className="header-right">
<ApplicationNavSecondary application={this.props.app}/>
{PagerDutyButton}
<PagerDutyButton app={this.props.app}/>
</div>
</div>
</div>
Expand Down
@@ -0,0 +1,92 @@
import * as React from 'react';
import { BindAll } from 'lodash-decorators';
import { Subscription } from 'rxjs';

import { Application } from 'core/application';
import { Refresher } from 'core/presentation/refresher/Refresher';

export interface IApplicationRefresherProps {
app: Application;
}

export interface IApplicationRefresherState {
refreshing: boolean;
lastRefresh: number;
}

@BindAll()
export class ApplicationRefresher extends React.Component<IApplicationRefresherProps, IApplicationRefresherState> {

private activeStateRefreshUnsubscribe: () => void;
private activeStateChangeSubscription: Subscription;
private stopListeningToAppRefresh: Function;

constructor(props: IApplicationRefresherProps) {
super(props);
this.configureApplicationEventListeners(props.app);
this.state = Object.assign(
this.parseRefreshState(props),
);
}

private resetActiveStateRefreshStream(props: IApplicationRefresherProps): void {
if (this.activeStateRefreshUnsubscribe) { this.activeStateRefreshUnsubscribe(); }
const activeState = props.app.activeState || props.app;
this.activeStateRefreshUnsubscribe = activeState.onRefresh(null, () => {
this.setState(this.parseRefreshState(props));
});
}

public componentWillReceiveProps(nextProps: IApplicationRefresherProps) {
this.configureApplicationEventListeners(nextProps.app);
}

private configureApplicationEventListeners(app: Application): void {
app.ready().then(() => this.setState(this.parseRefreshState(this.props)));
this.clearApplicationListeners();
this.activeStateChangeSubscription = app.activeStateChangeStream.subscribe(() => {
this.resetActiveStateRefreshStream(this.props);
this.setState(this.parseRefreshState(this.props));
});
this.stopListeningToAppRefresh = app.onRefresh(null, () => {
this.setState(this.parseRefreshState(this.props));
});
}

private clearApplicationListeners(): void {
if (this.activeStateChangeSubscription) {
this.activeStateChangeSubscription.unsubscribe();
}
if (this.stopListeningToAppRefresh) {
this.stopListeningToAppRefresh();
}
}

private parseRefreshState(props: IApplicationRefresherProps): IApplicationRefresherState {
const activeState = props.app.activeState || props.app;
return {
lastRefresh: activeState.lastRefresh,
refreshing: activeState.loading,
};
}

public componentWillUnmount(): void {
this.clearApplicationListeners();
}

public handleRefresh(): void {
// Force set refreshing to true since we are forcing the refresh
this.setState({ refreshing: true });
this.props.app.refresh(true);
}

public render() {
return (
<Refresher
refreshing={this.state.refreshing}
lastRefresh={this.state.lastRefresh}
refresh={this.handleRefresh}
/>
);
}
}
34 changes: 34 additions & 0 deletions app/scripts/modules/core/src/application/nav/PagerDutyButton.tsx
@@ -0,0 +1,34 @@
import * as React from 'react';
import { BindAll } from 'lodash-decorators';

import { Application } from 'core/application';
import { ReactInjector } from 'core/reactShims';
import { Tooltip } from 'core/presentation';

export interface IPagerDutyButtonProps {
app: Application;
}

@BindAll()
export class PagerDutyButton extends React.Component<IPagerDutyButtonProps> {

private pageApplicationOwner(): void {
ReactInjector.pagerDutyWriter.pageApplicationOwnerModal(this.props.app);
}

public render() {
if (!this.props.app.attributes.pdApiKey) {
return null;
}
return (
<Tooltip value="Page application owner">
<button
className="btn btn-xs page-button btn-page-owner"
onClick={this.pageApplicationOwner}
>
<i className="fa fa-phone"/>
</button>
</Tooltip>
);
}
}

0 comments on commit c128b91

Please sign in to comment.