- {taskStatus === ITaskStatus.statusProcessing &&
+ {taskStatus === ITaskStatus.StatusProcessing &&
{
>
}
- {taskStatus !== ITaskStatus.statusProcessing &&
+ {taskStatus !== ITaskStatus.StatusProcessing &&
{
};
}, []);
useEffect(() => {
- const needRefresh = taskList.filter(item => item.taskStatus === ITaskStatus.statusProcessing).length > 0;
+ const needRefresh = taskList.filter(item => item.taskStatus === ITaskStatus.StatusProcessing).length > 0;
if(needRefresh && isMounted) {
timer.current = setTimeout(asyncGetTaskList, 2000);
} else {
diff --git a/app/pages/Schema/SchemaConfig/List/Index/index.tsx b/app/pages/Schema/SchemaConfig/List/Index/index.tsx
index 7daaef51..1a10b160 100644
--- a/app/pages/Schema/SchemaConfig/List/Index/index.tsx
+++ b/app/pages/Schema/SchemaConfig/List/Index/index.tsx
@@ -1,7 +1,7 @@
import { Button, Popconfirm, Radio, Table, message } from 'antd';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import intl from 'react-intl-universal';
-import { Link, useHistory, useParams } from 'react-router-dom';
+import { useHistory, useParams } from 'react-router-dom';
import Icon from '@app/components/Icon';
import { observer } from 'mobx-react-lite';
import { useStore } from '@app/stores';
diff --git a/app/pages/Schema/SchemaConfig/List/SpaceStats/index.less b/app/pages/Schema/SchemaConfig/List/SpaceStats/index.less
new file mode 100644
index 00000000..0d0ffa9c
--- /dev/null
+++ b/app/pages/Schema/SchemaConfig/List/SpaceStats/index.less
@@ -0,0 +1,20 @@
+@import '~@app/common.less';
+.nebula-stats {
+ .operations {
+ margin: 20px 0 17px;
+ display: flex;
+ align-items: center;
+ font-size: 14px;
+ .ant-btn {
+ width: 110px;
+ }
+ .label {
+ margin-left: 30px;
+ color: @darkGray;
+ }
+ .label::after {
+ content: ": ";
+ padding-right: 5px;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/pages/Schema/SchemaConfig/List/SpaceStats/index.tsx b/app/pages/Schema/SchemaConfig/List/SpaceStats/index.tsx
new file mode 100644
index 00000000..013d3580
--- /dev/null
+++ b/app/pages/Schema/SchemaConfig/List/SpaceStats/index.tsx
@@ -0,0 +1,125 @@
+import { Button, Table, message } from 'antd';
+import dayjs from 'dayjs';
+import React, { useEffect, useMemo, useRef, useState } from 'react';
+import intl from 'react-intl-universal';
+import { useParams } from 'react-router-dom';
+import { observer } from 'mobx-react-lite';
+import { useStore } from '@app/stores';
+import { IJobStatus } from '@app/interfaces/schema';
+import { trackPageView } from '@app/utils/stat';
+import Cookie from 'js-cookie';
+
+import './index.less';
+
+const SpaceStats = () => {
+ const timer = useRef(null);
+ const { schema: { getJobStatus, submitStats, getStats } } = useStore();
+ const { space } = useParams() as { space :string };
+ const [data, setData] = useState([]);
+ const [updateTime, setUpdateTime] = useState('');
+ const [jobId, setJobId] = useState(null);
+ const [loading, setLoading] = useState(false);
+ const columns = useMemo(() => [
+ {
+ title: intl.get('schema.statsType'),
+ dataIndex: 'Type',
+ },
+ {
+ title: intl.get('schema.statsName'),
+ dataIndex: 'Name',
+ },
+ {
+ title: intl.get('schema.statsCount'),
+ dataIndex: 'Count',
+ },
+ ], [Cookie.get('lang')]);
+ useEffect(() => {
+ trackPageView('/space/stats');
+ initData();
+ getJobs();
+ return () => {
+ timer.current && clearTimeout(timer.current);
+ };
+ }, [space]);
+
+ const initData = () => {
+ setJobId(null);
+ setUpdateTime('');
+ setData([]);
+ };
+
+ const getData = async() => {
+ const { code, data } = await getStats();
+ if (code === 0) {
+ setData(data.tables);
+ }
+ };
+
+ const getJobs = async() => {
+ const { code, data } = await getJobStatus();
+ if (code === 0) {
+ const stat = data.tables.filter(item => item.Command === 'STATS')[0];
+ if (stat?.Status === IJobStatus.Finished) {
+ getData();
+ setUpdateTime(stat['Stop Time']);
+ } else if (stat) {
+ const jobId = stat['Job Id'];
+ setJobId(jobId);
+ getStatStatus(jobId);
+ }
+ }
+ };
+
+ const getStatStatus = async id => {
+ const { code, data } = await getJobStatus(id);
+ if (code === 0) {
+ const job = data.tables[0];
+ if (job.Status === IJobStatus.Finished) {
+ getData();
+ setUpdateTime(job['Stop Time']);
+ setJobId(null);
+ message.success(intl.get('schema.statFinished'));
+ } else if ([IJobStatus.Running, IJobStatus.Queue].includes(job.Status)) {
+ timer.current = setTimeout(() => getStatStatus(id), 2000);
+ } else if (job.Status === 'FAILED') {
+ message.warning(intl.get('schema.statError'));
+ setJobId(null);
+ }
+ }
+ };
+ const handleSubmitStats = async() => {
+ setLoading(true);
+ const { code, data } = await submitStats();
+ setLoading(false);
+ if (code === 0) {
+ const id = data.tables[0]['New Job Id'];
+ setJobId(id);
+ await getStatStatus(id);
+ }
+ };
+ return (
+
+
+
+ {intl.get('schema.lastRefreshTime')}
+
+ {updateTime ? dayjs(updateTime).format('YYYY-MM-DD HH:mm:ss') : null}
+
+
+
+
+ );
+};
+
+export default observer(SpaceStats);
diff --git a/app/pages/Schema/SchemaConfig/index.tsx b/app/pages/Schema/SchemaConfig/index.tsx
index 50da781d..ce96bc93 100644
--- a/app/pages/Schema/SchemaConfig/index.tsx
+++ b/app/pages/Schema/SchemaConfig/index.tsx
@@ -7,6 +7,7 @@ import Breadcrumb from '@app/components/Breadcrumb';
import TagList from './List/Tag';
import EdgeList from './List/Edge';
import IndexList from './List/Index/index';
+import SpaceStats from './List/SpaceStats';
import CommonCreate from './Create/CommonCreate';
import IndexCreate from './Create/IndexCreate';
import CommonEdit from './Edit/CommonEdit';
@@ -113,6 +114,11 @@ const SchemaConfig = () => {
exact={true}
component={IndexList}
/>
+
item['Index Status'] !== IJobStatus.finished)
+ .filter(item => item['Index Status'] !== IJobStatus.Finished)
.map(item => item.Name);
}
return null;
}
+ // stats
+ submitStats = async() => {
+ const { code, data } = (await service.execNGQL(
+ {
+ gql: `
+ SUBMIT JOB STATS
+ `,
+ },
+ {
+ trackEventConfig: {
+ category: 'schema',
+ action: 'submit_stats',
+ },
+ },
+ )) as any;
+ return { code, data };
+ }
+
+ getStats = async() => {
+ const { code, data } = (await service.execNGQL({
+ gql: `
+ SHOW STATS
+ `,
+ })) as any;
+ return { code, data };
+ }
+
+ getJobStatus = async(id?) => {
+ const gql = id === undefined ? 'SHOW JOBS' : `SHOW JOB ${id}`;
+ const { code, data } = (await service.execNGQL({
+ gql,
+ })) as any;
+ return { code, data };
+ }
}
const schemaStore = new SchemaStore();