Skip to content

Commit ed29261

Browse files
Feat(router): Add placeholder page for ARK loader
1 parent 47bec18 commit ed29261

24 files changed

Lines changed: 386 additions & 45 deletions

packages/demo/404.html

Lines changed: 0 additions & 19 deletions
This file was deleted.

packages/demo/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"i18next-resources-to-backend": "catalog:",
2323
"react": "catalog:",
2424
"react-dom": "catalog:",
25-
"react-i18next": "catalog:"
25+
"react-i18next": "catalog:",
26+
"react-router": "catalog:"
2627
},
2728
"devDependencies": {
2829
"@types/node": "catalog:",

packages/demo/src/App.tsx

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,40 @@
11
import { ThemeProvider } from "@mui/material";
22
import CssBaseline from "@mui/material/CssBaseline";
3+
import { createHashRouter, RouterProvider } from "react-router";
34

45
import { I18nProvider } from "./i18n/I18nProvider";
56
import { Layout } from "./layout/Layout";
7+
import { Loader } from "./layout/Loader";
8+
import { ArkViewer, arkViewerLoader } from "./modules/ark-viewer/ArkViewer";
9+
import { FileViewer } from "./modules/file-viewer/FileViewer";
610
import theme from "./theme";
7-
import { UploadPage } from "./upload/UploadPage";
8-
import { ViewerContextProvider } from "./viewer/ViewerContext";
9-
import { ViewerPage } from "./viewer/ViewerPage";
11+
12+
const router = createHashRouter([
13+
{
14+
path: "/",
15+
Component: Layout,
16+
children: [
17+
{
18+
index: true,
19+
Component: FileViewer,
20+
},
21+
22+
{
23+
path: "ark/:id",
24+
loader: arkViewerLoader,
25+
HydrateFallback: Loader,
26+
Component: ArkViewer,
27+
},
28+
],
29+
},
30+
]);
1031

1132
function App() {
1233
return (
1334
<ThemeProvider theme={theme}>
1435
<I18nProvider>
15-
<Layout>
16-
<CssBaseline />
17-
<ViewerContextProvider>
18-
<UploadPage />
19-
<ViewerPage />
20-
</ViewerContextProvider>
21-
</Layout>
36+
<CssBaseline />
37+
<RouterProvider router={router} />
2238
</I18nProvider>
2339
</ThemeProvider>
2440
);

packages/demo/src/i18n/locales/en.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,8 @@ export const en: Translation = {
3737
buttonLabel: "Teeft Enrichment",
3838
},
3939
},
40+
ark: {
41+
documentNotFound: "The requested document was not found.",
42+
goToIstexSearch: "Return to Istex Search",
43+
},
4044
};

packages/demo/src/i18n/locales/fr.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ export const fr = {
3535
buttonLabel: "Enrichissement TEEFT",
3636
},
3737
},
38+
ark: {
39+
documentNotFound: "Le document demandé n'a pas été trouvé.",
40+
goToIstexSearch: "Retourner sur Istex Search",
41+
},
3842
};
3943

4044
export type Translation = typeof fr;
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
import { Outlet } from "react-router";
12
import Header from "./Header";
23
import Navbar from "./NavBar";
34

4-
export function Layout({ children }: { children: React.ReactNode }) {
5+
export function Layout() {
56
return (
67
<>
78
<Navbar />
89
<Header />
9-
{children}
10+
<Outlet />
1011
</>
1112
);
1213
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import CircularProgress from "@mui/material/CircularProgress";
2+
import Container from "@mui/material/Container";
3+
4+
export function Loader() {
5+
return (
6+
<Container
7+
maxWidth="sm"
8+
sx={{
9+
display: "flex",
10+
justifyContent: "center",
11+
alignItems: "center",
12+
flexGrow: 1,
13+
}}
14+
>
15+
<CircularProgress size={48} />
16+
</Container>
17+
);
18+
}

packages/demo/src/modules/ark-viewer/ArkViewer.spec.tsx

Whitespace-only changes.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { Viewer } from "@istex/react-tei/Viewer.js";
2+
import KeyboardBackspaceIcon from "@mui/icons-material/KeyboardBackspace";
3+
import Alert from "@mui/material/Alert";
4+
import Button from "@mui/material/Button";
5+
import Container from "@mui/material/Container";
6+
import Link from "@mui/material/Link";
7+
import { useTranslation } from "react-i18next";
8+
import { type LoaderFunction, useLoaderData } from "react-router";
9+
import document from "./document/minimal.tei.xml?raw";
10+
import unitexEnrichment from "./document/minimal.unitex.xml?raw";
11+
12+
export type ArkViewerLoaderData = {
13+
document: string | null;
14+
unitexEnrichment?: string | null;
15+
teeftEnrichment?: string | null;
16+
multicatEnrichment?: string | null;
17+
nbEnrichment?: string | null;
18+
};
19+
20+
export const arkViewerLoader: LoaderFunction = async ({
21+
params,
22+
}): Promise<ArkViewerLoaderData> => {
23+
const { id } = params;
24+
25+
// Simulate loading time
26+
await new Promise((resolve) => setTimeout(resolve, 1000));
27+
28+
if (!id) {
29+
return {
30+
document: null,
31+
};
32+
}
33+
34+
return {
35+
document,
36+
unitexEnrichment,
37+
};
38+
};
39+
40+
export function ArkViewer() {
41+
const { document, ...rest } = useLoaderData<ArkViewerLoaderData>();
42+
43+
if (!document) {
44+
return <DocumentNotFound />;
45+
}
46+
47+
return (
48+
<Viewer
49+
document={document}
50+
{...rest}
51+
height="calc(100dvh - 49.5px - 118.5px)"
52+
/>
53+
);
54+
}
55+
56+
function DocumentNotFound() {
57+
const { t } = useTranslation();
58+
return (
59+
<Container
60+
maxWidth="sm"
61+
sx={{
62+
display: "flex",
63+
justifyContent: "center",
64+
alignItems: "center",
65+
flexDirection: "column",
66+
gap: 2,
67+
flexGrow: 1,
68+
}}
69+
>
70+
<Alert
71+
severity="warning"
72+
sx={{
73+
width: "100%",
74+
}}
75+
>
76+
{t("ark.documentNotFound")}
77+
</Alert>
78+
<Button
79+
component={Link}
80+
href="https://search.istex.fr/fr-FR"
81+
fullWidth
82+
variant="contained"
83+
startIcon={<KeyboardBackspaceIcon />}
84+
>
85+
{t("ark.goToIstexSearch")}
86+
</Button>
87+
</Container>
88+
);
89+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<TEI version="3.3.0" xmlns="http://www.tei-c.org/ns/1.0">
2+
<teiHeader>
3+
<fileDesc>
4+
<titleStmt>
5+
<title>The shortest TEI Document Imaginable</title>
6+
</titleStmt>
7+
<publicationStmt>
8+
<p>First published as part of TEI P2, this is the P5
9+
version using a namespace.</p>
10+
</publicationStmt>
11+
<sourceDesc>
12+
<p>No source: this is an original work.</p>
13+
</sourceDesc>
14+
</fileDesc>
15+
</teiHeader>
16+
<text>
17+
<body>
18+
<div>
19+
<head>Correspondance simple</head>
20+
<p>lorem ipsum Gustave Eiffel</p>
21+
22+
<head>Entité encadrée par une ponctuation</head>
23+
<p>lorem ipsum (Gustave Eiffel)</p>
24+
25+
<head>Entité suivie d'une ponctuation</head>
26+
<p>Gustave Eiffel, lorem ipsum</p>
27+
28+
<head>Entité avec abréviation</head>
29+
<p>Eiffel G., lorem ipsum</p>
30+
31+
<head>Entité contenant un caractère HTML</head>
32+
<p>Gustave&#9;Eiffel, lorem ipsum</p>
33+
</div>
34+
<div>
35+
<head>Juxtaposition</head>
36+
<p>Gustave Eiffel Marie Curie</p>
37+
</div>
38+
<div>
39+
<head>Rendition complète : L'intégralité de l'entité est formatée</head>
40+
<p>lorem ipsum <hi rend="bold">Gustave Eiffel</hi></p>
41+
42+
<head>Rendition partielle : L'entité est partiellement formatée</head>
43+
<p>lorem ipsum (Gustave <hi rend="bold">Eiffel</hi>)</p>
44+
45+
<head>Rendition imbriquée : Renditions imbriquées sur l'entité</head>
46+
<p>lorem ipsum (<hi rend="italic">Gustave <hi rend="bold">Eiffel</hi></hi>)</p>
47+
</div>
48+
<div>
49+
<head>Inclusion totale : Une entité est complètement incluse dans une autre</head>
50+
<p>Laboratoire Marie Curie de l'Université Saclay</p>
51+
</div>
52+
<div>
53+
<head>Overlap : Une entité est partiellement incluse dans une autre</head>
54+
<p>Université Gustave Eiffel, lorem ipsum</p>
55+
</div>
56+
57+
<div>
58+
<head>Titre avec annotation: Gustave Eiffel</head>
59+
<p>Gustave Eiffel</p>
60+
</div>
61+
<div>
62+
<head>
63+
Overlap: deux annotations du même groupe se chevauchent partiellement
64+
</head>
65+
<p>Gustave Eiffel G.</p>
66+
</div>
67+
<div>
68+
<head>
69+
Overlap: deux annotations de groupes différents se chevauchent
70+
partiellement
71+
</head>
72+
<p>Université Gustave Eiffel G.</p>
73+
</div>
74+
</body>
75+
</text>
76+
</TEI>

0 commit comments

Comments
 (0)