mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-06-22 15:35:03 +00:00
Routing for operators, Styling for main page
This commit is contained in:
parent
f7f6d40eee
commit
51e35ee0ee
@ -15,13 +15,11 @@
|
||||
"@stirling-pdf/shared-operations": "^0.0.0",
|
||||
"@tauri-apps/api": "^1.5.1",
|
||||
"archiver": "^6.0.1",
|
||||
"bootstrap": "^5.3.2",
|
||||
"i18next": "^23.6.0",
|
||||
"i18next-browser-languagedetector": "^7.1.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"pdfjs-dist": "^4.0.189",
|
||||
"react": "^18.2.0",
|
||||
"react-bootstrap": "^2.9.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-i18next": "^13.3.1",
|
||||
"react-icons": "^4.11.0",
|
||||
|
@ -2,18 +2,16 @@ import { Suspense } from "react";
|
||||
|
||||
import { Routes, Route, Outlet } from "react-router-dom";
|
||||
import Home from "./pages/Home";
|
||||
import Dynamic from "./pages/Dynamic";
|
||||
import Operators from "./pages/Operators";
|
||||
import NoMatch from "./pages/NoMatch";
|
||||
import NavBar from "./components/NavBar";
|
||||
|
||||
import "bootstrap/dist/css/bootstrap.min.css";
|
||||
import { Container } from "react-bootstrap";
|
||||
|
||||
import { useTranslation, initReactI18next } from "react-i18next";
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
|
||||
import i18next from "i18next";
|
||||
import resourcesToBackend from "i18next-resources-to-backend";
|
||||
import { listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
|
||||
|
||||
i18next.use(LanguageDetector).use(initReactI18next).use(resourcesToBackend((language: string, namespace: string) => import(`../../shared-operations/public/locales/${namespace}/${language}.json`)))
|
||||
.init({
|
||||
@ -27,8 +25,6 @@ i18next.use(LanguageDetector).use(initReactI18next).use(resourcesToBackend((lang
|
||||
initImmediate: false // Makes loading blocking but sync
|
||||
}); // TODO: use i18next.config.ts instead
|
||||
|
||||
import "./root.css";
|
||||
|
||||
export default function App() {
|
||||
|
||||
return (
|
||||
@ -39,13 +35,21 @@ export default function App() {
|
||||
<Routes>
|
||||
<Route path="/" element={<Layout />}>
|
||||
<Route index element={<Home />} />
|
||||
<Route path="dynamic" element={<Dynamic />} />
|
||||
|
||||
{/* Using path="*"" means "match anything", so this route
|
||||
acts like a catch-all for URLs that we don't have explicit
|
||||
routes for. */}
|
||||
<Route path="*" element={<NoMatch />} />
|
||||
</Route>
|
||||
|
||||
<Route path="/operators" element={<Layout />}>
|
||||
<Route index element={<NoMatch />} />
|
||||
{listOperatorNames().map((name) => {
|
||||
return <Route key={name} path={name} element={<Operators/>} />;
|
||||
})}
|
||||
<Route path="*" element={<NoMatch />} />
|
||||
</Route>
|
||||
|
||||
<Route path="/convert" element={<Layout />}>
|
||||
{/* <Route path="file-to-pdf" element={<ToPdf />} /> */}
|
||||
<Route path="*" element={<NoMatch />} />
|
||||
@ -69,9 +73,7 @@ function Layout() {
|
||||
{/* An <Outlet> renders whatever child route is currently active,
|
||||
so you can think about this <Outlet> as a placeholder for
|
||||
the child routes we defined above. */}
|
||||
<Container fluid="sm" className="">
|
||||
<Outlet/>
|
||||
</Container>
|
||||
<Outlet/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,16 +1,13 @@
|
||||
import { Container } from "react-bootstrap";
|
||||
import StirlingLogo from "../assets/favicon.svg";
|
||||
import NavBarStyles from "./NavBar.module.css";
|
||||
|
||||
function NavBar() {
|
||||
return (
|
||||
<nav>
|
||||
<Container>
|
||||
<a className={NavBarStyles.navbar_brand} href="/">
|
||||
<img className={NavBarStyles.main_icon} src={StirlingLogo} alt="icon"/>
|
||||
<span className={NavBarStyles.icon_text}>Stirling PDF</span>
|
||||
</a>
|
||||
</Container>
|
||||
<a className={NavBarStyles.navbar_brand} href="/">
|
||||
<img className={NavBarStyles.main_icon} src={StirlingLogo} alt="icon"/>
|
||||
<span className={NavBarStyles.icon_text}>Stirling PDF</span>
|
||||
</a>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
22
client-tauri/src/components/OperatorCard.module.css
Normal file
22
client-tauri/src/components/OperatorCard.module.css
Normal file
@ -0,0 +1,22 @@
|
||||
.operator_card {
|
||||
border: 1px solid var(--md-sys-color-surface-5);
|
||||
border-radius: 1.75rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
background: var(--md-sys-color-surface-5);
|
||||
transition: transform 0.3s, border 0.3s;
|
||||
transform-origin: center center;
|
||||
outline: 0px solid transparent;
|
||||
}
|
||||
|
||||
.operator_card h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.operator_card:hover {
|
||||
cursor: pointer;
|
||||
transform: scale(1.08);
|
||||
box-shadow: var(--md-sys-elevation-2);
|
||||
}
|
33
client-tauri/src/components/OperatorCard.tsx
Normal file
33
client-tauri/src/components/OperatorCard.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { getSchemaByName } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
|
||||
|
||||
import styles from './OperatorCard.module.css';
|
||||
interface OperatorCardProps {
|
||||
/** The text to display inside the button */
|
||||
operatorInternalName: string;
|
||||
}
|
||||
|
||||
export function OperatorCard({ operatorInternalName }: OperatorCardProps) {
|
||||
const [schema, setSchema] = useState<any>(undefined); // TODO: Type as joi type
|
||||
|
||||
useEffect(() => {
|
||||
getSchemaByName(operatorInternalName).then(schema => {
|
||||
if(schema) {
|
||||
setSchema(schema.schema);
|
||||
}
|
||||
});
|
||||
}, [operatorInternalName]);
|
||||
|
||||
return (
|
||||
<a key={operatorInternalName} href={"/operators/" + operatorInternalName}>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
<div className={styles.operator_card}>
|
||||
<h3>{ schema?.describe().flags.label }</h3>
|
||||
{ schema?.describe().flags.description }
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
@ -10,22 +10,15 @@ interface BuildFieldsProps {
|
||||
|
||||
export function BuildFields({ schemaDescription, onSubmit }: BuildFieldsProps) {
|
||||
console.log("Render Build Fields", schemaDescription);
|
||||
const label = (schemaDescription?.flags as any)?.label
|
||||
const description = (schemaDescription?.flags as any)?.description;
|
||||
const values = (schemaDescription?.keys as any)?.values.keys as { [key: string]: Joi.Description};
|
||||
return (
|
||||
<div>
|
||||
<h3>{label}</h3>
|
||||
{description}
|
||||
<hr />
|
||||
<form onSubmit={(e) => { onSubmit(e); e.preventDefault(); }}>
|
||||
{
|
||||
values ? Object.keys(values).map((key) => {
|
||||
return (<GenericField key={key} fieldName={key} joiDefinition={values[key]} />)
|
||||
}) : undefined
|
||||
}
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
</div>
|
||||
<form onSubmit={(e) => { onSubmit(e); e.preventDefault(); }}>
|
||||
{
|
||||
values ? Object.keys(values).map((key) => {
|
||||
return (<GenericField key={key} fieldName={key} joiDefinition={values[key]} />)
|
||||
}) : undefined
|
||||
}
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
);
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
import { Link } from "react-router-dom";
|
||||
import { getOperatorByName, getSchemaByName, listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
|
||||
|
||||
import styles from './home.module.css';
|
||||
import { listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
|
||||
import { OperatorCard } from "../components/OperatorCard";
|
||||
|
||||
|
||||
import styles from './Home.module.css';
|
||||
|
||||
function Home() {
|
||||
const operators = listOperatorNames();
|
||||
@ -20,13 +23,10 @@ function Home() {
|
||||
<div className={styles.operator_container}>
|
||||
{
|
||||
operators.map((operator) => {
|
||||
return (<a key={operator} href={"/operators/" + operator}><div className={styles.operator_card}>{operator}</div></a>)
|
||||
return (<OperatorCard key={operator} operatorInternalName={operator}></OperatorCard>)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
<Link to="/dynamic">Dynamic</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { Fragment } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
function NoMatch() {
|
||||
return (
|
||||
<div>
|
||||
<Fragment>
|
||||
<h2>The Page you are trying to access does not exist.</h2>
|
||||
<p>
|
||||
<Link to="/">Go back home...</Link>
|
||||
</p>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,53 +1,52 @@
|
||||
import { Link } from "react-router-dom";
|
||||
import { Fragment } from "react";
|
||||
import { Fragment, useEffect } from "react";
|
||||
|
||||
import { BaseSyntheticEvent, useRef, useState } from "react";
|
||||
import { Operator, OperatorSchema } from "@stirling-pdf/shared-operations/src/functions";
|
||||
import Joi from "@stirling-tools/joi";
|
||||
import { BuildFields } from "../components/fields/BuildFields";
|
||||
import { getOperatorByName, getSchemaByName, listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
|
||||
import { getOperatorByName, getSchemaByName } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
|
||||
import { PdfFile, RepresentationType } from "@stirling-pdf/shared-operations/src/wrappers/PdfFile";
|
||||
import { Action } from "@stirling-pdf/shared-operations/declarations/Action";
|
||||
|
||||
import { useLocation } from 'react-router-dom'
|
||||
|
||||
|
||||
function Dynamic() {
|
||||
const [schemaDescription, setSchemaDescription] = useState<Joi.Description>();
|
||||
const [schema, setSchema] = useState<any>(undefined); // TODO: Type as joi type
|
||||
|
||||
const operators = listOperatorNames();
|
||||
const location = useLocation();
|
||||
|
||||
const activeOperatorName = useRef<string>();
|
||||
const activeOperator = useRef<typeof Operator>();
|
||||
const activeSchema = useRef<OperatorSchema>();
|
||||
const operatorInternalName = location.pathname.split("/")[2]; // /operators/<operatorInternalName>
|
||||
|
||||
async function selectionChanged(s: BaseSyntheticEvent) {
|
||||
const selectedValue = s.target.value;
|
||||
console.log("Selection changed to", selectedValue);
|
||||
if(selectedValue == "none") {
|
||||
setSchemaDescription(undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
getSchemaByName(selectedValue).then(async schema => {
|
||||
useEffect(() => {
|
||||
getSchemaByName(operatorInternalName).then(schema => {
|
||||
if(schema) {
|
||||
const description = schema.schema.describe();
|
||||
activeOperatorName.current = selectedValue;
|
||||
activeOperator.current = await getOperatorByName(selectedValue);
|
||||
activeSchema.current = schema;
|
||||
|
||||
// This will update children
|
||||
setSchemaDescription(description);
|
||||
setSchema(schema.schema);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [location]);
|
||||
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<h3>{ schema?.describe().flags.label }</h3>
|
||||
{ schema?.describe().flags.description }
|
||||
|
||||
<br />
|
||||
<input type="file" id="pdfFile" accept=".pdf" multiple />
|
||||
<br />
|
||||
|
||||
<div id="values">
|
||||
<BuildFields schemaDescription={schema?.describe()} onSubmit={handleSubmit}></BuildFields>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
async function handleSubmit(e: BaseSyntheticEvent) {
|
||||
console.clear();
|
||||
if(!activeOperatorName.current || !activeOperator.current || !activeSchema.current) {
|
||||
throw new Error("Please select an Operator in the Dropdown");
|
||||
}
|
||||
|
||||
const formData = new FormData(e.target);
|
||||
const values = Object.fromEntries(formData.entries());
|
||||
let action: Action = {type: activeOperatorName.current, values: values};
|
||||
let action: Action = {type: operatorInternalName, values: values};
|
||||
|
||||
// Validate PDF File
|
||||
|
||||
@ -71,14 +70,16 @@ function Dynamic() {
|
||||
}
|
||||
}
|
||||
|
||||
const validationResults = activeSchema.current.schema.validate({input: inputs, values: action.values});
|
||||
const validationResults = schema.validate({input: inputs, values: action.values});
|
||||
|
||||
if(validationResults.error) {
|
||||
console.error({error: "Validation failed", details: validationResults.error.message}, validationResults.error.stack);
|
||||
}
|
||||
else {
|
||||
action.values = validationResults.value.values;
|
||||
const operation = new activeOperator.current(action);
|
||||
const Operator = (await getOperatorByName(operatorInternalName))!;
|
||||
|
||||
const operation = new Operator(action);
|
||||
operation.run(validationResults.value.input, (progress) => {
|
||||
console.log("OperationProgress: " + progress.operationProgress, "CurFileProgress: " + progress.curFileProgress);
|
||||
}).then(async pdfFiles => {
|
||||
@ -92,29 +93,6 @@ function Dynamic() {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<h2>Dynamic test page for operators</h2>
|
||||
|
||||
<input type="file" id="pdfFile" accept=".pdf" multiple />
|
||||
<br />
|
||||
<select id="pdfOptions" onChange={selectionChanged}>
|
||||
<option value="none">none</option>
|
||||
{ operators.map((operator) => {
|
||||
return (<option key={operator} value={operator}>{operator}</option>)
|
||||
}) }
|
||||
</select>
|
||||
|
||||
<div id="values">
|
||||
<BuildFields schemaDescription={schemaDescription} onSubmit={handleSubmit}></BuildFields>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<Link to="/">Go back home...</Link>
|
||||
</p>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2,17 +2,4 @@
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(15rem, 3fr));
|
||||
gap: 30px 30px;
|
||||
}
|
||||
|
||||
.operator_card {
|
||||
border: 1px solid var(--md-sys-color-surface-5);
|
||||
border-radius: 1.75rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
background: var(--md-sys-color-surface-5);
|
||||
transition: transform 0.3s, border 0.3s;
|
||||
transform-origin: center center;
|
||||
outline: 0px solid transparent;
|
||||
}
|
@ -1,34 +1,34 @@
|
||||
:root {
|
||||
--md-sys-color-primary: rgb(162 201 255);
|
||||
--md-sys-color-surface-tint: rgb(162 201 255);
|
||||
--md-sys-color-on-primary: rgb(0 49 92);
|
||||
--md-sys-color-primary-container: rgb(0 118 208);
|
||||
--md-sys-color-on-primary-container: rgb(255 255 255);
|
||||
--md-sys-color-secondary: rgb(169 201 246);
|
||||
--md-sys-color-on-secondary: rgb(12 49 87);
|
||||
--md-sys-color-secondary-container: rgb(29 62 100);
|
||||
--md-sys-color-on-secondary-container: rgb(180 210 255);
|
||||
--md-sys-color-tertiary: rgb(193 194 248);
|
||||
--md-sys-color-on-tertiary: rgb(42 44 88);
|
||||
--md-sys-color-tertiary-container: rgb(110 112 161);
|
||||
--md-sys-color-on-tertiary-container: rgb(255 255 255);
|
||||
--md-sys-color-error: rgb(255 180 171);
|
||||
--md-sys-color-on-error: rgb(105 0 5);
|
||||
--md-sys-color-error-container: rgb(147 0 10);
|
||||
--md-sys-color-on-error-container: rgb(255 218 214);
|
||||
--md-sys-color-background: rgb(15 20 26);
|
||||
--md-sys-color-on-background: rgb(223 226 235);
|
||||
--md-sys-color-surface: rgb(15 20 26);
|
||||
--md-sys-color-on-surface: rgb(223 226 235);
|
||||
--md-sys-color-surface-variant: rgb(64 71 83);
|
||||
--md-sys-color-on-surface-variant: rgb(192 199 213);
|
||||
--md-sys-color-outline: rgb(138 145 158);
|
||||
--md-sys-color-outline-variant: rgb(64 71 83);
|
||||
--md-sys-color-primary: rgb(0 96 170);
|
||||
--md-sys-color-surface-tint: rgb(0 96 170);
|
||||
--md-sys-color-on-primary: rgb(255 255 255);
|
||||
--md-sys-color-primary-container: rgb(80 163 255);
|
||||
--md-sys-color-on-primary-container: rgb(0 20 43);
|
||||
--md-sys-color-secondary: rgb(65 96 136);
|
||||
--md-sys-color-on-secondary: rgb(255 255 255);
|
||||
--md-sys-color-secondary-container: rgb(188 215 255);
|
||||
--md-sys-color-on-secondary-container: rgb(32 65 103);
|
||||
--md-sys-color-tertiary: rgb(88 90 138);
|
||||
--md-sys-color-on-tertiary: rgb(255 255 255);
|
||||
--md-sys-color-tertiary-container: rgb(151 153 205);
|
||||
--md-sys-color-on-tertiary-container: rgb(7 9 55);
|
||||
--md-sys-color-error: rgb(186 26 26);
|
||||
--md-sys-color-on-error: rgb(255 255 255);
|
||||
--md-sys-color-error-container: rgb(255 218 214);
|
||||
--md-sys-color-on-error-container: rgb(65 0 2);
|
||||
--md-sys-color-background: rgb(248 249 255);
|
||||
--md-sys-color-on-background: rgb(24 28 34);
|
||||
--md-sys-color-surface: rgb(248 249 255);
|
||||
--md-sys-color-on-surface: rgb(24 28 34);
|
||||
--md-sys-color-surface-variant: rgb(220 227 241);
|
||||
--md-sys-color-on-surface-variant: rgb(64 71 83);
|
||||
--md-sys-color-outline: rgb(112 119 132);
|
||||
--md-sys-color-outline-variant: rgb(192 199 213);
|
||||
--md-sys-color-shadow: rgb(0 0 0);
|
||||
--md-sys-color-scrim: rgb(0 0 0);
|
||||
--md-sys-color-inverse-surface: rgb(223 226 235);
|
||||
--md-sys-color-inverse-on-surface: rgb(45 49 55);
|
||||
--md-sys-color-inverse-primary: rgb(0 96 170);
|
||||
--md-sys-color-inverse-surface: rgb(45 49 55);
|
||||
--md-sys-color-inverse-on-surface: rgb(238 241 250);
|
||||
--md-sys-color-inverse-primary: rgb(162 201 255);
|
||||
--md-sys-color-primary-fixed: rgb(211 228 255);
|
||||
--md-sys-color-on-primary-fixed: rgb(0 28 56);
|
||||
--md-sys-color-primary-fixed-dim: rgb(162 201 255);
|
||||
@ -41,33 +41,58 @@
|
||||
--md-sys-color-on-tertiary-fixed: rgb(20 22 66);
|
||||
--md-sys-color-tertiary-fixed-dim: rgb(193 194 248);
|
||||
--md-sys-color-on-tertiary-fixed-variant: rgb(64 67 112);
|
||||
--md-sys-color-surface-dim: rgb(15 20 26);
|
||||
--md-sys-color-surface-bright: rgb(53 57 64);
|
||||
--md-sys-color-surface-container-lowest: rgb(10 14 20);
|
||||
--md-sys-color-surface-container-low: rgb(24 28 34);
|
||||
--md-sys-color-surface-container: rgb(28 32 38);
|
||||
--md-sys-color-surface-container-high: rgb(38 42 49);
|
||||
--md-sys-color-surface-container-highest: rgb(49 53 60);
|
||||
--md-sys-color-surface-dim: rgb(215 218 227);
|
||||
--md-sys-color-surface-bright: rgb(248 249 255);
|
||||
--md-sys-color-surface-container-lowest: rgb(255 255 255);
|
||||
--md-sys-color-surface-container-low: rgb(241 243 253);
|
||||
--md-sys-color-surface-container: rgb(235 238 247);
|
||||
--md-sys-color-surface-container-high: rgb(229 232 241);
|
||||
--md-sys-color-surface-container-highest: rgb(223 226 235);
|
||||
--md-nav-section-color-opacity: 1;
|
||||
--md-nav-on-section-color-opacity: 1;
|
||||
--md-nav-section-color-sign: rgba(25, 101, 212, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-sign: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-sign: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-organize: rgba(120, 130, 255, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-organize: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-organize: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-convert: rgba(25, 177, 212, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-convert: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-convert: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-security: rgba(255, 120, 146, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-security: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-security: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-other: rgba(72, 189, 84, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-other: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-other: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-advance: rgba(245, 84, 84, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-advance: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-advance: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-image: rgba(212, 172, 25, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-image: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-image: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-word: rgba(61, 153, 245, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-word: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-word: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-ppt: rgba(255, 128, 0, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-ppt: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-ppt: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
|
||||
--bs-blue: #0d6efd;
|
||||
--bs-indigo: #6610f2;
|
||||
--bs-purple: #6f42c1;
|
||||
--bs-pink: #d63384;
|
||||
--bs-red: #dc3545;
|
||||
--bs-orange: #fd7e14;
|
||||
--bs-yellow: #ffc107;
|
||||
--bs-green: #198754;
|
||||
--bs-teal: #20c997;
|
||||
--bs-cyan: #0dcaf0;
|
||||
--bs-white: #fff;
|
||||
--bs-gray: #6c757d;
|
||||
--bs-gray-dark: #343a40;
|
||||
--bs-primary: #0d6efd;
|
||||
--bs-secondary: #6c757d;
|
||||
--bs-success: #198754;
|
||||
--bs-info: #0dcaf0;
|
||||
--bs-warning: #ffc107;
|
||||
--bs-danger: #dc3545;
|
||||
--bs-light: #f8f9fa;
|
||||
--bs-dark: #212529;
|
||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
}
|
||||
|
||||
:where(html, .light-theme, .dark-theme), .tokens, :host {
|
||||
@ -100,8 +125,10 @@ body, select, textarea {
|
||||
background-color: var(--md-sys-color-surface);
|
||||
color: var(--md-sys-color-on-surface);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
margin: 10px auto;
|
||||
padding: 0 20px;
|
||||
font-family: var(--bs-font-sans-serif);
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
@ -110,4 +137,11 @@ body {
|
||||
background-color: #fff;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: inherit;
|
||||
color: inherit;
|
||||
}
|
209
package-lock.json
generated
209
package-lock.json
generated
@ -27,13 +27,11 @@
|
||||
"@stirling-pdf/shared-operations": "^0.0.0",
|
||||
"@tauri-apps/api": "^1.5.1",
|
||||
"archiver": "^6.0.1",
|
||||
"bootstrap": "^5.3.2",
|
||||
"i18next": "^23.6.0",
|
||||
"i18next-browser-languagedetector": "^7.1.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"pdfjs-dist": "^4.0.189",
|
||||
"react": "^18.2.0",
|
||||
"react-bootstrap": "^2.9.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-i18next": "^13.3.1",
|
||||
"react-icons": "^4.11.0",
|
||||
@ -1598,29 +1596,6 @@
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@popperjs/core": {
|
||||
"version": "2.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-aria/ssr": {
|
||||
"version": "3.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.1.tgz",
|
||||
"integrity": "sha512-NqzkLFP8ZVI4GSorS0AYljC13QW2sc8bDqJOkBvkAt3M8gbcAXJWVRGtZBCRscki9RZF+rNlnPdg0G0jYkhJcg==",
|
||||
"dependencies": {
|
||||
"@swc/helpers": "^0.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.2.tgz",
|
||||
@ -1629,45 +1604,6 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@restart/hooks": {
|
||||
"version": "0.4.15",
|
||||
"resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.15.tgz",
|
||||
"integrity": "sha512-cZFXYTxbpzYcieq/mBwSyXgqnGMHoBVh3J7MU0CCoIB4NRZxV9/TuwTBAaLMqpNhC3zTPMCgkQ5Ey07L02Xmcw==",
|
||||
"dependencies": {
|
||||
"dequal": "^2.0.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@restart/ui": {
|
||||
"version": "1.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz",
|
||||
"integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@popperjs/core": "^2.11.6",
|
||||
"@react-aria/ssr": "^3.5.0",
|
||||
"@restart/hooks": "^0.4.9",
|
||||
"@types/warning": "^3.0.0",
|
||||
"dequal": "^2.0.3",
|
||||
"dom-helpers": "^5.2.0",
|
||||
"uncontrollable": "^8.0.1",
|
||||
"warning": "^4.0.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.14.0",
|
||||
"react-dom": ">=16.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@restart/ui/node_modules/uncontrollable": {
|
||||
"version": "8.0.4",
|
||||
"resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz",
|
||||
"integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-alias": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz",
|
||||
@ -2381,6 +2317,7 @@
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz",
|
||||
"integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
@ -2890,14 +2827,6 @@
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-transition-group": {
|
||||
"version": "4.4.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz",
|
||||
"integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==",
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/readdir-glob": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/readdir-glob/-/readdir-glob-1.1.5.tgz",
|
||||
@ -2959,11 +2888,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.10.tgz",
|
||||
"integrity": "sha512-e2PNXoXLr6Z+dbfx5zSh9TRlXJrELycxiaXznp4S5+D2M3b9bqJEitNHA5923jhnB2zzFiZHa2f0SI1HoIahpg=="
|
||||
},
|
||||
"node_modules/@types/warning": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz",
|
||||
"integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q=="
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "6.18.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz",
|
||||
@ -3570,24 +3494,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
},
|
||||
"node_modules/bootstrap": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz",
|
||||
"integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/twbs"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/bootstrap"
|
||||
}
|
||||
],
|
||||
"peerDependencies": {
|
||||
"@popperjs/core": "^2.11.8"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
@ -4062,11 +3968,6 @@
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/classnames": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
|
||||
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
|
||||
},
|
||||
"node_modules/clean-stack": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
|
||||
@ -4687,14 +4588,6 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/dequal": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/des.js": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz",
|
||||
@ -4773,15 +4666,6 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-helpers": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
|
||||
"integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.8.7",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/domain-browser": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.23.0.tgz",
|
||||
@ -6346,14 +6230,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
|
||||
},
|
||||
"node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/iobuffer": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/iobuffer/-/iobuffer-5.3.2.tgz",
|
||||
@ -8562,18 +8438,6 @@
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types-extra": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz",
|
||||
"integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==",
|
||||
"dependencies": {
|
||||
"react-is": "^16.3.2",
|
||||
"warning": "^4.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
@ -8748,35 +8612,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-bootstrap": {
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.9.2.tgz",
|
||||
"integrity": "sha512-a36B+EHsAI/aH+ZhXNILBFnqscE3zr10dWmjBmfhIb2QR7KSXJiGzYd6Faf/25G8G7/CP9TCL2B0WhUBOD2UBQ==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.22.5",
|
||||
"@restart/hooks": "^0.4.9",
|
||||
"@restart/ui": "^1.6.6",
|
||||
"@types/react-transition-group": "^4.4.6",
|
||||
"classnames": "^2.3.2",
|
||||
"dom-helpers": "^5.2.1",
|
||||
"invariant": "^2.2.4",
|
||||
"prop-types": "^15.8.1",
|
||||
"prop-types-extra": "^1.1.0",
|
||||
"react-transition-group": "^4.4.5",
|
||||
"uncontrollable": "^7.2.1",
|
||||
"warning": "^4.0.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": ">=16.14.8",
|
||||
"react": ">=16.14.0",
|
||||
"react-dom": ">=16.14.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||
@ -8824,11 +8659,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/react-lifecycles-compat": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
|
||||
@ -8880,21 +8710,6 @@
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-transition-group": {
|
||||
"version": "4.4.5",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"dom-helpers": "^5.0.1",
|
||||
"loose-envify": "^1.4.0",
|
||||
"prop-types": "^15.6.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.6.0",
|
||||
"react-dom": ">=16.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
@ -10391,20 +10206,6 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/uncontrollable": {
|
||||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz",
|
||||
"integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.6.3",
|
||||
"@types/react": ">=16.9.11",
|
||||
"invariant": "^2.2.4",
|
||||
"react-lifecycles-compat": "^3.0.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=15.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
@ -11154,14 +10955,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/warning": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/watchpack": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
||||
|
Loading…
x
Reference in New Issue
Block a user