diff --git a/console/src/components/Services/Data/Metadata/Metadata.js b/console/src/components/Services/Data/Metadata/Metadata.js
index bc57d1b51534f..09f1a3351a5d0 100644
--- a/console/src/components/Services/Data/Metadata/Metadata.js
+++ b/console/src/components/Services/Data/Metadata/Metadata.js
@@ -89,48 +89,48 @@ class Metadata extends Component {
{this.state.showMetadata
? [
-
-
Reload metadata
-
+
+
Reload metadata
+
Refresh Hasura metadata, typically required if you have
changed the underlying postgres.
-
-
,
-
-
-
,
-
,
+
+
+
,
+
+
Reset Metadata
+
Permanently clear GraphQL Engine's metadata and configure it
from scratch (tracking relevant tables and relationships).
This process is not reversible.
-
-
,
-
-
-
,
- ]
+
+
,
+
+
+
,
+ ]
: null}
{window.localStorage.CONSOLE_ACCESS_KEY
? [
-
-
Clear access key (logout)
-
+
+
Clear access key (logout)
+
The console caches the access key (HASURA_GRAPHQL_ACCESS_KEY)
in the browser. You can clear this cache to force a prompt for
the access key when the console is accessed next using this
browser.
-
-
,
-
-
-
,
- ]
+
+
,
+
+
+
,
+ ]
: null}
);
diff --git a/console/src/components/Services/Data/RawSQL/Actions.js b/console/src/components/Services/Data/RawSQL/Actions.js
index 7bcb5853fd3db..d92fcc449902e 100644
--- a/console/src/components/Services/Data/RawSQL/Actions.js
+++ b/console/src/components/Services/Data/RawSQL/Actions.js
@@ -49,7 +49,7 @@ const executeSQL = (isMigration, migrationName) => (dispatch, getState) => {
const regExp = /create (view|table) ((\"?\w+\"?)\.(\"?\w+\"?)|(\"?\w+\"?))/; // eslint-disable-line
const matches = sql.match(new RegExp(regExp, 'gmi'));
if (matches) {
- matches.forEach((element) => {
+ matches.forEach(element => {
const itemMatch = element.match(new RegExp(regExp, 'i'));
if (itemMatch && itemMatch.length === 6) {
const trackQuery = {
@@ -66,8 +66,12 @@ const executeSQL = (isMigration, migrationName) => (dispatch, getState) => {
trackQuery.args.schema = itemMatch[3];
}
// replace and trim schema and table name
- trackQuery.args.name = trackQuery.args.name.replace(/['"]+/g, '').trim();
- trackQuery.args.schema = trackQuery.args.schema.replace(/['"]+/g, '').trim();
+ trackQuery.args.name = trackQuery.args.name
+ .replace(/['"]+/g, '')
+ .trim();
+ trackQuery.args.schema = trackQuery.args.schema
+ .replace(/['"]+/g, '')
+ .trim();
schemaChangesUp.push(trackQuery);
}
});
diff --git a/console/src/components/Services/Data/TablePermissions/Permissions.js b/console/src/components/Services/Data/TablePermissions/Permissions.js
index e1561759112d5..e304a515693d5 100644
--- a/console/src/components/Services/Data/TablePermissions/Permissions.js
+++ b/console/src/components/Services/Data/TablePermissions/Permissions.js
@@ -253,21 +253,21 @@ class Permissions extends Component {
const bulkSelect = permsState.bulkSelect;
const currentInputSelection = bulkSelect.filter(e => e === role)
.length ? (
-
- ) : (
-
- );
+
+ ) : (
+
+ );
_permissionsRowHtml.push(
diff --git a/console/src/components/Services/EventTrigger/Add/AddActions.js b/console/src/components/Services/EventTrigger/Add/AddActions.js
index 452894fe9bd1a..e696531deb8b4 100644
--- a/console/src/components/Services/EventTrigger/Add/AddActions.js
+++ b/console/src/components/Services/EventTrigger/Add/AddActions.js
@@ -27,6 +27,11 @@ const UPDATE_TABLE_LIST = 'AddTrigger/UPDATE_TABLE_LIST';
const TOGGLE_COLUMNS = 'AddTrigger/TOGGLE_COLUMNS';
const TOGGLE_QUERY_TYPE_SELECTED = 'AddTrigger/TOGGLE_QUERY_TYPE_SELECTED';
const TOGGLE_QUERY_TYPE_DESELECTED = 'AddTrigger/TOGGLE_QUERY_TYPE_DESELECTED';
+const REMOVE_HEADER = 'AddTrigger/REMOVE_HEADER';
+const SET_HEADERKEY = 'AddTrigger/SET_HEADERKEY';
+const SET_HEADERTYPE = 'AddTrigger/SET_HEADERTYPE';
+const SET_HEADERVALUE = 'AddTrigger/SET_HEADERVALUE';
+const ADD_HEADER = 'AddTrigger/ADD_HEADER';
const setTriggerName = value => ({ type: SET_TRIGGERNAME, value });
const setTableName = value => ({ type: SET_TABLENAME, value });
@@ -35,6 +40,24 @@ const setWebhookURL = value => ({ type: SET_WEBHOOK_URL, value });
const setRetryNum = value => ({ type: SET_RETRY_NUM, value });
const setRetryInterval = value => ({ type: SET_RETRY_INTERVAL, value });
const setDefaults = () => ({ type: SET_DEFAULTS });
+const addHeader = () => ({ type: ADD_HEADER });
+const removeHeader = i => ({ type: REMOVE_HEADER, index: i });
+const setHeaderKey = (key, index) => ({
+ type: SET_HEADERKEY,
+ key,
+ index,
+});
+const setHeaderType = (headerType, index) => ({
+ type: SET_HEADERTYPE,
+ headerType,
+ index,
+});
+const setHeaderValue = (headerValue, index) => ({
+ type: SET_HEADERVALUE,
+ headerValue,
+ index,
+});
+
// General error during validation.
// const validationError = (error) => ({type: VALIDATION_ERROR, error: error});
const validationError = error => {
@@ -82,6 +105,19 @@ const createTrigger = () => {
if (currentState.retryConf) {
payload.args.retry_conf = currentState.retryConf;
}
+
+ // create header payload
+ const headers = [];
+ currentState.headers.map(header => {
+ if (header.key !== '' && header.type !== '') {
+ if (header.type === 'static') {
+ headers.push({ name: header.key, value: header.value });
+ } else if (header.type === 'env') {
+ headers.push({ name: header.key, value_from_env: header.value });
+ }
+ }
+ });
+ payload.args.headers = headers;
const upQueryArgs = [];
upQueryArgs.push(payload);
const downQueryArgs = [];
@@ -196,6 +232,49 @@ const setOperationSelection = (type, isChecked) => {
const addTriggerReducer = (state = defaultState, action) => {
switch (action.type) {
+ case ADD_HEADER:
+ return {
+ ...state,
+ headers: [...state.headers, { key: '', type: '', value: '' }],
+ };
+ case REMOVE_HEADER:
+ return {
+ ...state,
+ headers: [
+ ...state.headers.slice(0, action.index),
+ ...state.headers.slice(action.index + 1),
+ ],
+ };
+ case SET_HEADERKEY:
+ const i = action.index;
+ return {
+ ...state,
+ headers: [
+ ...state.headers.slice(0, i),
+ { ...state.headers[i], key: action.key },
+ ...state.headers.slice(i + 1),
+ ],
+ };
+ case SET_HEADERTYPE:
+ const ij = action.index;
+ return {
+ ...state,
+ headers: [
+ ...state.headers.slice(0, ij),
+ { ...state.headers[ij], type: action.headerType },
+ ...state.headers.slice(ij + 1),
+ ],
+ };
+ case SET_HEADERVALUE:
+ const ik = action.index;
+ return {
+ ...state,
+ headers: [
+ ...state.headers.slice(0, ik),
+ { ...state.headers[ik], value: action.headerValue },
+ ...state.headers.slice(ik + 1),
+ ],
+ };
case SET_DEFAULTS:
return {
...defaultState,
@@ -280,6 +359,11 @@ const addTriggerReducer = (state = defaultState, action) => {
export default addTriggerReducer;
export {
+ addHeader,
+ setHeaderKey,
+ setHeaderValue,
+ setHeaderType,
+ removeHeader,
setTriggerName,
setTableName,
setSchemaName,
diff --git a/console/src/components/Services/EventTrigger/Add/AddState.js b/console/src/components/Services/EventTrigger/Add/AddState.js
index a698c35a83082..e3f692ba5ed31 100644
--- a/console/src/components/Services/EventTrigger/Add/AddState.js
+++ b/console/src/components/Services/EventTrigger/Add/AddState.js
@@ -11,6 +11,7 @@ const defaultState = {
lastError: null,
internalError: null,
lastSuccess: null,
+ headers: [{ key: '', type: '', value: '' }],
};
export default defaultState;
diff --git a/console/src/components/Services/EventTrigger/Add/AddTrigger.js b/console/src/components/Services/EventTrigger/Add/AddTrigger.js
index 75dc32cb7e3a0..ee5af1a146e6b 100644
--- a/console/src/components/Services/EventTrigger/Add/AddTrigger.js
+++ b/console/src/components/Services/EventTrigger/Add/AddTrigger.js
@@ -5,6 +5,11 @@ import * as tooltip from './Tooltips';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
import {
+ removeHeader,
+ setHeaderKey,
+ setHeaderValue,
+ setHeaderType,
+ addHeader,
setTriggerName,
setTableName,
setSchemaName,
@@ -16,6 +21,7 @@ import {
setOperationSelection,
setDefaults,
} from './AddActions';
+import { listDuplicate } from '../../../../utils/data';
import { showErrorNotification } from '../Notification';
import { createTrigger } from './AddActions';
import { fetchTableListBySchema } from './AddActions';
@@ -80,6 +86,27 @@ class AddTrigger extends Component {
customMsg =
'Please select a minimum of one column for update operation';
}
+ } else if (this.props.headers.length === 1) {
+ if (this.props.headers[0].key !== '') {
+ // let the default value through and ignore it while querying?
+ // Need a better method
+ if (this.props.headers[0].type === '') {
+ isValid = false;
+ errorMsg = 'No type selected for trigger header';
+ customMsg = 'Please select a type for the trigger header';
+ }
+ }
+ } else if (this.props.headers.length > 1) {
+ // repitition check
+ const repeatList = listDuplicate(
+ this.props.headers.map(header => header.key)
+ );
+ if (repeatList.length > 0) {
+ isValid = false;
+ errorMsg = 'Duplicate entries in trigger headers';
+ customMsg = `You have the following column names repeated: [${repeatList}]`;
+ }
+ // Check for empty header keys and key/value validation?
}
if (isValid) {
this.props.dispatch(createTrigger());
@@ -107,6 +134,7 @@ class AddTrigger extends Component {
lastError,
lastSuccess,
internalError,
+ headers,
} = this.props;
const styles = require('../TableCommon/Table.scss');
let createBtnText = 'Create';
@@ -188,6 +216,72 @@ class AddTrigger extends Component {
return null;
};
+ const heads = headers.map((header, i) => {
+ let removeIcon;
+ if (i + 1 === headers.length) {
+ removeIcon =
;
+ } else {
+ removeIcon = (
+
{
+ dispatch(removeHeader(i));
+ }}
+ />
+ );
+ }
+ return (
+
+ {
+ dispatch(setHeaderKey(e.target.value, i));
+ }}
+ data-test={`header-${i}`}
+ />
+ {
+ dispatch(setHeaderType(e.target.value, i));
+ if (i + 1 === headers.length) {
+ dispatch(addHeader());
+ }
+ }}
+ data-test={`header-type-${i}`}
+ >
+ {header.type === '' ? (
+
+ -- value type --
+
+ ) : null}
+
+ static
+
+
+ from env variable
+
+ {' '}
+ {
+ dispatch(setHeaderValue(e.target.value, i));
+ }}
+ data-test={`header-value-${i}`}
+ />{' '}
+ {removeIcon}
+
+ );
+ });
+
return (
+
+
Headers
+ {heads}
+
) : null}
diff --git a/console/src/components/Services/EventTrigger/Settings/Settings.js b/console/src/components/Services/EventTrigger/Settings/Settings.js
index 5d33492ba2e78..20ec339d9cda6 100644
--- a/console/src/components/Services/EventTrigger/Settings/Settings.js
+++ b/console/src/components/Services/EventTrigger/Settings/Settings.js
@@ -70,6 +70,25 @@ class Settings extends Component {
{triggerSchema.retry_interval > 1 ? 'seconds' : 'second'}
+ {'headers' in triggerSchema ? (
+
+ Headers
+
+
+
+
+ ) : null}
Operation / Columns
@@ -83,6 +102,7 @@ class Settings extends Component {
width="100%"
showPrintMargin={false}
showGutter={false}
+ readOnly
/>