mirror of
https://github.com/getredash/redash.git
synced 2026-03-21 07:00:07 -04:00
* Added screen reader CSS * Added description to external links * Added spinner icon accessibility * Added accessibility to exclamation and big message * Added question and exclamation accessibility * Hide decorative icons * Standardized link design * Added a11y to refresh icons * Added aria-label to anchors and buttons * Added a11y to conditional icons * Added applicable labels to Ant Icons * Changed escape to interpolation * Replaced external links with opens in new tab * Improved Tooltip hosts * Added aria live to temporary elements * Removed mistakenly added redundant helper * Undoes unnecessarily added interpolation * Replaced empty label with hidden * Improved full icon label * Improved display of live regions * Added note * remove unused class * Created unique id * Remove TODOs * Proper action label * Improved feedback for autocomplete toggle * feature: add id hook * refactor: use id hook * standardize white space
154 lines
4.7 KiB
JavaScript
154 lines
4.7 KiB
JavaScript
import { get, find, toUpper } from "lodash";
|
|
import React from "react";
|
|
import PropTypes from "prop-types";
|
|
|
|
import Modal from "antd/lib/modal";
|
|
import routeWithUserSession from "@/components/ApplicationArea/routeWithUserSession";
|
|
import navigateTo from "@/components/ApplicationArea/navigateTo";
|
|
import LoadingState from "@/components/items-list/components/LoadingState";
|
|
import DynamicForm from "@/components/dynamic-form/DynamicForm";
|
|
import helper from "@/components/dynamic-form/dynamicFormHelper";
|
|
import HelpTrigger, { TYPES as HELP_TRIGGER_TYPES } from "@/components/HelpTrigger";
|
|
import wrapSettingsTab from "@/components/SettingsWrapper";
|
|
|
|
import DataSource, { IMG_ROOT } from "@/services/data-source";
|
|
import notification from "@/services/notification";
|
|
import routes from "@/services/routes";
|
|
|
|
class EditDataSource extends React.Component {
|
|
static propTypes = {
|
|
dataSourceId: PropTypes.string.isRequired,
|
|
onError: PropTypes.func,
|
|
};
|
|
|
|
static defaultProps = {
|
|
onError: () => {},
|
|
};
|
|
|
|
state = {
|
|
dataSource: null,
|
|
type: null,
|
|
loading: true,
|
|
};
|
|
|
|
componentDidMount() {
|
|
DataSource.get({ id: this.props.dataSourceId })
|
|
.then(dataSource => {
|
|
const { type } = dataSource;
|
|
this.setState({ dataSource });
|
|
DataSource.types().then(types => this.setState({ type: find(types, { type }), loading: false }));
|
|
})
|
|
.catch(error => this.props.onError(error));
|
|
}
|
|
|
|
saveDataSource = (values, successCallback, errorCallback) => {
|
|
const { dataSource } = this.state;
|
|
helper.updateTargetWithValues(dataSource, values);
|
|
DataSource.save(dataSource)
|
|
.then(() => successCallback("Saved."))
|
|
.catch(error => {
|
|
const message = get(error, "response.data.message", "Failed saving.");
|
|
errorCallback(message);
|
|
});
|
|
};
|
|
|
|
deleteDataSource = callback => {
|
|
const { dataSource } = this.state;
|
|
|
|
const doDelete = () => {
|
|
DataSource.delete(dataSource)
|
|
.then(() => {
|
|
notification.success("Data source deleted successfully.");
|
|
navigateTo("data_sources");
|
|
})
|
|
.catch(() => {
|
|
callback();
|
|
});
|
|
};
|
|
|
|
Modal.confirm({
|
|
title: "Delete Data Source",
|
|
content: "Are you sure you want to delete this data source?",
|
|
okText: "Delete",
|
|
okType: "danger",
|
|
onOk: doDelete,
|
|
onCancel: callback,
|
|
maskClosable: true,
|
|
autoFocusButton: null,
|
|
});
|
|
};
|
|
|
|
testConnection = callback => {
|
|
const { dataSource } = this.state;
|
|
DataSource.test({ id: dataSource.id })
|
|
.then(httpResponse => {
|
|
if (httpResponse.ok) {
|
|
notification.success("Success");
|
|
} else {
|
|
notification.error("Connection Test Failed:", httpResponse.message, { duration: 10 });
|
|
}
|
|
callback();
|
|
})
|
|
.catch(() => {
|
|
notification.error(
|
|
"Connection Test Failed:",
|
|
"Unknown error occurred while performing connection test. Please try again later.",
|
|
{ duration: 10 }
|
|
);
|
|
callback();
|
|
});
|
|
};
|
|
|
|
renderForm() {
|
|
const { dataSource, type } = this.state;
|
|
const fields = helper.getFields(type, dataSource);
|
|
const helpTriggerType = `DS_${toUpper(type.type)}`;
|
|
const formProps = {
|
|
fields,
|
|
type,
|
|
actions: [
|
|
{ name: "Delete", type: "danger", callback: this.deleteDataSource },
|
|
{ name: "Test Connection", pullRight: true, callback: this.testConnection, disableWhenDirty: true },
|
|
],
|
|
onSubmit: this.saveDataSource,
|
|
feedbackIcons: true,
|
|
defaultShowExtraFields: helper.hasFilledExtraField(type, dataSource),
|
|
};
|
|
|
|
return (
|
|
<div className="row" data-test="DataSource">
|
|
<div className="text-right m-r-10">
|
|
{HELP_TRIGGER_TYPES[helpTriggerType] && (
|
|
<HelpTrigger className="f-13" type={helpTriggerType}>
|
|
Setup Instructions <i className="fa fa-question-circle" aria-hidden="true" />
|
|
<span className="sr-only">(help)</span>
|
|
</HelpTrigger>
|
|
)}
|
|
</div>
|
|
<div className="text-center m-b-10">
|
|
<img className="p-5" src={`${IMG_ROOT}/${type.type}.png`} alt={type.name} width="64" />
|
|
<h3 className="m-0">{type.name}</h3>
|
|
</div>
|
|
<div className="col-md-4 col-md-offset-4 m-b-10">
|
|
<DynamicForm {...formProps} />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
render() {
|
|
return this.state.loading ? <LoadingState className="" /> : this.renderForm();
|
|
}
|
|
}
|
|
|
|
const EditDataSourcePage = wrapSettingsTab("DataSources.Edit", null, EditDataSource);
|
|
|
|
routes.register(
|
|
"DataSources.Edit",
|
|
routeWithUserSession({
|
|
path: "/data_sources/:dataSourceId",
|
|
title: "Data Sources",
|
|
render: pageProps => <EditDataSourcePage {...pageProps} />,
|
|
})
|
|
);
|