rtgk-screen-web/components/screen/InfoCardList/index.js

362 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, {
useState,
useImperativeHandle,
useRef,
useCallback,
useEffect,
useMemo,
} from "react";
import InfoCard from "./InfoCard";
import Row from "../Row";
const gutter = 20;
const cardBottom = 20;
const InfoCardList = React.forwardRef((props, ref) => {
const {
mainKey,
speed = 50,
span = 4,
withClassify = false,
autoNext = true,
classifyKey = { name: "name", children: "children" },
pageFinished,
type = "move",
extraColumnsOpt,
...otherProps
} = props;
const sizeRef = useRef();
const infoCardListRef = useRef();
const pageBoxRef = useRef();
const pageRef = useRef(1);
const [data, setData] = useState([]);
const [energy, setEnergy] = useState([]);
const [autoScroll, setAutoScroll] = useState([0, 0]);
const classifyRef = useRef([]);
const classifyBoxRef = useRef();
const pageSize = useMemo(() => Math.floor(24 / span), [span]);
const totalPage = useMemo(() => {
if (withClassify) {
let { children } = classifyKey;
let size = 0;
classifyRef.current = [];
data.forEach((item) => {
let itemPageSize = Math.ceil((item[children].length || 0) / pageSize);
size += itemPageSize;
classifyRef.current.push(size);
});
return size;
} else return Math.ceil(data.length / pageSize);
}, [data, pageSize, withClassify, classifyKey]);
const [pageHeight, setPageHeight] = useState(0);
const setActiveClassify = useCallback(
(page) => {
if (!classifyBoxRef.current) return;
let classifyIndex =
classifyRef.current.findIndex((maxPageSize) => page <= maxPageSize) ||
0;
let { name } = classifyKey;
let oprationname = data?.[classifyIndex]?.[name].split("】")[1];
let text = oprationname === undefined ? "" : "- " + oprationname;
if (text) {
classifyBoxRef.current.style.display = "block";
classifyBoxRef.current.innerText = text;
} else classifyBoxRef.current.style.display = "none";
},
[data]
);
const setPageBoxCss = useCallback(
(page) => {
pageRef.current = page;
setActiveClassify(page);
pageBoxRef.current.style.transition =
page === 1 ? "none" : "transform 0.3s";
pageBoxRef.current.style.transform = `translateY(${
-(page - 1) * (pageHeight + cardBottom)
}px)`;
},
[pageHeight, setActiveClassify]
);
const nextPage = useCallback(() => {
// console.log();
let page = pageRef.current;
if (page + 1 > totalPage) {
if (autoNext) {
setPageBoxCss(1);
} else {
pageFinished && pageFinished();
}
} else {
setPageBoxCss(page + 1);
}
}, [totalPage]);
const moveChecking = useCallback(() => {
let { offsetWidth, scrollWidth } = infoCardListRef.current;
setAutoScroll([offsetWidth, scrollWidth]);
}, [data]);
const pageChecking = useCallback(() => {
let { scrollHeight, offsetHeight } = sizeRef.current;
setPageHeight(scrollHeight);
}, []);
useEffect(() => {
if (type === "move") {
let innerWindow = sizeRef.current.contentDocument.defaultView;
innerWindow.addEventListener("resize", moveChecking);
moveChecking();
return () => {
innerWindow.removeEventListener("resize", moveChecking);
};
}
}, [moveChecking]);
useEffect(() => {
if (type === "page") {
let innerWindow = sizeRef.current.contentDocument.defaultView;
innerWindow.addEventListener("resize", pageChecking);
pageChecking();
return () => {
innerWindow.removeEventListener("resize", pageChecking);
};
}
}, [pageChecking]);
useEffect(() => {
setPageBoxCss(1);
}, [data, setPageBoxCss]);
useImperativeHandle(
ref,
() => ({
setData: (data) => {
setData(data);
setPageBoxCss(1);
},
setEnergy:(data)=>{
setEnergy(data);
},
nextPage,
}),
[nextPage]
);
return (
<div className="infoCardList" ref={infoCardListRef}>
{type === "move" && (
<div className="box move">
{data.map((item) => {
return (
<div key={item[mainKey]} className="item">
<InfoCard {...otherProps} data={item} />
</div>
);
})}
</div>
)}
{type === "page" && (
<div className="page-content">
{withClassify === true && (
<div className="classify" ref={classifyBoxRef}></div>
)}
<div className="classifycenter -mt-14 w-full text-center ">
<label className="bg-[#1890ff] p-1 pt-0.5 pb-0.5">能源信息</label>
</div>
<div className="classifycenterval grid grid-cols-2 gap-1 place-items-start -mt-7 w-full">
{console.log("ernergy",energy)}
{/* {props.energy ?? `日期:${props.energy[0]} 水: ${props.energy[0].water} 电: ${1} 气: ${1}`} */}
{
energy.map(x=>{
return (
<span className={ energy.indexOf(x)===0?`flex-1 mr-20 justify-self-end`:`flex-1 ml-20 justify-self-start`}> 日期{x.time} &nbsp; {x.water} &nbsp; {x.electricity} &nbsp; {x.gas}</span>
)
})}
</div>
<div className="page-box">
<object
ref={sizeRef}
tabIndex="-1"
type="text/html"
aria-hidden="true"
data="about:blank"
style={{
display: "block",
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%",
border: "none",
padding: 0,
margin: 0,
opacity: 0,
zIndex: -1000,
pointerEvents: "none",
}}
></object>
<div className="page" ref={pageBoxRef}>
{withClassify === false && (
<Row className="height-100" gutter={20}>
{data.map((item) => {
let extraColumns = [];
if (extraColumnsOpt) {
let { key, name, val, max } = extraColumnsOpt;
let extraData = item[key];
extraData.forEach((i, index) => {
if (index < max)
extraColumns.push({ title: i[name], text: i[val] });
});
}
return (
<Row.Col span={span} key={item[mainKey]}>
<div className="item height-100">
<InfoCard
{...otherProps}
extraColumns={extraColumns}
data={item}
cardWidth={false}
/>
</div>
</Row.Col>
);
})}
</Row>
)}
{withClassify === true &&
data.map((item) => {
let { name, children } = classifyKey;
return (
<Row gutter={20} key={item[name]}>
{item[children].map((item) => {
let extraColumns = [];
if (extraColumnsOpt) {
let { key, name, val, max } = extraColumnsOpt;
let extraData = item[key];
extraData.forEach((i, index) => {
if (index < max)
extraColumns.push({
title: i[name],
text: i[val],
});
});
}
return (
<Row.Col span={span} key={item[mainKey]}>
<div className="item">
<InfoCard
{...otherProps}
extraColumns={extraColumns}
data={item}
cardWidth={false}
/>
</div>
</Row.Col>
);
})}
</Row>
);
})}
</div>
</div>
</div>
)}
<style jsx>{`
.infoCardList {
height: 100%;
overflow: hidden;
position: relative;
}
.infoCardList > .box {
height: 100%;
display: flex;
justify-content: flex-start;
}
.infoCardList > .box > .item {
height: 100%;
padding-right: ${gutter}px;
}
.infoCardList > .box.move {
animation: move ${autoScroll[1] / speed}s linear infinite;
animation-fill-mode: forwards;
transform: translateX(0px);
}
@keyframes move {
from {
transform: translateX(${autoScroll[0]}px);
}
to {
transform: translateX(${-autoScroll[1]}px);
}
}
.infoCardList .page {
height: 100%;
}
.infoCardList .page :global(.col) {
margin-bottom: ${cardBottom}px;
}
.infoCardList .page .item {
height: ${pageHeight}px;
}
.infoCardList .page-content {
height: 100%;
padding-top: 55px;
padding-bottom: 15px;
position: relative;
}
.infoCardList .classify {
position: absolute;
z-index: 100;
font-weight: 600;
font-size: 1.125rem;
left: 100px;
top: 0px;
// background: #15579f;
// border-radius: 3px;
// transition: all .3s;
}
.infoCardList .classifycenter label {
font-weight: 600;
font-size: 1.125rem;
}
.infoCardList .classifycenter {
position: absolute;
z-index: 100;
// left: 48.5%;
// padding: 2px 5px;
// top: -3px;
// background: #1890ff;
// border-radius: 3px;
// transition: all .3s;
}
.infoCardList .classifycenterval {
position: absolute;
z-index: 100;
font-weight: 600;
font-size: 1.125rem;
// left: 19%;
// top: 20px;
// padding: 2px 5px;
// border-radius: 3px;
// transition: all .3s;
}
.infoCardList .page-box {
height: 100%;
overflow: hidden;
position: relative;
}
`}</style>
</div>
);
});
export default InfoCardList;