Skip to content

Commit

Permalink
feat(cf): Reactify resize and rollback modals (#6325)
Browse files Browse the repository at this point in the history
Co-Authored-By: Jammy Louie <jlouie@pivotal.io>
  • Loading branch information
Jammy Louie authored and jkschneider committed Jan 8, 2019
1 parent 6fee54d commit 8106122
Show file tree
Hide file tree
Showing 10 changed files with 433 additions and 346 deletions.
2 changes: 0 additions & 2 deletions app/scripts/modules/cloudfoundry/src/cf.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { CLOUD_FOUNDRY_LOAD_BALANCER_MODULE } from './loadBalancer/loadBalancer.
import { CLOUD_FOUNDRY_REACT_MODULE } from './reactShims/cf.react.module';
import { CLOUD_FOUNDRY_SERVER_GROUP_TRANSFORMER } from './serverGroup/serverGroup.transformer';
import { CLOUD_FOUNDRY_SERVER_GROUP_COMMAND_BUILDER } from './serverGroup/configure/serverGroupCommandBuilder.service.cf';
import { SERVER_GROUP_DETAILS_MODULE } from './serverGroup/details/serverGroupDetails.module';
import { CLOUD_FOUNDRY_SEARCH_FORMATTER } from './search/searchResultFormatter';
import './help/cloudfoundry.help';

Expand Down Expand Up @@ -60,7 +59,6 @@ module(CLOUD_FOUNDRY_MODULE, [
CLOUD_FOUNDRY_SEARCH_FORMATTER,
CLOUD_FOUNDRY_SERVER_GROUP_COMMAND_BUILDER,
CLOUD_FOUNDRY_SERVER_GROUP_TRANSFORMER,
SERVER_GROUP_DETAILS_MODULE,
]).config(() => {
CloudProviderRegistry.registerProvider('cloudfoundry', {
name: 'Cloud Foundry',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import * as React from 'react';

import { Dropdown, Tooltip } from 'react-bootstrap';
import { get, find, filter, orderBy } from 'lodash';
import { filter, find, get, orderBy } from 'lodash';

import {
ClusterTargetBuilder,
IOwnerOption,
IServerGroupActionsProps,
IServerGroupJob,
ModalInjector,
NgReact,
ReactInjector,
ServerGroupWarningMessageService,
Expand All @@ -19,6 +18,8 @@ import { ICloudFoundryServerGroup } from 'cloudfoundry/domain';
import { ICloudFoundryCreateServerGroupCommand } from 'cloudfoundry/serverGroup/configure/serverGroupConfigurationModel.cf';
import { CloudFoundryCreateServerGroupModal } from 'cloudfoundry/serverGroup/configure/wizard/CreateServerGroupModal';
import { CloudFoundryReactInjector } from 'cloudfoundry/reactShims';
import { CloudFoundryResizeServerGroupModal } from './resize/CloudFoundryResizeServerGroupModal';
import { CloudFoundryRollbackServerGroupModal } from './rollback/CloudFoundryRollbackServerGroupModal';

export interface ICloudFoundryServerGroupActionsProps extends IServerGroupActionsProps {
serverGroup: ICloudFoundryServerGroup;
Expand Down Expand Up @@ -238,43 +239,28 @@ export class CloudFoundryServerGroupActions extends React.Component<ICloudFoundr
// if there is only one other server group, default to it being the rollback target
previousServerGroup = allServerGroups[0];
}
const cluster = find(app.clusters, {
name: serverGroup.cluster,
account: serverGroup.account,
serverGroups: [],
});
const disabledServerGroups: ICloudFoundryServerGroup[] = filter(cluster.serverGroups, {
isDisabled: true,
region: serverGroup.region,
}) as ICloudFoundryServerGroup[];

ModalInjector.modalService.open({
templateUrl: ReactInjector.overrideRegistry.getTemplate(
'cf.rollback.modal',
require('./rollback/rollbackServerGroup.html'),
),
controller: 'cloudfoundryRollbackServerGroupCtrl as ctrl',
resolve: {
serverGroup: () => serverGroup,
previousServerGroup: () => previousServerGroup,
disabledServerGroups: () => {
const cluster = find(app.clusters, {
name: serverGroup.cluster,
account: serverGroup.account,
serverGroups: [],
});
return filter(cluster.serverGroups, { isDisabled: true, region: serverGroup.region });
},
allServerGroups: () => allServerGroups,
application: () => app,
},
CloudFoundryRollbackServerGroupModal.show({
serverGroup,
previousServerGroup,
disabledServerGroups: disabledServerGroups.sort((a, b) => b.name.localeCompare(a.name)),
allServerGroups: allServerGroups.sort((a, b) => b.name.localeCompare(a.name)),
application: app,
});
};

private resizeServerGroup = (): void => {
ModalInjector.modalService.open({
templateUrl: ReactInjector.overrideRegistry.getTemplate(
'cf.resize.modal',
require('./resize/resizeServerGroup.html'),
),
size: 'lg',
controller: 'cloudfoundryResizeServerGroupCtrl as ctrl',
resolve: {
serverGroup: () => this.props.serverGroup,
application: () => this.props.app,
},
});
const { app, serverGroup } = this.props;
CloudFoundryResizeServerGroupModal.show({ application: app, serverGroup });
};

private cloneServerGroup = (): void => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import * as React from 'react';
import { Modal, ModalFooter } from 'react-bootstrap';
import { Form, Formik, FormikProps } from 'formik';

import {
Application,
FormikFormField,
ICapacity,
IModalComponentProps,
IServerGroupJob,
ModalClose,
NgReact,
noop,
NumberInput,
ReactInjector,
ReactModal,
TaskMonitor,
TaskReason,
} from '@spinnaker/core';

import { ICloudFoundryServerGroup } from 'cloudfoundry/domain';

export interface ICloudFoundryResizeServerGroupModalProps extends IModalComponentProps {
application: Application;
serverGroup: ICloudFoundryServerGroup;
}

export interface ICloudFoundryResizeServerGroupModalState {
initialValues: ICloudFoundryResizeServerGroupValues;
taskMonitor: TaskMonitor;
}

export interface ICloudFoundryResizeServerGroupValues {
desired: number;
diskQuota?: number;
memory?: number;
reason?: string;
}

export interface ICloudFoundryResizeJob extends IServerGroupJob {
capacity?: Partial<ICapacity>;
diskQuota?: number;
instanceCount?: number;
memory?: number;
serverGroupName: string;
reason?: string;
}

export class CloudFoundryResizeServerGroupModal extends React.Component<
ICloudFoundryResizeServerGroupModalProps,
ICloudFoundryResizeServerGroupModalState
> {
public static defaultProps: Partial<ICloudFoundryResizeServerGroupModalProps> = {
closeModal: noop,
dismissModal: noop,
};

private formikRef = React.createRef<Formik<ICloudFoundryResizeServerGroupValues>>();

public static show(props: ICloudFoundryResizeServerGroupModalProps): Promise<ICloudFoundryResizeJob> {
const modalProps = {};
return ReactModal.show(CloudFoundryResizeServerGroupModal, props, modalProps);
}

constructor(props: ICloudFoundryResizeServerGroupModalProps) {
super(props);

const { capacity, diskQuota, memory } = props.serverGroup;
const { desired } = capacity;
this.state = {
initialValues: {
desired,
diskQuota: diskQuota,
memory: memory,
},
taskMonitor: new TaskMonitor({
application: props.application,
title: 'Resizing your server group',
modalInstance: TaskMonitor.modalInstanceEmulation(() => this.props.dismissModal()),
onTaskComplete: () => this.props.application.serverGroups.refresh(),
}),
};
}

private close = (args?: any): void => {
this.props.dismissModal.apply(null, args);
};

private submit = (values: ICloudFoundryResizeServerGroupValues): void => {
const { desired, diskQuota, memory, reason } = values;
const { serverGroup, application } = this.props;
const capacity = {
min: desired,
max: desired,
desired,
};

const command: ICloudFoundryResizeJob = {
capacity,
diskQuota,
memory,
reason,
serverGroupName: serverGroup.name,
};

this.state.taskMonitor.submit(() => {
return ReactInjector.serverGroupWriter.resizeServerGroup(serverGroup, application, command);
});
};

private renderDesired(formik: FormikProps<ICloudFoundryResizeServerGroupValues>): JSX.Element {
const { serverGroup } = this.props;
const { capacity } = serverGroup;
return (
<div>
<div className="form-group">
<div className="col-md-3 sm-label-right">Current size</div>
<div className="col-md-4">
<div className="horizontal middle">
<input type="number" className="NumberInput form-control" value={capacity.desired} disabled={true} />
<div className="sp-padding-xs-xaxis">instances</div>
</div>
</div>
</div>
<div className="form-group">
<div className="col-md-3 sm-label-right">Resize to</div>
<div className="col-md-4">
<div className="horizontal middle">
<FormikFormField
name="desired"
input={props => <NumberInput {...props} min={0} />}
touched={true}
required={true}
onChange={value => {
formik.setFieldValue('min', value);
formik.setFieldValue('max', value);
}}
/>
<div className="sp-padding-xs-xaxis">instances</div>
</div>
</div>
</div>
</div>
);
}

private renderQuota(
formik: FormikProps<ICloudFoundryResizeServerGroupValues>,
field: string,
initialValue: number,
): JSX.Element {
return (
<div>
<div className="form-group">
<div className="col-md-3 sm-label-right">Current size</div>
<div className="col-md-4">
<div className="horizontal middle">
<input type="number" className="NumberInput form-control" value={initialValue} disabled={true} />
<div className="sp-padding-xs-xaxis">MB</div>
</div>
</div>
</div>
<div className="form-group">
<div className="col-md-3 sm-label-right">Resize to</div>
<div className="col-md-4">
<div className="horizontal middle">
<FormikFormField
name={field}
input={props => <NumberInput {...props} min={64} />}
touched={true}
required={true}
onChange={value => {
formik.setFieldValue('min', value);
formik.setFieldValue('max', value);
}}
/>
<div className="sp-padding-xs-xaxis">MB</div>
</div>
</div>
</div>
</div>
);
}

public render() {
const { serverGroup } = this.props;
const { diskQuota, memory } = serverGroup;
const { initialValues } = this.state;
const { TaskMonitorWrapper } = NgReact;
return (
<>
<TaskMonitorWrapper monitor={this.state.taskMonitor} />
<Formik<ICloudFoundryResizeServerGroupValues>
ref={this.formikRef}
initialValues={initialValues}
onSubmit={this.submit}
render={formik => {
return (
<>
<Modal.Header>
<h3>Resize {serverGroup.name}</h3>
</Modal.Header>
<ModalClose dismiss={this.close} />
<Modal.Body>
<Form className="form-horizontal">
{this.renderDesired(formik)}
{this.renderQuota(formik, 'diskQuota', diskQuota)}
{this.renderQuota(formik, 'memory', memory)}
<TaskReason reason={formik.values.reason} onChange={val => formik.setFieldValue('reason', val)} />
</Form>
</Modal.Body>
<ModalFooter>
<button className="btn btn-default" onClick={this.close}>
Cancel
</button>
<button
type="submit"
className="btn btn-primary"
onClick={() => this.submit(formik.values)}
disabled={!formik.isValid}
>
Submit
</button>
</ModalFooter>
</>
);
}}
/>
</>
);
}
}

This file was deleted.

Loading

0 comments on commit 8106122

Please sign in to comment.