Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wisdom-components
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ReactWeb5
wisdom-components
Commits
6c311207
Commit
6c311207
authored
Mar 22, 2024
by
陈龙
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:升级历史曲线、统计曲线的错误空值交互;剔除预测值的曲线
parent
30223b18
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
208 additions
and
64 deletions
+208
-64
SingleChart.js
packages/extend-components/EC_HistoryView/src/SingleChart.js
+12
-5
index.js
packages/extend-components/EC_HistoryView/src/apis/index.js
+3
-3
index.js
packages/extend-components/EC_HistoryView/src/demos/index.js
+47
-2
index.js
packages/extend-components/EC_HistoryView/src/index.js
+18
-8
Basic.tsx
...-components/EC_StatisticalHistoryView/src/demos/Basic.tsx
+7
-1
index.js
.../extend-components/EC_StatisticalHistoryView/src/index.js
+121
-45
No files found.
packages/extend-components/EC_HistoryView/src/SingleChart.js
View file @
6c311207
...
...
@@ -24,7 +24,8 @@ const SingleChart = memo((props) => {
lineDataType
,
showBoxOption
,
special
,
predicateData
predicateData
,
emptyOrError
}
=
props
;
const
chartRef
=
useRef
();
const
timerRef
=
useRef
();
...
...
@@ -57,10 +58,16 @@ const SingleChart = memo((props) => {
return
specialTypeChartOptionGenerator
({
dataSource
,
config
});
}
let
_option
=
optionGenerator
(
dataSource
,
null
,
contrast
,
contrastOption
,
smooth
,
config
,
lineDataType
,
predicateData
);
let
isEmpty
=
_option
.
series
.
length
===
0
;
if
(
isEmpty
)
{
_option
.
yAxis
.
max
=
100
;
_option
.
yAxis
.
min
=
0
;
if
(
emptyOrError
.
empty
||
emptyOrError
.
error
)
{
if
(
isArray
(
_option
.
yAxis
))
{
_option
.
yAxis
.
forEach
(
item
=>
{
item
.
max
=
100
;
item
.
min
=
0
;
})
}
else
{
_option
.
yAxis
.
max
=
100
;
_option
.
yAxis
.
min
=
0
;
}
}
return
_option
;
},
[
dataSource
,
smooth
,
curveCenter
,
chartType
,
predicateData
]);
...
...
packages/extend-components/EC_HistoryView/src/apis/index.js
View file @
6c311207
...
...
@@ -69,7 +69,7 @@ export function getSensorType() {
export
function
getPredicateSensor
(
params
)
{
return
request
({
url
:
`
${
baseUrl
}
/PandaWater/CityWater/PiZhou
/GetPredicateSensor`
,
url
:
`
${
monitorDeviceUrl
}
/GetPredicateSensor`
,
method
:
REQUEST_METHOD_GET
,
params
})
...
...
@@ -84,9 +84,9 @@ export function getStatisticsInfo(data) {
});
}
export
function
getSensorsRealName
(
data
)
{
export
function
getSensorsRealName
(
data
)
{
return
request
({
url
:
`
${
baseUrl
}
/PandaMonitor/Monitor/Device/GetStaticRealName`
,
url
:
`
${
baseUrl
}
/PandaMonitor/Monitor/Device/GetStaticRealName`
,
method
:
REQUEST_METHOD_POST
,
data
,
})
...
...
packages/extend-components/EC_HistoryView/src/demos/index.js
View file @
6c311207
...
...
@@ -211,17 +211,62 @@ import { MobileHistoryChart } from '../mobile';
];*/
const
deviceParams
=
[
// 新乐,水厂数据异常的问题
{
/*
{
"deviceCode": "SC00000004",
"sensors": "进水瞬时流量,1#出水瞬时流量,2#出水瞬时流量",
"deviceType": "水厂"
}
}*/
/* {
"deviceCode": "EGJZ00000073",
"sensors": "进水压力",
"deviceType": "二供机组"
}*/
/* {
"deviceCode": "EGJZ00000006",
"sensors": "进水压力",
"deviceType": "二供机组"
}*/
/* {
"deviceCode": "EGBF00000002",
"deviceType": "二供泵房",
"sensors": "进水压力"
},
{
"deviceType": "二供机组",
"deviceCode": "EGJZ00000005",
"sensors": "出水压力"
},
{
"deviceType": "二供机组",
"deviceCode": "EGJZ00000001",
"sensors": "出水压力"
},
{
"deviceType": "二供机组",
"deviceCode": "EGJZ00000004",
"sensors": "出水压力"
},
{
"deviceType": "二供机组",
"deviceCode": "EGJZ00000003",
"sensors": "出水压力"
},
{
"deviceType": "二供机组",
"deviceCode": "EGJZ00000002",
"sensors": "出水压力"
}*/
// 182:8088 报警设备
/* {
"deviceCode": "XMYL00000043",
"sensors": "进水压力",
"deviceType": "熊猫压力表"
}*/
{
"deviceCode"
:
"LLJ00000001"
,
"sensors"
:
"瞬时流量"
,
"deviceType"
:
"流量计"
}
]
const
Demo
=
()
=>
{
return
(
...
...
packages/extend-components/EC_HistoryView/src/index.js
View file @
6c311207
...
...
@@ -376,7 +376,11 @@ const HistoryView = (props) => {
const
[
predicateDevice
,
setPredicateDevice
]
=
useState
(
null
);
const
[
predicateData
,
setPredicateData
]
=
useState
([]);
const
[
predicateTime
,
setPredicateTime
]
=
useState
(
null
);
// 需要处理默认数据,确保图表能够一直显示坐标轴。用来存储当前的请求状态。
const
emptyOrError
=
useRef
({
empty
:
true
,
error
:
true
})
// 这部分功能有问题,等待解决后上线 2024年3月13日
const
[
discreteDeviceType
,
setDiscreteDeviceType
]
=
useState
([
'水厂'
])
// 历史数据相关的特征描述
...
...
@@ -1170,6 +1174,7 @@ const HistoryView = (props) => {
Promise
.
all
(
requestArr
)
.
then
((
results
)
=>
{
setLoading
(
false
);
emptyOrError
.
current
.
error
=
false
;
if
(
results
.
length
)
{
let
data
=
[];
let
_predicateData
=
[];
...
...
@@ -1234,6 +1239,9 @@ const HistoryView = (props) => {
}
});
setLoading
(
false
);
if
(
data
.
length
!==
0
)
{
emptyOrError
.
current
.
empty
=
false
;
}
handleTableData
(
data
)
setChartDataSource
(
data
);
setPredicateData
(
_predicateData
);
...
...
@@ -1356,6 +1364,7 @@ const HistoryView = (props) => {
<
div
className
=
{
`
${
prefixCls
}
-content`
}
>
{
grid
===
true
?
(
<
GridChart
emptyOrError
=
{
emptyOrError
.
current
}
curveCenter
=
{
curveCenter
}
prefixCls
=
{
prefixCls
}
dataSource
=
{
chartDataSource
}
...
...
@@ -1370,6 +1379,7 @@ const HistoryView = (props) => {
/
>
)
:
(
<
SingleChart
emptyOrError
=
{
emptyOrError
.
current
}
dateRange
=
{
dateRange
}
showBoxOption
=
{
showBoxOption
}
lineDataType
=
{
lineDataType
}
...
...
@@ -1432,29 +1442,29 @@ const HistoryView = (props) => {
// 以下请求为处理状态值、开关值的图表,只允许单曲线单指标情况下展示
let
_request1
=
getPointAddressEntry
(
_params
);
let
_request2
=
getSensorType
();
let
_request3
=
getPredicateSensor
({
deviceCode
,
sensors
});
await
Promise
.
all
([
_request0
,
_request1
,
_request2
,
_request3
]).
then
((
result
)
=>
{
//
let _request3 = getPredicateSensor({deviceCode, sensors});
await
Promise
.
all
([
_request0
,
_request1
,
_request2
]).
then
((
result
)
=>
{
if
(
result
)
{
let
_res0
=
result
[
0
];
let
_res1
=
result
[
1
];
let
_res2
=
result
[
2
];
let
_res3
=
result
[
3
];
//
let _res3 = result[3];
let
_checkboxData
=
[...
checkboxData
];
// 单设备单曲线时,查询是否配置为预测点
if
(
_res3
.
code
===
0
&&
_res3
.
data
)
{
/*
if (_res3.code === 0 && _res3.data) {
// 1. 如果是单曲线,并且配置了预测,那么默认开启预测;
// 2024年3月11日 物联预测功能支撑后,再开发这部分
/*
_checkboxData.push({
_checkboxData.push({
key: 'predicate',
label: '数据预测',
checked: true,
showInCurve: true,
showInTable: true,
})
*/
})
setPredicateDevice({..._res3.data, deviceType: '预测'});
} else {
setPredicateDevice(null);
}
}
*/
// 查字典配置
if
(
_res0
.
code
===
0
)
{
let
_opt
=
_res0
.
data
.
reduce
((
final
,
cur
)
=>
{
...
...
packages/extend-components/EC_StatisticalHistoryView/src/demos/Basic.tsx
View file @
6c311207
...
...
@@ -9,11 +9,17 @@ const Demo = () => {
// deviceType: '加压泵站',
// statisticType: '',
// }
const
params
=
{
/*
const params = {
deviceCode: 'LLJ00000001',
sensors: '今日水量',
deviceType: '流量计',
statisticType: '',
} */
const
params
=
{
deviceCode
:
'EGBF00000023'
,
sensors
:
'今日供水量'
,
deviceType
:
'二供泵房'
,
statisticType
:
''
,
}
return
(
<>
...
...
packages/extend-components/EC_StatisticalHistoryView/src/index.js
View file @
6c311207
import
React
,
{
useState
,
useEffect
,
useRef
,
useContext
}
from
'react'
;
import
React
,
{
useState
,
useEffect
,
useRef
,
useContext
}
from
'react'
;
import
classNames
from
'classnames'
;
import
moment
from
'moment'
;
import
Empty
from
'@wisdom-components/empty'
;
import
LoadBox
from
'@wisdom-components/loadbox'
;
import
BasicTable
from
'@wisdom-components/basictable'
;
import
{
ExportExcel
}
from
'@wisdom-components/exportexcel'
;
import
{
ConfigProvider
,
Select
,
DatePicker
,
Radio
,
Table
,
Button
}
from
'antd'
;
import
{
VerticalAlignBottomOutlined
}
from
'@ant-design/icons'
;
import
{
BasicChart
}
from
'@wisdom-components/basicchart'
;
import
{
getStatisticsInfo
}
from
'./apis'
;
import
{
ExportExcel
}
from
'@wisdom-components/exportexcel'
;
import
{
ConfigProvider
,
Select
,
DatePicker
,
Radio
,
Table
,
Button
}
from
'antd'
;
import
{
VerticalAlignBottomOutlined
}
from
'@ant-design/icons'
;
import
{
BasicChart
}
from
'@wisdom-components/basicchart'
;
import
{
getStatisticsInfo
}
from
'./apis'
;
import
'./index.less'
;
const
StatisticalHistoryView
=
(
props
)
=>
{
const
{
getPrefixCls
}
=
useContext
(
ConfigProvider
.
ConfigContext
);
const
{
getPrefixCls
}
=
useContext
(
ConfigProvider
.
ConfigContext
);
const
prefixCls
=
getPrefixCls
(
'ec-statistical-history-view'
);
const
chartRef
=
useRef
(
null
);
const
defaultOptionRef
=
useRef
({
...
...
@@ -49,8 +49,8 @@ const StatisticalHistoryView = (props) => {
yAxis
:
[
{
type
:
'value'
,
max
:
100
,
min
:
0
,
max
:
100
,
min
:
0
,
position
:
'left'
,
alignTicks
:
true
,
axisLine
:
{
...
...
@@ -61,14 +61,19 @@ const StatisticalHistoryView = (props) => {
},
},
],
series
:
[{
series
:
[{
type
:
'line'
,
data
:
[
[
moment
(
moment
().
format
(
'YYYY-MM-DD 00:00:00'
)).
valueOf
(),
null
],
[
moment
(
moment
().
format
(
'YYYY-MM-DD 23:59:59'
)).
valueOf
(),
null
],
data
:
[
[
moment
(
moment
().
format
(
'YYYY-MM-DD 00:00:00'
)).
valueOf
(),
null
],
[
moment
(
moment
().
format
(
'YYYY-MM-DD 23:59:59'
)).
valueOf
(),
null
],
]
}]
});
// 用来判定是否是初始化、是否时报错
const
emptyOrError
=
useRef
({
empty
:
true
,
error
:
true
})
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
historyRender
,
setHistoryRender
]
=
useState
(
true
);
const
[
historyParams
,
setHistoryParams
]
=
useState
({});
...
...
@@ -85,7 +90,7 @@ const StatisticalHistoryView = (props) => {
const
[
options
,
setOptions
]
=
useState
({});
const
[
dateValue
,
setDateValue
]
=
useState
(
'today'
);
const
[
picker
,
setPicker
]
=
useState
(
'day'
);
const
[
time
,
setTime
]
=
useState
({
startTime
:
''
,
endTime
:
''
});
const
[
time
,
setTime
]
=
useState
({
startTime
:
''
,
endTime
:
''
});
const
[
dateTime
,
setDateTime
]
=
useState
(
moment
().
format
(
'YYYY-MM-DD HH:mm:ss'
));
// 时间切换筛选
...
...
@@ -98,7 +103,7 @@ const StatisticalHistoryView = (props) => {
setPicker
(
value
);
let
start
=
moment
(
dateTime
).
subtract
(
2
,
value
).
startOf
(
value
).
format
(
'YYYY-MM-DD 00:00:00'
);
let
end
=
moment
(
dateTime
).
endOf
(
value
).
format
(
'YYYY-MM-DD 23:59:59'
);
setTime
({
startDate
:
start
,
endDate
:
end
});
setTime
({
startDate
:
start
,
endDate
:
end
});
};
// 自定义时间选择
...
...
@@ -106,7 +111,7 @@ const StatisticalHistoryView = (props) => {
setDateTime
(
dateString
);
const
start
=
moment
(
value
).
subtract
(
2
,
picker
).
startOf
(
picker
).
format
(
'YYYY-MM-DD 00:00:00'
);
const
end
=
moment
(
value
).
endOf
(
picker
).
format
(
'YYYY-MM-DD 23:59:59'
);
setTime
({
startDate
:
start
,
endDate
:
end
});
setTime
({
startDate
:
start
,
endDate
:
end
});
};
const
exportExcelBtn
=
(
e
)
=>
{
...
...
@@ -138,10 +143,64 @@ const StatisticalHistoryView = (props) => {
],
});
};
// 生成对应的数据结构
const returnDataStructure = (dateFrom, dateTo, dateType, dateValue) => {
//
let length = new Array(3).fill(false);
let finalData = [];
if (dateType === 'day') {
let days = length.map((item, index) => {
return moment(dateTo).subtract(index, 'days').format('YYYY-MM-DD')
});
let hours = new Array(24).fill(false).map((item, index) => {
return index < 10 ? `
0
$
{
index
}
` : index;
})
days.forEach(day => {
hours.forEach(hour => {
finalData.push(`
$
{
day
}
$
{
hour
}
`);
})
})
}
if (dateType === 'month') {
let months = length.map((item, index) => {
return moment(dateTo).subtract(index, 'months').format('YYYY-MM')
});
let days = new Array(31).fill(false).map((item, index) => {
return index < 9 ? `
0
$
{
index
+
1
}
` : index + 1;
})
months.forEach(month => {
days.forEach(day => {
finalData.push(`
$
{
month
}
$
{
day
}
`);
})
})
}
if (dateType === 'year') {
let years = length.map((item, index) => {
return moment(dateTo).subtract(index, 'years').format('YYYY')
});
let months = new Array(12).fill(false).map((item, index) => {
return index < 9 ? `
0
$
{
index
+
1
}
` : index + 1;
})
years.forEach(year => {
months.forEach(month => {
finalData.push(`
$
{
year
}
$
{
month
}
`);
})
})
}
return finalData.map(item => {
return {
time: item,
value: null,
}
});
};
const handleDataForEmptyOrError = () => {
let _data = returnDataStructure(time.startDate, time.endDate, picker, dateValue);
dataMenthod({nameDate: _data, dName: props?.deviceParams?.sensors ?? ''});
}
// 获取历史统计数据
const getHistoryData = async () => {
const { deviceCode = '', sensors = '', deviceType = '', statisticType = ''
} = historyParams;
const {deviceCode = '', sensors = '', deviceType = '', statisticType = ''
} = historyParams;
const nameTypeList = [];
if (!deviceCode || !sensors) return setOptions(null);
nameTypeList.push({
...
...
@@ -162,11 +221,18 @@ const StatisticalHistoryView = (props) => {
let results = null;
try {
results = await getStatisticsInfo(params);
emptyOrError.current.error = false;
} catch (err) {
if (historyParams.sensors) {
handleDataForEmptyOrError()
}
return setLoading(false);
}
setLoading(false);
const list = results?.data?.list || [];
if (list.length === 0) {
handleDataForEmptyOrError()
}
const dataList = list.length ? list[0] : {};
const dNameDataList = dataList.dNameDataList ? dataList.dNameDataList : [];
const data = dNameDataList.length ? dNameDataList[0] : null;
...
...
@@ -175,7 +241,10 @@ const StatisticalHistoryView = (props) => {
};
const dataMenthod = (data) => {
const { nameDate } = data;
const {nameDate} = data;
nameDate.forEach(item => {
if (item.value !== null) emptyOrError.current.empty = false;
})
let time0 = '',
time1 = '',
time2 = '';
...
...
@@ -192,9 +261,9 @@ const StatisticalHistoryView = (props) => {
nameDate.forEach((item) => {
const times = moment(item.time).format('YYYY-MM-DD');
const pt = moment(item.time).format('HH时');
if (times === time0) data0.push({ ...item, pt: pt
});
if (times === time1) data1.push({ ...item, pt: pt
});
if (times === time2) data2.push({ ...item, pt: pt
});
if (times === time0) data0.push({...item, pt: pt
});
if (times === time1) data1.push({...item, pt: pt
});
if (times === time2) data2.push({...item, pt: pt
});
});
break;
case 'thisWeek':
...
...
@@ -205,9 +274,9 @@ const StatisticalHistoryView = (props) => {
nameDate.forEach((item) => {
const times = moment(item.time).format('WW');
const pt = getWeek(item.time);
if (times === time0) data0.push({ ...item, pt: pt
});
if (times === time1) data1.push({ ...item, pt: pt
});
if (times === time2) data2.push({ ...item, pt: pt
});
if (times === time0) data0.push({...item, pt: pt
});
if (times === time1) data1.push({...item, pt: pt
});
if (times === time2) data2.push({...item, pt: pt
});
});
break;
case 'thisMonth':
...
...
@@ -218,9 +287,9 @@ const StatisticalHistoryView = (props) => {
nameDate.forEach((item) => {
const times = moment(item.time).format('YYYY-MM');
const pt = moment(item.time).format('DD日');
if (times === time0) data0.push({ ...item, pt: pt
});
if (times === time1) data1.push({ ...item, pt: pt
});
if (times === time2) data2.push({ ...item, pt: pt
});
if (times === time0) data0.push({...item, pt: pt
});
if (times === time1) data1.push({...item, pt: pt
});
if (times === time2) data2.push({...item, pt: pt
});
});
break;
case 'thisYear':
...
...
@@ -231,9 +300,9 @@ const StatisticalHistoryView = (props) => {
nameDate.forEach((item) => {
const times = moment(item.time).format('YYYY');
const pt = moment(item.time).format('MM月');
if (times === time0) data0.push({ ...item, pt: pt
});
if (times === time1) data1.push({ ...item, pt: pt
});
if (times === time2) data2.push({ ...item, pt: pt
});
if (times === time0) data0.push({...item, pt: pt
});
if (times === time1) data1.push({...item, pt: pt
});
if (times === time2) data2.push({...item, pt: pt
});
});
break;
case 'customer':
...
...
@@ -246,9 +315,9 @@ const StatisticalHistoryView = (props) => {
nameDate.forEach((item) => {
const times = moment(item.time).format(format);
const pt = moment(item.time).format(style);
if (times === time0) data0.push({ ...item, pt: pt
});
if (times === time1) data1.push({ ...item, pt: pt
});
if (times === time2) data2.push({ ...item, pt: pt
});
if (times === time0) data0.push({...item, pt: pt
});
if (times === time1) data1.push({...item, pt: pt
});
if (times === time2) data2.push({...item, pt: pt
});
});
break;
}
...
...
@@ -273,12 +342,12 @@ const StatisticalHistoryView = (props) => {
const renderChart = (dataInfo, data) => {
if (!dataInfo) return setOptions(null);
const { unit, dName
} = data;
const {unit, dName
} = data;
const series = [];
let xData = [];
dataInfo.data.forEach((item, index) => {
const config = !index && dName.indexOf('流量') > -1 ? { areaStyle: {}
} : {};
const style = index ? { lineStyle: { normal: { type: 'dashed' } }
} : {};
const config = !index && dName.indexOf('流量') > -1 ? {areaStyle: {}
} : {};
const style = index ? {lineStyle: {normal: {type: 'dashed'}}
} : {};
const list = {
name: dataInfo.name[index],
type: 'line',
...
...
@@ -297,6 +366,7 @@ const StatisticalHistoryView = (props) => {
return arr.pt;
});
});
let showMinMax = emptyOrError.current.empty && emptyOrError.current.error;
const option = {
title: {
show: false,
...
...
@@ -349,6 +419,7 @@ const StatisticalHistoryView = (props) => {
axisLabel: {
formatter: '{value}',
},
...(showMinMax ? {min: 0, max: 100} : {})
},
],
series: series,
...
...
@@ -423,7 +494,11 @@ const StatisticalHistoryView = (props) => {
</Table.Summary.Row>
);
};
useEffect(() => {
if (props?.deviceParams?.sensors) {
handleDataForEmptyOrError()
}
}, [])
useEffect(() => {
setHistoryParams(props.deviceParams || {});
}, [props.deviceParams]);
...
...
@@ -457,7 +532,7 @@ const StatisticalHistoryView = (props) => {
end = moment(dateTime).endOf(picker).format('YYYY-MM-DD 23:59:59');
break;
}
setTime({ startDate: start, endDate: end
});
setTime({startDate: start, endDate: end
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dateValue]);
...
...
@@ -488,7 +563,8 @@ const StatisticalHistoryView = (props) => {
onChange={onPickerChange}
className={classNames(`
$
{
prefixCls
}
-
select
`)}
/>
<DatePicker onChange={onDateChange} value={moment(dateTime)} picker={picker} allowClear={false}/>
<DatePicker onChange={onDateChange} value={moment(dateTime)} picker={picker}
allowClear={false}/>
</>
)}
</div>
...
...
@@ -498,7 +574,7 @@ const StatisticalHistoryView = (props) => {
onClick={exportExcelBtn}
disabled={!dataSource.length}
>
<VerticalAlignBottomOutlined
/>
<VerticalAlignBottomOutlined
/>
下载
</Button>
</div>
...
...
@@ -509,9 +585,9 @@ const StatisticalHistoryView = (props) => {
{
<BasicChart
ref={chartRef}
option={(!options||
!options?.series) ? defaultOptionRef.current : options}
option={(!options ||
!options?.series) ? defaultOptionRef.current : options}
notMerge
style={{ width: '100%', height: '100%'
}}
style={{width: '100%', height: '100%'
}}
/>
}
</div>
...
...
@@ -545,7 +621,7 @@ const StatisticalHistoryView = (props) => {
}, // 鼠标移出行
};
}}
scroll={{ x: '100%', y: 'calc(100% - 40px)'
}}
scroll={{x: '100%', y: 'calc(100% - 40px)'
}}
summary={Summary}
/>
</div>
...
...
@@ -555,7 +631,7 @@ const StatisticalHistoryView = (props) => {
</div>
{loading && (
<div className={classNames(`
$
{
prefixCls
}
-
load
-
box
`)}>
<LoadBox spinning={loading}
/>
<LoadBox spinning={loading}
/>
</div>
)}
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment