fix: 实时监控 预警记录添加滚动条
This commit is contained in:
parent
a47aa0c431
commit
15a46122e8
@ -1,4 +1,4 @@
|
||||
import React, { useContext } from 'react';
|
||||
import React, { useContext, useRef } from 'react';
|
||||
import WindowToggle, { ISize } from './components/WindowToggle';
|
||||
import WarningRecordList from './components/WarningRecordList';
|
||||
import { ConfigProvider } from '@zhst/meta';
|
||||
@ -34,6 +34,7 @@ interface RealTimeMonitorProps {
|
||||
largeImageTitle?: string;
|
||||
size: ISize;
|
||||
setSize: React.Dispatch<React.SetStateAction<ISize>>
|
||||
maxRecordCount?: number;
|
||||
}
|
||||
|
||||
export const RealTimeMonitor: React.FC<RealTimeMonitorProps> = (props) => {
|
||||
@ -53,19 +54,22 @@ export const RealTimeMonitor: React.FC<RealTimeMonitorProps> = (props) => {
|
||||
selectedRecordId,
|
||||
isRecordListLoading,
|
||||
size,
|
||||
setSize
|
||||
setSize,
|
||||
maxRecordCount
|
||||
} = props
|
||||
const toggleRef = useRef<HTMLDivElement>()
|
||||
const componentName = getPrefixCls('biz-real-time-monitor', customizePrefixCls);
|
||||
|
||||
return (
|
||||
<div className={componentName} style={{ display: 'flex' }} >
|
||||
<WindowToggle
|
||||
<WindowToggle
|
||||
toggleRef={toggleRef}
|
||||
selectedWindowKey={selectedWindowKey}
|
||||
dataSource={videoDataSource}
|
||||
handleWindowClick={handleWindowClick}
|
||||
handleCloseButtonClick={handleCloseButtonClick}
|
||||
size = {size}
|
||||
setSize = {setSize}
|
||||
size={size}
|
||||
setSize={setSize}
|
||||
/>
|
||||
<WarningRecordList
|
||||
dataSource={warningDataSource}
|
||||
@ -75,6 +79,8 @@ export const RealTimeMonitor: React.FC<RealTimeMonitorProps> = (props) => {
|
||||
viewLargerImageModalRef={viewLargerImageModalRef}
|
||||
isRecordListLoading={isRecordListLoading}
|
||||
recordListTitle="监控预警记录"
|
||||
maxHeight={toggleRef.current?.offsetHeight}
|
||||
maxRecordCount={maxRecordCount}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -4,6 +4,7 @@ import { ViewLargerImageModalRef } from '../../../ViewLargerImageModal';
|
||||
import WarningRecordCard from '../../../WarningRecordCard';
|
||||
import ViewLargerImageModal from '../../../ViewLargerImageModal';
|
||||
import { Empty, Space, Spin } from 'antd';
|
||||
import { pxToRem } from '@zhst/func'
|
||||
import { LoadingOutlined } from '@ant-design/icons';
|
||||
import "./index.less"
|
||||
|
||||
@ -28,6 +29,8 @@ interface WarningRecordListProps {
|
||||
cardStyle?: React.CSSProperties;
|
||||
imgStyle?: React.CSSProperties;
|
||||
largeImageTitle?: string;
|
||||
maxHeight?: number;
|
||||
maxRecordCount?: number;
|
||||
}
|
||||
|
||||
const WarningRecordList: React.FC<WarningRecordListProps> = (props) => {
|
||||
@ -43,11 +46,12 @@ const WarningRecordList: React.FC<WarningRecordListProps> = (props) => {
|
||||
style,
|
||||
cardStyle,
|
||||
imgStyle,
|
||||
largeImageTitle
|
||||
largeImageTitle,
|
||||
maxHeight,
|
||||
maxRecordCount = 10
|
||||
} = props
|
||||
|
||||
return (
|
||||
<div className='zhst-biz-warning-record-list' style={style}>
|
||||
<div className='zhst-biz-warning-record-list' style={{ maxHeight : `${pxToRem(`${maxHeight}`)}` , ...style }} >
|
||||
<div className='header'>{recordListTitle}</div>
|
||||
<div className='body'>
|
||||
{
|
||||
@ -58,7 +62,7 @@ const WarningRecordList: React.FC<WarningRecordListProps> = (props) => {
|
||||
: (dataSource?.length) > 0 ?
|
||||
<Space direction='vertical' size={10} >
|
||||
{dataSource?.map((record, index) => {
|
||||
if (index > 2) return
|
||||
if (index > maxRecordCount -1) return
|
||||
return (<WarningRecordCard
|
||||
key={record?.id}
|
||||
record={record}
|
||||
|
@ -2,19 +2,21 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-left: solid 1px #00000026;
|
||||
width: 320px;
|
||||
min-width: 320px;
|
||||
|
||||
.header {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
background-color: #EFF2F4;
|
||||
padding: 10px 20px;
|
||||
padding: 0 20px;
|
||||
box-sizing: border-box;
|
||||
line-height: 48px;
|
||||
}
|
||||
|
||||
.body {
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
// overflow-x: hidden;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
@ -1,53 +1,56 @@
|
||||
import React from 'react';
|
||||
import VideoPlayerCard from '../../../VideoPlayerCard';
|
||||
import { VideoPlayerCardProps } from '../../../VideoPlayerCard';
|
||||
import { Segmented } from 'antd';
|
||||
import { ConfigProvider, Segmented, theme } from 'antd';
|
||||
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
|
||||
import { theme } from 'antd/lib';
|
||||
import { pxToRem } from '@zhst/func'
|
||||
import './index.less'
|
||||
|
||||
|
||||
export type ISize = 'large' | 'small'
|
||||
|
||||
interface WindowToggleProps {
|
||||
|
||||
dataSource?: VideoPlayerCardProps[];
|
||||
handleWindowClick?: (key?: string) => void;
|
||||
handleCloseButtonClick?: (key?: string) => void;
|
||||
selectedWindowKey?: string;
|
||||
size: ISize;
|
||||
setSize: React.Dispatch<React.SetStateAction<ISize>>
|
||||
toggleRef: React.MutableRefObject<any>
|
||||
}
|
||||
|
||||
export const WindowToggle: React.FC<WindowToggleProps> = (props) => {
|
||||
|
||||
const { dataSource = [], handleWindowClick, handleCloseButtonClick, selectedWindowKey , size = "large",setSize} = props
|
||||
const { dataSource = [], handleWindowClick, handleCloseButtonClick, selectedWindowKey, size = "large", setSize, toggleRef } = props
|
||||
const { useToken } = theme
|
||||
const { token } = useToken()
|
||||
|
||||
const getLabelStyle = (isSelected: boolean) => ({
|
||||
padding: "0 11px", background: "#fff",
|
||||
padding: `0 ${pxToRem("11px")}`, background: "#fff",
|
||||
...(isSelected ? { background: token.colorPrimary, color: '#fff' } : {}),
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
<div className='zhst-biz-window-toggle'>
|
||||
<div className='zhst-biz-window-toggle' ref={toggleRef}>
|
||||
{/* 切换按钮 */}
|
||||
<div className='header'>
|
||||
<Segmented
|
||||
defaultValue='large'
|
||||
options={[
|
||||
{ value: 'large', label: <div style={getLabelStyle(size === 'large')}><BarsOutlined /></div> },
|
||||
{ value: 'small', label: <div style={getLabelStyle(size === 'small')}><AppstoreOutlined /></div> },
|
||||
]}
|
||||
onChange={(value) => {
|
||||
// 当一个窗口时 默认 selectedkey 第一条数据的 windowkey
|
||||
if (value === 'large' && dataSource.length > 0) {
|
||||
const { windowKey } = dataSource[0]
|
||||
handleWindowClick?.(windowKey)
|
||||
}
|
||||
setSize(value as ISize)
|
||||
}}
|
||||
/>
|
||||
<Segmented
|
||||
defaultValue='large'
|
||||
options={[
|
||||
{ value: 'large', label: <div style={getLabelStyle(size === 'large')}><BarsOutlined /></div> },
|
||||
{ value: 'small', label: <div style={getLabelStyle(size === 'small')}><AppstoreOutlined /></div> },
|
||||
]}
|
||||
onChange={(value) => {
|
||||
// 当一个窗口时 默认 selectedkey 第一条数据的 windowkey
|
||||
if (value === 'large' && dataSource.length > 0) {
|
||||
const { windowKey } = dataSource[0]
|
||||
handleWindowClick?.(windowKey)
|
||||
}
|
||||
setSize(value as ISize)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='body'>
|
||||
@ -57,7 +60,7 @@ export const WindowToggle: React.FC<WindowToggleProps> = (props) => {
|
||||
if (size === "large" && index > 0) return
|
||||
return (
|
||||
<VideoPlayerCard
|
||||
key={item.windowKey}
|
||||
key={size === "large" ? "" : item.windowKey}
|
||||
selectedWindowKey={selectedWindowKey}
|
||||
size={size}
|
||||
handleWindowClick={handleWindowClick}
|
||||
|
@ -87,7 +87,7 @@ export default () => {
|
||||
setTimeout(() => {
|
||||
// 对后端返回数据进行处理 组装一套符合属性的 数据
|
||||
// videoSrc : videoData.videoSrc
|
||||
const newVideoData: VideoPlayerCardProps = { imageKey: videoData.imageKey, title: videoData.title, odRect: videoData.odRect, videoSrc: videoData.videoSrc }
|
||||
const newVideoData: VideoPlayerCardProps = { imageKey: videoData.imageKey, title: videoData.title, odRect: videoData.odRect}
|
||||
setVideoDataSource((pre) => {
|
||||
const newVideoDataSource: VideoPlayerCardProps[] = pre.map((item) => {
|
||||
// 传给 选中的视频窗口
|
||||
|
@ -3,6 +3,7 @@ import { theme } from 'antd/lib';
|
||||
import { ConfigProvider, VideoPlayer, CropperImage, type VideoViewRef, } from '@zhst/meta';
|
||||
import React, { useState, useEffect, ReactNode, useRef, useContext } from 'react';
|
||||
import { CloseOutlined, LoadingOutlined } from '@ant-design/icons';
|
||||
import { pxToRem } from '@zhst/func'
|
||||
import './index.less'
|
||||
export interface VideoPlayerCardProps {
|
||||
prefixCls?: string;
|
||||
@ -48,11 +49,10 @@ export const VideoPlayerCard: React.FC<VideoPlayerCardProps> = (props) => {
|
||||
border: `2px solid ${token.colorPrimary}`, boxShadow: " 0px 2px 9px 0px rgba(0,0,0,0.16)"
|
||||
}
|
||||
const cardStyle: React.CSSProperties = {
|
||||
...(size === 'large' ? { height: 931 } : { height: 456, cursor: 'pointer' }),
|
||||
...(size === 'large' ? { height: `${pxToRem("931px")}` } : { height: `${pxToRem("456px")}` , cursor: 'pointer' }),
|
||||
...(size === 'small' && selectedWindowKey === windowKey ? selectedBorderStyle : {})
|
||||
};
|
||||
const videoPlayerCardStyle = size === 'small' ? { width: "calc(50% - 20px)" } : { flex: 1 }
|
||||
|
||||
const videoPlayerCardStyle = size === 'small' ? { width: `calc(50% - ${pxToRem("20px")})` } : { flex: 1 }
|
||||
useEffect(() => {
|
||||
if (!isWindowLoading && (videoSrc || imageKey)) {
|
||||
let contentElement: JSX.Element | null = null;
|
||||
@ -65,7 +65,7 @@ export const VideoPlayerCard: React.FC<VideoPlayerCardProps> = (props) => {
|
||||
} else if (imageKey) {
|
||||
contentElement = (
|
||||
|
||||
<div style={{ width: "100%", height: "100%", display: 'block' }}>
|
||||
<div style={{ width: "100%", height: "100%" }}>
|
||||
<CropperImage
|
||||
// editAble={true}
|
||||
odList={odRectDefault}
|
||||
@ -102,7 +102,7 @@ export const VideoPlayerCard: React.FC<VideoPlayerCardProps> = (props) => {
|
||||
{cardContent}
|
||||
</>
|
||||
) : (
|
||||
<div style={{ backgroundColor: '#000', height: '100%', display: 'flex', padding: '20px', boxSizing: 'border-box' }}>
|
||||
<div style={{ backgroundColor: '#000', height: '100%', display: 'flex', padding: `${pxToRem("20px")}`, boxSizing: 'border-box' }}>
|
||||
{
|
||||
isWindowLoading ?
|
||||
<div style={{ flex: 1, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
||||
|
Loading…
Reference in New Issue
Block a user