create down migration when a column is dropped (close #2291) (#2385)

This commit is contained in:
Aravind Shankar 2019-06-26 18:42:44 +05:30 committed by Shahidh K Muhammed
parent b52ed4ccf0
commit c17bf2f94b
29 changed files with 257 additions and 373 deletions

View File

@ -1,6 +1,7 @@
package api
import (
"fmt"
"net/http"
"net/url"
"strings"
@ -130,7 +131,7 @@ func MigrateAPI(c *gin.Context) {
c.JSON(http.StatusInternalServerError, &Response{Code: "internal_error", Message: err.Error()})
return
}
c.JSON(http.StatusOK, &Response{Name: request.Name})
c.JSON(http.StatusOK, &Response{Name: fmt.Sprintf("%d_%s", timestamp, request.Name)})
default:
c.JSON(http.StatusMethodNotAllowed, &gin.H{"message": "Method not allowed"})
}

View File

@ -234,8 +234,7 @@ export const passRemoveUniqueKey = () => {
};
export const passMTDeleteCol = () => {
// cy.get(getElementFromAlias(`edit-${getColName(0)}`)).click();
// cy.wait(500);
cy.get(getElementFromAlias('modify-table-edit-column-1')).click();
cy.get(getElementFromAlias('modify-table-column-1-remove')).click();
cy.on('window:alert', str => {
expect(str === 'Are you sure you want to delete?').to.be.true;

View File

@ -40,31 +40,8 @@ const showNotification = ({
Notifications.show(
{
position,
autoDismiss: level === 'error' ? 0 : 5,
dismissible: level === 'error' ? 'click' : 'both',
children: json ? jsonFormat(json) : null,
...options,
},
level
)
);
};
};
const showTempNotification = ({
level = 'info',
position = 'tr',
json,
...options
} = {}) => {
return dispatch => {
dispatch(Notifications.removeAll());
dispatch(
Notifications.show(
{
position,
autoDismiss: 2,
dismissible: 'both',
autoDismiss: ['error', 'warning'].includes(level) ? 0 : 5,
dismissible: ['error', 'warning'].includes(level) ? 'button' : 'both',
children: json ? jsonFormat(json) : null,
...options,
},
@ -161,5 +138,4 @@ export {
notifExpand,
notifMsg,
showNotification,
showTempNotification,
};

View File

@ -853,6 +853,10 @@ code {
background: #f2f2f2 !important;
}
.text_gray {
color: #767E96
}
.docsButton {
background-color: #fff;
border-radius: 5px;

View File

@ -1,12 +1,12 @@
import React from 'react';
import AceEditor from 'react-ace';
import { showNotification, showTempNotification } from '../../App/Actions';
import { showNotification } from '../../App/Actions';
import { notifExpand, notifMsg } from '../../App/Actions';
import Button from '../../Common/Button/Button';
const styles = require('../../Common/TableCommon/Table.scss');
const showErrorNotification = (title, message, reqBody, error) => {
const showErrorNotification = (title, message, error) => {
let modMessage;
let refreshBtn;
@ -36,7 +36,7 @@ const showErrorNotification = (title, message, reqBody, error) => {
} else {
modMessage = error.code;
}
} else if (error && 'internal' in error) {
} else if (error && 'internal' in error && 'error' in error.internal) {
modMessage = error.code + ' : ' + error.internal.error.message;
} else if (error && 'custom' in error) {
modMessage = error.custom;
@ -146,19 +146,6 @@ const showSuccessNotification = (title, message) => {
};
};
const showTempErrorNotification = (title, message) => {
return dispatch => {
dispatch(
showTempNotification({
level: 'error',
title,
message: message ? message : null,
autoDismiss: 3,
})
);
};
};
const showInfoNotification = title => {
return dispatch => {
dispatch(
@ -170,9 +157,42 @@ const showInfoNotification = title => {
};
};
const showWarningNotification = (title, message, dataObj) => {
const children = [];
if (dataObj) {
children.push(
<div className={styles.aceBlock}>
<AceEditor
readOnly
showPrintMargin={false}
mode="json"
showGutter={false}
theme="github"
name="notification-response"
value={JSON.stringify(dataObj, null, 4)}
minLines={1}
maxLines={15}
width="100%"
/>
</div>
);
}
return dispatch => {
dispatch(
showNotification({
level: 'warning',
title,
message,
children,
})
);
};
};
export {
showErrorNotification,
showSuccessNotification,
showInfoNotification,
showTempErrorNotification,
showWarningNotification,
};

View File

@ -136,7 +136,6 @@ class AddTable extends Component {
showErrorNotification(
'Error creating table!',
'Minimum one column required',
'',
{
custom: ATLEAST_ONE_COLUMN_MSG,
}
@ -155,7 +154,6 @@ class AddTable extends Component {
showErrorNotification(
'Error creating table!',
'Column name cannot be empty',
'',
{
custom: 'Column name cannot be empty',
}
@ -167,7 +165,6 @@ class AddTable extends Component {
showErrorNotification(
gqlColumnErrorNotif[0],
gqlColumnErrorNotif[1],
gqlColumnErrorNotif[2],
gqlColumnErrorNotif[3]
)
);
@ -192,7 +189,6 @@ class AddTable extends Component {
showErrorNotification(
gqlColumnErrorNotif[0],
gqlColumnErrorNotif[1],
gqlColumnErrorNotif[2],
gqlColumnErrorNotif[3]
)
);
@ -214,7 +210,6 @@ class AddTable extends Component {
showErrorNotification(
'Error creating table!',
'Select atleast one primary key',
'',
{
custom: ATLEAST_ONE_PRIMARY_KEY_MSG,
}
@ -233,7 +228,6 @@ class AddTable extends Component {
showErrorNotification(
'Error creating table!',
'Table name cannot be empty',
'',
{
custom: 'Table name cannot be empty. Please add a name',
}
@ -245,7 +239,6 @@ class AddTable extends Component {
showErrorNotification(
gqlTableErrorNotif[0],
gqlTableErrorNotif[1],
gqlTableErrorNotif[2],
gqlTableErrorNotif[3]
)
);

View File

@ -435,34 +435,23 @@ const setTable = tableName => ({ type: SET_TABLE, tableName });
/* **********Shared functions between table actions********* */
const handleMigrationErrors = (title, errorMsg) => dispatch => {
const requestMsg = title;
if (globals.consoleMode === SERVER_CONSOLE_MODE) {
// handle errors for run_sql based workflow
dispatch(showErrorNotification(title, errorMsg.code, requestMsg, errorMsg));
dispatch(showErrorNotification(title, errorMsg.code, errorMsg));
} else if (errorMsg.code === 'migration_failed') {
dispatch(
showErrorNotification(title, 'Migration Failed', requestMsg, errorMsg)
);
dispatch(showErrorNotification(title, 'Migration Failed', errorMsg));
} else if (errorMsg.code === 'data_api_error') {
const parsedErrorMsg = errorMsg;
parsedErrorMsg.message = JSON.parse(errorMsg.message);
dispatch(
showErrorNotification(
title,
parsedErrorMsg.message.error,
requestMsg,
parsedErrorMsg
)
showErrorNotification(title, parsedErrorMsg.message.error, parsedErrorMsg)
);
} else {
// any other unhandled codes
const parsedErrorMsg = errorMsg;
parsedErrorMsg.message = JSON.parse(errorMsg.message);
dispatch(
showErrorNotification(title, errorMsg.code, requestMsg, parsedErrorMsg)
);
dispatch(showErrorNotification(title, errorMsg.code, parsedErrorMsg));
}
// dispatch(showErrorNotification(msg, firstDisplay, request, response));
};
const makeMigrationCall = (
@ -512,7 +501,7 @@ const makeMigrationCall = (
body: JSON.stringify(finalReqBody),
};
const onSuccess = () => {
const onSuccess = data => {
if (!shouldSkipSchemaReload) {
if (globals.consoleMode === 'cli') {
dispatch(loadMigrationStatus()); // don't call for server mode
@ -522,7 +511,7 @@ const makeMigrationCall = (
if (successMsg) {
dispatch(showSuccessNotification(successMsg));
}
customOnSuccess();
customOnSuccess(data, globals.consoleMode, currMigrationMode);
};
const onError = err => {
@ -600,7 +589,6 @@ const fetchColumnTypeInfo = () => {
showErrorNotification(
'Error fetching column types',
'Kindly reach out to us in case you face this issue again',
error,
error
)
);

View File

@ -113,7 +113,6 @@ const executeSQL = (isMigration, migrationName) => (dispatch, getState) => {
showErrorNotification(
'SQL execution failed!',
'Something is wrong. Data sent back an invalid response json.',
requestBody,
parsedErrorMsg
)
);

View File

@ -13,7 +13,6 @@ export const createNewSchema = (schemaName, successCb, errorCb) => {
showErrorNotification(
gqlSchemaErrorNotif[0],
gqlSchemaErrorNotif[1],
gqlSchemaErrorNotif[2],
gqlSchemaErrorNotif[3]
)
);

View File

@ -95,9 +95,7 @@ const editItem = (tableName, colValues) => {
);
},
err => {
dispatch(
showErrorNotification('Edit failed!', err.error, reqBody, err)
);
dispatch(showErrorNotification('Edit failed!', err.error, err));
}
);
};

View File

@ -195,9 +195,7 @@ const deleteItem = pkClause => {
);
},
err => {
dispatch(
showErrorNotification('Deleting row failed!', err.error, reqBody, err)
);
dispatch(showErrorNotification('Deleting row failed!', err.error, err));
}
);
};

View File

@ -100,9 +100,7 @@ const insertItem = (tableName, colValues) => {
);
},
err => {
dispatch(
showErrorNotification('Insert failed!', err.error, reqBody, err)
);
dispatch(showErrorNotification('Insert failed!', err.error, err));
}
);
};

View File

@ -38,7 +38,6 @@ const useColumnEditor = (dispatch, tableName) => {
showErrorNotification(
gqlColumnErrorNotif[0],
gqlColumnErrorNotif[1],
gqlColumnErrorNotif[2],
gqlColumnErrorNotif[3]
)
);
@ -47,7 +46,6 @@ const useColumnEditor = (dispatch, tableName) => {
showErrorNotification(
'Error creating column!',
'Column name/type cannot be empty',
'',
{
custom: 'Column name/type cannot be empty',
}

View File

@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import React from 'react';
import SearchableSelectBox from '../../../Common/SearchableSelect/SearchableSelect';
import CustomInputAutoSuggest from '../../../Common/CustomInputAutoSuggest/CustomInputAutoSuggest';
@ -8,7 +8,6 @@ import { getValidAlterOptions } from './utils';
const ColumnEditor = ({
onSubmit,
dispatch,
columnComment,
columnProperties,
selectedProperties,
editColumn,
@ -23,12 +22,6 @@ const ColumnEditor = ({
const styles = require('./ModifyTable.scss');
useEffect(() => {
if (columnComment) {
dispatch(editColumn(colName, 'comment', columnComment || ''));
}
}, [columnComment]);
const getColumnType = () => {
return (
colName in selectedProperties &&
@ -78,7 +71,7 @@ const ColumnEditor = ({
dispatch(editColumn(colName, 'isUnique', e.target.value === 'true'));
};
const getDefaultInput = () => {
const getColumnDefaultInput = () => {
const theme = require('../../../Common/CustomInputAutoSuggest/CustomThemes/EditColumnDefault.scss');
return (
@ -156,19 +149,7 @@ const ColumnEditor = ({
</div>
<div className={`${styles.display_flex} form-group`}>
<label className="col-xs-2">Default</label>
<div className="col-xs-6">
{getDefaultInput()}
{/*
<input
className="input-sm form-control"
value={selectedProperties[colName].default || ''}
onChange={updateColumnDef}
type="text"
disabled={columnProperties.pkConstraint}
data-test="edit-col-default"
/>
*/}
</div>
<div className="col-xs-6">{getColumnDefaultInput()}</div>
</div>
<div className={`${styles.display_flex} form-group`}>
<label className="col-xs-2">Comment</label>

View File

@ -71,16 +71,17 @@ const ColumnEditorList = ({
: false,
// uniqueConstraint: columnUniqueConstraints[colName],
default: col.column_default || '',
comment: col.comment || '',
};
const onSubmit = () => {
dispatch(saveColumnChangesSql(colName, col));
const onSubmit = toggleEditor => {
dispatch(saveColumnChangesSql(colName, col, toggleEditor));
};
const onDelete = () => {
const isOk = confirm('Are you sure you want to delete?');
if (isOk) {
dispatch(deleteColumnSql(tableName, colName, col));
dispatch(deleteColumnSql(col, tableSchema));
}
};
@ -91,11 +92,13 @@ const ColumnEditorList = ({
}
const isOk = window.confirm(confirmMessage);
if (isOk) {
dispatch(deleteColumnSql(tableName, colName, col));
dispatch(deleteColumnSql(col, tableSchema));
}
};
const keyProperties = () => {
const propertiesDisplay = [];
const propertiesList = [];
propertiesList.push(columnProperties.display_type_name);
@ -118,7 +121,17 @@ const ColumnEditorList = ({
const keyPropertiesString = propertiesList.join(', ');
return <i>{keyPropertiesString && `- ${keyPropertiesString}`}</i>;
propertiesDisplay.push(
<i key={'props'}>{keyPropertiesString && `- ${keyPropertiesString}`}</i>
);
propertiesDisplay.push(<br />);
propertiesDisplay.push(
<span key={'comment'} className={styles.text_gray}>
{columnProperties.comment && `${columnProperties.comment}`}
</span>
);
return propertiesDisplay;
};
const collapsedLabel = () => {
@ -192,7 +205,6 @@ const ColumnEditorList = ({
tableName={tableName}
dispatch={dispatch}
currentSchema={currentSchema}
columnComment={col.comment}
columnProperties={columnProperties}
selectedProperties={columnEdit}
editColumn={editColumn}

View File

@ -11,6 +11,7 @@ import { SET_SQL } from '../RawSQL/Actions';
import {
showErrorNotification,
showSuccessNotification,
showWarningNotification,
} from '../../Common/Notification';
import dataHeaders from '../Common/Headers';
import { UPDATE_MIGRATION_STATUS_ERROR } from '../../../Main/Actions';
@ -497,7 +498,6 @@ const changeTableOrViewName = (isTable, oldName, newName) => {
showErrorNotification(
gqlValidationError[4],
gqlValidationError[1],
gqlValidationError[2],
gqlValidationError[3]
)
);
@ -750,12 +750,7 @@ const fetchViewDefinition = (viewName, isRedirect) => {
},
err => {
dispatch(
showErrorNotification(
'Fetching definition failed!',
err.error,
reqBody,
err
)
showErrorNotification('Fetching definition failed!', err.error, err)
);
}
);
@ -808,61 +803,191 @@ const deleteViewSql = viewName => {
};
};
const deleteColumnSql = (tableName, colName) => {
const deleteColumnSql = (column, tableSchema) => {
return (dispatch, getState) => {
const currentSchema = getState().tables.currentSchema;
const deleteQueryUp =
'ALTER TABLE ' +
'"' +
currentSchema +
'"' +
'.' +
'"' +
tableName +
'"' +
' DROP COLUMN ' +
'"' +
colName +
'"';
const name = column.column_name;
const tableName = column.table_name;
const currentSchema = column.table_schema;
const comment = column.comment;
const is_nullable = column.is_nullable;
const col_type = column.udt_name;
const foreign_key_constraints = tableSchema.foreign_key_constraints.filter(
fkc => {
const columnKeys = Object.keys(fkc.column_mapping);
return columnKeys.includes(name);
}
);
const opp_foreign_key_constraints = tableSchema.opp_foreign_key_constraints.filter(
fkc => {
const columnKeys = Object.values(fkc.column_mapping);
return columnKeys.includes(name);
}
);
const unique_constraints = tableSchema.unique_constraints.filter(uc =>
uc.columns.includes(name)
);
const alterStatement =
'ALTER TABLE ' + '"' + currentSchema + '"' + '.' + '"' + tableName + '" ';
const schemaChangesUp = [
{
type: 'run_sql',
args: {
sql: deleteQueryUp,
sql: alterStatement + 'DROP COLUMN ' + '"' + name + '" CASCADE',
},
},
];
const schemaChangesDown = [];
/*
const schemaChangesDown = [{
schemaChangesDown.push({
type: 'run_sql',
args: {
'sql': deleteQueryDown
}
}];
*/
sql: alterStatement + 'ADD COLUMN ' + '"' + name + '"' + ' ' + col_type,
},
});
if (is_nullable) {
schemaChangesDown.push({
type: 'run_sql',
args: {
sql:
alterStatement +
'ALTER COLUMN ' +
'"' +
name +
'" ' +
'DROP NOT NULL',
},
});
} else {
schemaChangesDown.push({
type: 'run_sql',
args: {
sql:
alterStatement +
'ALTER COLUMN ' +
'"' +
name +
'" ' +
'SET NOT NULL',
},
});
}
const merged_fkc = foreign_key_constraints.concat(opp_foreign_key_constraints);
if (merged_fkc.length > 0) {
merged_fkc.forEach(fkc => {
// add foreign key constraint to down migration
const lcol = Object.keys(fkc.column_mapping);
const rcol = Object.values(fkc.column_mapping);
const onUpdate = pgConfTypes[fkc.on_update];
const onDelete = pgConfTypes[fkc.on_delete];
schemaChangesDown.push({
type: 'run_sql',
args: {
sql:
alterStatement +
'ADD CONSTRAINT ' +
`${fkc.constraint_name} ` +
'FOREIGN KEY ' +
`(${lcol.join(', ')}) ` +
'REFERENCES ' +
`"${fkc.ref_table_table_schema}"."${fkc.ref_table}" ` +
`(${rcol.join(', ')}) ` +
`ON DELETE ${onDelete} ` +
`ON UPDATE ${onUpdate}`,
},
});
});
}
if (unique_constraints.length > 0) {
unique_constraints.forEach(uc => {
// add unique constraint to down migration
schemaChangesDown.push({
type: 'run_sql',
args: {
sql:
alterStatement +
'ADD CONSTRAINT ' +
`${uc.constraint_name} ` +
'UNIQUE ' +
`(${uc.columns.join(', ')})`,
},
});
});
}
if (column.column_default !== null) {
// add column default to down migration
schemaChangesDown.push({
type: 'run_sql',
args: {
sql:
alterStatement +
'ALTER COLUMN ' +
`"${name}" ` +
'SET DEFAULT ' +
column.column_default,
},
});
}
// COMMENT ON COLUMN my_table.my_column IS 'Employee ID number';
if (comment) {
schemaChangesDown.push({
type: 'run_sql',
args: {
sql:
'COMMENT ON COLUMN ' +
'"' +
currentSchema +
'"' +
'.' +
'"' +
tableName +
'"' +
'.' +
'"' +
name +
'"' +
' ' +
'IS ' +
"'" +
comment +
"'",
},
});
}
// Apply migrations
const migrationName =
'alter_table_' +
currentSchema +
'_' +
tableName +
'_drop_column_' +
colName;
'alter_table_' + currentSchema + '_' + tableName + '_drop_column_' + name;
const requestMsg = 'Deleting Column...';
const successMsg = 'Column deleted';
const errorMsg = 'Deleting column failed';
const customOnSuccess = () => {};
const customOnSuccess = (data, consoleMode, migrationMode) => {
if (consoleMode === 'cli' && migrationMode) {
// show warning information
dispatch(
showWarningNotification(
'Check down migration',
'Please verify that the down migration will reset the DB to the previous state (you ' +
'might need to add recreation of some dependent objects like indexes, etc.)',
data
)
);
}
};
const customOnError = () => {};
makeMigrationCall(
dispatch,
getState,
schemaChangesUp,
[],
schemaChangesDown,
migrationName,
customOnSuccess,
customOnError,
@ -1159,7 +1284,7 @@ const isColumnUnique = (tableSchema, colName) => {
);
};
const saveColumnChangesSql = (colName, column) => {
const saveColumnChangesSql = (colName, column, onSuccess) => {
// eslint-disable-line no-unused-vars
return (dispatch, getState) => {
const columnEdit = getState().tables.modify.columnEdit[colName];
@ -1663,7 +1788,6 @@ const saveColumnChangesSql = (colName, column) => {
showErrorNotification(
gqlColumnErrorNotif[4],
gqlColumnErrorNotif[1],
gqlColumnErrorNotif[2],
gqlColumnErrorNotif[3]
)
);
@ -1696,7 +1820,8 @@ const saveColumnChangesSql = (colName, column) => {
const errorMsg = 'Modifying column failed';
const customOnSuccess = () => {
dispatch(setColumnEdit(columnEdit));
dispatch(resetColumnEdit(colName));
onSuccess();
};
const customOnError = () => {};
@ -1750,7 +1875,6 @@ const fetchColumnCasts = () => {
showErrorNotification(
'Error fetching column casts information',
'Kindly reach out to us in case you face this issue again',
error,
error
)
);

View File

@ -371,7 +371,6 @@ const addRelViewMigrate = (tableSchema, toggleEditor) => (
showErrorNotification(
'Error adding relationship!',
'Please select a name for the relationship',
'',
{ custom: 'Relationship name cannot be empty' }
)
);
@ -380,7 +379,6 @@ const addRelViewMigrate = (tableSchema, toggleEditor) => (
showErrorNotification(
gqlRelErrorNotif[0],
gqlRelErrorNotif[1],
gqlRelErrorNotif[2],
gqlRelErrorNotif[3]
)
);

View File

@ -52,7 +52,6 @@ class RelationshipEditor extends React.Component {
showErrorNotification(
gqlRelErrorNotif[4],
gqlRelErrorNotif[1],
gqlRelErrorNotif[2],
gqlRelErrorNotif[3]
)
);

View File

@ -52,7 +52,6 @@ const addRelationshipCellView = (
showErrorNotification(
'Error adding relationship!',
'Please select a name for the relationship',
'',
{ custom: 'Relationship name cannot be empty' }
)
);
@ -62,7 +61,6 @@ const addRelationshipCellView = (
showErrorNotification(
gqlRelErrorNotif[0],
gqlRelErrorNotif[1],
gqlRelErrorNotif[2],
gqlRelErrorNotif[3]
)
);

View File

@ -1,7 +1,7 @@
import defaultState from './AddState';
import _push from '../push';
import { loadTriggers, makeMigrationCall, setTrigger } from '../EventActions';
import { showSuccessNotification } from '../Notification';
import { showSuccessNotification } from '../../Common/Notification';
import { UPDATE_MIGRATION_STATUS_ERROR } from '../../../Main/Actions';
import { updateSchemaInfo } from '../../Data/DataActions';

View File

@ -27,7 +27,7 @@ import {
loadTableList,
} from './AddActions';
import { listDuplicate } from '../../../../utils/data';
import { showErrorNotification } from '../Notification';
import { showErrorNotification } from '../../Common/Notification';
import { createTrigger } from './AddActions';
import DropdownButton from '../../../Common/DropdownButton/DropdownButton';
@ -146,7 +146,7 @@ class AddTrigger extends Component {
this.props.dispatch(createTrigger());
} else {
this.props.dispatch(
showErrorNotification('Error creating trigger!', errorMsg, '', {
showErrorNotification('Error creating trigger!', errorMsg, {
custom: customMsg,
})
);

View File

@ -5,7 +5,10 @@ import processedEventsReducer from './ProcessedEvents/ViewActions';
import pendingEventsReducer from './PendingEvents/ViewActions';
import runningEventsReducer from './RunningEvents/ViewActions';
import streamingLogsReducer from './StreamingLogs/LogActions';
import { showErrorNotification, showSuccessNotification } from './Notification';
import {
showSuccessNotification,
showErrorNotification,
} from '../Common/Notification';
import dataHeaders from './Common/Headers';
import { loadMigrationStatus } from '../../Main/Actions';
import returnMigrateUrl from './Common/getMigrateUrl';
@ -317,34 +320,23 @@ const setRedeliverEvent = eventId => dispatch => {
/* **********Shared functions between table actions********* */
const handleMigrationErrors = (title, errorMsg) => dispatch => {
const requestMsg = title;
if (globals.consoleMode === SERVER_CONSOLE_MODE) {
// handle errors for run_sql based workflow
dispatch(showErrorNotification(title, errorMsg.code, requestMsg, errorMsg));
dispatch(showErrorNotification(title, errorMsg.code, errorMsg));
} else if (errorMsg.code === 'migration_failed') {
dispatch(
showErrorNotification(title, 'Migration Failed', requestMsg, errorMsg)
);
dispatch(showErrorNotification(title, 'Migration Failed', errorMsg));
} else if (errorMsg.code === 'data_api_error') {
const parsedErrorMsg = errorMsg;
parsedErrorMsg.message = JSON.parse(errorMsg.message);
dispatch(
showErrorNotification(
title,
parsedErrorMsg.message.error,
requestMsg,
parsedErrorMsg
)
showErrorNotification(title, parsedErrorMsg.message.error, parsedErrorMsg)
);
} else {
// any other unhandled codes
const parsedErrorMsg = errorMsg;
parsedErrorMsg.message = JSON.parse(errorMsg.message);
dispatch(
showErrorNotification(title, errorMsg.code, requestMsg, parsedErrorMsg)
);
dispatch(showErrorNotification(title, errorMsg.code, parsedErrorMsg));
}
// dispatch(showErrorNotification(msg, firstDisplay, request, response));
};
const makeMigrationCall = (

View File

@ -1,7 +1,7 @@
import defaultState from './State';
import { loadTriggers, makeMigrationCall, setTrigger } from '../EventActions';
import { UPDATE_MIGRATION_STATUS_ERROR } from '../../../Main/Actions';
import { showErrorNotification } from '../Notification';
import { showErrorNotification } from '../../Common/Notification';
import { MANUAL_TRIGGER_VAR } from './utils';
@ -70,7 +70,7 @@ export const REQUEST_COMPLETE = 'ModifyTrigger/REQUEST_COMPLETE';
export const showValidationError = message => {
return dispatch => {
dispatch(
showErrorNotification('Error modifying trigger!', 'Invalid input', '', {
showErrorNotification('Error modifying trigger!', 'Invalid input', {
custom: message,
})
);

View File

@ -1,178 +0,0 @@
import React from 'react';
import AceEditor from 'react-ace';
import { showNotification, showTempNotification } from '../../App/Actions';
import { notifExpand, notifMsg } from '../../App/Actions';
import Button from '../../Common/Button/Button';
const styles = require('../../Common/TableCommon/Table.scss');
const showErrorNotification = (title, message, reqBody, error) => {
let modMessage;
let refreshBtn;
if (
error &&
error.message &&
(error.message.error === 'postgres query error' ||
error.message.error === 'query execution failed')
) {
if (error.message.internal) {
modMessage =
error.message.code + ': ' + error.message.internal.error.message;
} else {
modMessage = error.code + ': ' + error.message.error;
}
} else if (error && 'info' in error) {
modMessage = error.info;
} else if (error && 'message' in error) {
if (error.code) {
if (error.message.error) {
modMessage = error.message.error.message;
} else {
modMessage = error.message;
}
} else if (error && error.message && 'code' in error.message) {
modMessage = error.message.code + ' : ' + message;
} else {
modMessage = error.code;
}
} else if (error && 'internal' in error) {
modMessage = error.code + ' : ' + error.internal.error.message;
} else if (error && 'custom' in error) {
modMessage = error.custom;
} else if (error && 'code' in error && 'error' in error && 'path' in error) {
// Data API error
modMessage = error.error;
} else {
modMessage = error ? error : message;
}
let finalJson = error ? error.message : '{}';
if (error && 'action' in error) {
refreshBtn = (
<Button
className={styles.add_mar_top_small}
color="yellow"
size="sm"
onClick={e => {
e.preventDefault();
window.location.reload();
}}
>
Refresh Console
</Button>
);
finalJson = error.action;
} else if (error && 'internal' in error) {
finalJson = error.internal;
}
return dispatch => {
const expandClicked = finalMsg => {
// trigger a modal with a bigger view
dispatch(notifExpand(true));
dispatch(notifMsg(JSON.stringify(finalMsg, null, 4)));
};
const getNotificationAction = () => {
let action = null;
if (reqBody) {
const notification = [
<div className={styles.aceBlock}>
<i
onClick={e => {
e.preventDefault();
expandClicked(finalJson);
}}
className={styles.aceBlockExpand + ' fa fa-expand'}
/>
<AceEditor
readOnly
showPrintMargin={false}
mode="json"
showGutter={false}
theme="github"
name="notification-response"
value={JSON.stringify(finalJson, null, 4)}
minLines={1}
maxLines={15}
width="100%"
/>
{refreshBtn}
</div>,
];
action = {
label: 'Details',
callback: () => {
dispatch(
showNotification({
level: 'error',
title,
message: modMessage,
dismissible: 'button',
children: notification,
})
);
},
};
}
return action;
};
dispatch(
showNotification({
level: 'error',
title,
message: modMessage,
action: getNotificationAction(),
})
);
};
};
const showSuccessNotification = (title, message) => {
return dispatch => {
dispatch(
showNotification({
level: 'success',
title,
message: message ? message : null,
})
);
};
};
const showTempErrorNotification = (title, message) => {
return dispatch => {
dispatch(
showTempNotification({
level: 'error',
title,
message: message ? message : null,
autoDismiss: 3,
})
);
};
};
const showInfoNotification = title => {
return dispatch => {
dispatch(
showNotification({
title,
autoDismiss: 0,
})
);
};
};
export {
showErrorNotification,
showSuccessNotification,
showInfoNotification,
showTempErrorNotification,
};

View File

@ -6,7 +6,7 @@ import { findTableFromRel } from '../utils';
import {
showSuccessNotification,
showErrorNotification,
} from '../Notification';
} from '../../Common/Notification';
import dataHeaders from '../Common/Headers';
/* ****************** View actions *************/
@ -192,9 +192,7 @@ const deleteItem = pkClause => {
);
},
err => {
dispatch(
showErrorNotification('Deleting row failed!', err.error, reqBody, err)
);
dispatch(showErrorNotification('Deleting row failed!', err.error, err));
}
);
};

View File

@ -306,7 +306,6 @@ export const addAllowedQueries = (queries, isEmptyList, callback) => {
showErrorNotification(
'Adding query to allow-list failed',
null,
null,
error
)
);
@ -338,7 +337,6 @@ export const deleteAllowList = () => {
showErrorNotification(
'Deleting queries from allow-list failed',
null,
null,
error
)
);
@ -372,7 +370,6 @@ export const deleteAllowedQuery = (queryName, isLastQuery) => {
showErrorNotification(
'Deleting query from allow-list failed',
null,
null,
error
)
);
@ -399,12 +396,7 @@ export const updateAllowedQuery = (queryName, newQuery) => {
error => {
console.error(error);
dispatch(
showErrorNotification(
'Updating allow-list query failed',
null,
null,
error
)
showErrorNotification('Updating allow-list query failed', null, error)
);
}
);

View File

@ -63,7 +63,6 @@ class ExportMetadata extends Component {
showErrorNotification(
'Metadata export failed',
'Something is wrong.',
requestBody,
parsedErrorMsg
)
);

View File

@ -63,7 +63,6 @@ class ImportMetadata extends Component {
showErrorNotification(
'Metadata import failed',
'Something is wrong.',
requestBody,
parsedErrorMsg
)
);

View File

@ -66,7 +66,6 @@ class ResetMetadata extends Component {
showErrorNotification(
'Metadata reset failed',
'Something went wrong.',
requestBody,
parsedErrorMsg
)
);