Skip to content

Commit

Permalink
feat: support open in explorer (#141)
Browse files Browse the repository at this point in the history
mod: code review
  • Loading branch information
hetao92 authored Mar 9, 2022
1 parent 2c0b69d commit c52a497
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 9 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ name: Studio nightly Package
on:
push:
branches:
- master
- v3.3.0-dev
jobs:
call-workflow:
uses: vesoft-inc/nebula-studio/.github/workflows/build.yml@master
uses: vesoft-inc/nebula-studio/.github/workflows/build.yml@v3.3.0-dev
secrets:
oss_endpoint: ${{ secrets.OSS_ENDPOINT }}
oss_id: ${{ secrets.OSS_ID }}
Expand Down
3 changes: 3 additions & 0 deletions app/app.less
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
border: none;
white-space: nowrap;
color: @darkBlue;
&.ant-radio-button-wrapper-checked {
color: #fff;
}

&:not(.ant-radio-button-wrapper-checked) {
background: none;
Expand Down
4 changes: 2 additions & 2 deletions app/config/locale/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"import": "Import",
"ask": "Are you sure to proceed?",
"output": "Export CSV File",
"openInExplore": "Open In Explore",
"openInExplore": "Open In Explorer",
"schema": "Schema",
"create": "Create",
"serialNumber": "No.",
Expand Down Expand Up @@ -137,7 +137,7 @@
"execTime": "Execution Time",
"exportVertex": "Please choose the column representing vertex IDs from the table",
"exportEdge": "Please choose the columns representing source vertex ID, destination vertex ID, and rank of an edge",
"showSubgraphs": "View Subgraphs",
"showSubgraphs": "Open in Explorer",
"deleteHistory": "Clear History",
"cypherParam": "Cypher Parameter",
"favorites": "Favorites",
Expand Down
148 changes: 148 additions & 0 deletions app/pages/Console/ExportModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { Button, Form, Input, Modal, Radio, Select } from 'antd';
import React from 'react';
import intl from 'react-intl-universal';
import { observer } from 'mobx-react-lite';
import { useStore } from '@app/stores';

import './index.less';
const Option = Select.Option;

const layout = {
labelCol: { span: 10 },
wrapperCol: { span: 8 },
};

interface IProps {
data: any;
visible: boolean;
onClose: () => void;
onExplorer: (params: {
space: string;
vertexes: any[],
edges: any[]
}) => void
}
const ExportModal = (props: IProps) => {
const { data, visible, onClose, onExplorer } = props;
const { schema: { currentSpace } } = useStore();
const { headers, tables } = data;
const handleExport = (values) => {
const { type, vertexId, srcId, dstId, edgeType, rank } = values;
const vertexes =
type === 'vertex'
? tables
.map(vertex => {
if (vertex.type === 'vertex') {
return vertex.vid;
} else {
return vertex[vertexId].toString();
}
})
.filter(vertexId => vertexId !== '')
: tables
.map(edge => [edge[srcId], edge[dstId]])
.flat()
.filter(id => id !== '');
const edges =
type === 'edge'
? tables
.map(edge => ({
srcId: edge[srcId],
dstId: edge[dstId],
rank: rank !== '' && rank !== undefined ? edge[rank] : 0,
edgeType,
}))
.filter(edge => edge.srcId !== '' && edge.dstId !== '')
: [];
onExplorer({
space: currentSpace,
vertexes,
edges
});
};
if(!data) {
return;
}
return (
<Modal
className="export-node-modal"
footer={null}
width="650px"
visible={visible}
onCancel={onClose}
>
<Form {...layout} onFinish={handleExport} initialValues={{
type: 'vertex'
}}>
<Form.Item name="type" className="select-type">
<Radio.Group className="nebula-tab-group" buttonStyle="solid">
<Radio.Button value="vertex">
{intl.get('import.vertexText')}
</Radio.Button>
<Radio.Button value="edge">
{intl.get('common.edge')}
</Radio.Button>
</Radio.Group>
</Form.Item>
<Form.Item noStyle={true} dependencies={['type']}>
{({ getFieldValue }) => {
const type = getFieldValue('type');
return type === 'vertex' ? <>
<p>{intl.get('console.exportVertex')}</p>
<Form.Item className="select-component" label="vid" name="vertexId" rules={[{ required: true }]}>
<Select>
{headers.map(i => (
<Option value={i} key={i}>
{i}
</Option>
))}
</Select>
</Form.Item>
</> : <>
<p>{intl.get('console.exportEdge')}</p>
<Form.Item className="select-component" label="Edge Type" name="edgeType" rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item className="select-component" label="Src ID" name="srcId" rules={[{ required: true }]}>
<Select>
{headers.map(i => (
<Option value={i} key={i}>
{i}
</Option>
))}
</Select>
</Form.Item>
<Form.Item className="select-component" label="Dst ID" name="dstId" rules={[{ required: true }]}>
<Select>
{headers.map(i => (
<Option value={i} key={i}>
{i}
</Option>
))}
</Select>
</Form.Item>
<Form.Item className="select-component" label="Rank" name="rank">
<Select allowClear={true}>
{headers.map(i => (
<Option value={i} key={i}>
{i}
</Option>
))}
</Select>
</Form.Item>
</>;
}}
</Form.Item>
<Form.Item noStyle={true}>
<Button
htmlType="submit"
type="primary"
>
{intl.get('common.import')}
</Button>
</Form.Item>
</Form>
</Modal>
);
};
export default observer(ExportModal);
1 change: 1 addition & 0 deletions app/pages/Console/OutputBox/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
.output-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 15px 18px;
width: 100%;
height: 65px;
Expand Down
40 changes: 37 additions & 3 deletions app/pages/Console/OutputBox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Table, Tabs, Tooltip } from 'antd';
import { Button, Table, Tabs, Tooltip } from 'antd';
import { BigNumber } from 'bignumber.js';
import React, { useCallback, useEffect, useState } from 'react';
import intl from 'react-intl-universal';
Expand All @@ -8,6 +8,7 @@ import { trackEvent } from '@app/utils/stat';
import { v4 as uuidv4 } from 'uuid';
import Icon from '@app/components/Icon';
import Graphviz from './Graphviz';
import { parseSubGraph } from '@app/utils/parseData';

import './index.less';
import classNames from 'classnames';
Expand All @@ -17,14 +18,21 @@ interface IProps {
gql: string;
result: any;
onHistoryItem: (gql: string) => void;
onExplorer?: (params: {
space: string;
vertexes: any[],
edges: any[]
}) => void;
onResultConfig?: (data: any) => void
}

const OutputBox = (props: IProps) => {
const { gql, result: { code, data, message }, onHistoryItem, index } = props;
const { global, console } = useStore();
const { gql, result: { code, data, message }, onHistoryItem, index, onExplorer, onResultConfig } = props;
const { global, console, schema } = useStore();
const [visible, setVisible] = useState(true);
const { username, host } = global;
const { results, update, favorites, updateFavorites } = console;
const { spaceVidType, currentSpace } = schema;
const [columns, setColumns] = useState<any>([]);
const [dataSource, setDataSource] = useState<any>([]);
const [isFavorited, setIsFavorited] = useState(false);
Expand Down Expand Up @@ -165,6 +173,31 @@ const OutputBox = (props: IProps) => {
link.click();
document.body.removeChild(link);
};

const handleExplore = () => {
if (
data.tables.filter(
item =>
item._verticesParsedList ||
item._edgesParsedList ||
item._pathsParsedList,
).length > 0
) {
parseToGraph();
} else {
onResultConfig!(data);
}
};

const parseToGraph = () => {
const { vertexes, edges } = parseSubGraph(data.tables, spaceVidType);
onExplorer!({
space: currentSpace,
vertexes,
edges
});
};

return <div className="output-box">
<div className="output-header">
<p className={classNames('gql', { 'error-info': code !== 0 })} onClick={() => onHistoryItem(gql)}>
Expand Down Expand Up @@ -266,6 +299,7 @@ const OutputBox = (props: IProps) => {
{`${intl.get('console.execTime')} ${data.timeCost /
1000000} (s)`}
</span>
{onExplorer && <Button className="primary-btn" type="text" onClick={handleExplore}>{intl.get('common.openInExplore')}</Button>}
</div>
)}
</>}
Expand Down
9 changes: 9 additions & 0 deletions app/pages/Console/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@
}
}

.export-node-modal {
.select-type {
display: inline-flex;
}
.ant-modal-body {
text-align: center;
}
}

.historyList, .favoriteList {
height: 80%;
overflow: hidden;
Expand Down
36 changes: 34 additions & 2 deletions app/pages/Console/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Button, Select, Tooltip, message } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import intl from 'react-intl-universal';
import { observer } from 'mobx-react-lite';
import { trackPageView } from '@app/utils/stat';
import { trackPageView, trackEvent } from '@app/utils/stat';
import { useStore } from '@app/stores';
import Instruction from '@app/components/Instruction';
import Icon from '@app/components/Icon';
Expand All @@ -12,6 +12,7 @@ import { maxLineNum } from '@app/config/nebulaQL';
import HistoryBtn from './HistoryBtn';
import FavoriteBtn from './FavoriteBtn';
import CypherParameterBox from './CypherParameterBox';
import ExportModal from './ExportModal';
import './index.less';
const Option = Select.Option;

Expand All @@ -26,12 +27,22 @@ const getHistory = () => {
return [];
};

const Console = () => {
interface IProps {
onExplorer?: (params: {
space: string;
vertexes: any[],
edges: any[]
}) => void
}
const Console = (props: IProps) => {
const { schema, console, global } = useStore();
const { onExplorer } = props;
const { spaces, getSpaces, switchSpace, currentSpace } = schema;
const { runGQL, currentGQL, results, runGQLLoading, getParams, update, paramsMap } = console;
const { username, host } = global;
const [isUpDown, setUpDown] = useState(false);
const [modalVisible, setModalVisible] = useState(false);
const [modalData, setModalData] = useState<any>(null);
const editor = useRef<any>(null);
useEffect(() => {
trackPageView('/console');
Expand Down Expand Up @@ -93,6 +104,20 @@ const Console = () => {
const addParam = (param: string) => {
update({ currentGQL: currentGQL + ` $${param}` });
};

const handleResultConfig = (data: any) => {
setModalData(data);
setModalVisible(true);
};

const handleExplorer = (data) => {
if(!onExplorer) {
return;
}
onExplorer!(data);
!modalVisible && setModalVisible(false);
trackEvent('navigation', 'view_explore', 'from_console_btn');
};
return (
<div className="nebula-console">
<div className="space-select">
Expand Down Expand Up @@ -146,7 +171,9 @@ const Console = () => {
index={index}
result={item}
gql={item.gql}
onExplorer={onExplorer ? handleExplorer : undefined}
onHistoryItem={gql => updateGql(gql)}
onResultConfig={handleResultConfig}
/>
)) : <OutputBox
key="empty"
Expand All @@ -157,6 +184,11 @@ const Console = () => {
/>}
</div>
</div>
{modalVisible && <ExportModal
visible={modalVisible}
data={modalData}
onClose={() => setModalVisible(false)}
onExplorer={handleExplorer} />}
</div>
);
};
Expand Down
1 change: 1 addition & 0 deletions scripts/deb/start.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/bash
mkdir -p /usr/lib/systemd/system
cd /usr/local/nebula-graph-studio/
cp ./lib/nebula-graph-studio.service /usr/lib/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable nebula-graph-studio.service && sudo systemctl start nebula-graph-studio.service

0 comments on commit c52a497

Please sign in to comment.