Skip to content

Commit 2715f12

Browse files
committed
frontend/latex/output: fix manual forward sync to output/PDF and make the files an antd list
1 parent ae04aa7 commit 2715f12

File tree

3 files changed

+93
-21
lines changed

3 files changed

+93
-21
lines changed

src/packages/frontend/frame-editors/latex-editor/actions.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,12 +1473,12 @@ export class Actions extends BaseActions<LatexEditorState> {
14731473
}
14741474

14751475
_get_most_recent_output_panel(): string | undefined {
1476-
let result = this._get_most_recent_active_frame_id_of_type("latex-output");
1476+
let result = this._get_most_recent_active_frame_id_of_type("output");
14771477
console.log("LaTeX: _get_most_recent_output_panel() via active history returning", result);
14781478

14791479
// If no recently active output panel found, look for any output panel
14801480
if (!result) {
1481-
result = this._get_any_frame_id_of_type("latex-output");
1481+
result = this._get_any_frame_id_of_type("output");
14821482
console.log("LaTeX: _get_any_frame_id_of_type() returning", result);
14831483
}
14841484

@@ -1589,7 +1589,7 @@ export class Actions extends BaseActions<LatexEditorState> {
15891589
_is_output_panel(id: string): boolean {
15901590
const frame = this._get_frame_node(id);
15911591
const frameType = frame?.get("type");
1592-
return frameType === "latex-output";
1592+
return frameType === "output";
15931593
}
15941594

15951595
// Public method to save local view state (delegates to parent's debounced method)

src/packages/frontend/frame-editors/latex-editor/latex-word-count.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* License: MS-RSL – see LICENSE.md for details
44
*/
55

6-
import { React, useRedux } from "../../app-framework";
6+
import { React, useRedux } from "@cocalc/frontend/app-framework";
77

88
interface LatexWordCountProps {
99
name: string;

src/packages/frontend/frame-editors/latex-editor/output.tsx

Lines changed: 89 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ With build controls at the top (build, force build, clean, etc.)
1717
*/
1818

1919
import type { TabsProps } from "antd";
20-
import { Spin, Tabs, Tag } from "antd";
20+
import { List as AntdList, Spin, Tabs, Tag } from "antd";
2121
import { List } from "immutable";
2222
import { useCallback, useMemo, useState } from "react";
2323
import { useIntl } from "react-intl";
@@ -58,6 +58,12 @@ interface OutputProps {
5858

5959
type TabType = "pdf" | "contents" | "files" | "build" | "errors";
6060

61+
interface FileListItem {
62+
path: string;
63+
isMain: boolean;
64+
summary: string;
65+
}
66+
6167
export function Output(props: OutputProps) {
6268
const {
6369
id,
@@ -120,6 +126,13 @@ export function Output(props: OutputProps) {
120126
// List of LaTeX files in the project
121127
const switch_to_files: List<string> = useRedux([name, "switch_to_files"]);
122128

129+
// File summaries state with caching (1 minute max)
130+
const [fileSummaries, setFileSummaries] = useState<Record<string, string>>(
131+
{},
132+
);
133+
const [lastSummariesFetch, setLastSummariesFetch] = useState<number>(0);
134+
const [summariesLoading, setSummariesLoading] = useState<boolean>(false);
135+
123136
// Update table of contents when component mounts
124137
useEffect(() => {
125138
// We have to do this update
@@ -232,6 +245,37 @@ export function Output(props: OutputProps) {
232245
return { errors, warnings, typesetting };
233246
}, [build_logs, knitr]);
234247

248+
// Function to generate basic file summaries (placeholder for future implementation)
249+
const generateFileSummaries = useCallback(() => {
250+
if (!switch_to_files || switch_to_files.size === 0) return;
251+
252+
const now = Date.now();
253+
const oneMinute = 60 * 1000;
254+
255+
// Only update if it's been more than 1 minute since last fetch
256+
if (now - lastSummariesFetch < oneMinute) return;
257+
258+
setSummariesLoading(true);
259+
260+
// Generate basic summaries - this is scaffolding for future implementation
261+
const summaries: Record<string, string> = {};
262+
switch_to_files.forEach((filePath) => {
263+
// Basic placeholder - can be enhanced with actual file content analysis
264+
summaries[filePath] = "LaTeX document";
265+
});
266+
267+
setFileSummaries(summaries);
268+
setLastSummariesFetch(now);
269+
setSummariesLoading(false);
270+
}, [switch_to_files, lastSummariesFetch]);
271+
272+
// Generate file summaries when files change
273+
React.useEffect(() => {
274+
if (switch_to_files && switch_to_files.size > 1) {
275+
generateFileSummaries();
276+
}
277+
}, [switch_to_files, generateFileSummaries]);
278+
235279
// No automatic tab switching - let user control tabs manually
236280
// Errors are indicated with red exclamation icon only
237281

@@ -324,31 +368,59 @@ export function Output(props: OutputProps) {
324368
return a.localeCompare(b);
325369
});
326370

371+
const listData = sortedFiles.toJS().map((filePath: string) => ({
372+
path: filePath,
373+
isMain: filePath === path,
374+
summary: fileSummaries[filePath] || "Loading...",
375+
}));
376+
327377
return {
328378
key: "files",
329379
label: (
330380
<span style={{ display: "flex", alignItems: "center", gap: "2px" }}>
331381
<Icon name="file" />
332382
Files
383+
{summariesLoading && <Spin size="small" />}
333384
</span>
334385
),
335386
children: (
336-
<div className="smc-vfill" style={{ padding: "10px" }}>
337-
{sortedFiles.map((filePath) => (
338-
<div
339-
key={filePath}
340-
style={{
341-
padding: "8px",
342-
cursor: "pointer",
343-
borderBottom: `1px solid ${COLORS.GRAY_LL}`,
344-
fontFamily: "monospace",
345-
fontSize: "12px",
346-
}}
347-
onClick={() => actions.switch_to_file(filePath)}
348-
>
349-
{path === filePath ? <b>{filePath} (main)</b> : filePath}
350-
</div>
351-
))}
387+
<div
388+
className="smc-vfill"
389+
style={{ padding: "10px", overflowY: "auto" }}
390+
>
391+
<AntdList
392+
size="small"
393+
dataSource={listData}
394+
renderItem={(item: FileListItem) => (
395+
<AntdList.Item
396+
style={{
397+
cursor: "pointer",
398+
padding: "12px 8px",
399+
}}
400+
onClick={() => actions.switch_to_file(item.path)}
401+
>
402+
<AntdList.Item.Meta
403+
title={
404+
<div style={{ fontFamily: "monospace", fontSize: "13px" }}>
405+
{item.isMain ? <b>{item.path} (main)</b> : item.path}
406+
</div>
407+
}
408+
description={
409+
<div
410+
style={{
411+
fontSize: "12px",
412+
color: COLORS.GRAY_D,
413+
marginTop: "4px",
414+
whiteSpace: "pre-wrap",
415+
}}
416+
>
417+
{item.summary}
418+
</div>
419+
}
420+
/>
421+
</AntdList.Item>
422+
)}
423+
/>
352424
</div>
353425
),
354426
};

0 commit comments

Comments
 (0)