Skip to content

Commit

Permalink
Merge pull request #4985 from Hyperkid123/replace-service-form
Browse files Browse the repository at this point in the history
Replace service form
  • Loading branch information
martinpovolny committed Nov 30, 2018
2 parents 63986be + a049c5f commit 2b5e0f1
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 192 deletions.

This file was deleted.

52 changes: 52 additions & 0 deletions app/javascript/components/service-form/index.jsx
@@ -0,0 +1,52 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Grid } from 'patternfly-react';
import createSchema from './schema';
import MiqFormRenderer from '../../forms/data-driven-form';
import { http } from '../../http_api';
import { cleanVirtualDom } from '../../miq-component/helpers';

class ServiceForm extends Component {
constructor(props) {
super(props);
this.state = {
schema: createSchema(props.maxNameLen, props.maxDescLen),
};
}
componentDidMount() {
cleanVirtualDom();
miqSparkleOn();
http.get(`/service/service_form_fields/${this.props.serviceFormId}`)
.then(data => this.setState({ initialValues: { ...data } }, miqSparkleOff()));
}
render() {
const { serviceFormId } = this.props;
const cancelUrl = `/service/service_edit/${serviceFormId}?button=cancel`;
const submitUrl = `/service/service_edit/${serviceFormId}?button=save`;
return (
<Grid fluid style={{ paddingTop: 20 }}>
<MiqFormRenderer
initialValues={this.state.initialValues}
schema={this.state.schema}
onSubmit={values => miqAjaxButton(submitUrl, values)}
onCancel={() => miqAjaxButton(cancelUrl)}
onReset={() => add_flash(__('All changes have been reset'), 'warn')}
canReset
buttonsLabels={{
submitLabel: __('Save'),
resetLabel: __('Reset'),
cancelLabel: __('Cancel'),
}}
/>
</Grid>
);
}
}

ServiceForm.propTypes = {
maxNameLen: PropTypes.number.isRequired,
maxDescLen: PropTypes.number.isRequired,
serviceFormId: PropTypes.number.isRequired,
};

export default ServiceForm;
27 changes: 27 additions & 0 deletions app/javascript/components/service-form/schema.js
@@ -0,0 +1,27 @@
function createSchema(maxNameLen, maxDescLen) {
return {
fields: [{
component: 'text-field',
name: 'name',
maxLength: maxNameLen,
label: __('Name'),
validateOnMount: true,
autoFocus: true,
validate: [{
type: 'required-validator',
}],
}, {
component: 'text-field',
name: 'description',
maxLength: maxDescLen,
label: __('Description'),
validateOnMount: true,
autoFocus: true,
validate: [{
type: 'required-validator',
}],
}],
};
}

export default createSchema;
1 change: 0 additions & 1 deletion app/javascript/forms/data-driven-form.jsx
Expand Up @@ -10,5 +10,4 @@ const MiqFormRenderer = props => (
{...props}
/>
);

export default MiqFormRenderer;
2 changes: 2 additions & 0 deletions app/javascript/packs/component-definitions-common.js
Expand Up @@ -7,6 +7,7 @@ import VmSnapshotFormComponent from '../components/vm-snapshot-form-component';
import FormButtonsRedux from '../forms/form-buttons-redux';
import MiqAboutModal from '../components/miq-about-modal';
import CloudTennantForm from '../components/cloud-tenant-form/cloud-tenant-form';
import ServiceForm from '../components/service-form';

/**
* Add component definitions to this file.
Expand All @@ -24,3 +25,4 @@ ManageIQ.component.addReact('VmSnapshotFormComponent', VmSnapshotFormComponent);
ManageIQ.component.addReact('FormButtonsRedux', FormButtonsRedux);
ManageIQ.component.addReact('MiqAboutModal', MiqAboutModal);
ManageIQ.component.addReact('CloudTennantForm', CloudTennantForm);
ManageIQ.component.addReact('ServiceForm', ServiceForm);
94 changes: 94 additions & 0 deletions app/javascript/spec/service-form/service-form.spec.js
@@ -0,0 +1,94 @@
import React from 'react';
import { mount } from 'enzyme';
import fetchMock from 'fetch-mock';
import FormRender from '@data-driven-forms/react-form-renderer';
import ServiceForm from '../../components/service-form';

describe('Cloud tenant form component', () => {
let initialProps;
let submitSpy;
let flashSpy;

beforeEach(() => {
initialProps = {
maxNameLen: 1,
maxDescLen: 2,
serviceFormId: 3,
};
submitSpy = jest.spyOn(window, 'miqAjaxButton');
flashSpy = jest.spyOn(window, 'add_flash');
});

afterEach(() => {
fetchMock.reset();
fetchMock.restore();
submitSpy.mockRestore();
});

it('should request data after mount and set to state', (done) => {
fetchMock
.getOnce('/service/service_form_fields/3', {
foo: 'bar',
});
const wrapper = mount(<ServiceForm {...initialProps} />);
expect(fetchMock.lastUrl()).toEqual('/service/service_form_fields/3');
setImmediate(() => {
wrapper.update();
expect(wrapper.state().initialValues).toEqual({ foo: 'bar' });
done();
});
});

it('should call cancel action', (done) => {
fetchMock
.getOnce('/service/service_form_fields/3', {
name: 'foo',
description: 'bar',
});
const wrapper = mount(<ServiceForm {...initialProps} />);

setImmediate(() => {
wrapper.find('button').last().simulate('click');
expect(submitSpy).toHaveBeenCalledWith('/service/service_edit/3?button=cancel');
done();
});
});

it('should enable reset button and call reset callback', (done) => {
fetchMock
.getOnce('/service/service_form_fields/3', {});
const wrapper = mount(<ServiceForm {...initialProps} />);

setImmediate(() => {
// reset should be disabled
wrapper.find('button').at(1).simulate('click');
expect(flashSpy).not.toHaveBeenCalled();
// change value of some input to enable reset button
wrapper.find('input').first().simulate('change', {
target: {
value: 'foo',
},
});
wrapper.find('button').at(1).simulate('click');
expect(flashSpy).toHaveBeenCalledWith(expect.any(String), 'warn');
done();
});
});

it('should enable submit button and call submit callback', (done) => {
fetchMock
.getOnce('/service/service_form_fields/3', {});
const wrapper = mount(<ServiceForm {...initialProps} />);

setImmediate(() => {
// reset should be disabled
wrapper.find('button').at(0).simulate('click');
// change form state to enable reset button
wrapper.find(FormRender).childAt(0).instance().form.change('name', 'foo');
wrapper.find(FormRender).childAt(0).instance().form.change('description', 'bar');
wrapper.find('button').at(0).simulate('click');
expect(submitSpy).toHaveBeenCalledWith('/service/service_edit/3?button=save', { name: 'foo', description: 'bar' });
done();
});
});
});
45 changes: 2 additions & 43 deletions app/views/service/_service_form.html.haml
@@ -1,43 +1,2 @@
- @angular_form = true

%form.form-horizontal#form_div{"name" => "angularForm",
"ng-controller" => "serviceFormController as vm",
"ng-show" => "vm.afterGet",
"model" => "vm.serviceModel",
"model-copy" => "vm.modelCopy",
"miq-form" => true,
"form-changed" => true}
= render :partial => "layouts/flash_msg"
%div
%div
.form-group{"ng-class" => "{'has-error': angularForm.name.$invalid}"}
%div
%div
.form-group{"ng-class" => "{'has-error': angularForm.name.$invalid}"}
%label.col-md-2.control-label{"for" => "name"}
= _("Name")
.col-md-8
%input.form-control{"type" => "text",
"id" => "name",
"name" => "name",
"ng-model" => "vm.serviceModel.name",
"maxlength" => "#{ViewHelper::MAX_NAME_LEN}",
"required" => true,
"auto-focus" => ""}
%span.help-block{"ng-show" => "angularForm.name.$error.miqrequired"}
= _("Required")
.form-group{"ng-class" => "{'has-error': angularForm.description.$invalid}"}
%label.col-md-2.control-label{"for" => "description"}
= _("Description")
.col-md-8
%input.form-control{"type" => "text",
"id" => "description",
"name" => "description",
"ng-model" => "vm.serviceModel.description",
"maxlength" => "#{ViewHelper::MAX_DESC_LEN}",
"required" => true}
= render :partial => "layouts/angular/generic_form_buttons"

:javascript
ManageIQ.angular.app.value('serviceFormId', '#{@service.id}');
miq_bootstrap('#form_div');
= render :partial => "layouts/flash_msg"
= react('ServiceForm', { :maxNameLen => ViewHelper::MAX_NAME_LEN, :maxDescLen => ViewHelper::MAX_DESC_LEN, :serviceFormId => @service.id})
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -43,7 +43,6 @@
"bootstrap-switch": "~3.3.4",
"codemirror": "~5.19.0",
"connected-react-router": "^4.3.0",
"enzyme-to-json": "^3.3.4",
"eonasdan-bootstrap-datetimepicker": "~4.17.47",
"es6-shim": "~0.35.3",
"graphiql": "^0.11.11",
Expand Down Expand Up @@ -112,6 +111,7 @@
"enhanced-resolve": "~4.0.0",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"enzyme-to-json": "^3.3.4",
"eslint": "^4.14.0",
"eslint-config-airbnb": "^16.0.0",
"eslint-config-angular": "~0.5.0",
Expand Down

0 comments on commit 2b5e0f1

Please sign in to comment.