Skip to content

Commit

Permalink
feat(core): Create a react modal wizard (#4695)
Browse files Browse the repository at this point in the history
  • Loading branch information
Justin Reynolds committed Jan 22, 2018
1 parent 3b47e26 commit d768df5
Show file tree
Hide file tree
Showing 14 changed files with 498 additions and 41 deletions.
@@ -0,0 +1,82 @@
import * as React from 'react';
import { BindAll } from 'lodash-decorators';

import { Application, ILoadBalancer, ReactInjector, Tooltip } from '@spinnaker/core';

export interface ICreateLoadBalancerButtonProps {
app: Application;
}

export interface ICreateLoadBalancerButtonState {
provider: any;
showModal: boolean;
}

@BindAll()
export class CreateLoadBalancerButton extends React.Component<ICreateLoadBalancerButtonProps, ICreateLoadBalancerButtonState> {

constructor(props: ICreateLoadBalancerButtonProps) {
super(props);
this.state = {
provider: null,
showModal: false,
};
}

public componentDidMount(): void {
const { providerSelectionService, cloudProviderRegistry, versionSelectionService } = ReactInjector;
const { app } = this.props;
providerSelectionService.selectProvider(app, 'loadBalancer').then((selectedProvider) => {
versionSelectionService.selectVersion(selectedProvider).then((selectedVersion) => {
this.setState({ provider: cloudProviderRegistry.getValue(selectedProvider, 'loadBalancer', selectedVersion) });
});
});
}

private createLoadBalancer(): void {
const { provider } = this.state;
if (!provider) { return; }

if (provider.CreateLoadBalancerModal) {
// react
this.setState({ showModal: true });
} else {
// angular
ReactInjector.modalService.open({
templateUrl: provider.createLoadBalancerTemplateUrl,
controller: `${provider.createLoadBalancerController} as ctrl`,
size: 'lg',
resolve: {
application: () => this.props.app,
loadBalancer: (): ILoadBalancer => null,
isNew: () => true,
forPipelineConfig: () => false
}
}).result.catch(() => {});
}
}

private showModal(show: boolean): void {
this.setState({ showModal: show });
}

public render() {
const { app } = this.props;
const { provider, showModal } = this.state;

const CreateLoadBalancerModal = provider ? provider.CreateLoadBalancerModal : null;

return (
<div>
<button className="btn btn-sm btn-default" onClick={this.createLoadBalancer}>
<span className="glyphicon glyphicon-plus-sign visible-lg-inline"/>
<Tooltip value="Create Load Balancer">
<span className="glyphicon glyphicon-plus-sign visible-md-inline visible-sm-inline"/>
</Tooltip>
<span className="visible-lg-inline"> Create Load Balancer</span>
</button>
{CreateLoadBalancerModal && <CreateLoadBalancerModal app={app} forPipelineConfig={false} loadBalancer={null} show={showModal} showCallback={this.showModal} />}
</div>
);
}
}
33 changes: 3 additions & 30 deletions app/scripts/modules/core/src/loadBalancer/LoadBalancers.tsx
Expand Up @@ -4,12 +4,12 @@ import { Subscription } from 'rxjs';

import { Application } from 'core/application/application.model';
import { FilterTags, IFilterTag } from 'core/filterModel/FilterTags';
import { ILoadBalancer, ILoadBalancerGroup } from 'core/domain';
import { ILoadBalancerGroup } from 'core/domain';
import { LoadBalancerPod } from './LoadBalancerPod';
import { Tooltip } from 'core/presentation/Tooltip';
import { Spinner } from 'core/widgets/spinners/Spinner';

import { NgReact, ReactInjector } from 'core/reactShims';
import { CreateLoadBalancerButton } from 'core/loadBalancer/CreateLoadBalancerButton';

export interface ILoadBalancersProps {
app: Application;
Expand Down Expand Up @@ -81,27 +81,6 @@ export class LoadBalancers extends React.Component<ILoadBalancersProps, ILoadBal
this.updateLoadBalancerGroups();
}

private createLoadBalancer(): void {
const { providerSelectionService, cloudProviderRegistry, versionSelectionService } = ReactInjector;
const { app } = this.props;
providerSelectionService.selectProvider(app, 'loadBalancer').then((selectedProvider) => {
versionSelectionService.selectVersion(selectedProvider).then((selectedVersion) => {
const provider = cloudProviderRegistry.getValue(selectedProvider, 'loadBalancer', selectedVersion);
ReactInjector.modalService.open({
templateUrl: provider.createLoadBalancerTemplateUrl,
controller: `${provider.createLoadBalancerController} as ctrl`,
size: 'lg',
resolve: {
application: () => app,
loadBalancer: (): ILoadBalancer => null,
isNew: () => true,
forPipelineConfig: () => false
}
}).result.catch(() => {});
});
});
};

private updateUIState(state: ILoadBalancersState): void {
const params: any = {
hideServerGroups: undefined,
Expand Down Expand Up @@ -181,13 +160,7 @@ export class LoadBalancers extends React.Component<ILoadBalancersProps, ILoadBal
<div className="col-lg-4 col-md-2">
<div className="form-inline clearfix filters"/>
<div className="application-actions">
<button className="btn btn-sm btn-default" onClick={this.createLoadBalancer}>
<span className="glyphicon glyphicon-plus-sign visible-lg-inline"/>
<Tooltip value="Create Load Balancer">
<span className="glyphicon glyphicon-plus-sign visible-md-inline visible-sm-inline"/>
</Tooltip>
<span className="visible-lg-inline"> Create Load Balancer</span>
</button>
<CreateLoadBalancerButton app={this.props.app} />
</div>
</div>
<FilterTags tags={this.state.tags} tagCleared={this.tagCleared} clearFilters={this.clearFilters}/>
Expand Down
1 change: 1 addition & 0 deletions app/scripts/modules/core/src/loadBalancer/index.ts
Expand Up @@ -2,6 +2,7 @@ export * from './loadBalancerDataUtils';
export * from './loadBalancer.read.service';
export * from './loadBalancer.write.service';

export * from './CreateLoadBalancerButton';
export * from './LoadBalancerClusterContainer';
export * from './LoadBalancerInstances';
export * from './LoadBalancerServerGroup';
Expand Down
17 changes: 17 additions & 0 deletions app/scripts/modules/core/src/modal/buttons/ModalClose.tsx
@@ -0,0 +1,17 @@
import * as React from 'react';

export interface IModalCloseProps {
dismiss: () => void;
}

export class ModalClose extends React.Component<IModalCloseProps> {
public render() {
return (
<div className="modal-close close-button pull-right">
<button className="link" onClick={this.props.dismiss}>
<span className="glyphicon glyphicon-remove"/>
</button>
</div>
);
}
}
14 changes: 9 additions & 5 deletions app/scripts/modules/core/src/modal/buttons/SubmitButton.tsx
Expand Up @@ -2,30 +2,34 @@ import * as React from 'react';
import { Button } from 'react-bootstrap';

import { NgReact } from 'core/reactShims';
import { noop } from 'core/utils';

export interface ISubmitButtonProps {
onClick: () => void;
onClick?: () => void;
isDisabled?: boolean;
isFormSubmit?: boolean;
isNew?: boolean;
submitting: boolean;
label: string;
}

export class SubmitButton extends React.Component<ISubmitButtonProps> {
public render() {
const { isDisabled, isFormSubmit, isNew, label, onClick, submitting } = this.props;
const { ButtonBusyIndicator } = NgReact;
return (
<Button
className="btn btn-primary"
disabled={this.props.isDisabled}
onClick={this.props.onClick}
disabled={isDisabled}
onClick={onClick ? onClick : noop}
type={isFormSubmit ? 'submit' : 'button'}
>
{ !this.props.submitting && (
{ !submitting && (
<i className="fa fa-check-circle-o"/>
) || (
<ButtonBusyIndicator/>
)}&nbsp;
{this.props.label || (this.props.isNew ? 'Create' : 'Update')}
{label || (isNew ? 'Create' : 'Update')}
</Button>
);
}
Expand Down
3 changes: 3 additions & 0 deletions app/scripts/modules/core/src/modal/index.ts
@@ -1,3 +1,6 @@
export * from './buttons/ModalClose';
export * from './buttons/SubmitButton';
export * from './wizard/WizardModal';
export * from './wizard/WizardPage';
export { V2_MODAL_WIZARD_COMPONENT, V2ModalWizard } from './wizard/v2modalWizard.component';
export { WizardPage, V2_MODAL_WIZARD_SERVICE, V2ModalWizardService, WizardPageState } from './wizard/v2modalWizard.service';

0 comments on commit d768df5

Please sign in to comment.