Skip to content

Commit

Permalink
feat: support cypher parameter
Browse files Browse the repository at this point in the history
refactor: change to  English comment

fix: remove sessionStorage

fix: wrapper safeParse

mod: add param query

mod: remove code
  • Loading branch information
xigongdaEricyang authored and hetao92 committed Dec 28, 2021
1 parent e19daae commit 5f59f9a
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 29 deletions.
3 changes: 2 additions & 1 deletion app/assets/components/CodeMirror.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default class ReactCodeMirror extends React.PureComponent<IProps, any> {
if (stream.eatSpace()) {
return null;
}
stream.eatWhile(/[\$\w\u4e00-\u9fa5]/);
stream.eatWhile(/[\$:\w\u4e00-\u9fa5]/);
const cur = stream.current();
if (keyWords.some(item => item === cur)) {
return 'keyword';
Expand Down Expand Up @@ -127,6 +127,7 @@ export default class ReactCodeMirror extends React.PureComponent<IProps, any> {
change.preventDefault();
}
};

codemirrorValueChange = (doc, change) => {
if (change.origin !== 'setValue') {
if (this.props.onChange) {
Expand Down
5 changes: 5 additions & 0 deletions app/assets/config/nebulaQL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ const nebulaWordsUppercase = [
'USERS',
'UUID',
'VALUES',
'COMMENT',
':PARAM',
':PARAMS',
];

export const ban = ['use', 'USE'];
Expand Down Expand Up @@ -217,6 +220,8 @@ export const operators = [
'MINUS',
// uuid
'uuid',
// assignment
'=>',
];

const nebulaWordsLowercase = nebulaWordsUppercase.map(w => w.toLowerCase());
Expand Down
32 changes: 32 additions & 0 deletions app/assets/modules/Console/LocalCmdOutputBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Alert } from 'antd';
import React from 'react';

import './index.less';

interface IProps {
cmd: string;
result?: string;
onHistoryItem: (value: string) => void;
}

class LocalCmdOutputBox extends React.Component<IProps> {
render() {
const { cmd, result } = this.props;
return (
<div className="cmd-box">
<Alert
message={
<p className="gql" onClick={() => this.props.onHistoryItem(cmd)}>
$ {cmd}
</p>
}
className="cmd-value"
type={result?.includes('success') ? 'success' : 'error'}
/>
<div className="cmd-result">{result}</div>
</div>
);
}
}

export default LocalCmdOutputBox;
35 changes: 35 additions & 0 deletions app/assets/modules/Console/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,38 @@
}
}

.cmd-box {
background: #fff;
position: relative;
display: flex;
flex-direction: column;
margin-bottom: 15px;

.cmd-value {
padding: 0 12px;
width: 100%;
cursor: pointer;
font-size: 16px;
white-space: nowrap;
text-overflow: ellipsis;
line-height: 42px;
border: none;

.gql {
overflow: hidden;
text-overflow: ellipsis;
}
}

.ant-alert-success .gql {
color: #52c41a;
}

.ant-alert-error .gql {
color: #ff4d4f;
}

.cmd-result {
padding: 20px;
}
}
98 changes: 74 additions & 24 deletions app/assets/modules/Console/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ import { IDispatch, IRootState } from '#assets/store';
import { trackPageView } from '#assets/utils/stat';

import './index.less';
import LocalCmdOutputBox from './LocalCmdOutputBox';
import SpaceSearchInput from './SpaceSearchInput';

interface IState {
isUpDown: boolean;
history: boolean;
lastCmd: string | null;
lastGql: string | null;
}

const mapState = (state: IRootState) => ({
Expand All @@ -41,6 +44,8 @@ interface IProps
ReturnType<typeof mapDispatch>,
RouteComponentProps {}

// split from semicolon out of quotation marks
const SEMICOLON_REG = /((?:[^;'"]*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')[^;'"]*)+)|;/;
class Console extends React.Component<IProps, IState> {
codemirror;
editor;
Expand All @@ -51,6 +56,8 @@ class Console extends React.Component<IProps, IState> {
this.state = {
isUpDown: true,
history: false,
lastCmd: null,
lastGql: null,
};
}

Expand All @@ -66,36 +73,68 @@ class Console extends React.Component<IProps, IState> {
return [];
};

handleSaveQuery = (query: string) => {
if (query !== '') {
const history = this.getLocalStorage();
history.push(query);
localStorage.setItem('history', JSON.stringify(history));
}
};

checkSwitchSpaceGql = (query: string) => {
const queryList = query.split(SEMICOLON_REG).filter(Boolean);
const reg = /^USE `?[0-9a-zA-Z_]+`?(?=[\s*;?]?)/gim;
if (queryList.some(sentence => sentence.trim().match(reg))) {
return intl.get('common.disablesUseToSwitchSpace');
}
};
handleRun = async () => {
const gql = this.editor.getValue();
if (!gql) {
const query = this.editor.getValue();
if (!query) {
message.error(intl.get('common.sorryNGQLCannotBeEmpty'));
return;
}
// Hack:
// replace the string in quotes with a constant, avoid special symbols in quotation marks from affecting regex match
// then split the gql entered by the user into sentences based on semicolons
// use regex to determine whether each sentence is a 'use space' statement
const _gql = gql
.replace(/[\r\n]/g, '')
.replace(/(["'])[^]*?\1/g, '_CONTENT_')
.toUpperCase();
const sentenceList = _gql.split(';');
const reg = /^USE `?[0-9a-zA-Z_]+`?(?=[\s*;?]?)/gm;
if (sentenceList.some(sentence => sentence.match(reg))) {
return message.error(intl.get('common.disablesUseToSwitchSpace'));
const errInfo = this.checkSwitchSpaceGql(query);
if (errInfo) {
return message.error(errInfo);
}

this.editor.execCommand('goDocEnd');
const history = this.getLocalStorage();
history.push(gql);
localStorage.setItem('history', JSON.stringify(history));
const { gqlList, paramList } = this.splitQuery(query);
const _gql = gqlList.join(';');
const _cmd = paramList.join(';');
this.handleSaveQuery(_gql);
this.handleSaveQuery(_cmd);

await this.props.asyncRunGQL(gql);
await this.props.asyncRunGQL({
gql: _gql,
paramList,
});
this.setState({
isUpDown: true,
lastCmd: _cmd,
lastGql: _gql,
});
};

splitQuery = (query: string) => {
const queryList = query.split(SEMICOLON_REG).filter(Boolean);
const paramList: string[] = [];
const gqlList: string[] = [];
queryList.forEach(query => {
const _query = query.trim();
if (_query.startsWith(':')) {
paramList.push(_query);
} else {
gqlList.push(_query);
}
});
return {
paramList,
gqlList,
};
};

handleHistoryItem = (value: string) => {
this.props.updateCurrentGQL(value);
this.setState({
Expand Down Expand Up @@ -148,7 +187,7 @@ class Console extends React.Component<IProps, IState> {
};

render() {
const { isUpDown, history } = this.state;
const { isUpDown, history, lastCmd, lastGql } = this.state;
const { currentSpace, currentGQL, result, runGQLLoading } = this.props;
return (
<div className="nebula-console padding-page">
Expand Down Expand Up @@ -207,11 +246,22 @@ class Console extends React.Component<IProps, IState> {
</div>
</div>
<div className="result-wrap">
<OutputBox
result={result}
value={this.getLocalStorage().pop()}
onHistoryItem={e => this.handleHistoryItem(e)}
/>
{lastCmd && (
<LocalCmdOutputBox
cmd={lastCmd}
result={result.cmdResult as string}
onHistoryItem={e => this.handleHistoryItem(e)}
/>
)}
{lastGql !== '' && (
<OutputBox
result={result}
value={this.getLocalStorage()
.filter(item => !item.startsWith(':'))
.pop()}
onHistoryItem={e => this.handleHistoryItem(e)}
/>
)}
</div>
<Modal
title={
Expand Down
12 changes: 8 additions & 4 deletions app/assets/store/models/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { createModel } from '@rematch/core';
import service from '#assets/config/service';

interface IState {
version: string;
currentGQL: string;
result: any;
}

export const _console = createModel({
state: {
currentGQL: 'SHOW SPACES;',
result: {},
},
} as IState,
reducers: {
update: (state: IState, payload: any) => {
return {
Expand All @@ -20,9 +21,12 @@ export const _console = createModel({
},
},
effects: {
async asyncRunGQL(gql) {
async asyncRunGQL({ gql, paramList }) {
const result = (await service.execNGQL(
{ gql },
{
gql,
paramList,
},
{
trackEventConfig: {
category: 'console',
Expand Down

0 comments on commit 5f59f9a

Please sign in to comment.