Skip to content

Commit 5196fc1

Browse files
committed
frontend/process info table: compute height correctly
1 parent 8395e83 commit 5196fc1

File tree

2 files changed

+90
-22
lines changed

2 files changed

+90
-22
lines changed

src/packages/frontend/project/info/full.tsx

Lines changed: 77 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55

66
declare let DEBUG;
77

8-
import { InfoCircleOutlined, ScheduleOutlined } from "@ant-design/icons";
98
import { Alert, Button, Form, Modal, Popconfirm, Switch, Table } from "antd";
9+
import { useEffect, useRef, useState } from "react";
10+
11+
import { InfoCircleOutlined, ScheduleOutlined } from "@ant-design/icons";
1012
import { Col, Row } from "@cocalc/frontend/antd-bootstrap";
1113
import { CSS, ProjectActions, redux } from "@cocalc/frontend/app-framework";
1214
import { A, Loading, Tip } from "@cocalc/frontend/components";
@@ -89,6 +91,58 @@ export function Full(props: Readonly<Props>): React.JSX.Element {
8991
onCellProps,
9092
} = props;
9193

94+
const problemsRef = useRef<HTMLDivElement>(null);
95+
const cgroupRef = useRef<HTMLDivElement>(null);
96+
const headerRef = useRef<HTMLDivElement>(null);
97+
const explanationRef = useRef<HTMLDivElement>(null);
98+
const tableContainerRef = useRef<HTMLDivElement>(null);
99+
const [tableHeight, setTableHeight] = useState<number>(400);
100+
101+
useEffect(() => {
102+
const calculateTableHeight = () => {
103+
// Find the parent container with class "smc-vfill"
104+
let parentContainer = headerRef.current?.closest(
105+
".smc-vfill",
106+
) as HTMLElement;
107+
if (!parentContainer) return;
108+
109+
const parentHeight = parentContainer.getBoundingClientRect().height;
110+
let usedHeight = 0;
111+
112+
// Add height of ProjectProblems component
113+
if (problemsRef.current) {
114+
usedHeight += problemsRef.current.offsetHeight;
115+
}
116+
117+
// Add height of CGroup component
118+
if (cgroupRef.current) {
119+
usedHeight += cgroupRef.current.offsetHeight;
120+
}
121+
122+
// Add height of header row
123+
if (headerRef.current) {
124+
usedHeight += headerRef.current.offsetHeight;
125+
}
126+
127+
// Add height of explanation row if visible
128+
if (explanationRef.current) {
129+
usedHeight += explanationRef.current.offsetHeight;
130+
}
131+
132+
// Add more buffer for table header, margins, and other spacing
133+
usedHeight += 120;
134+
135+
const availableHeight = Math.max(300, parentHeight - usedHeight);
136+
setTableHeight(availableHeight);
137+
};
138+
139+
calculateTableHeight();
140+
141+
// Recalculate on window resize
142+
window.addEventListener("resize", calculateTableHeight);
143+
return () => window.removeEventListener("resize", calculateTableHeight);
144+
}, [show_explanation, ptree]);
145+
92146
function render_help() {
93147
return (
94148
<Form.Item label="Help:">
@@ -295,11 +349,16 @@ export function Full(props: Readonly<Props>): React.JSX.Element {
295349
</Tip>
296350
);
297351

298-
const table_style: CSS = { marginBottom: "2rem" };
352+
const table_style: CSS = {
353+
marginBottom: "2rem",
354+
};
299355

300356
return (
301357
<>
302-
<Row style={{ marginBottom: "10px", marginTop: "20px" }}>
358+
<Row
359+
ref={headerRef}
360+
style={{ marginBottom: "10px", marginTop: "20px" }}
361+
>
303362
<Col md={9}>
304363
<Form layout="inline">
305364
<Form.Item label="Table of Processes" />
@@ -314,13 +373,13 @@ export function Full(props: Readonly<Props>): React.JSX.Element {
314373
</Form>
315374
</Col>
316375
</Row>
317-
<Row>{render_explanation()}</Row>
376+
<Row ref={explanationRef}>{render_explanation()}</Row>
318377
<Row>
319378
<Table<ProcessRow>
320379
dataSource={ptree}
321380
size={"small"}
322381
pagination={false}
323-
scroll={{ y: "65vh" }}
382+
scroll={{ y: tableHeight }}
324383
style={table_style}
325384
expandable={expandable}
326385
rowSelection={rowSelection}
@@ -472,15 +531,19 @@ export function Full(props: Readonly<Props>): React.JSX.Element {
472531
function render_body() {
473532
return (
474533
<>
475-
<ProjectProblems project_status={project_status} />
476-
<CGroup
477-
have_cgroup={info?.cgroup != null}
478-
cg_info={cg_info}
479-
disk_usage={disk_usage}
480-
pt_stats={pt_stats}
481-
start_ts={start_ts}
482-
project_status={project_status}
483-
/>
534+
<div ref={problemsRef}>
535+
<ProjectProblems project_status={project_status} />
536+
</div>
537+
<div ref={cgroupRef}>
538+
<CGroup
539+
have_cgroup={info?.cgroup != null}
540+
cg_info={cg_info}
541+
disk_usage={disk_usage}
542+
pt_stats={pt_stats}
543+
start_ts={start_ts}
544+
project_status={project_status}
545+
/>
546+
</div>
484547
{render_top()}
485548
{render_modals()}
486549
{DEBUG && render_general_status()}

src/packages/frontend/project/info/project-info.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55

66
import { Alert } from "antd";
7+
8+
import { cgroup_stats } from "@cocalc/comm/project-status/utils";
79
import {
810
React,
911
Rendered,
@@ -13,20 +15,19 @@ import {
1315
useState,
1416
useTypedRedux,
1517
} from "@cocalc/frontend/app-framework";
18+
import ShowError from "@cocalc/frontend/components/error";
1619
import { useProjectContext } from "@cocalc/frontend/project/context";
20+
import { unreachable } from "@cocalc/util/misc";
1721
import {
1822
Process,
1923
ProjectInfo as ProjectInfoType,
2024
} from "@cocalc/util/types/project-info/types";
21-
import { cgroup_stats } from "@cocalc/comm/project-status/utils";
22-
import { unreachable } from "@cocalc/util/misc";
2325
import { CoCalcFile, render_cocalc_btn } from "./components";
2426
import { Flyout } from "./flyout";
2527
import { Full } from "./full";
2628
import { CGroupInfo, DUState, PTStats, ProcessRow } from "./types";
27-
import { grid_warning, linearList, process_tree, sum_children } from "./utils";
2829
import useProjectInfo from "./use-project-info";
29-
import ShowError from "@cocalc/frontend/components/error";
30+
import { grid_warning, linearList, process_tree, sum_children } from "./utils";
3031

3132
interface Props {
3233
project_id: string;
@@ -82,7 +83,7 @@ export const ProjectInfo: React.FC<Props> = React.memo(
8283
const [ptree, set_ptree] = useState<ProcessRow[] | undefined>(undefined);
8384
const [pt_stats, set_pt_stats] = useState<PTStats>(pt_stats_init);
8485
const [selected, set_selected] = useState<number[]>([]);
85-
const [expanded, set_expanded] = useState<(string|number)[]>([]);
86+
const [expanded, set_expanded] = useState<(string | number)[]>([]);
8687
const [have_children, set_have_children] = useState<string[]>([]);
8788
const [cg_info, set_cg_info] = useState<CGroupInfo>(gc_info_init);
8889
const [disk_usage, set_disk_usage] = useState<DUState>(du_init);
@@ -116,7 +117,7 @@ export const ProjectInfo: React.FC<Props> = React.memo(
116117

117118
function update_top(info: ProjectInfoType) {
118119
// this shouldn't be the case, but somehow I saw this happening once
119-
// the ProjectInfoType type is updated to refrect this edge case and here we bail out
120+
// the ProjectInfoType type is updated to reflect this edge case and here we bail out
120121
// and wait for the next update of "info" to get all processes…
121122
if (info.processes == null) return;
122123
switch (mode) {
@@ -216,7 +217,7 @@ export const ProjectInfo: React.FC<Props> = React.memo(
216217
to_str?: (val) => Rendered,
217218
) {
218219
const cell_val = (val, proc): number => {
219-
// we have to check for length==0, because initally rows are all expanded but
220+
// we have to check for length==0, because initially rows are all expanded but
220221
// onExpandedRowsChange isn't triggered
221222
if (
222223
expanded.length == 0 ||
@@ -296,7 +297,11 @@ export const ProjectInfo: React.FC<Props> = React.memo(
296297
}
297298

298299
const showError = (
299-
<ShowError style={{ margin: "15px 0" }} error={error} setError={setError} />
300+
<ShowError
301+
style={{ margin: "15px 0" }}
302+
error={error}
303+
setError={setError}
304+
/>
300305
);
301306

302307
switch (mode) {

0 commit comments

Comments
 (0)