Skip to content

Commit

Permalink
[YW][#3680] Enable multi-table backups in CreateBackups modal.
Browse files Browse the repository at this point in the history
Summary:
Enabled a multi select on react-select component in YBFormSelect. Clear the select field of
all tables if the user selects or has selected 'Full Universe Backup'.

Test Plan:
Open a specific universe and go to the Backups tab. Try Creating a backup and select
multiple tables to backup. Ensure that a single table, and full universe backup still work.

Reviewers: arnav, ram

Reviewed By: ram

Subscribers: ui

Differential Revision: https://phabricator.dev.yugabyte.com/D7977
  • Loading branch information
Andrew Cai committed Feb 18, 2020
1 parent 751e647 commit 6dda063
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void run() {
try {
Universe universe = Universe.get(taskParams().universeUUID);
Map<String, String> config = universe.getConfig();
if (config.isEmpty() || config.get(Universe.TAKE_BACKUPS).equals("true")) {
if (config.isEmpty() || config.getOrDefault(Universe.TAKE_BACKUPS, "true").equals("true")) {
ShellProcessHandler.ShellResponse response = tableManager.createBackup(taskParams());
JsonNode jsonNode = Json.parse(response.message);
if (response.code != 0 || jsonNode.has("error")) {
Expand Down
12 changes: 5 additions & 7 deletions managed/ui/src/components/common/forms/fields/YBFormSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ import Select from 'react-select';
export default class YBFormSelect extends Component {
handleChange = option => {
const { form, field, onChange } = this.props;
if (isDefinedNotNull(option)) {
if (isDefinedNotNull(onChange) && typeof(onChange) === "function") {
onChange(this.props, option);
} else if (isDefinedNotNull(option)) {
form.setFieldValue(field.name, option);
} else {
form.setFieldValue(field.name, "");
}
if (isDefinedNotNull(onChange)
&& typeof(onChange) === "function")
onChange(this.props, option);
};

handleBlur = () => {
Expand All @@ -25,7 +24,7 @@ export default class YBFormSelect extends Component {
};

render() {
const { field, options } = this.props;
const { field } = this.props;
const customStyles = {
option: (provided, state) => ({
...provided,
Expand Down Expand Up @@ -78,7 +77,6 @@ export default class YBFormSelect extends Component {
margin: "0"
}),
};

return (
<YBLabel {...this.props} >
<Select
Expand All @@ -88,7 +86,7 @@ export default class YBFormSelect extends Component {
{...this.props}
onChange={this.handleChange}
onBlur={this.handleBlur}
value={options ? options.find(option => option.value === field.value) : ''}
value={field.value}
isOptionDisabled={(option) => !!option.disabled}
/>
</YBLabel>
Expand Down
66 changes: 32 additions & 34 deletions managed/ui/src/components/tables/CreateBackup/CreateBackup.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ import * as Yup from "yup";
import '../common.scss';

export default class CreateBackup extends Component {
constructor(props) {
super(props);
this.state = {
isMulti: true
};
}

static propTypes = {
tableInfo: PropTypes.object
};
Expand All @@ -36,21 +29,26 @@ export default class CreateBackup extends Component {
} = this.props;

if (isDefinedNotNull(values.backupTableUUID) &&
values.backupTableUUID.length &&
isDefinedNotNull(values.storageConfigUUID)) {
const payload = {
"storageConfigUUID": values.storageConfigUUID,
"sse": values.enableSSE,
"schedulingFrequency": isEmptyString(values.schedulingFrequency) ? null : values.schedulingFrequency,
"cronExpression": isNonEmptyString(values.cronExpression) ? values.cronExpression : null,
};
if (values.backupTableUUID === "fulluniverse") {
if (values.backupTableUUID[0] === "fulluniverse") {
createUniverseBackup(universeUUID, payload);
} else if (values.backupTableUUID.length > 1) {
payload.tableUUIDList = values.backupTableUUID;
createUniverseBackup(universeUUID, payload);
} else {
const backupTable = universeTables.find((table) => table.tableUUID === values.backupTableUUID);
payload.actionType = "CREATE";
const backupTable = universeTables
.find((table) => table.tableUUID === values.backupTableUUID[0]);
payload.tableName = backupTable.tableName;
payload.keyspace = backupTable.keySpace;
createTableBackup(universeUUID, backupTable.tableUUID, payload);
payload.actionType = "CREATE";
createTableBackup(universeUUID, values.backupTableUUID, payload);
}
onHide();
browserHistory.push('/universes/' + universeUUID + "/backups");
Expand All @@ -59,19 +57,18 @@ export default class CreateBackup extends Component {

backupItemChanged = (props, option) => {
if (isNonEmptyObject(option) && option.value === "fulluniverse") {
this.setState({isMulti: false});
props.form.setFieldValue(props.field.name, option);
} else if (isNonEmptyArray(option)) {
const index = option.findIndex((item, index) => item.value === "fulluniverse");
if (index + 1 > 0) {
this.setState({isMulti: false});
props.form.setFieldValue(props.field.name, option[index]);
if (index > -1) {
// Clear all other values except 'Full Universe Backup'
props.form.setFieldValue(props.field.name, [option[index]]);
} else {
props.form.setFieldValue(props.field.name, option);
}
} else {
this.setState({isMulti: true});
if (isNonEmptyObject(option)) {
props.form.setFieldValue(props.field.name, [option]);
}
// Clear form
props.form.setFieldValue(props.field.name, []);
}
}

Expand All @@ -94,14 +91,18 @@ export default class CreateBackup extends Component {
tableOptions = universeTables.map((tableInfo) => {
return {value: tableInfo.tableUUID, label: tableInfo.keySpace + "." + tableInfo.tableName};
}).sort((a, b) => a.label.toLowerCase() < b.label.toLowerCase() ? -1 : 1);
tableOptions = [{
label: <b>Full Universe Backup</b>,
value: "fulluniverse",
icon: <span className={"fa fa-globe"} />
},{
label: "Tables",
options: tableOptions
}];
tableOptions = [
{
label: <b>Full Universe Backup</b>,
value: "fulluniverse",
icon: <span className={"fa fa-globe"} />
},
{
label: "Tables",
value: 'tables',
options: tableOptions
}
];
}

initialValues.schedulingFrequency = "";
Expand Down Expand Up @@ -130,7 +131,7 @@ export default class CreateBackup extends Component {
onFormSubmit={(values) => {
const payload = {
...values,
backupTableUUID: values.backupTableUUID.value,
backupTableUUID: values.backupTableUUID.map(x => x.value),
storageConfigUUID: values.storageConfigUUID.value,
};
this.createBackup(payload);
Expand All @@ -154,11 +155,7 @@ export default class CreateBackup extends Component {
render={props => {
const isSchedulingFrequencyReadOnly = props.values.cronExpression !== "";
const isCronExpressionReadOnly = props.values.schedulingFrequency !== "";
// TODO: for multitablebackups just add
//
// isMulti={this.state.isMulti}
// onChange={this.backupItemChanged}
//

// params for backupTableUUID <Field>
// NOTE: No entire keyspace selection implemented
return (<Fragment>
Expand All @@ -178,7 +175,8 @@ export default class CreateBackup extends Component {
}}
label={`Tables to backup`}
options={tableOptions}
isMulti={false}
isMulti={true}
onChange={this.backupItemChanged}
readOnly={isNonEmptyObject(tableInfo)}
/>
<Field
Expand Down

0 comments on commit 6dda063

Please sign in to comment.