mirror of
https://github.com/getredash/redash.git
synced 2026-05-11 09:01:27 -04:00
* Migrate TypePicker to React
* Migrate DataSources and Destinations List
* Fixes to DestinationsList
* Add CreateDataSource (testing with Steps)
* Render the form after type selection
* Add HELP_LINKS to CreateDataSource
* Add Done behavior
* Add scrollToTop to CreateDataSource
* TypePicker styling adjusts
* Add CreateDestination
* Update resouce gets to componentDidMount
* Create EditForm components
* Migrate Edit pages
* Remove angular logic from DynamicForm
* Add actions to EditPages
* TypePicker title style adjustments
* Add Empty and Loading state
* UX improvements
* Review changes
* Styling updates on TypePicker, forms background fix
* Add blank line removed by mistaken
* Reorganize TypePicker
* Hide Search on List Pages
* Fix spacing in Forms
* Update Create Data Source and Destination to be a Dialog
* Remove max-height from the form
* Fix DynamicForm import in CreateUserDialog
* Route /new to open CreateSourceDialog
* Add HelpTrigger + refine styling and Edit Pages
* Remove help links from data source resource
* Update Cypress specs
* TypePicker -> CardsList
* Remove old TypePicker styling and change CardsList styling to less
* Test if Percy shows Dialogs
* Personal review cleanup
* CR
* Remove unnecessary query on dialog success
* Handle resource errors in Edit Pages
* Add CreateDestination policy
* Add placeholder and separator to the Name field
* Use cy.click instead of cy.wait
* Revert "Use cy.click instead of cy.wait" (Didn't work)
This reverts commit 77285d9fa3.
* Align help trigger on the right and rename Steps
* Refine behavior for long names
* Update toastr calls to use notification instead
* Redirect to target after creation
* Remove autoFocus on DynamicForm for Edit Pages
* Add eslint-disable for cy.wait
112 lines
2.9 KiB
JavaScript
112 lines
2.9 KiB
JavaScript
import React from 'react';
|
|
import { each, includes, isUndefined } from 'lodash';
|
|
|
|
function orderedInputs(properties, order, targetOptions) {
|
|
const inputs = new Array(order.length);
|
|
Object.keys(properties).forEach((key) => {
|
|
const position = order.indexOf(key);
|
|
const input = {
|
|
name: key,
|
|
title: properties[key].title,
|
|
type: properties[key].type,
|
|
placeholder: properties[key].default && properties[key].default.toString(),
|
|
required: properties[key].required,
|
|
initialValue: targetOptions[key],
|
|
};
|
|
|
|
if (position > -1) {
|
|
inputs[position] = input;
|
|
} else {
|
|
inputs.push(input);
|
|
}
|
|
});
|
|
return inputs;
|
|
}
|
|
|
|
function normalizeSchema(configurationSchema) {
|
|
each(configurationSchema.properties, (prop, name) => {
|
|
if (name === 'password' || name === 'passwd') {
|
|
prop.type = 'password';
|
|
}
|
|
|
|
if (name.endsWith('File')) {
|
|
prop.type = 'file';
|
|
}
|
|
|
|
if (prop.type === 'boolean') {
|
|
prop.type = 'checkbox';
|
|
}
|
|
|
|
if (prop.type === 'string') {
|
|
prop.type = 'text';
|
|
}
|
|
|
|
prop.required = includes(configurationSchema.required, name);
|
|
});
|
|
|
|
configurationSchema.order = configurationSchema.order || [];
|
|
}
|
|
|
|
function setDefaultValueForCheckboxes(configurationSchema, options = {}) {
|
|
if (Object.keys(options).length === 0) {
|
|
const properties = configurationSchema.properties;
|
|
Object.keys(properties).forEach((property) => {
|
|
if (!isUndefined(properties[property].default) && properties[property].type === 'checkbox') {
|
|
options[property] = properties[property].default;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function getFields(type = {}, target = { options: {} }) {
|
|
const configurationSchema = type.configuration_schema;
|
|
normalizeSchema(configurationSchema);
|
|
setDefaultValueForCheckboxes(configurationSchema, target.options);
|
|
|
|
const isNewTarget = !target.id;
|
|
const inputs = [
|
|
{
|
|
name: 'name',
|
|
title: 'Name',
|
|
type: 'text',
|
|
required: true,
|
|
initialValue: target.name,
|
|
contentAfter: React.createElement('hr'),
|
|
placeholder: `My ${type.name}`,
|
|
autoFocus: isNewTarget,
|
|
},
|
|
...orderedInputs(configurationSchema.properties, configurationSchema.order, target.options),
|
|
];
|
|
|
|
return inputs;
|
|
}
|
|
|
|
function updateTargetWithValues(target, values) {
|
|
target.name = values.name;
|
|
Object.keys(values).forEach((key) => {
|
|
if (key !== 'name') {
|
|
target.options[key] = values[key];
|
|
}
|
|
});
|
|
}
|
|
|
|
function toHuman(text) {
|
|
return text.replace(/_/g, ' ').replace(/(?:^|\s)\S/g, a => a.toUpperCase());
|
|
}
|
|
|
|
function getBase64(file) {
|
|
return new Promise((resolve, reject) => {
|
|
const reader = new FileReader();
|
|
reader.readAsDataURL(file);
|
|
reader.onload = () => resolve(reader.result.substr(reader.result.indexOf(',') + 1));
|
|
reader.onerror = error => reject(error);
|
|
});
|
|
}
|
|
|
|
export default {
|
|
getFields,
|
|
updateTargetWithValues,
|
|
toHuman,
|
|
getBase64,
|
|
};
|