这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
5 changes: 4 additions & 1 deletion console/src/Globals.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SERVER_CONSOLE_MODE } from './constants';
import { getFeaturesCompatibility } from './helpers/versionUtils';
import { stripTrailingSlash } from './components/Common/utils/urlUtils';
import { isEmpty } from './components/Common/utils/jsUtils';

// TODO: move this section to a more appropriate location
/* set helper tools into window */
Expand Down Expand Up @@ -29,7 +30,9 @@ const globals = {
urlPrefix: stripTrailingSlash(window.__env.urlPrefix || '/'), // overridden below if server mode in production
adminSecret: window.__env.adminSecret || null, // gets updated after login/logout in server mode
isAdminSecretSet:
window.__env.isAdminSecretSet || window.__env.adminSecret || false,
window.__env.isAdminSecretSet ||
!isEmpty(window.__env.adminSecret) ||
false,
consoleMode: window.__env.consoleMode || SERVER_CONSOLE_MODE,
enableTelemetry: window.__env.enableTelemetry,
telemetryTopic: isProduction ? 'console' : 'console_test',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,25 @@ import React from 'react';

import WarningSymbol from '../WarningSymbol/WarningSymbol';

const GqlCompatibilityWarning = () => {
const gqlPattern = /^[_A-Za-z][_0-9A-Za-z]*$/;

const GqlCompatibilityWarning = ({ identifier, className = null }) => {
const isGraphQLCompatible = gqlPattern.test(identifier);

if (isGraphQLCompatible) {
return null;
}

const gqlCompatibilityTip =
'This identifier name does not conform to the GraphQL naming standard. Names in GraphQL should be limited to this ASCII subset: /[_A-Za-z][_0-9A-Za-z]*/.';
'This identifier name does not conform to the GraphQL naming standard. ' +
'Names in GraphQL should be limited to this ASCII subset: /[_A-Za-z][_0-9A-Za-z]*/. ' +
'All GraphQL types depending on this identifier will not be exposed over the GraphQL API';

return <WarningSymbol tooltipText={gqlCompatibilityTip} />;
return (
<span className={className}>
<WarningSymbol tooltipText={gqlCompatibilityTip} />
</span>
);
};

export default GqlCompatibilityWarning;
21 changes: 11 additions & 10 deletions console/src/components/Common/utils/v1QueryUtils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
export const getRunSqlQuery = (sql, shouldCascade, readOnly) => {
return {
type: 'run_sql',
args: {
sql,
cascade: !!shouldCascade,
read_only: !!readOnly,
},
};
};

export const getCreatePermissionQuery = (
action,
tableDef,
Expand Down Expand Up @@ -39,13 +50,3 @@ export const getSetCustomRootFieldsQuery = (
},
};
};

export const getRunSqlQuery = (sql, shouldCascade) => {
return {
type: 'run_sql',
args: {
sql,
cascade: !!shouldCascade,
},
};
};
2 changes: 1 addition & 1 deletion console/src/components/Error/ErrorPage.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

.errorStack {
max-height: 300px;
width: 450px;
width: 95%;
}
}
}
Expand Down
51 changes: 32 additions & 19 deletions console/src/components/Services/About/About.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import React, { Component } from 'react';
import Helmet from 'react-helmet';

import Endpoints from '../../../Endpoints';
import Endpoints, { globalCookiePolicy } from '../../../Endpoints';

import globals from '../../../Globals';

import styles from './About.scss';
import requestAction from '../../../utils/requestAction';
import { showErrorNotification } from '../Common/Notification';
import { getRunSqlQuery } from '../../Common/utils/v1QueryUtils';

class About extends Component {
state = {
Expand All @@ -32,24 +35,32 @@ class About extends Component {
})
);

fetch(Endpoints.query, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'run_sql',
args: {
sql: 'SELECT version();',
const fetchPgVersion = () => {
const { dispatch, dataHeaders } = this.props;

const url = Endpoints.query;
const options = {
method: 'POST',
credentials: globalCookiePolicy,
headers: dataHeaders,
body: JSON.stringify(getRunSqlQuery('SELECT version();', false, true)),
};

dispatch(requestAction(url, options)).then(
data => {
this.setState({
pgVersion: data.result[1][0],
});
},
}),
})
.then(response => response.json())
.then(data =>
this.setState({
pgVersion: data.result[1],
})
error => {
dispatch(
showErrorNotification('Failed fetching PG version', null, error)
);
}
);
};

fetchPgVersion();
}

render() {
Expand Down Expand Up @@ -165,8 +176,10 @@ class About extends Component {
}
}

const mapStateToProps = () => {
return {};
const mapStateToProps = state => {
return {
dataHeaders: state.tables.dataHeaders,
};
};

const aboutConnector = connect => connect(mapStateToProps)(About);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
getAdminSecret,
getPersistedAdminSecretHeaderWasAdded,
persistAdminSecretHeaderWasAdded,
removePersistedAdminSecretHeaderWasAdded,
} from './utils';

import styles from '../ApiExplorer.scss';
Expand Down Expand Up @@ -90,6 +91,7 @@ class ApiRequest extends Component {
if (adminSecret && !adminSecretHeaderWasAdded) {
const headerKeys = graphiqlHeaders.map(h => h.key);

// add admin secret header if not present
if (!headerKeys.includes(ADMIN_SECRET_HEADER_KEY)) {
graphiqlHeaders.push({
key: ADMIN_SECRET_HEADER_KEY,
Expand All @@ -104,6 +106,22 @@ class ApiRequest extends Component {
persistAdminSecretHeaderWasAdded();
}

// if admin secret is not set and admin secret header was ever added to headers, remove admin secret header if present
if (!adminSecret && adminSecretHeaderWasAdded) {
const headerKeys = graphiqlHeaders.map(h => h.key);

// remove admin secret header if present
const adminSecretHeaderIndex = headerKeys.indexOf(
ADMIN_SECRET_HEADER_KEY
);
if (adminSecretHeaderIndex >= 0) {
graphiqlHeaders.splice(adminSecretHeaderIndex, 1);
}

// remove from local storage that admin secret header has been automatically added
removePersistedAdminSecretHeaderWasAdded();
}

// add an empty placeholder header
graphiqlHeaders.push({
key: '',
Expand Down
20 changes: 14 additions & 6 deletions console/src/components/Services/ApiExplorer/ApiRequest/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,26 @@ export const getAdminSecret = () => {
return adminSecret;
};

const LS_API_EXPLORER_ADMIN_SECRET_HEADER_WAS_ADDED =
'ApiExplorer:AdminSecretHeaderWasAdded';

export const persistAdminSecretHeaderWasAdded = () => {
window.localStorage.setItem('ApiExplorer:AdminSecretHeaderWasAdded', true);
window.localStorage.setItem(
LS_API_EXPLORER_ADMIN_SECRET_HEADER_WAS_ADDED,
'true'
);
};

export const getPersistedAdminSecretHeaderWasAdded = () => {
const defaultIsSet = false;
export const removePersistedAdminSecretHeaderWasAdded = () => {
window.localStorage.removeItem(LS_API_EXPLORER_ADMIN_SECRET_HEADER_WAS_ADDED);
};

const isSet = window.localStorage.getItem(
'ApiExplorer:AdminSecretHeaderWasAdded'
export const getPersistedAdminSecretHeaderWasAdded = () => {
const lsValue = window.localStorage.getItem(
LS_API_EXPLORER_ADMIN_SECRET_HEADER_WAS_ADDED
);

return isSet ? isSet === 'true' : defaultIsSet;
return lsValue ? lsValue === 'true' : false;
};

export const persistGraphiQLHeaders = headers => {
Expand Down
5 changes: 5 additions & 0 deletions console/src/components/Services/Data/DataPageContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import globals from '../../../Globals';
import LeftContainer from '../../Common/Layout/LeftContainer/LeftContainer';
import PageContainer from '../../Common/Layout/PageContainer/PageContainer';
import DataSubSidebar from './DataSubSidebar';
import GqlCompatibilityWarning from '../../Common/GqlCompatibilityWarning/GqlCompatibilityWarning';

import { updateCurrentSchema } from './DataActions';
import { NotFoundError } from '../../Error/PageNotFound';
Expand Down Expand Up @@ -77,6 +78,10 @@ const DataPageContainer = ({
>
{getSchemaOptions()}
</select>
<GqlCompatibilityWarning
identifier={currentSchema}
className={styles.add_mar_left_mid}
/>
</div>
</div>
</Link>
Expand Down
15 changes: 4 additions & 11 deletions console/src/components/Services/Data/DataSubSidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { connect } from 'react-redux';
import { Link } from 'react-router';

import LeftSubSidebar from '../../Common/Layout/LeftSubSidebar/LeftSubSidebar';
import gqlPattern from './Common/GraphQLValidation';
import GqlCompatibilityWarning from '../../Common/GqlCompatibilityWarning/GqlCompatibilityWarning';
import {
displayTableName,
Expand Down Expand Up @@ -107,15 +106,6 @@ class DataSubSidebar extends React.Component {
const isActive =
tableName === currentTable && currentLocation.includes(tableName);

let gqlCompatibilityWarning = null;
if (!gqlPattern.test(tableName)) {
gqlCompatibilityWarning = (
<span className={styles.add_mar_left_mid}>
<GqlCompatibilityWarning />
</span>
);
}

return (
<li
className={isActive ? styles.activeLink : ''}
Expand All @@ -135,7 +125,10 @@ class DataSubSidebar extends React.Component {
/>
{displayTableName(table)}
</Link>
{gqlCompatibilityWarning}
<GqlCompatibilityWarning
identifier={tableName}
className={styles.add_mar_left_mid}
/>
</li>
);
});
Expand Down
36 changes: 33 additions & 3 deletions console/src/components/Services/Data/RawSQL/RawSQL.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import Helmet from 'react-helmet';
import AceEditor from 'react-ace';
Expand Down Expand Up @@ -40,6 +40,32 @@ const RawSQL = ({
}) => {
const styles = require('../../../Common/TableCommon/Table.scss');

/* hooks */

// set up sqlRef to use in unmount
const sqlRef = useRef(sql);

// set SQL from localStorage on mount and write back to localStorage on unmount
useEffect(() => {
const LS_RAW_SQL_SQL = 'rawSql:sql';

const sqlFromLocalStorage = localStorage.getItem(LS_RAW_SQL_SQL);
if (sqlFromLocalStorage) {
dispatch({ type: SET_SQL, data: sqlFromLocalStorage });
}

return () => {
localStorage.setItem(LS_RAW_SQL_SQL, sqlRef.current);
};
}, []);

// set SQL to sqlRef
useEffect(() => {
sqlRef.current = sql;
}, [sql]);

/* hooks - end */

const cascadeTip = (
<Tooltip id="tooltip-cascade">
Cascade actions on all dependent metadata references, like relationships
Expand Down Expand Up @@ -252,7 +278,9 @@ const RawSQL = ({
<h4 className={styles.subheading_text}>SQL Result:</h4>
<div className={styles.tableContainer}>
<table
className={`table table-bordered table-striped table-hover ${styles.table} `}
className={`table table-bordered table-striped table-hover ${
styles.table
} `}
>
<thead>
<tr>{getTableHeadings()}</tr>
Expand Down Expand Up @@ -474,7 +502,9 @@ const RawSQL = ({
</div>

<div
className={`${styles.padd_left_remove} ${styles.add_mar_bottom} col-xs-8`}
className={`${styles.padd_left_remove} ${
styles.add_mar_bottom
} col-xs-8`}
>
{getTrackThisSection()}
{getMetadataCascadeSection()}
Expand Down
Loading