diff --git a/src/components/CurationSection.tsx b/src/components/CurationSection.tsx
index de5b495..3f51e56 100644
--- a/src/components/CurationSection.tsx
+++ b/src/components/CurationSection.tsx
@@ -1,9 +1,22 @@
import { getFileIdentities } from "@/serverFns/latex.server";
-import { Group, Loader, SimpleGrid, Stack, Text, Title } from "@mantine/core";
+import {
+ Group,
+ Loader,
+ Select,
+ SimpleGrid,
+ Stack,
+ Text,
+ Title,
+} from "@mantine/core";
import { useQuery } from "@tanstack/react-query";
import { StexCuration } from "./StexCuration";
-export function CurationSection() {
+type Props = {
+ curationLevel: string | null;
+ setCurationLevel: (value: string | null) => void;
+};
+
+export function CurationSection({ curationLevel, setCurationLevel }: Props) {
const { data: fileGroups = [], isLoading } = useQuery({
queryKey: ["fileIdentities"],
queryFn: getFileIdentities,
@@ -11,6 +24,18 @@ export function CurationSection() {
return (
+
FTML Definitions by File
diff --git a/src/components/ExtractedTextList.tsx b/src/components/ExtractedTextList.tsx
index 95c6c46..fa50d40 100644
--- a/src/components/ExtractedTextList.tsx
+++ b/src/components/ExtractedTextList.tsx
@@ -13,6 +13,7 @@ import { FolderSymlink } from "lucide-react";
import { FtmlPreview } from "./FtmlPreview";
interface ExtractedTextPanelProps {
+ isLocked?: boolean;
extracts: ExtractedItem[];
editingId: string | null;
selectedId: string | null;
@@ -21,13 +22,14 @@ interface ExtractedTextPanelProps {
id: string,
statement: ExtractedItem["statement"],
) => Promise;
+ onDownload?: (item: ExtractedItem) => void;
onDelete: (id: string) => void;
onSelection: (extractId: string) => void;
onOpenSemanticPanel: (definitionId: string) => void;
showPageNumber?: boolean;
showDefinitionMeta?: boolean;
- onEditDefinitionMeta?: (item: ExtractedItem) => void;
- showDefinitionMetaIconOnly?: boolean;
+ onEditDefinitionMeta?: (item: ExtractedItem) => void;
+ showDefinitionMetaIconOnly?: boolean;
}
export function ExtractedTextPanel({
@@ -43,6 +45,7 @@ export function ExtractedTextPanel({
showDefinitionMeta = true,
showDefinitionMetaIconOnly = false,
onEditDefinitionMeta,
+ isLocked = false,
}: ExtractedTextPanelProps) {
return (
@@ -84,6 +87,7 @@ export function ExtractedTextPanel({
onDelete(item.id)}
>
@@ -92,6 +96,7 @@ export function ExtractedTextPanel({
onToggleEdit(item.id)}
>
@@ -100,6 +105,7 @@ export function ExtractedTextPanel({
onOpenSemanticPanel(item.id)}
>
diff --git a/src/components/StexCuration.tsx b/src/components/StexCuration.tsx
index cd894cc..a6b544c 100644
--- a/src/components/StexCuration.tsx
+++ b/src/components/StexCuration.tsx
@@ -1,5 +1,7 @@
import { queryClient } from "@/queryClient";
+import { generateStexFromFtml } from "@/server/ftml/generateStexFromFtml";
import { ExtractedItem } from "@/server/text-selection";
+import { getCombinedDefinitionFtml } from "@/serverFns/definitionAggregate.server";
import {
deleteDefinition,
updateDefinition,
@@ -7,20 +9,26 @@ import {
import {
FileIdentity,
getDefinitionsByIdentity,
+ getLatexHistory,
} from "@/serverFns/latex.server";
import { FtmlStatement } from "@/types/ftml.types";
import {
+ ActionIcon,
Badge,
Box,
+ Button,
Group,
Loader,
+ Menu,
+ Modal,
Paper,
ScrollArea,
Stack,
Text,
+ Textarea,
} from "@mantine/core";
import { useQuery } from "@tanstack/react-query";
-import { FolderSymlink } from "lucide-react";
+import { ChevronDown, Download, FolderSymlink } from "lucide-react";
import { useState } from "react";
import { DefinitionIdentityDialog } from "./DefinitionFilePathDialog";
import { ExtractedTextPanel } from "./ExtractedTextList";
@@ -35,6 +43,8 @@ export function StexCuration({ identity }: { identity: FileIdentity }) {
const [semanticPanelDefId, setSemanticPanelDefId] = useState(
null,
);
+ const [latexOpen, setLatexOpen] = useState(false);
+ const [latexCode, setLatexCode] = useState("");
const { data, isLoading } = useQuery({
queryKey: ["definitionsByIdentity", identity],
@@ -44,12 +54,73 @@ export function StexCuration({ identity }: { identity: FileIdentity }) {
}),
});
+ const { data: latexHistory } = useQuery({
+ queryKey: [
+ "latex-status",
+ identity.documentId,
+ identity.futureRepo,
+ identity.filePath,
+ identity.fileName,
+ identity.language,
+ ],
+ queryFn: () =>
+ getLatexHistory({
+ data: identity,
+ }),
+ });
+
+ const latexStatus = latexHistory?.status ?? "EXTRACTED";
+
const hasSymbols = (data?.symbols.length ?? 0) > 0;
function handleEditDefinitionMeta(item: ExtractedItem) {
setDefinitionMetaTarget(item);
setDefinitionMetaEditOpen(true);
}
+ async function handleDownload() {
+ try {
+ const ftmlAst = await getCombinedDefinitionFtml({
+ data: {
+ documentId: identity.documentId,
+ futureRepo: identity.futureRepo,
+ filePath: identity.filePath,
+ fileName: identity.fileName,
+ language: identity.language,
+ },
+ });
+
+ if (!ftmlAst) {
+ alert("No FTML found.");
+ return;
+ }
+
+ const stex = await generateStexFromFtml(ftmlAst, identity.fileName);
+
+ if (!stex) {
+ alert("LaTeX generation failed.");
+ return;
+ }
+
+ const blob = new Blob([stex], {
+ type: "application/x-tex",
+ });
+
+ const url = URL.createObjectURL(blob);
+
+ const a = document.createElement("a");
+ a.href = url;
+ a.download = `${identity.fileName}.${identity.language}.tex`;
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+
+ setTimeout(() => URL.revokeObjectURL(url), 100);
+ } catch (error) {
+ console.error(error);
+ alert("Something went wrong while downloading.");
+ }
+ }
+
async function handleDelete(id: string) {
await deleteDefinition({ data: { id } });
await queryClient.invalidateQueries({
@@ -73,6 +144,33 @@ export function StexCuration({ identity }: { identity: FileIdentity }) {
setSemanticPanelDefId(id);
setSemanticPanelOpen(true);
}
+
+ async function handleOpenLatexPreview() {
+ try {
+ const ftmlAst = await getCombinedDefinitionFtml({
+ data: {
+ documentId: identity.documentId,
+ futureRepo: identity.futureRepo,
+ filePath: identity.filePath,
+ fileName: identity.fileName,
+ language: identity.language,
+ },
+ });
+
+ if (!ftmlAst) {
+ alert("No FTML found");
+ return;
+ }
+
+ const stex = await generateStexFromFtml(ftmlAst, identity.fileName);
+
+ setLatexCode(stex || "");
+ setLatexOpen(true);
+ } catch (e) {
+ console.error(e);
+ alert("Failed to load LaTeX preview");
+ }
+ }
return (
<>
-
- Symbol Declared
-
+
+
+ Symbol Declared
+
+
+
+
+
+
{hasSymbols ? (
@@ -144,9 +248,71 @@ export function StexCuration({ identity }: { identity: FileIdentity }) {
}}
>
-
- Definitions
-
+
+
+ Definitions
+
+
+
+
{}}
onOpenSemanticPanel={handleOpenSemanticPanel}
@@ -177,6 +344,7 @@ export function StexCuration({ identity }: { identity: FileIdentity }) {
showDefinitionMeta
showDefinitionMetaIconOnly
onEditDefinitionMeta={handleEditDefinitionMeta}
+ isLocked={latexStatus === "SUBMITTED"}
/>
)}
@@ -190,29 +358,60 @@ export function StexCuration({ identity }: { identity: FileIdentity }) {
borderBottom: "1px solid var(--mantine-color-gray-2)",
}}
>
- {
- setDefinitionMetaTarget(null);
- setDefinitionMetaEditOpen(true);
- }}
- >
-
-
- {[
- identity.futureRepo,
- identity.filePath,
- identity.fileName,
- identity.language,
- ]
- .filter(Boolean)
- .join(" / ")}
-
+
+ {
+ setDefinitionMetaTarget(null);
+ setDefinitionMetaEditOpen(true);
+ }}
+ >
+
+
+ {[
+ identity.futureRepo,
+ identity.filePath,
+ identity.fileName,
+ identity.language,
+ ]
+ .filter(Boolean)
+ .join(" / ")}
+
+
+
+
+
+ setLatexOpen(false)}
+ title="LaTeX Preview"
+ size="xl"
+ >
+
+
{
diff --git a/src/routes/create-latex.tsx b/src/routes/create-latex.tsx
index 5be8a40..8d094a5 100644
--- a/src/routes/create-latex.tsx
+++ b/src/routes/create-latex.tsx
@@ -7,6 +7,7 @@ import {
saveLatexDraft,
saveLatexFinal,
} from "@/serverFns/latex.server";
+
import {
ActionIcon,
Badge,
@@ -20,8 +21,8 @@ import {
Text,
Textarea,
Title,
- Tooltip,
} from "@mantine/core";
+
import { useQuery } from "@tanstack/react-query";
import { createFileRoute, redirect, useNavigate } from "@tanstack/react-router";
import { Download } from "lucide-react";
@@ -236,8 +237,32 @@ ${lines.join("\n")}`;
LaTeX Editor
sTeX
+
+ {historyData?.status === "SUBMITTED" && (
+ MathHub Submitted
+ )}
+
+
+