show warning for tables, columns, relationships which do not conform to GraphQL naming scheme (close #212) (#2422)

This commit is contained in:
Aravind Shankar 2019-07-24 20:11:18 +05:30 committed by Rikin Kachhia
parent 3445de3630
commit 4405bac577
9 changed files with 111 additions and 53 deletions

View File

@ -116,7 +116,7 @@ table thead tr th {
display: inline-block;
}
}
}
}
}
.sidebarCreateTable {

View File

@ -0,0 +1,30 @@
import React from 'react';
import Tooltip from 'react-bootstrap/lib/Tooltip';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
import styles from './GqlCompatibilityWarning.scss';
const GqlCompatibilityWarning = () => {
const gqlCompatibilityTip = (
<Tooltip id="tooltip-scheme-warning">
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]*/.
</Tooltip>
);
return (
<div className={styles.display_inline}>
<OverlayTrigger placement="right" overlay={gqlCompatibilityTip}>
<i
className={`fa fa-exclamation-triangle ${
styles.gqlCompatibilityWarning
}`}
aria-hidden="true"
/>
</OverlayTrigger>
</div>
);
};
export default GqlCompatibilityWarning;

View File

@ -0,0 +1,5 @@
@import "../Common.scss";
.gqlCompatibilityWarning {
color: #d9534f;
}

View File

@ -133,7 +133,7 @@
li {
border-bottom: 0px !important;
padding: 0 0 !important;
padding: 4px 0 !important;
.tableFunctionDivider {
margin-top: 5px;
@ -146,6 +146,7 @@
padding: 5px 0px !important;
font-weight: 400 !important;
padding-left: 5px !important;
display: initial !important;
.tableIcon, .functionIcon {
margin-right: 5px;

View File

@ -3,6 +3,8 @@ 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';
const appPrefix = '/data';
@ -101,6 +103,8 @@ class DataSubSidebar extends React.Component {
tableLinks = Object.keys(tables)
.sort()
.map((tableName, i) => {
let _childLink;
let activeTableClass = '';
if (
tableName === currentTable &&
@ -108,8 +112,15 @@ class DataSubSidebar extends React.Component {
) {
activeTableClass = styles.activeTable;
}
const gqlCompatibilityWarning = !gqlPattern.test(tableName) ? (
<span className={styles.add_mar_left_mid}>
<GqlCompatibilityWarning />
</span>
) : null;
if (tables[tableName].table_type === 'BASE TABLE') {
return (
_childLink = (
<li className={activeTableClass} key={i}>
<Link
to={
@ -128,31 +139,35 @@ class DataSubSidebar extends React.Component {
/>
{tableName}
</Link>
{gqlCompatibilityWarning}
</li>
);
} else {
_childLink = (
<li className={activeTableClass} key={i}>
<Link
to={
appPrefix +
'/schema/' +
currentSchema +
'/views/' +
tableName +
'/browse'
}
data-test={tableName}
>
<i
className={styles.tableIcon + ' fa fa-table'}
aria-hidden="true"
/>
<i>{tableName}</i>
</Link>
{gqlCompatibilityWarning}
</li>
);
}
return (
<li className={activeTableClass} key={i}>
<Link
to={
appPrefix +
'/schema/' +
currentSchema +
'/views/' +
tableName +
'/browse'
}
data-test={tableName}
>
<i
className={styles.tableIcon + ' fa fa-table'}
aria-hidden="true"
/>
<i>{tableName}</i>
</Link>
</li>
);
return _childLink;
});
}

View File

@ -31,6 +31,8 @@ import globals from '../../../../Globals';
import { getRelDef } from '../TableRelationships/utils';
import { createNewSchema, deleteCurrentSchema } from './Actions';
import CollapsibleToggle from '../../../Common/CollapsibleToggle/CollapsibleToggle';
import gqlPattern from '../Common/GraphQLValidation';
import GqlCompatibilityWarning from '../../../Common/GqlCompatibilityWarning/GqlCompatibilityWarning';
const appPrefix = globals.urlPrefix + '/data';
@ -98,6 +100,11 @@ class Schema extends Component {
table => !table.is_table_tracked && table.table_schema === currentSchema
);
// update tableInfo with graphql compatibility
_untrackedTables.forEach(t => {
t.isGQLCompatible = gqlPattern.test(t.table_name);
});
return _untrackedTables.sort(tableSortFunc);
};
@ -317,6 +324,12 @@ class Schema extends Component {
dispatch(addExistingTableSql());
};
const gqlCompatibilityWarning = !table.isGQLCompatible ? (
<span className={styles.add_mar_left_mid}>
<GqlCompatibilityWarning />
</span>
) : null;
untrackedTablesList.push(
<div className={styles.padd_bottom} key={`untracked-${i}`}>
<div
@ -333,6 +346,7 @@ class Schema extends Component {
</Button>
</div>
<div className={styles.display_inline}>{table.table_name}</div>
{gqlCompatibilityWarning}
</div>
);
});

View File

@ -17,6 +17,9 @@ import {
inferDefaultValues,
} from '../Common/utils';
import gqlPattern from '../Common/GraphQLValidation';
import GqlCompatibilityWarning from '../../../Common/GqlCompatibilityWarning/GqlCompatibilityWarning';
import styles from './ModifyTable.scss';
const ColumnEditorList = ({
@ -96,6 +99,14 @@ const ColumnEditorList = ({
}
};
const gqlCompatibilityWarning = () => {
return !gqlPattern.test(colName) ? (
<span className={styles.add_mar_left_small}>
<GqlCompatibilityWarning />
</span>
) : null;
};
const keyProperties = () => {
const propertiesDisplay = [];
@ -121,9 +132,7 @@ const ColumnEditorList = ({
const keyPropertiesString = propertiesList.join(', ');
propertiesDisplay.push(
<i key={'props'}>{keyPropertiesString && `- ${keyPropertiesString}`}</i>
);
propertiesDisplay.push(<i key={'props'}>{keyPropertiesString}</i>);
propertiesDisplay.push(<br key={'br1'} />);
@ -139,7 +148,7 @@ const ColumnEditorList = ({
const collapsedLabel = () => {
return (
<div key={colName}>
<b>{colName}</b> {keyProperties()}
<b>{colName}</b> {gqlCompatibilityWarning()} - {keyProperties()}
</div>
);
};

View File

@ -4,7 +4,10 @@ import Button from '../../../Common/Button/Button';
import { deleteRelMigrate, saveRenameRelationship } from './Actions';
import { showErrorNotification } from '../../Common/Notification';
import gqlPattern, { gqlRelErrorNotif } from '../Common/GraphQLValidation';
import GqlCompatibilityWarning from '../../../Common/GqlCompatibilityWarning/GqlCompatibilityWarning';
import styles from '../TableModify/ModifyTable.scss';
import tableStyles from '../../../Common/TableCommon/TableStyles.scss';
class RelationshipEditor extends React.Component {
constructor(props) {
@ -71,7 +74,11 @@ class RelationshipEditor extends React.Component {
const { text, isEditting } = this.state;
const { relName } = relConfig;
const tableStyles = require('../../../Common/TableCommon/TableStyles.scss');
const gqlCompatibilityWarning = !gqlPattern.test(relName) ? (
<span className={styles.add_mar_left_small}>
<GqlCompatibilityWarning />
</span>
) : null;
const onDelete = e => {
e.preventDefault();
@ -91,7 +98,7 @@ class RelationshipEditor extends React.Component {
Edit
</Button>
&nbsp;
<b>{relName}</b>
<b>{relName}</b> {gqlCompatibilityWarning}
<div className={tableStyles.relationshipTopPadding}>
{getRelDef(relConfig)}
</div>

View File

@ -623,29 +623,6 @@ GROUP BY t.typname
ORDER BY t.typname ASC;
`;
export const fetchTableTriggersSQL = (schema, table) => {
return `
select
COALESCE(
json_agg(
row_to_json(t)
),
'[]' :: JSON
) AS result FROM (
select
trigger_schema,
trigger_name,
event_manipulation,
action_timing,
action_statement,
event_object_schema,
event_object_table
FROM information_schema.triggers
WHERE event_object_schema = '${schema}' AND event_object_table = '${table}'
) AS t
`;
};
const postgresFunctionTester = /.*\(\)$/gm;
export const isPostgresFunction = str =>