change default endpoint to v1/graphql; remove semver checks (#2181)

This commit is contained in:
Rishichandra Wawhal 2019-05-16 14:38:44 +05:30 committed by Shahidh K Muhammed
parent 76ceb707f4
commit 3ef1219fa0
45 changed files with 409 additions and 1157 deletions

View File

@ -78,6 +78,7 @@
"jsx-a11y/anchor-is-valid": 0,
"jsx-a11y/lang": 0,
"jsx-a11y/alt-text": 0,
"jsx-a11y/no-autofocus": 0,
"max-len": 0,
"no-continue": 0
},

View File

@ -15,7 +15,7 @@
"start": "concurrently --kill-others \"npm run start-prod\"",
"start-prod": "better-npm-run start-prod",
"build": "webpack --progress -p --colors --display-error-details --config webpack/prod.config.js",
"server-build": "npm run build && mkdir -p static/dist/versioned && cp static/dist/*.js static/dist/*.css static/dist/versioned/ && gzip -r static/dist/versioned",
"server-build": "npm run build && mkdir -p static/dist/versioned && cp static/dist/*.js static/dist/*.css static/dist/versioned/ && gzip -r -f static/dist/versioned",
"build-unused": "webpack --verbose --colors --display-error-details --config webpack/prod.config.js --json | webpack-unused -s src",
"postinstall": "webpack --display-error-details --config webpack/prod.config.js",
"lint": "eslint -c .eslintrc src api",

View File

@ -8,7 +8,7 @@ const hasuractlUrl = hasuractlApiHost + ':' + hasuractlApiPort;
const Endpoints = {
getSchema: `${baseUrl}/v1/query`,
graphQLUrl: `${baseUrl}/v1alpha1/graphql`,
graphQLUrl: `${baseUrl}/v1/graphql`,
schemaChange: `${baseUrl}/v1/query`,
query: `${baseUrl}/v1/query`,
rawSQL: `${baseUrl}/v1/query`,

View File

@ -19,7 +19,7 @@ class ErrorBoundary extends React.Component {
this.setState({ hasError: true, info: info, error: error });
// TODO logErrorToMyService(error, info);
const { dispatch } = this.props;
dispatch(loadInconsistentObjects(null, true)).then(() => {
dispatch(loadInconsistentObjects(true)).then(() => {
if (this.props.metadata.inconsistentObjects.length > 0) {
if (!window.location.pathname.includes('/metadata/status')) {
this.setState({ hasError: false, info: null, error: null });

View File

@ -10,6 +10,7 @@ import {
ADMIN_SECRET_ERROR,
UPDATE_DATA_HEADERS,
} from '../Services/Data/DataActions';
import semverCheck, { componentsSemver } from '../../helpers/semver';
import { changeRequestHeader } from '../Services/ApiExplorer/Actions';
const SET_MIGRATION_STATUS_SUCCESS = 'Main/SET_MIGRATION_STATUS_SUCCESS';
@ -30,6 +31,26 @@ const UPDATE_ADMIN_SECRET_INPUT = 'Main/UPDATE_ADMIN_SECRET_INPUT';
const LOGIN_IN_PROGRESS = 'Main/LOGIN_IN_PROGRESS';
const LOGIN_ERROR = 'Main/LOGIN_ERROR';
const SET_SEMVER = 'Main/SET_SEMVER';
const setSemverBulk = data => ({
type: SET_SEMVER,
data,
});
const semverInit = () => {
return (dispatch, getState) => {
const { serverVersion } = getState().main;
if (!serverVersion) {
return;
}
const semverObj = {};
Object.keys(componentsSemver).forEach(feature => {
semverObj[feature] = semverCheck(feature, serverVersion);
});
return dispatch(setSemverBulk(semverObj));
};
};
const loadMigrationStatus = () => dispatch => {
const url = Endpoints.hasuractlMigrateSettings;
const options = {
@ -237,7 +258,6 @@ const mainReducer = (state = defaultState, action) => {
...state,
serverVersion: null,
};
case SET_LATEST_SERVER_VERSION_SUCCESS:
return {
...state,
@ -285,7 +305,11 @@ const mainReducer = (state = defaultState, action) => {
return { ...state, loginInProgress: action.data };
case LOGIN_ERROR:
return { ...state, loginError: action.data };
case SET_SEMVER:
return {
...state,
semver: { ...action.data },
};
default:
return state;
}
@ -305,4 +329,5 @@ export {
validateLogin,
loadServerVersion,
checkServerUpdates,
semverInit,
};

View File

@ -6,10 +6,9 @@ import globals from '../../Globals';
import * as tooltip from './Tooltips';
import 'react-toggle/style.css';
import Spinner from '../Common/Spinner/Spinner';
import { loadServerVersion, checkServerUpdates } from './Actions';
import { loadServerVersion, checkServerUpdates, semverInit } from './Actions';
import { loadConsoleOpts } from '../../telemetry/Actions.js';
import './NotificationOverrides.css';
import semverCheck from '../../helpers/semver';
import {
loadInconsistentObjects,
redirectToMetadataStatus,
@ -27,23 +26,28 @@ class Main extends React.Component {
super(props);
this.state = {
showBannerNotification: false,
showEvents: false,
showSchemaStitch: false,
};
this.state.loveConsentState = getLoveConsentState();
this.handleBodyClick = this.handleBodyClick.bind(this);
}
componentDidMount() {
const { dispatch } = this.props;
document
.querySelector('body')
.addEventListener('click', this.handleBodyClick);
dispatch(loadServerVersion()).then(() => {
dispatch(loadInconsistentObjects(this.props.serverVersion)).then(() => {
dispatch(semverInit());
dispatch(loadInconsistentObjects()).then(() => {
this.handleMetadataRedirect();
});
dispatch(loadConsoleOpts());
dispatch(checkServerUpdates()).then(() => {
let isUpdateAvailable = false;
try {
@ -66,29 +70,9 @@ class Main extends React.Component {
console.error(e);
}
});
this.checkEventsTab().then(() => {
this.checkSchemaStitch();
});
});
}
checkSchemaStitch() {
const showSchemaStitch = semverCheck(
'schemaStitching',
this.props.serverVersion
);
if (showSchemaStitch) {
this.setState({ showSchemaStitch: true });
}
return Promise.resolve();
}
checkEventsTab() {
const showEvents = semverCheck('eventsTab', this.props.serverVersion);
if (showEvents) {
this.setState({ showEvents: true });
}
return Promise.resolve();
}
handleBodyClick(e) {
const heartDropDownOpen = document.querySelectorAll(
'#dropdown_wrapper.open'
@ -100,14 +84,17 @@ class Main extends React.Component {
document.getElementById('dropdown_wrapper').classList.remove('open');
}
}
handleDropdownToggle() {
document.getElementById('dropdown_wrapper').classList.toggle('open');
}
handleMetadataRedirect() {
if (this.props.metadata.inconsistentObjects.length > 0) {
this.props.dispatch(redirectToMetadataStatus());
}
}
closeLoveIcon() {
const s = {
isDismissed: true,
@ -117,6 +104,7 @@ class Main extends React.Component {
loveConsentState: { ...getLoveConsentState() },
});
}
closeUpdateBanner() {
const { latestServerVersion } = this.props;
window.localStorage.setItem(
@ -399,68 +387,6 @@ class Main extends React.Component {
return helpDropdownPosStyle;
};
const getRemoteSchemaLink = () => {
let remoteSchemaLink = null;
if (this.state.showSchemaStitch) {
remoteSchemaLink = (
<OverlayTrigger placement="right" overlay={tooltip.customresolver}>
<li>
<Link
className={
currentActiveBlock === 'remote-schemas'
? styles.navSideBarActive
: ''
}
to={appPrefix + '/remote-schemas/manage/schemas'}
>
<div className={styles.iconCenter}>
<i
title="Remote Schemas"
className="fa fa-plug"
aria-hidden="true"
/>
</div>
<p>Remote Schemas</p>
</Link>
</li>
</OverlayTrigger>
);
}
return remoteSchemaLink;
};
const getEventsLink = () => {
let eventsLink = null;
if (this.state.showEvents) {
eventsLink = (
<OverlayTrigger placement="right" overlay={tooltip.events}>
<li>
<Link
className={
currentActiveBlock === 'events' ? styles.navSideBarActive : ''
}
to={appPrefix + '/events/manage/triggers'}
>
<div className={styles.iconCenter}>
<i
title="Events"
className="fa fa-cloud"
aria-hidden="true"
/>
</div>
<p>Events</p>
</Link>
</li>
</OverlayTrigger>
);
}
return eventsLink;
};
return (
<div className={styles.container}>
<div className={styles.flexRow}>
@ -525,10 +451,51 @@ class Main extends React.Component {
</Link>
</li>
</OverlayTrigger>
{getRemoteSchemaLink()}
{getEventsLink()}
<OverlayTrigger
placement="right"
overlay={tooltip.customresolver}
>
<li>
<Link
className={
currentActiveBlock === 'remote-schemas'
? styles.navSideBarActive
: ''
}
to={appPrefix + '/remote-schemas/manage/schemas'}
>
<div className={styles.iconCenter}>
<i
title="Remote Schemas"
className="fa fa-plug"
aria-hidden="true"
/>
</div>
<p>Remote Schemas</p>
</Link>
</li>
</OverlayTrigger>
<OverlayTrigger placement="right" overlay={tooltip.events}>
<li>
<Link
className={
currentActiveBlock === 'events'
? styles.navSideBarActive
: ''
}
to={appPrefix + '/events/manage/triggers'}
>
<div className={styles.iconCenter}>
<i
title="Events"
className="fa fa-cloud"
aria-hidden="true"
/>
</div>
<p>Events</p>
</Link>
</li>
</OverlayTrigger>
</ul>
</div>
<div id="dropdown_wrapper" className={styles.clusterInfoWrapper}>

View File

@ -144,21 +144,17 @@ const graphQLFetcherFinal = (graphQLParams, url, headers) => {
};
/* Analyse Fetcher */
const analyzeFetcher = (url, headers, analyzeApiChange) => {
const analyzeFetcher = (url, headers) => {
return query => {
const editedQuery = {
query,
};
let user = {};
const user = {
'x-hasura-role': 'admin',
};
const reqHeaders = getHeadersAsJSON(headers);
if (!analyzeApiChange) {
user.role = 'admin';
user.headers = reqHeaders;
} else {
user = {
'x-hasura-role': 'admin',
};
}
// Check if x-hasura-role is available in some form in the headers
const totalHeaders = Object.keys(reqHeaders);
@ -176,6 +172,7 @@ const analyzeFetcher = (url, headers, analyzeApiChange) => {
});
editedQuery.user = user;
return fetch(`${url}/explain`, {
method: 'post',
headers: reqHeaders,

View File

@ -6,7 +6,6 @@ import OneGraphExplorer from '../OneGraphExplorer/OneGraphExplorer';
import { clearCodeMirrorHints, setQueryVariableSectionHeight } from './utils';
import { analyzeFetcher, graphQLFetcherFinal } from '../Actions';
import semverCheck from '../../../../helpers/semver';
import './GraphiQL.css';
@ -18,29 +17,13 @@ class GraphiQLWrapper extends Component {
error: false,
noSchema: false,
onBoardingEnabled: false,
supportAnalyze: false,
analyzeApiChange: false,
};
}
componentDidMount() {
if (this.props.data.serverVersion) {
this.checkSemVer(this.props.data.serverVersion).then(() =>
this.checkNewAnalyzeVersion(this.props.data.serverVersion)
);
}
setQueryVariableSectionHeight();
}
componentWillReceiveProps(nextProps) {
if (nextProps.data.serverVersion !== this.props.data.serverVersion) {
this.checkSemVer(nextProps.data.serverVersion).then(() =>
this.checkNewAnalyzeVersion(nextProps.data.serverVersion)
);
}
}
componentWillUnmount() {
clearCodeMirrorHints();
}
@ -49,52 +32,10 @@ class GraphiQLWrapper extends Component {
return !nextProps.headerFocus;
}
checkSemVer(version) {
try {
const showAnalyze = semverCheck('sqlAnalyze', version);
if (showAnalyze) {
this.updateAnalyzeState(true);
} else {
this.updateAnalyzeState(false);
}
} catch (e) {
this.updateAnalyzeState(false);
console.error(e);
}
return Promise.resolve();
}
checkNewAnalyzeVersion(version) {
try {
const analyzeApiChange = semverCheck('analyzeApiChange', version);
if (analyzeApiChange) {
this.updateAnalyzeApiState(true);
} else {
this.updateAnalyzeApiState(false);
}
} catch (e) {
this.updateAnalyzeApiState(false);
console.error(e);
}
return Promise.resolve();
}
updateAnalyzeState(supportAnalyze) {
this.setState({
supportAnalyze: supportAnalyze,
});
}
updateAnalyzeApiState(analyzeApiChange) {
this.setState({
analyzeApiChange: analyzeApiChange,
});
}
render() {
const styles = require('../../../Common/Common.scss');
const { supportAnalyze, analyzeApiChange, headerFocus } = this.state;
const { headerFocus } = this.state;
const { numberOfTables, urlParams } = this.props;
const graphqlNetworkData = this.props.data;
@ -113,16 +54,15 @@ class GraphiQLWrapper extends Component {
const analyzeFetcherInstance = analyzeFetcher(
graphqlNetworkData.url,
graphqlNetworkData.headers,
analyzeApiChange
graphqlNetworkData.headers
);
const renderGraphiql = graphiqlProps => {
return (
<GraphiQL
fetcher={graphQLFetcher}
supportAnalyze
analyzeFetcher={analyzeFetcherInstance}
supportAnalyze={supportAnalyze}
{...graphiqlProps}
/>
);

View File

@ -32,7 +32,7 @@ dataApisContent.push({
},
request: {
method: 'POST',
url: getUrl('/v1alpha1/graphql'),
url: getUrl('/v1/graphql'),
headers: defaultHeader,
bodyType: 'graphql',
params: JSON.stringify({}, null, 4),

View File

@ -44,7 +44,7 @@ class Common extends React.Component {
const graphqlurl = (
<Tooltip id="tooltip-cascade">
Remote GraphQL servers URL. E.g. https://my-domain/v1alpha1/graphql
Remote GraphQL servers URL. E.g. https://my-domain/v1/graphql
</Tooltip>
);

View File

@ -362,7 +362,7 @@ const loadSchema = () => (dispatch, getState) => {
);
}
dispatch({ type: LOAD_SCHEMA, allSchemas: schemas });
dispatch(loadInconsistentObjects(null, false));
dispatch(loadInconsistentObjects(false));
},
error => {
console.error('Failed to load schema ' + JSON.stringify(error));

View File

@ -6,7 +6,6 @@ import { Link } from 'react-router';
import LeftSubSidebar from '../../Common/Layout/LeftSubSidebar/LeftSubSidebar';
import { LISTING_SCHEMA, UPDATE_TRACKED_FUNCTIONS } from './DataActions';
import semverCheck from '../../../helpers/semver';
const appPrefix = '/data';
@ -22,15 +21,12 @@ const DataSubSidebar = ({
dispatch,
location,
currentFunction,
serverVersion,
metadata,
}) => {
const styles = require('../../Common/Layout/LeftSubSidebar/LeftSubSidebar.scss');
const functionSymbol = require('../../Common/Layout/LeftSubSidebar/function.svg');
const functionSymbolActive = require('../../Common/Layout/LeftSubSidebar/function_high.svg');
const handleFunc = semverCheck('customFunctionSection', serverVersion);
if (metadata.ongoingRequest) {
return null;
}
@ -60,7 +56,7 @@ const DataSubSidebar = ({
type="text"
onChange={tableSearch.bind(this)}
className="form-control"
placeholder={`search table/view${handleFunc ? '/function' : ''}`}
placeholder="search table/view/function"
data-test="search-tables"
/>
);

View File

@ -18,8 +18,6 @@ import { parseCreateSQL } from './utils';
import dataHeaders from '../Common/Headers';
import returnMigrateUrl from '../Common/getMigrateUrl';
import semverCheck from '../../../../helpers/semver';
const MAKING_REQUEST = 'RawSQL/MAKING_REQUEST';
const SET_SQL = 'RawSQL/SET_SQL';
const SET_CASCADE_CHECKED = 'RawSQL/SET_CASCADE_CHECKED';
@ -39,13 +37,8 @@ const executeSQL = (isMigration, migrationName) => (dispatch, getState) => {
dispatch(showSuccessNotification('Executing the Query...'));
const sql = getState().rawSQL.sql;
const serverVersion = getState().main.serverVersion;
const currMigrationMode = getState().main.migrationMode;
const handleFunc = semverCheck('customFunctionSection', serverVersion)
? true
: false;
const migrateUrl = returnMigrateUrl(currMigrationMode);
const isCascadeChecked = getState().rawSQL.isCascadeChecked;
@ -59,7 +52,7 @@ const executeSQL = (isMigration, migrationName) => (dispatch, getState) => {
// check if track view enabled
if (getState().rawSQL.isTableTrackChecked) {
const objects = parseCreateSQL(sql, handleFunc);
const objects = parseCreateSQL(sql);
objects.forEach(object => {
const trackQuery = {

View File

@ -19,7 +19,6 @@ import {
} from './Actions';
import { modalOpen, modalClose } from './Actions';
import globals from '../../../../Globals';
import semverCheck from '../../../../helpers/semver';
import './AceEditorFix.css';
const RawSQL = ({
@ -36,7 +35,6 @@ const RawSQL = ({
isMigrationChecked,
isTableTrackChecked,
migrationMode,
serverVersion,
allSchemas,
}) => {
const styles = require('../../../Common/TableCommon/Table.scss');
@ -58,12 +56,10 @@ const RawSQL = ({
'run_sql_migration'
</Tooltip>
);
const trackTableTip = _hasFunctionSupport => (
const trackTableTip = () => (
<Tooltip id="tooltip-tracktable">
{`If you are creating a table/view${
_hasFunctionSupport ? '/function' : ''
}, checking this will also expose them
over the GraphQL API`}
If you are creating a table/view/function, checking this will also expose
them over the GraphQL API
</Tooltip>
);
@ -135,11 +131,6 @@ const RawSQL = ({
);
}
const hasFunctionSupport = semverCheck(
'customFunctionSection',
serverVersion
);
const getMigrationModal = () => {
const onModalClose = () => {
dispatch(modalClose());
@ -321,9 +312,9 @@ const RawSQL = ({
statement fails, none of the statements will be applied.
</li>
<li>
If you are creating a Table/View
{hasFunctionSupport ? '/Function' : ''} using Raw SQL, checking the{' '}
<b>Track this</b> checkbox will also expose it over the GraphQL API.
If you are creating a Table/View/Function using Raw SQL, checking
the <b>Track this</b> checkbox will also expose it over the GraphQL
API.
</li>
<li>
If migrations are enabled, down migrations will not be generated for
@ -381,10 +372,7 @@ const RawSQL = ({
/>
Track this
</label>
<OverlayTrigger
placement="right"
overlay={trackTableTip(hasFunctionSupport)}
>
<OverlayTrigger placement="right" overlay={trackTableTip()}>
<i
className={`${styles.add_mar_left_small} fa fa-info-circle`}
aria-hidden="true"

View File

@ -13,10 +13,10 @@ const getSQLValue = value => {
return sqlValue.replace(/['"]+/g, '');
};
const parseCreateSQL = (sql, allowFunction) => {
const parseCreateSQL = (sql) => {
const _objects = [];
const regExp = allowFunction ? createSQLRegex : createSQLRegexNoFunction;
const regExp = createSQLRegex;
const matches = sql.match(new RegExp(regExp, 'gmi'));
if (matches) {

View File

@ -12,7 +12,6 @@ const ViewHeader = ({
currentSchema,
migrationMode,
dispatch,
allowRename,
}) => {
const styles = require('../../../Common/TableCommon/Table.scss');
let capitalised = tabName;
@ -65,7 +64,7 @@ const ViewHeader = ({
currentValue={tableName}
save={saveViewNameChange}
loading={false}
editable={tabName === 'modify' && allowRename}
editable={tabName === 'modify'}
dispatch={dispatch}
property="view"
/>

View File

@ -14,8 +14,6 @@ import ViewHeader from './ViewHeader';
import ViewRows from './ViewRows';
import { replace } from 'react-router-redux';
import semverCheck from '../../../../helpers/semver';
const genHeadings = headings => {
if (headings.length === 0) {
return [];
@ -78,39 +76,24 @@ class ViewTable extends Component {
this.state = {
dispatch: props.dispatch,
tableName: props.tableName,
supportManualTriggers: false,
};
this.getInitialData(this.props.tableName);
}
componentDidMount() {
this.checkSupportedFeatures(this.props.serverVersion);
}
componentWillReceiveProps(nextProps) {
if (nextProps.serverVersion !== this.props.serverVersion) {
this.checkSupportedFeatures(nextProps.serverVersion);
}
if (nextProps.tableName !== this.props.tableName) {
this.getInitialData(nextProps.tableName);
}
}
checkSupportedFeatures(version) {
if (semverCheck('manualTriggers', version)) {
this.setState({ supportManualTriggers: true });
}
}
getInitialData(tableName) {
const { dispatch } = this.props;
Promise.all([
dispatch(setTable(tableName)),
dispatch(vSetDefaults(tableName)),
dispatch(vMakeRequest()),
this.retrieveManualTriggers(tableName),
dispatch(fetchManualTriggers(tableName)),
]);
}
@ -127,11 +110,7 @@ class ViewTable extends Component {
document.body.offsetHeight - document.body.scrollTop;
}
componentDidUpdate(prevProps, prevState) {
if (this.state.supportManualTriggers !== prevState.supportManualTriggers) {
this.retrieveManualTriggers(this.state.tableName);
}
componentDidUpdate() {
if (this.shouldScrollBottom) {
document.body.scrollTop = document.body.offsetHeight - window.innerHeight;
}
@ -159,13 +138,6 @@ class ViewTable extends Component {
});
};
retrieveManualTriggers = tableName => {
const { dispatch } = this.props;
return this.state.supportManualTriggers
? dispatch(fetchManualTriggers(tableName))
: Promise.resolve();
};
render() {
const {
tableName,

View File

@ -13,7 +13,6 @@ const TableHeader = ({
migrationMode,
currentSchema,
dispatch,
allowRename,
}) => {
const styles = require('../../../Common/TableCommon/Table.scss');
let capitalised = tabName;
@ -74,7 +73,7 @@ const TableHeader = ({
currentValue={tableName}
save={saveTableNameChange}
loading={false}
editable={tabName === 'modify' && allowRename}
editable={tabName === 'modify'}
dispatch={dispatch}
property="table"
/>

View File

@ -249,8 +249,7 @@ const modifyReducer = (tableName, schemas, modifyStateOrig, action) => {
const permState = getBasePermissionsState(
action.tableSchema,
action.role,
action.query,
action.insertPermColumnRestriction
action.query
);
return {
...modifyState,

View File

@ -19,7 +19,6 @@ const ColumnEditor = ({
onSubmit,
dispatch,
columnComment,
allowRename,
columnProperties,
selectedProperties,
editColumn,
@ -138,20 +137,18 @@ const ColumnEditor = ({
return (
<div className={`${styles.colEditor} container-fluid`}>
<form className="form-horizontal" onSubmit={onSubmit}>
{allowRename && (
<div className={`${styles.display_flex} form-group`}>
<label className="col-xs-2">Name</label>
<div className="col-xs-6">
<input
className="input-sm form-control"
value={selectedProperties[colName].name}
onChange={updateColumnName}
type="text"
data-test="edit-col-name"
/>
</div>
<div className={`${styles.display_flex} form-group`}>
<label className="col-xs-2">Name</label>
<div className="col-xs-6">
<input
className="input-sm form-control"
value={selectedProperties[colName].name}
onChange={updateColumnName}
type="text"
data-test="edit-col-name"
/>
</div>
)}
</div>
<div className={`${styles.display_flex} form-group`}>
<label className="col-xs-2">Type</label>
<div className="col-xs-6">

View File

@ -17,7 +17,6 @@ import styles from './ModifyTable.scss';
const ColumnEditorList = ({
tableSchema,
currentSchema,
allowRename,
columnEdit,
dispatch,
columnComments,
@ -56,7 +55,7 @@ const ColumnEditorList = ({
};
const onSubmit = () => {
dispatch(saveColumnChangesSql(colName, col, allowRename));
dispatch(saveColumnChangesSql(colName, col));
};
const onDelete = () => {
@ -129,7 +128,6 @@ const ColumnEditorList = ({
dispatch={dispatch}
currentSchema={currentSchema}
columnComment={columnComments[col.column_name]}
allowRename={allowRename}
columnProperties={columnProperties}
selectedProperties={columnEdit}
editColumn={editColumn}

View File

@ -162,8 +162,8 @@ const savePrimaryKeys = (tableName, schemaName, constraintName) => {
sql: `
alter table "${schemaName}"."${tableName}"
add constraint "${tableName}_pkey" primary key ( ${selectedPkColumns.join(
', '
)} );
', '
)} );
`,
},
});
@ -188,8 +188,8 @@ const savePrimaryKeys = (tableName, schemaName, constraintName) => {
sql: `
alter table "${schemaName}"."${tableName}"
add constraint "${constraintName}" primary key ( ${tableSchema.primary_key.columns.join(
', '
)} );
', '
)} );
`,
});
}
@ -1054,7 +1054,7 @@ const isColumnUnique = (tableSchema, colName) => {
);
};
const saveColumnChangesSql = (colName, column, allowRename) => {
const saveColumnChangesSql = (colName, column) => {
// eslint-disable-line no-unused-vars
return (dispatch, getState) => {
const columnEdit = getState().tables.modify.columnEdit[colName];
@ -1064,7 +1064,7 @@ const saveColumnChangesSql = (colName, column, allowRename) => {
const unique = columnEdit.isUnique;
const def = columnEdit.default || '';
const comment = columnEdit.comment || '';
const newName = allowRename ? columnEdit.name : null;
const newName = columnEdit.name;
const currentSchema = columnEdit.schemaName;
// ALTER TABLE <table> ALTER COLUMN <column> TYPE <column_type>;
let defWithQuotes;
@ -1121,24 +1121,24 @@ const saveColumnChangesSql = (colName, column, allowRename) => {
const schemaChangesUp =
originalColType !== colType
? [
{
type: 'run_sql',
args: {
sql: columnChangesUpQuery,
},
{
type: 'run_sql',
args: {
sql: columnChangesUpQuery,
},
]
},
]
: [];
const schemaChangesDown =
originalColType !== colType
? [
{
type: 'run_sql',
args: {
sql: columnChangesDownQuery,
},
{
type: 'run_sql',
args: {
sql: columnChangesDownQuery,
},
]
},
]
: [];
/* column default up/down migration */

View File

@ -15,45 +15,16 @@ import PrimaryKeyEditor from './PrimaryKeyEditor';
import TableCommentEditor from './TableCommentEditor';
import ForeignKeyEditor from './ForeignKeyEditor';
import UniqueKeyEditor from './UniqueKeyEditor';
import semverCheck from '../../../../helpers/semver';
import styles from './ModifyTable.scss';
class ModifyTable extends React.Component {
state = {
supportTableColumnRename: false,
};
componentDidMount() {
const { dispatch, serverVersion } = this.props;
const { dispatch } = this.props;
dispatch({ type: RESET });
dispatch(setTable(this.props.tableName));
dispatch(fetchTableComment(this.props.tableName));
if (serverVersion) {
this.checkTableColumnRenameSupport(serverVersion);
}
}
componentWillReceiveProps(nextProps) {
if (
nextProps.serverVersion &&
nextProps.serverVersion !== this.props.serverVersion
) {
this.checkTableColumnRenameSupport(nextProps.serverVersion);
}
}
checkTableColumnRenameSupport = serverVersion => {
try {
if (semverCheck('tableColumnRename', serverVersion)) {
this.setState({
supportTableColumnRename: true,
});
}
} catch (e) {
console.error(e);
}
};
render() {
const {
tableName,
@ -114,7 +85,6 @@ class ModifyTable extends React.Component {
tabName="modify"
migrationMode={migrationMode}
currentSchema={currentSchema}
allowRename={this.state.supportTableColumnRename}
/>
<br />
<div className={`container-fluid ${styles.padd_left_remove}`}>
@ -134,7 +104,6 @@ class ModifyTable extends React.Component {
<ColumnEditorList
tableSchema={tableSchema}
columnEdit={columnEdit}
allowRename={this.state.supportTableColumnRename}
columnComments={columnComments}
dispatch={dispatch}
currentSchema={currentSchema}

View File

@ -16,44 +16,16 @@ import {
import { ordinalColSort } from '../utils';
import { setTable, fetchTableComment } from '../DataActions';
import Button from '../../../Common/Button/Button';
import semverCheck from '../../../../helpers/semver';
class ModifyView extends Component {
state = {
supportTableColumnRename: false,
};
componentDidMount() {
const { dispatch, serverVersion } = this.props;
const { dispatch } = this.props;
dispatch({ type: RESET });
dispatch(setTable(this.props.tableName));
dispatch(fetchViewDefinition(this.props.tableName, false));
dispatch(fetchTableComment(this.props.tableName));
if (serverVersion) {
this.checkTableColumnRenameSupport(serverVersion);
}
}
componentWillReceiveProps(nextProps) {
if (
nextProps.serverVersion &&
nextProps.serverVersion !== this.props.serverVersion
) {
this.checkTableColumnRenameSupport(nextProps.serverVersion);
}
}
checkTableColumnRenameSupport = serverVersion => {
try {
if (semverCheck('tableColumnRename', serverVersion)) {
this.setState({
supportTableColumnRename: true,
});
}
} catch (e) {
console.error(e);
}
};
modifyViewDefinition = viewName => {
// fetch the definition
this.props.dispatch(fetchViewDefinition(viewName, true));
@ -250,7 +222,6 @@ class ModifyView extends Component {
tabName="modify"
currentSchema={currentSchema}
migrationMode={migrationMode}
allowRename={this.state.supportTableColumnRename}
/>
<br />
<div className={'container-fluid ' + styles.padd_left_remove}>

View File

@ -55,13 +55,11 @@ const permOpenEdit = (
tableSchema,
role,
query,
insertPermColumnRestriction
) => ({
type: PERM_OPEN_EDIT,
tableSchema,
role,
query,
insertPermColumnRestriction,
});
const permSetFilter = filter => ({ type: PERM_SET_FILTER, filter });
const permSetFilterSameAs = filter => ({
@ -124,7 +122,6 @@ const getBasePermissionsState = (
tableSchema,
role,
query,
insertPermColumnRestriction
) => {
const _permissions = JSON.parse(JSON.stringify(defaultPermissionsState));
@ -142,12 +139,10 @@ const getBasePermissionsState = (
// If the query is insert, transform set object if exists to an array
if (q === 'insert' || q === 'update') {
// If set is an object
if (insertPermColumnRestriction) {
if (!_permissions[q].columns) {
_permissions[q].columns = tableSchema.columns.map(
c => c.column_name
);
}
if (!_permissions[q].columns) {
_permissions[q].columns = tableSchema.columns.map(
c => c.column_name
);
}
if ('set' in _permissions[q]) {
if (

View File

@ -20,7 +20,7 @@ import {
permCloseEdit,
permSetRoleName,
permChangePermissions,
permToggleAllowUpsert,
// permToggleAllowUpsert,
permToggleAllowAggregation,
permToggleModifyLimit,
permCustomChecked,
@ -45,7 +45,6 @@ import EnhancedInput from '../../../Common/InputChecker/InputChecker';
import { setTable, fetchViewInfoFromInformationSchema } from '../DataActions';
import { getIngForm, getEdForm, escapeRegExp } from '../utils';
import { allOperators, getLegacyOperator } from './PermissionBuilder/utils';
import semverCheck from '../../../../helpers/semver';
import Button from '../../../Common/Button/Button';
import { defaultPresetsState } from '../DataState';
@ -53,26 +52,22 @@ class Permissions extends Component {
constructor() {
super();
this.state = {};
this.state.viewInfo = {};
this.state.showAggregation = false;
this.state.showIshowInsertPresets = false;
this.state.showUpdatePresets = false;
this.state.presetsInfo = {
insert: {
columnTypeMap: {},
},
update: {
columnTypeMap: {},
this.state = {
viewInfo: {},
presetsInfo: {
insert: {
columnTypeMap: {},
},
update: {
columnTypeMap: {},
},
},
};
}
componentDidMount() {
if (this.props.serverVersion) {
this.checkSemVer(this.props.serverVersion);
}
this.props.dispatch({ type: RESET });
const currentSchema = this.props.allSchemas.find(
t => t.table_name === this.props.tableName
);
@ -97,22 +92,6 @@ class Permissions extends Component {
});
}
componentWillReceiveProps(nextProps) {
if (nextProps.serverVersion !== this.props.serverVersion) {
this.checkSemVer(nextProps.serverVersion);
}
}
checkSemVer(version) {
this.setState({
showAggregation: semverCheck('aggregationPerm', version),
showUpsertSection: !semverCheck('permHideUpsertSection', version),
showInsertPresets: semverCheck('insertPrefix', version),
showUpdatePresets: semverCheck('permUpdatePresets', version),
allowInsertPermColumns: semverCheck('insertPermRestrictColumns', version),
});
}
render() {
const {
dispatch,
@ -315,22 +294,13 @@ class Permissions extends Component {
const _permissionsRowsHtml = [];
const getPermissionsTableRow = (role, newPermRow = null) => {
const { allowInsertPermColumns } = this.state;
const dispatchOpenEdit = queryType => () => {
if (newPermRow && permissionsState.newRole !== '') {
dispatch(
permOpenEdit(tableSchema, permissionsState.newRole, queryType)
);
} else if (role !== '') {
dispatch(
permOpenEdit(
tableSchema,
role,
queryType,
allowInsertPermColumns
)
);
dispatch(permOpenEdit(tableSchema, role, queryType));
} else {
document.getElementById('newRoleInput').focus();
}
@ -583,13 +553,6 @@ class Permissions extends Component {
dispatch(permCloseEdit());
};
const {
showAggregation,
showUpsertSection,
showInsertPresets,
showUpdatePresets,
} = this.state;
const query = permissionsState.query;
const noPermissions = !permissionsState[query];
@ -930,16 +893,6 @@ class Permissions extends Component {
};
const getColumnSection = () => {
const { allowInsertPermColumns } = this.state;
const getQueriesWithPermColumns = allowInsert => {
const queries = ['select', 'update'];
if (allowInsert) {
queries.push('insert');
}
return queries;
};
const getColumnList = () => {
const _columnList = [];
@ -1027,9 +980,7 @@ class Permissions extends Component {
let _columnSection = '';
const queriesWithPermColumns = getQueriesWithPermColumns(
allowInsertPermColumns
);
const queriesWithPermColumns = ['select', 'update', 'insert'];
if (queriesWithPermColumns.includes(query)) {
const getAccessText = () => {
@ -1102,59 +1053,59 @@ class Permissions extends Component {
return _columnSection;
};
const getUpsertSection = () => {
if (query !== 'insert') {
return;
}
const dispatchToggleAllowUpsert = checked => {
dispatch(permToggleAllowUpsert(checked));
};
const upsertAllowed = permissionsState.insert
? permissionsState.insert.allow_upsert
: false;
const upsertToolTip = (
<Tooltip id="tooltip-upsert">
Allow upsert queries. Upsert lets you update a row if it already
exists, otherwise insert it
</Tooltip>
);
const upsertStatus = upsertAllowed ? 'enabled' : 'disabled';
return (
<CollapsibleToggle
title={getSectionHeader(
'Upsert queries permissions',
upsertToolTip,
upsertStatus
)}
useDefaultTitleStyle
testId={'toggle-upsert-permission'}
>
<div
className={sectionClasses}
title={noPermissions ? noPermissionsMsg : ''}
>
<div className="checkbox">
<label>
<input
type="checkbox"
checked={upsertAllowed}
value="toggle_upsert"
onChange={e => dispatchToggleAllowUpsert(e.target.checked)}
disabled={noPermissions}
/>
Allow role <b>{permissionsState.role}</b> to make upsert
queries
</label>
</div>
</div>
</CollapsibleToggle>
);
};
// const getUpsertSection = () => {
// if (query !== 'insert') {
// return;
// }
//
// const dispatchToggleAllowUpsert = checked => {
// dispatch(permToggleAllowUpsert(checked));
// };
//
// const upsertAllowed = permissionsState.insert
// ? permissionsState.insert.allow_upsert
// : false;
//
// const upsertToolTip = (
// <Tooltip id="tooltip-upsert">
// Allow upsert queries. Upsert lets you update a row if it already
// exists, otherwise insert it
// </Tooltip>
// );
//
// const upsertStatus = upsertAllowed ? 'enabled' : 'disabled';
//
// return (
// <CollapsibleToggle
// title={getSectionHeader(
// 'Upsert queries permissions',
// upsertToolTip,
// upsertStatus
// )}
// useDefaultTitleStyle
// testId={'toggle-upsert-permission'}
// >
// <div
// className={sectionClasses}
// title={noPermissions ? noPermissionsMsg : ''}
// >
// <div className="checkbox">
// <label>
// <input
// type="checkbox"
// checked={upsertAllowed}
// value="toggle_upsert"
// onChange={e => dispatchToggleAllowUpsert(e.target.checked)}
// disabled={noPermissions}
// />
// Allow role <b>{permissionsState.role}</b> to make upsert
// queries
// </label>
// </div>
// </div>
// </CollapsibleToggle>
// );
// };
const getPresetsSection = action => {
if (query !== action) {
@ -1802,10 +1753,10 @@ class Permissions extends Component {
<div>
{getRowSection()}
{getColumnSection()}
{showAggregation && getAggregationSection()}
{showUpsertSection && getUpsertSection()}
{showInsertPresets && getPresetsSection('insert')}
{showUpdatePresets && getPresetsSection('update')}
{getAggregationSection()}
{/*{getUpsertSection()}*/}
{getPresetsSection('insert')}
{getPresetsSection('update')}
{getButtonsSection()}
{getClonePermsSection()}
</div>

View File

@ -1,4 +1,3 @@
/* eslint-disable jsx-a11y/no-autofocus */
import React from 'react';
import { getRelDef } from './utils';
import Button from '../../../Common/Button/Button';
@ -60,14 +59,7 @@ class RelationshipEditor extends React.Component {
};
render() {
const {
dispatch,
tableName,
relName,
relConfig,
isObjRel,
allowRename,
} = this.props;
const { dispatch, tableName, relName, relConfig, isObjRel } = this.props;
const { text, isEditting } = this.state;
const { lcol, rtable, rcol } = relConfig;
@ -86,16 +78,12 @@ class RelationshipEditor extends React.Component {
const collapsed = () => (
<div>
<Button
color={allowRename ? 'white' : 'red'}
size={allowRename ? 'xs' : 'sm'}
onClick={allowRename ? this.toggleEditor : onDelete}
data-test={
allowRename
? `relationship-toggle-editor-${relName}`
: `relationship-remove-${relName}`
}
color={'white'}
size={'xs'}
onClick={this.toggleEditor}
data-test={`relationship-toggle-editor-${relName}`}
>
{allowRename ? 'Edit' : 'Remove'}
Edit
</Button>
&nbsp;
<b>{relName}</b>

View File

@ -22,7 +22,6 @@ import Button from '../../../Common/Button/Button';
import AddManualRelationship from './AddManualRelationship';
import suggestedRelationshipsRaw from './autoRelations';
import RelationshipEditor from './RelationshipEditor';
import semverCheck from '../../../../helpers/semver';
const addRelationshipCellView = (
dispatch,
@ -308,39 +307,12 @@ const AddRelationship = ({
};
class Relationships extends Component {
state = {
supportRename: false,
};
componentDidMount() {
const { dispatch, serverVersion, tableName } = this.props;
const { dispatch, tableName } = this.props;
dispatch({ type: RESET });
dispatch(setTable(tableName));
if (serverVersion) {
this.checkRenameSupport(serverVersion);
}
}
componentWillReceiveProps(nextProps) {
if (
nextProps.serverVersion &&
nextProps.serverVersion !== this.props.serverVersion
) {
this.checkRenameSupport(nextProps.serverVersion);
}
}
checkRenameSupport = serverVersion => {
try {
if (semverCheck('tableColumnRename', serverVersion)) {
this.setState({
supportRename: true,
});
}
} catch (e) {
console.error(e);
}
};
render() {
const {
tableName,
@ -418,7 +390,6 @@ class Relationships extends Component {
rel.objRel
)}
isObjRel
allowRename={this.state.supportRename}
/>
) : (
<td />
@ -435,7 +406,6 @@ class Relationships extends Component {
rel.arrRel
)}
isObjRel={false}
allowRename={this.state.supportRename}
/>
) : (
<td />

View File

@ -10,14 +10,10 @@ import { setTable, UPDATE_REMOTE_SCHEMA_MANUAL_REL } from '../DataActions';
import Button from '../../../Common/Button/Button';
import AddManualRelationship from './AddManualRelationship';
import RelationshipEditor from './RelationshipEditor';
import semverCheck from '../../../../helpers/semver';
class RelationshipsView extends Component {
state = {
supportRename: false,
};
componentDidMount() {
const { dispatch, serverVersion, currentSchema, tableName } = this.props;
const { dispatch, currentSchema, tableName } = this.props;
dispatch({ type: RESET });
dispatch(setTable(tableName));
// Sourcing the current schema into manual relationship
@ -25,31 +21,8 @@ class RelationshipsView extends Component {
type: UPDATE_REMOTE_SCHEMA_MANUAL_REL,
data: currentSchema,
});
if (serverVersion) {
this.checkRenameSupport(serverVersion);
}
}
componentWillReceiveProps(nextProps) {
if (
nextProps.serverVersion &&
nextProps.serverVersion !== this.props.serverVersion
) {
this.checkRenameSupport(nextProps.serverVersion);
}
}
checkRenameSupport = serverVersion => {
try {
if (semverCheck('tableColumnRename', serverVersion)) {
this.setState({
supportRename: true,
});
}
} catch (e) {
console.error(e);
}
};
render() {
const {
tableName,
@ -127,7 +100,6 @@ class RelationshipsView extends Component {
rel.objRel
)}
isObjRel
allowRename={this.state.supportRename}
/>
) : (
<td />
@ -144,7 +116,6 @@ class RelationshipsView extends Component {
rel.arrRel
)}
isObjRel={false}
allowRename={this.state.supportRename}
/>
) : (
<td />

View File

@ -201,28 +201,8 @@ const loadTableList = schemaName => {
dispatch(fetchTableListBySchema(schemaName, UPDATE_TABLE_LIST));
};
const operationToggleColumn = (
column,
operation,
supportColumnChangeFeature
) => {
const operationToggleColumn = (column, operation) => {
return (dispatch, getState) => {
if (supportColumnChangeFeature) {
if (operation === 'update') {
const currentOperations = getState().addTrigger.operations;
const currentCols = currentOperations[operation];
// check if column is in currentCols. if not, push
const isExists = currentCols.includes(column);
let finalCols = currentCols;
if (isExists) {
finalCols = currentCols.filter(col => col !== column);
} else {
finalCols.push(column);
}
dispatch({ type: TOGGLE_COLUMNS, cols: finalCols, op: operation });
}
return;
}
const currentOperations = getState().addTrigger.operations;
const currentCols = currentOperations[operation];
// check if column is in currentCols. if not, push
@ -237,18 +217,9 @@ const operationToggleColumn = (
};
};
const operationToggleAllColumns = (
columns,
supportListeningToColumnsUpdate
) => {
const operationToggleAllColumns = columns => {
return dispatch => {
if (supportListeningToColumnsUpdate) {
dispatch({ type: TOGGLE_ALL_COLUMNS, cols: columns });
} else {
dispatch({ type: TOGGLE_COLUMNS, cols: columns, op: 'insert' });
dispatch({ type: TOGGLE_COLUMNS, cols: columns, op: 'update' });
dispatch({ type: TOGGLE_COLUMNS, cols: columns, op: 'delete' });
}
dispatch({ type: TOGGLE_ALL_COLUMNS, cols: columns });
};
};

View File

@ -33,40 +33,15 @@ import { createTrigger } from './AddActions';
import DropdownButton from '../../../Common/DropdownButton/DropdownButton';
import CollapsibleToggle from '../../../Common/CollapsibleToggle/CollapsibleToggle';
import semverCheck from '../../../../helpers/semver';
class AddTrigger extends Component {
constructor(props) {
super(props);
this.props.dispatch(loadTableList('public'));
this.state = {
supportColumnChangeFeature: false,
supportWebhookEnv: false,
supportRetryTimeout: false,
supportManualTriggerInvocations: false,
};
}
componentDidMount() {
// set defaults
this.props.dispatch(setDefaults());
if (this.props.serverVersion) {
this.checkSemVer(this.props.serverVersion).then(() => {
this.checkWebhookEnvSupport(this.props.serverVersion);
this.checkRetryTimeoutSupport(this.props.serverVersion);
});
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.serverVersion !== this.props.serverVersion) {
this.checkSemVer(nextProps.serverVersion).then(() => {
this.checkWebhookEnvSupport(nextProps.serverVersion);
this.checkRetryTimeoutSupport(nextProps.serverVersion);
});
}
}
componentWillUnmount() {
@ -74,49 +49,6 @@ class AddTrigger extends Component {
this.props.dispatch(setDefaults());
}
checkSemVer(version) {
try {
const supportColumnChangeFeature = semverCheck(
'supportColumnChangeTrigger',
version
);
if (supportColumnChangeFeature) {
this.updateSupportColumnChangeFeature(true);
} else {
this.updateSupportColumnChangeFeature(false);
}
this.checkManualTriggerInvocationSupport(version);
} catch (e) {
this.updateSupportColumnChangeFeature(false);
console.error(e);
}
return Promise.resolve();
}
checkWebhookEnvSupport(version) {
const supportWebhookEnv = semverCheck('webhookEnvSupport', version);
this.setState({ supportWebhookEnv });
return Promise.resolve();
}
checkRetryTimeoutSupport(version) {
const supportRetryTimeout = semverCheck('triggerRetryTimeout', version);
this.setState({ supportRetryTimeout });
return Promise.resolve();
}
checkManualTriggerInvocationSupport(version) {
this.setState({
supportManualTriggerInvocations: semverCheck('manualTriggers', version),
});
}
updateSupportColumnChangeFeature(val) {
this.setState({
supportColumnChangeFeature: val,
});
}
updateWebhookUrlType(e) {
const field = e.target.getAttribute('value');
if (field === 'env' || field === 'url') {
@ -167,10 +99,7 @@ class AddTrigger extends Component {
errorMsg = 'Retry interval is not valid';
customMsg = 'Retry interval must be a postiive number';
}
if (
this.state.supportRetryTimeout &&
(isNaN(iTimeout) || iTimeout <= 0)
) {
if (isNaN(iTimeout) || iTimeout <= 0) {
isValid = false;
errorMsg = 'Timeout is not valid';
customMsg = 'Timeout must be a positive number';
@ -243,12 +172,6 @@ class AddTrigger extends Component {
enableManual,
} = this.props;
const {
supportColumnChangeFeature,
supportRetryTimeout,
supportManualTriggerInvocations,
} = this.state;
const styles = require('../TableCommon/EventTable.scss');
let createBtnText = 'Create Event Trigger';
@ -283,15 +206,13 @@ class AddTrigger extends Component {
columns.push(column);
});
}
dispatch(operationToggleAllColumns(columns, supportColumnChangeFeature));
dispatch(operationToggleAllColumns(columns));
};
const getColumnList = type => {
const dispatchToggleColumn = e => {
const column = e.target.value;
dispatch(
operationToggleColumn(column, type, supportColumnChangeFeature)
);
dispatch(operationToggleColumn(column, type));
};
const tableSchema = tableListBySchema.find(
t => t.table_name === tableName
@ -332,7 +253,7 @@ class AddTrigger extends Component {
});
};
const advancedColumnSection = supportColumnChangeFeature ? (
const advancedColumnSection = (
<div>
<h4 className={styles.subheading_text}>
Listen columns for update &nbsp; &nbsp;
@ -345,8 +266,7 @@ class AddTrigger extends Component {
</h4>
{selectedOperations.update ? (
<div className={styles.clear_fix + ' ' + styles.listenColumnWrapper}>
{' '}
{getColumnList('update')}{' '}
{getColumnList('update')}
</div>
) : (
<div className={styles.clear_fix + ' ' + styles.listenColumnWrapper}>
@ -354,65 +274,6 @@ class AddTrigger extends Component {
</div>
)}
</div>
) : (
<div>
<h4 className={styles.subheading_text}>
Advanced - Operation/Columns &nbsp; &nbsp;
<OverlayTrigger
placement="right"
overlay={tooltip.advancedOperationDescription}
>
<i className="fa fa-question-circle" aria-hidden="true" />
</OverlayTrigger>{' '}
</h4>
<div>
<div>
<label>
<input
onChange={handleOperationSelection}
className={styles.display_inline + ' ' + styles.add_mar_right}
type="checkbox"
value="insert"
checked={selectedOperations.insert}
/>
Insert
</label>
</div>
{getColumnList('insert')}
</div>
<hr />
<div>
<div>
<label>
<input
onChange={handleOperationSelection}
className={styles.display_inline + ' ' + styles.add_mar_right}
type="checkbox"
value="update"
checked={selectedOperations.update}
/>
Update
</label>
</div>
{getColumnList('update')}
</div>
<hr />
<div>
<div>
<label>
<input
onChange={handleOperationSelection}
className={styles.display_inline + ' ' + styles.add_mar_right}
type="checkbox"
value="delete"
checked={selectedOperations.delete}
/>
Delete
</label>
</div>
{getColumnList('delete')}
</div>
</div>
);
const headersList = headers.map((header, i) => {
@ -581,9 +442,6 @@ class AddTrigger extends Component {
>
<Operations
dispatch={dispatch}
supportManualTriggerInvocations={
supportManualTriggerInvocations
}
enableManual={enableManual}
selectedOperations={selectedOperations}
handleOperationSelection={handleOperationSelection}
@ -601,50 +459,37 @@ class AddTrigger extends Component {
</OverlayTrigger>{' '}
</h4>
<div>
{this.state.supportWebhookEnv ? (
<div className={styles.dropdown_wrapper}>
<DropdownButton
dropdownOptions={[
{ display_text: 'URL', value: 'url' },
{ display_text: 'From env var', value: 'env' },
]}
title={
(webhookUrlType === 'url' && 'URL') ||
(webhookUrlType === 'env' && 'From env var') ||
'Value'
}
dataKey={
(webhookUrlType === 'url' && 'url') ||
(webhookUrlType === 'env' && 'env')
}
onButtonChange={this.updateWebhookUrlType.bind(this)}
onInputChange={e => {
dispatch(setWebhookURL(e.target.value));
}}
required
bsClass={styles.dropdown_button}
inputVal={webhookURL}
id="webhook-url"
inputPlaceHolder={
(webhookUrlType === 'url' &&
'http://httpbin.org/post') ||
(webhookUrlType === 'env' && 'MY_WEBHOOK_URL')
}
testId="webhook"
/>
</div>
) : (
<input
type="url"
required
data-test="webhook"
placeholder="webhook url"
className={`${styles.tableNameInput} form-control`}
onChange={e => {
<div className={styles.dropdown_wrapper}>
<DropdownButton
dropdownOptions={[
{ display_text: 'URL', value: 'url' },
{ display_text: 'From env var', value: 'env' },
]}
title={
(webhookUrlType === 'url' && 'URL') ||
(webhookUrlType === 'env' && 'From env var') ||
'Value'
}
dataKey={
(webhookUrlType === 'url' && 'url') ||
(webhookUrlType === 'env' && 'env')
}
onButtonChange={this.updateWebhookUrlType.bind(this)}
onInputChange={e => {
dispatch(setWebhookURL(e.target.value));
}}
required
bsClass={styles.dropdown_button}
inputVal={webhookURL}
id="webhook-url"
inputPlaceHolder={
(webhookUrlType === 'url' &&
'http://httpbin.org/post') ||
(webhookUrlType === 'env' && 'MY_WEBHOOK_URL')
}
testId="webhook"
/>
)}
</div>
</div>
<br />
<small>
@ -713,32 +558,30 @@ class AddTrigger extends Component {
/>
</div>
</div>
{supportRetryTimeout && (
<div className={styles.retrySection}>
<div className={`col-md-3 ${styles.padd_left_remove}`}>
<label
className={`${styles.add_mar_right} ${
styles.retryLabel
}`}
>
Timeout in seconds (default: 60)
</label>
</div>
<div className={`col-md-6 ${styles.padd_left_remove}`}>
<input
onChange={e => {
dispatch(setRetryTimeout(e.target.value));
}}
data-test="timeout-seconds"
className={`${styles.display_inline} form-control ${
styles.width300
}`}
type="text"
placeholder="timeout in seconds"
/>
</div>
<div className={styles.retrySection}>
<div className={`col-md-3 ${styles.padd_left_remove}`}>
<label
className={`${styles.add_mar_right} ${
styles.retryLabel
}`}
>
Timeout in seconds (default: 60)
</label>
</div>
)}
<div className={`col-md-6 ${styles.padd_left_remove}`}>
<input
onChange={e => {
dispatch(setRetryTimeout(e.target.value));
}}
data-test="timeout-seconds"
className={`${styles.display_inline} form-control ${
styles.width300
}`}
type="text"
placeholder="timeout in seconds"
/>
</div>
</div>
</div>
<hr />
<div className={styles.add_mar_top}>

View File

@ -5,7 +5,6 @@ import * as tooltip from './Tooltips';
import { TOGGLE_ENABLE_MANUAL_CONFIG } from './AddActions';
const Operations = ({
supportManualTriggerInvocations,
enableManual,
selectedOperations,
handleOperationSelection,
@ -38,10 +37,6 @@ const Operations = ({
];
const getManualInvokeOperation = () => {
if (!supportManualTriggerInvocations) {
return null;
}
const handleManualOperationSelection = () => {
dispatch({ type: TOGGLE_ENABLE_MANUAL_CONFIG });
};
@ -122,7 +117,6 @@ const Operations = ({
};
Operations.propTypes = {
supportManualTriggerInvocations: PropTypes.bool.isRequired,
enableManual: PropTypes.bool.isRequired,
selectedOperations: PropTypes.object.isRequired,
handleOperationSelection: PropTypes.func.isRequired,

View File

@ -101,7 +101,7 @@ const loadTriggers = () => (dispatch, getState) => {
type: LOAD_TRIGGER_LIST,
triggerList: consistentTriggers || data[0],
});
dispatch(loadInconsistentObjects(null, false));
dispatch(loadInconsistentObjects(false));
},
error => {
console.error('Failed to load triggers' + JSON.stringify(error));

View File

@ -11,31 +11,13 @@ import OperationEditor from './OperationEditor';
import RetryConfEditor from './RetryConfEditor';
import HeadersEditor from './HeadersEditor';
import ActionButtons from './ActionButtons';
import semverCheck from '../../../../helpers/semver';
import { save, setDefaults, RESET_MODIFY_STATE } from './Actions';
class Modify extends React.Component {
constructor(props) {
super(props);
this.state = {
supportManualTriggerInvocations: false,
};
}
componentDidMount() {
const { serverVersion, dispatch } = this.props;
const { dispatch } = this.props;
dispatch(setDefaults());
if (serverVersion) {
this.checkSemver(serverVersion);
}
}
componentWillReceiveProps(nextProps) {
const { serverVersion } = nextProps;
if (serverVersion && serverVersion !== this.props.serverVersion) {
this.checkSemver(serverVersion);
}
}
componentWillUnmount() {
@ -45,16 +27,6 @@ class Modify extends React.Component {
});
}
checkSemver(version) {
this.checkManualTriggerInvocationSupport(version);
}
checkManualTriggerInvocationSupport(version) {
this.setState({
supportManualTriggerInvocations: semverCheck('manualTriggers', version),
});
}
render() {
const {
modifyTriggerName,
@ -65,8 +37,6 @@ class Modify extends React.Component {
tableSchemas,
} = this.props;
const { supportManualTriggerInvocations } = this.state;
const currentTrigger = triggerList.find(
tr => tr.name === modifyTriggerName
);
@ -123,7 +93,6 @@ class Modify extends React.Component {
newDefinition={null}
styles={styles}
save={() => dispatch(save('ops', modifyTriggerName))}
supportManualTriggerInvocations={supportManualTriggerInvocations}
/>
<RetryConfEditor
retryConf={retry_conf}

View File

@ -5,8 +5,8 @@ import Tooltip from '../../../Common/Tooltip/Tooltip';
import { toggleQueryType, toggleColumn, toggleManualType } from './Actions';
import {
getValidQueryTypes,
queryToInternalNameMap,
getTriggerOperations,
triggerOperationMap,
MANUAL_TRIGGER_VAR,
} from './utils';
@ -58,15 +58,14 @@ class OperationEditor extends React.Component {
save,
modifyTrigger,
dispatch,
supportManualTriggerInvocations,
} = this.props;
/*
* Query types will have `CONSOLE_QUERY` only for version > 45
*
* */
const queryTypes = getValidQueryTypes(supportManualTriggerInvocations);
const operationTypes = getTriggerOperations();
const renderOperation = (qt, i) => {
const isChecked = Boolean(definition[queryToInternalNameMap[qt]]);
const isChecked = Boolean(definition[triggerOperationMap[qt]]);
return (
<div
@ -89,7 +88,7 @@ class OperationEditor extends React.Component {
<div className={styles.modifyOps}>
<div className={styles.modifyOpsCollapsedContent}>
<div className={'col-md-12 ' + styles.padd_remove}>
{queryTypes.map((qt, i) => renderOperation(qt, i))}
{operationTypes.map((qt, i) => renderOperation(qt, i))}
</div>
</div>
<div className={styles.modifyOpsCollapsedContent}>
@ -138,7 +137,7 @@ class OperationEditor extends React.Component {
<div className={styles.modifyOpsPadLeft}>
<div className={styles.modifyOpsCollapsedContent}>
<div className={'col-md-12 ' + styles.padd_remove}>
{queryTypes.map((qt, i) => (
{operationTypes.map((qt, i) => (
<div
className={`${styles.opsCheckboxWrapper} col-md-2 ${
styles.padd_remove
@ -147,11 +146,9 @@ class OperationEditor extends React.Component {
onClick={() => {
dispatch(
this.toggleOperation({
query: queryToInternalNameMap[qt],
query: triggerOperationMap[qt],
columns: allTableColumns.map(c => c.name),
value: !modifyTrigger.definition[
queryToInternalNameMap[qt]
],
value: !modifyTrigger.definition[triggerOperationMap[qt]],
})
);
}}
@ -160,7 +157,7 @@ class OperationEditor extends React.Component {
type="checkbox"
className={`${styles.opsCheckbox} ${styles.cursorPointer}`}
checked={Boolean(
modifyTrigger.definition[queryToInternalNameMap[qt]]
modifyTrigger.definition[triggerOperationMap[qt]]
)}
/>
{qt}

View File

@ -8,40 +8,15 @@ import {
} from './Actions';
import Tooltip from '../../../Common/Tooltip/Tooltip';
import semverCheck from '../../../../helpers/semver';
class RetryConfEditor extends React.Component {
state = {
supportRetryTimeout: false,
};
componentDidMount() {
if (this.props.serverVersion) {
this.checkRetryTimeoutSupport(this.props.serverVersion);
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.serverVersion !== this.props.serverVersion) {
this.checkRetryTimeoutSupport(this.props.serverVersion);
}
}
setValues = () => {
const { dispatch } = this.props;
const retryConf = this.props.retryConf || {};
dispatch(setRetryNum(retryConf.num_retries || 0));
dispatch(setRetryInterval(retryConf.interval_sec || 10));
if (this.state.supportRetryTimeout) {
dispatch(setRetryTimeout(retryConf.timeout_sec || 60));
}
dispatch(setRetryTimeout(retryConf.timeout_sec || 60));
};
checkRetryTimeoutSupport(version) {
const supportRetryTimeout = semverCheck('triggerRetryTimeout', version);
this.setState({ supportRetryTimeout });
}
validateAndSave = () => {
const {
dispatch,
@ -69,20 +44,19 @@ class RetryConfEditor extends React.Component {
}
dispatch(setRetryInterval(iRetryInterval));
if (this.state.supportRetryTimeout) {
if (isNaN(iTimeout) || iTimeout <= 0) {
dispatch(showValidationError('Timeout must be a positive number!'));
return;
}
dispatch(setRetryTimeout(iTimeout));
if (isNaN(iTimeout) || iTimeout <= 0) {
dispatch(showValidationError('Timeout must be a positive number!'));
return;
}
dispatch(setRetryTimeout(iTimeout));
this.props.save();
};
render() {
const { styles, dispatch, modifyTrigger } = this.props;
const retryConf = this.props.retryConf || {};
const { supportRetryTimeout } = this.state;
const collapsed = () => (
<div className={styles.modifyOps}>
<div className={styles.modifyOpsCollapsedContent1}>
@ -101,16 +75,12 @@ class RetryConfEditor extends React.Component {
{retryConf.interval_sec || 10}
</div>
</div>
{supportRetryTimeout && (
<div className={styles.modifyOpsCollapsedContent1}>
<div className={'col-md-4 ' + styles.padd_remove}>
Timeout (sec):
</div>
<div className={'col-md-12 ' + styles.padd_remove}>
{retryConf.timeout_sec || 60}
</div>
<div className={styles.modifyOpsCollapsedContent1}>
<div className={'col-md-4 ' + styles.padd_remove}>Timeout (sec):</div>
<div className={'col-md-12 ' + styles.padd_remove}>
{retryConf.timeout_sec || 60}
</div>
)}
</div>
</div>
);
@ -146,23 +116,21 @@ class RetryConfEditor extends React.Component {
/>
</div>
</div>
{this.state.supportRetryTimeout && (
<div className={styles.modifyOpsCollapsedContent1}>
<div className={`col-md-4 ${styles.padd_remove}`}>
Timeout (sec):&nbsp;
</div>
<div className="col-md-12">
<input
type="text"
className={`${styles.input} form-control ${
styles.add_mar_right
} ${styles.modifyRetryConfTextbox}`}
value={modifyTrigger.retryConf.timeout}
onChange={e => dispatch(setRetryTimeout(e.target.value))}
/>
</div>
<div className={styles.modifyOpsCollapsedContent1}>
<div className={`col-md-4 ${styles.padd_remove}`}>
Timeout (sec):&nbsp;
</div>
)}
<div className="col-md-12">
<input
type="text"
className={`${styles.input} form-control ${
styles.add_mar_right
} ${styles.modifyRetryConfTextbox}`}
value={modifyTrigger.retryConf.timeout}
onChange={e => dispatch(setRetryTimeout(e.target.value))}
/>
</div>
</div>
</div>
);

View File

@ -1,17 +1,11 @@
export const MANUAL_TRIGGER_TEXT = 'Via console';
export const MANUAL_TRIGGER_VAR = 'enable_manual';
export const getValidQueryTypes = supportManualTriggerInvocations => {
const defaultQueryTypes = ['insert', 'update', 'delete'];
if (supportManualTriggerInvocations) {
defaultQueryTypes.push(MANUAL_TRIGGER_TEXT);
}
return defaultQueryTypes;
export const getTriggerOperations = () => {
return ['insert', 'update', 'delete', MANUAL_TRIGGER_TEXT];
};
export const queryToInternalNameMap = {
export const triggerOperationMap = {
insert: 'insert',
update: 'update',
delete: 'delete',

View File

@ -7,7 +7,6 @@ import Tabs from 'react-bootstrap/lib/Tabs';
import Tab from 'react-bootstrap/lib/Tab';
import RedeliverEvent from '../TableCommon/RedeliverEvent';
import TableHeader from '../TableCommon/TableHeader';
import semverCheck from '../../../../helpers/semver';
import parseRowData from './util';
import {
loadEventLogs,
@ -38,41 +37,18 @@ class StreamingLogs extends Component {
intervalId: null,
filtered: [],
filterAll: '',
showRedeliver: false,
};
this.refreshData = this.refreshData.bind(this);
this.filterAll = this.filterAll.bind(this);
this.props.dispatch(setTrigger(this.props.triggerName));
}
componentDidMount() {
if (this.props.serverVersion) {
this.checkSemVer(this.props.serverVersion);
}
this.props.dispatch(setTrigger(this.props.triggerName));
this.props.dispatch(loadEventLogs(this.props.triggerName));
}
componentWillReceiveProps(nextProps) {
if (nextProps.serverVersion !== this.props.serverVersion) {
this.checkSemVer(nextProps.serverVersion);
}
}
componentWillUnmount() {
this.props.dispatch(vSetDefaults());
}
checkSemVer(version) {
let showRedeliver = false;
try {
showRedeliver = semverCheck('eventRedeliver', version);
if (showRedeliver) {
this.setState({ showRedeliver: true });
} else {
this.setState({ showRedeliver: false });
}
} catch (e) {
console.error(e);
this.setState({ showRedeliver: false });
}
}
handleNewerEvents() {
// get the first element
const firstElement = this.props.log.rows[0];
@ -153,12 +129,10 @@ class StreamingLogs extends Component {
const invocationGridHeadings = [];
invocationColumns.map(column => {
if (!(column === 'redeliver' && !this.state.showRedeliver)) {
invocationGridHeadings.push({
Header: column,
accessor: column,
});
}
invocationGridHeadings.push({
Header: column,
accessor: column,
});
});
const invocationRowsData = [];
@ -229,7 +203,7 @@ class StreamingLogs extends Component {
</div>
);
}
if (col === 'redeliver' && this.state.showRedeliver) {
if (col === 'redeliver') {
return (
<div className={conditionalClassname}>
<i

View File

@ -3,7 +3,6 @@ import { push } from 'react-router-redux';
import globals from '../../../Globals';
import endpoints from '../../../Endpoints';
import defaultState from './State';
import semverCheck from '../../../helpers/semver';
import { filterSchema } from './utils';
import {
setConsistentSchema,
@ -62,21 +61,11 @@ export const filterInconsistentMetadata = (
};
export const loadInconsistentObjects = (
serverVersion,
shouldReloadCache,
successCb,
failureCb
) => {
return (dispatch, getState) => {
if (!semverCheck('inconsistentState', serverVersion)) {
return Promise.resolve();
}
if (!serverVersion) {
const serverVersionFromState = getState().main.serverVersion;
if (!semverCheck('inconsistentState', serverVersionFromState)) {
return Promise.resolve();
}
}
const headers = getState().tables.dataHeaders;
dispatch({ type: LOADING_METADATA });
return dispatch(
@ -130,38 +119,8 @@ export const loadInconsistentObjects = (
};
export const reloadMetadata = (successCb, failureCb) => {
return (dispatch, getState) => {
const serverVersionFromState = getState().main.serverVersion;
if (!semverCheck('inconsistentState', serverVersionFromState)) {
const headers = getState().tables.dataHeaders;
return dispatch(
requestAction(endpoints.query, {
method: 'POST',
headers,
body: JSON.stringify(reloadCacheQuery),
})
).then(
data => {
if (successCb) {
successCb(data);
}
},
error => {
console.error(error);
if (failureCb) {
failureCb(error);
}
}
);
}
return dispatch(
loadInconsistentObjects(
serverVersionFromState,
true,
successCb,
failureCb
)
);
return dispatch => {
return dispatch(loadInconsistentObjects(true, successCb, failureCb));
};
};
@ -179,7 +138,7 @@ export const dropInconsistentObjects = () => {
() => {
dispatch({ type: DROPPED_INCONSISTENT_METADATA });
dispatch(showSuccessNotification('Dropped inconsistent metadata'));
dispatch(loadInconsistentObjects(null, false));
dispatch(loadInconsistentObjects(false));
},
error => {
console.error(error);
@ -510,7 +469,7 @@ export const metadataReducer = (state = defaultState, action) => {
...state,
allowedQueries: [
...state.allowedQueries.map(q =>
q.name === action.data.queryName ? action.data.newQuery : q
(q.name === action.data.queryName ? action.data.newQuery : q)
),
],
};

View File

@ -1,76 +1,15 @@
import React, { useState, useEffect } from 'react';
import semverCheck from '../../../helpers/semver';
import React from 'react';
import Sidebar from './Sidebar';
import PageContainer from '../../Common/Layout/PageContainer/PageContainer';
const useMetadataSemver = serverVersion => {
const [supportMetadata, setSupportMetadata] = useState(false);
const [
supportInconsistentMetadata,
setSupportInconsistentMetadata,
] = useState(false);
const [supportAllowedQueries, setSupportAllowedQueries] = useState(false);
useEffect(() => {
if (serverVersion) {
setSupportMetadata(semverCheck('metadataReload', serverVersion));
}
}, [serverVersion]);
useEffect(() => {
if (serverVersion) {
setSupportInconsistentMetadata(
semverCheck('inconsistentState', serverVersion)
);
}
}, [serverVersion]);
useEffect(() => {
if (serverVersion) {
setSupportAllowedQueries(semverCheck('allowedQueries', serverVersion));
}
}, [serverVersion]);
return {
supportMetadata,
supportInconsistentMetadata,
supportAllowedQueries,
};
};
const Container = ({ location, serverVersion, children, metadata }) => {
const {
supportMetadata,
supportInconsistentMetadata,
supportAllowedQueries,
} = useMetadataSemver(serverVersion);
if (!supportMetadata) {
return null;
}
const sidebar = (
<Sidebar
semverChecks={{
supportMetadata,
supportInconsistentMetadata,
supportAllowedQueries,
}}
location={location}
metadata={metadata}
/>
);
const Container = ({ location, children, metadata }) => {
const helmet = 'Metadata | Hasura';
const childrenWithProps = React.Children.map(children, child =>
React.cloneElement(child, {
supportMetadata,
supportInconsistentMetadata,
metadata,
})
);
const sidebar = <Sidebar location={location} metadata={metadata} />;
const childrenWithProps = React.Children.map(children, child =>
React.cloneElement(child, { metadata })
);
return (
<PageContainer helmet={helmet} leftContainer={sidebar}>
{childrenWithProps}
@ -83,7 +22,6 @@ const mapStateToProps = state => {
...state.main,
metadata: state.metadata,
dataHeaders: { ...state.tables.dataHeaders },
serverVersion: state.main.serverVersion,
};
};

View File

@ -8,7 +8,6 @@ import ClearAdminSecret from './ClearAdminSecret';
import { CONSOLE_ADMIN_SECRET } from '../../../AppState';
const MetadataOptions = props => {
const { supportMetadata } = props;
const styles = require('../Metadata.scss');
const getMetadataImportExportSection = () => {
@ -33,40 +32,34 @@ const MetadataOptions = props => {
};
const getMetadataUpdateSection = () => {
let updateSection = null;
if (supportMetadata) {
updateSection = (
<div>
<div key="meta_data_1" className={styles.intro_note}>
<h4>Reload metadata</h4>
<div className={styles.content_width}>
Refresh Hasura metadata, typically required if you have changed
the underlying postgres.
</div>
</div>
<div key="meta_data_2">
<ReloadMetadata {...props} />
</div>
<div key="meta_data_3" className={styles.intro_note}>
<h4>Reset Metadata</h4>
<div className={styles.content_width}>
Permanently clear GraphQL Engine's metadata and configure it from
scratch (tracking relevant tables and relationships). This process
is not reversible.
</div>
</div>
<div key="meta_data_4">
<ResetMetadata {...props} />
return (
<div>
<div key="meta_data_1" className={styles.intro_note}>
<h4>Reload metadata</h4>
<div className={styles.content_width}>
Refresh Hasura metadata, typically required if you have changed the
underlying postgres.
</div>
</div>
);
}
return updateSection;
<div key="meta_data_2">
<ReloadMetadata {...props} />
</div>
<div key="meta_data_3" className={styles.intro_note}>
<h4>Reset Metadata</h4>
<div className={styles.content_width}>
Permanently clear GraphQL Engine's metadata and configure it from
scratch (tracking relevant tables and relationships). This process
is not reversible.
</div>
</div>
<div key="meta_data_4">
<ResetMetadata {...props} />
</div>
</div>
);
};
const getClearSecretSection = () => {
@ -123,6 +116,7 @@ const MetadataOptions = props => {
</a>
</div>
</div>
{getMetadataImportExportSection()}
{getMetadataUpdateSection()}

View File

@ -13,16 +13,12 @@ import CrossIcon from '../../../Common/Icons/Cross';
const MetadataStatus = ({
dispatch,
supportInconsistentMetadata,
metadata,
}) => {
const [shouldShowErrorBanner, toggleErrorBanner] = useState(true);
const dismissErrorBanner = () => {
toggleErrorBanner(false);
};
if (!supportInconsistentMetadata) {
return null;
}
const inconsistentObjectsTable = () => {
return (
<table
@ -100,7 +96,7 @@ const MetadataStatus = ({
};
const reloadCacheAndLoadInconsistentObjects = () => {
dispatch(loadInconsistentObjects(null, true))
dispatch(loadInconsistentObjects(true))
.then(() => {
dispatch(showSuccessNotification('Metadata reloaded'));
})

View File

@ -5,43 +5,37 @@ import styles from '../../Common/TableCommon/Table.scss';
import CheckIcon from '../../Common/Icons/Check';
import CrossIcon from '../../Common/Icons/Cross';
const Sidebar = ({ location, semverChecks, metadata }) => {
const Sidebar = ({ location, metadata }) => {
const sectionsData = [];
if (semverChecks.supportMetadata) {
sectionsData.push({
key: 'actions',
link: '/metadata/actions',
dataTestVal: 'metadata-actions-link',
title: 'Metadata Actions',
});
}
sectionsData.push({
key: 'actions',
link: '/metadata/actions',
dataTestVal: 'metadata-actions-link',
title: 'Metadata Actions',
});
if (semverChecks.supportInconsistentMetadata) {
const consistentIcon =
metadata.inconsistentObjects.length === 0 ? <CheckIcon /> : <CrossIcon />;
const consistentIcon =
metadata.inconsistentObjects.length === 0 ? <CheckIcon /> : <CrossIcon />;
sectionsData.push({
key: 'status',
link: '/metadata/status',
dataTestVal: 'metadata-status-link',
title: (
<div className={styles.display_flex}>
Metadata Status
<span className={styles.add_mar_left}>{consistentIcon}</span>
</div>
),
});
}
sectionsData.push({
key: 'status',
link: '/metadata/status',
dataTestVal: 'metadata-status-link',
title: (
<div className={styles.display_flex}>
Metadata Status
<span className={styles.add_mar_left}>{consistentIcon}</span>
</div>
),
});
if (semverChecks.supportAllowedQueries) {
sectionsData.push({
key: 'allowed-queries',
link: '/metadata/allowed-queries',
dataTestVal: 'metadata-allowed-queries-link',
title: 'Allowed Queries',
});
}
sectionsData.push({
key: 'allowed-queries',
link: '/metadata/allowed-queries',
dataTestVal: 'metadata-allowed-queries-link',
title: 'Allowed Queries',
});
const currentLocation = location.pathname;

View File

@ -1,25 +1,8 @@
const semver = require('semver');
// list of feature launch versions
const componentsSemver = {
eventsTab: '1.0.0-alpha16',
metadataReload: '1.0.0-alpha17',
eventRedeliver: '1.0.0-alpha17',
sqlAnalyze: '1.0.0-alpha25',
aggregationPerm: '1.0.0-alpha26',
supportColumnChangeTrigger: '1.0.0-alpha26',
analyzeApiChange: '1.0.0-alpha26',
insertPrefix: '1.0.0-alpha26',
insertPermRestrictColumns: '1.0.0-alpha28',
webhookEnvSupport: '1.0.0-alpha29',
schemaStitching: '1.0.0-alpha30',
permHideUpsertSection: '1.0.0-alpha32',
customFunctionSection: '1.0.0-alpha36',
triggerRetryTimeout: '1.0.0-alpha38',
permUpdatePresets: '1.0.0-alpha38',
tableColumnRename: '1.0.0-alpha39',
inconsistentState: '1.0.0-alpha43',
allowedQueries: '1.0.0-alpha46',
manualTriggers: '1.0.0-alpha46',
// feature: '1.0.1'
};
const getPreRelease = version => {
@ -27,6 +10,7 @@ const getPreRelease = version => {
if (!prerelease) {
return '';
}
// TODO: fix beta parsing
if (prerelease.length === 1) {
const regex = /(alpha|beta)(\d+)/gm;
const str = prerelease[0];
@ -95,4 +79,6 @@ const semverCheck = (component, serverVersion) => {
return false;
};
export { componentsSemver };
export default semverCheck;

View File

@ -50,7 +50,7 @@
<div id="content" class="mainContent"></div>
<script>
const assetsPathReadyEvent = new Event('assetsPathReadyEvent');
// helper functions
const loadIcon = (url) => {
linkElem = document.createElement('link');
linkElem.rel = 'icon';
@ -72,41 +72,30 @@
document.body.append(scriptElem);
};
const prependSlash = (str) => str === '' ? '' : '/' + str;
document.body.addEventListener('assetsPathReadyEvent', (e) => {
const loadAssets = () => {
loadCSS(window.__env.assetsPath + '/common/css/font-awesome.min.css.gz');
loadIcon(window.__env.assetsPath + '/common/img/hasura_icon_green.svg');
loadCSS(window.__env.versionedAssetsPath + '/main.css.gz');
loadScript(window.__env.versionedAssetsPath + '/main.js.gz');
loadScript(window.__env.versionedAssetsPath + '/vendor.js.gz');
// remove this before merging.
console.log(window.__env.assetsPath + '/common/css/font-awesome.min.css.gz');
console.log(window.__env.assetsPath + '/common/img/hasura_icon_green.svg');
console.log(window.__env.versionedAssetsPath + '/main.css.gz');
console.log(window.__env.versionedAssetsPath + '/main.js.gz');
console.log(window.__env.versionedAssetsPath + '/vendor.js.gz');
}, false);
};
// if cdnAssets is set to false, load assets from server instead of cdn
if (window.__env.cdnAssets === false) {
console.log('cdnAssets=false, loading assets from static-dir');
window.__env.assetsPath =
window.location.pathname.slice(
0, window.location.pathname.lastIndexOf(window.__env.consolePath)
) + '/console/assets';
// set the path to get versioned assets from server
window.__env.versionedAssetsPath = window.__env.assetsPath + '/versioned';
// dispatch the event to load the assets now
document.body.dispatchEvent(assetsPathReadyEvent);
// otherwise load from cdn itself
} else {
console.log('cdnAssets=true, loading assets from cdn');
// set the path (cdn-based) to get assets from
window.__env.versionedAssetsPath = window.__env.assetsPath + prependSlash(window.__env.assetsVersion);
// fire the event
document.body.dispatchEvent(assetsPathReadyEvent);
}
// load the assets now
loadAssets();
</script>
</body>
</html>