Skip to content
Snippets Groups Projects
Unverified Commit 17f720ac authored by Paul Rosenzweig's avatar Paul Rosenzweig Committed by GitHub
Browse files

Display form errors in database details form (#10644)

parent 00617e87
No related branches found
No related tags found
No related merge requests found
......@@ -57,10 +57,10 @@ export default class DatabaseDetailsForm extends Component {
engines: PropTypes.object.isRequired,
formError: PropTypes.object,
hiddenFields: PropTypes.object,
isNewDatabase: PropTypes.boolean,
isNewDatabase: PropTypes.bool,
submitButtonText: PropTypes.string.isRequired,
submitFn: PropTypes.func.isRequired,
submitting: PropTypes.boolean,
submitting: PropTypes.bool,
};
validateForm() {
......@@ -196,7 +196,7 @@ export default class DatabaseDetailsForm extends Component {
}
renderField(field, fieldIndex) {
const { engine } = this.props;
const { engine, formError } = this.props;
const { details } = this.state;
window.ENGINE = engine;
......@@ -415,8 +415,16 @@ export default class DatabaseDetailsForm extends Component {
);
} else {
return (
<FormField key={field.name} fieldName={field.name}>
<FormLabel title={field["display-name"]} fieldName={field.name} />
<FormField
key={field.name}
fieldName={field.name}
formError={formError}
>
<FormLabel
title={field["display-name"]}
fieldName={field.name}
formError={formError}
/>
{this.renderFieldInput(field, fieldIndex)}
<span className="Form-charm" />
</FormField>
......@@ -460,6 +468,19 @@ export default class DatabaseDetailsForm extends Component {
hiddenFields = hiddenFields || {};
if (formError && formError.data) {
// If we have a field error but no matching field, use that field error as
// a fallback for formError.data.message
const { message, errors = {} } = formError.data;
const fieldNames = new Set(fields.map(field => field.name));
const [unusedFieldKey] = Object.keys(errors).filter(
name => !fieldNames.has(name),
);
if (unusedFieldKey && !message) {
formError.data.message = errors[unusedFieldKey];
}
}
return (
<form onSubmit={this.formSubmitted.bind(this)} noValidate>
<div className="FormInputGroup pb2">
......
import React from "react";
import { mount } from "enzyme";
import DatabaseDetailsForm from "metabase/components/DatabaseDetailsForm";
const ENGINES = {
h2: {
"details-fields": [
{
name: "db",
"display-name": "Connection String",
placeholder: "file:/Users/camsaul/bird_sightings/toucans",
required: true,
},
],
"driver-name": "H2",
},
};
const DEFAULT_PROPS = {
details: {},
engines: ENGINES,
engine: Object.keys(ENGINES)[0],
submitButtonText: "Next",
submitFn: () => undefined,
};
describe("DatabaseDetailsForm", () => {
it("should render", () => {
mount(<DatabaseDetailsForm {...DEFAULT_PROPS} />);
});
it("should render field errors", () => {
const wrapper = mount(
<DatabaseDetailsForm
{...DEFAULT_PROPS}
formError={{ data: { errors: { db: "fix this field" } } }}
/>,
);
const labels = wrapper.find(".Form-label").map(e => e.text());
expect(labels).toContain("Connection String : fix this field");
});
it("should render field errors as a form message if there's no matching field", () => {
const wrapper = mount(
<DatabaseDetailsForm
{...DEFAULT_PROPS}
formError={{
data: { errors: { foobar: "couldn't find a field for this" } },
}}
/>,
);
const message = wrapper.find(".Form-message").text();
expect(message).toEqual("couldn't find a field for this");
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment