Skip to content

Commit 3b729d3

Browse files
committed
fix(msp): add chart
1 parent 55d1db8 commit 3b729d3

File tree

2 files changed

+85
-8
lines changed

2 files changed

+85
-8
lines changed

shell/app/common/components/card-list/index.tsx

+36-8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { get } from 'lodash';
1919
import classnames from 'classnames';
2020
import EmptyHolder from 'common/components/empty-holder';
2121
import ErdaIcon from 'common/components/erda-icon';
22+
import { useInViewPort } from 'common/use-hooks';
2223

2324
interface CardColumnsProps<T> {
2425
dataIndex: keyof T | string[];
@@ -41,6 +42,7 @@ interface IProps<T = Record<string, any>> {
4142
rowClassName?: string;
4243
columns: CardColumnsProps<T>[];
4344
emptyHolder?: React.ReactNode;
45+
onViewChange?: (data: T, flag?: boolean) => void;
4446
}
4547

4648
const renderChild = <T,>(record: T, columns: CardColumnsProps<T>[], index: number) => {
@@ -64,17 +66,41 @@ const renderChild = <T,>(record: T, columns: CardColumnsProps<T>[], index: numbe
6466
});
6567
};
6668

69+
interface IRowProps<T> {
70+
rowClass?: string;
71+
rowId: string | number;
72+
rowClick: () => void;
73+
columns: CardColumnsProps<T>[];
74+
record: T;
75+
index: number;
76+
onViewChange?: (data: T, flag?: boolean) => void;
77+
}
78+
79+
const RowItem = <T,>({ rowClick, rowId, rowClass, record, columns, index, onViewChange }: IRowProps<T>) => {
80+
const rowRef = React.useRef();
81+
const [isInView] = useInViewPort(rowRef);
82+
React.useEffect(() => {
83+
onViewChange?.(record, isInView);
84+
}, [isInView, record]);
85+
return (
86+
<Row ref={rowRef} onClick={rowClick} key={rowId} className={rowClass}>
87+
{renderChild<T>(record, columns, index)}
88+
</Row>
89+
);
90+
};
91+
6792
const CardList = <T,>({
6893
loading,
6994
dataSource,
70-
rowKey = 'key',
95+
rowKey,
7196
rowClassName,
7297
columns,
7398
rowClick,
7499
slot,
75100
size = 'default',
76101
emptyHolder,
77102
onRefresh,
103+
onViewChange
78104
}: IProps<T>) => {
79105
return (
80106
<div className="card-list flex flex-1 flex-col bg-white shadow pb-2">
@@ -114,15 +140,17 @@ const CardList = <T,>({
114140
},
115141
);
116142
return (
117-
<Row
118-
onClick={() => {
143+
<RowItem<T>
144+
rowId={rowId}
145+
rowClass={rowClass}
146+
rowClick={() => {
119147
rowClick?.(record);
120148
}}
121-
key={rowId}
122-
className={rowClass}
123-
>
124-
{renderChild<T>(record, columns, index)}
125-
</Row>
149+
columns={columns}
150+
index={index}
151+
record={record}
152+
onViewChange={onViewChange}
153+
/>
126154
);
127155
})
128156
: emptyHolder || <EmptyHolder relative />}

shell/app/common/use-hooks.tsx

+49
Original file line numberDiff line numberDiff line change
@@ -932,3 +932,52 @@ export const useFullScreen: IUseFullScreen = (target, options) => {
932932
},
933933
];
934934
};
935+
936+
type IUseInViewPort = (
937+
target: BasicTarget,
938+
options?: {
939+
rootMargin?: string;
940+
threshold?: number | number[];
941+
root?: BasicTarget<Element>;
942+
},
943+
) => [boolean | undefined, number | undefined];
944+
945+
export const useInViewPort: IUseInViewPort = (target, options) => {
946+
const [state, setState] = React.useState<boolean>();
947+
const [ratio, setRatio] = React.useState<number>();
948+
949+
React.useEffect(
950+
() => {
951+
const el = getTargetElement(target);
952+
if (!el) {
953+
return;
954+
}
955+
956+
const observer = new IntersectionObserver(
957+
(entries) => {
958+
for (const entry of entries) {
959+
setRatio(entry.intersectionRatio);
960+
if (entry.isIntersecting) {
961+
setState(true);
962+
} else {
963+
setState(false);
964+
}
965+
}
966+
},
967+
{
968+
...options,
969+
root: getTargetElement(options?.root),
970+
},
971+
);
972+
973+
observer.observe(el);
974+
975+
return () => {
976+
observer.disconnect();
977+
};
978+
},
979+
[]
980+
);
981+
982+
return [state, ratio];
983+
};

0 commit comments

Comments
 (0)