mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-06-22 23:45:02 +00:00
Added OperatorConstraints UI generator
This commit is contained in:
parent
d73a61ae3d
commit
42904788bf
@ -5,6 +5,7 @@ import Home from "./pages/Home";
|
|||||||
import About from "./pages/About";
|
import About from "./pages/About";
|
||||||
import Dashboard from "./pages/Dashboard";
|
import Dashboard from "./pages/Dashboard";
|
||||||
import ToPdf from "./pages/convert/ToPdf"
|
import ToPdf from "./pages/convert/ToPdf"
|
||||||
|
import Impose from "./pages/page-operations/Impose"
|
||||||
import NoMatch from "./pages/NoMatch";
|
import NoMatch from "./pages/NoMatch";
|
||||||
import NavBar from "./components/NavBar";
|
import NavBar from "./components/NavBar";
|
||||||
|
|
||||||
@ -39,13 +40,20 @@ export default function App() {
|
|||||||
<Route index element={<Home />} />
|
<Route index element={<Home />} />
|
||||||
<Route path="about" element={<About />} />
|
<Route path="about" element={<About />} />
|
||||||
<Route path="dashboard" element={<Dashboard />} />
|
<Route path="dashboard" element={<Dashboard />} />
|
||||||
<Route path="to-pdf" element={<ToPdf />} />
|
|
||||||
|
|
||||||
{/* Using path="*"" means "match anything", so this route
|
{/* Using path="*"" means "match anything", so this route
|
||||||
acts like a catch-all for URLs that we don't have explicit
|
acts like a catch-all for URLs that we don't have explicit
|
||||||
routes for. */}
|
routes for. */}
|
||||||
<Route path="*" element={<NoMatch />} />
|
<Route path="*" element={<NoMatch />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="/convert" element={<Layout />}>
|
||||||
|
<Route path="file-to-pdf" element={<ToPdf />} />
|
||||||
|
<Route path="*" element={<NoMatch />} />
|
||||||
|
</Route>
|
||||||
|
<Route path="/page-operations" element={<Layout />}>
|
||||||
|
<Route path="impose" element={<Impose />} />
|
||||||
|
<Route path="*" element={<NoMatch />} />
|
||||||
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
|
63
client-tauri/src/components/DynamicParameterFields.tsx
Normal file
63
client-tauri/src/components/DynamicParameterFields.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
import Form from 'react-bootstrap/Form';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { FieldConstraint, RecordConstraint } from '@stirling-pdf/shared-operations/src/dynamic-ui/OperatorConstraints'
|
||||||
|
|
||||||
|
interface DynamicParameterFieldsProps {
|
||||||
|
constraints: RecordConstraint;
|
||||||
|
parentKeyPath?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const DynamicParameterFields: React.FC<DynamicParameterFieldsProps> = ({constraints, parentKeyPath=["DPF"]}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
{Object.entries(constraints.record).map(([fieldName, value]) => {
|
||||||
|
console.log(fieldName, value)
|
||||||
|
const globallyUniqueId = joinKeyPath([...parentKeyPath, fieldName]);
|
||||||
|
return <div className='mb-3' key={fieldName} >
|
||||||
|
<label htmlFor={globallyUniqueId}>{t(value.displayNameKey)}</label>
|
||||||
|
{fieldConstraintToElement(fieldName, parentKeyPath, globallyUniqueId, value)}
|
||||||
|
</div>
|
||||||
|
})}
|
||||||
|
</>);
|
||||||
|
}
|
||||||
|
|
||||||
|
function joinKeyPath(keyPath: string[]) {
|
||||||
|
return keyPath.join(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
function fieldConstraintToElement(fieldName: string, parentKeyPath: string[], globallyUniqueId: string, fieldConstraint: FieldConstraint) {
|
||||||
|
if (Array.isArray(fieldConstraint.type)) {
|
||||||
|
if (fieldConstraint.type.every(e => typeof e == 'string' || typeof e == 'number')) {
|
||||||
|
return (
|
||||||
|
<Form.Select id={globallyUniqueId} name={fieldName}>
|
||||||
|
<option value="" disabled>Select an option</option>
|
||||||
|
{fieldConstraint.type.map((option) => <option key={option} value={option}>{option}</option> )}
|
||||||
|
</Form.Select>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return <div key={fieldName}>Error: Field type '{fieldConstraint.type}' not supported</div>
|
||||||
|
}
|
||||||
|
} else if (typeof fieldConstraint.type == 'string') {
|
||||||
|
switch (fieldConstraint.type) {
|
||||||
|
case "file.pdf":
|
||||||
|
return <input id={globallyUniqueId} type="file" name={fieldName} required={fieldConstraint.required} className="form-control required" accept="application/pdf" multiple={false}/>;
|
||||||
|
case "files.pdf":
|
||||||
|
return <input id={globallyUniqueId} type="file" name={fieldName} required={fieldConstraint.required} className="form-control required" accept="application/pdf" multiple={true}/>;
|
||||||
|
case "string":
|
||||||
|
return <input id={globallyUniqueId} type="text" name={fieldName} required={fieldConstraint.required} />;
|
||||||
|
case "number":
|
||||||
|
return <input id={globallyUniqueId} type="number" name={fieldName} required={fieldConstraint.required} />;
|
||||||
|
default:
|
||||||
|
return <div key={fieldName}>Error: Field type '{fieldConstraint.type}' not supported</div>
|
||||||
|
}
|
||||||
|
} else if (fieldConstraint.type instanceof RecordConstraint) {
|
||||||
|
//return <DynamicParameterFields constraints={fieldConstraint.type} parentKeyPath={[...parentKeyPath, fieldName]}/>
|
||||||
|
return <div key={fieldName}>Error: Field type 'RecordConstraint' not supported yet!</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div key={fieldName}>Error: Field type '{fieldConstraint.type}' not supported</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DynamicParameterFields;
|
@ -76,7 +76,7 @@ function NavBar() {
|
|||||||
{ displayText: t('home.pdfOrganiser.title'), icon: BsSortNumericDown, dest: "/nothing-here", tooltip: t('home.pdfOrganiser.desc') },
|
{ displayText: t('home.pdfOrganiser.title'), icon: BsSortNumericDown, dest: "/nothing-here", tooltip: t('home.pdfOrganiser.desc') },
|
||||||
{ displayText: t('home.rotate.title'), icon: BsArrowClockwise, dest: "/nothing-here", tooltip: t('home.rotate.desc') },
|
{ displayText: t('home.rotate.title'), icon: BsArrowClockwise, dest: "/nothing-here", tooltip: t('home.rotate.desc') },
|
||||||
{ displayText: t('home.removePages.title'), icon: BsFileEarmarkX, dest: "/nothing-here", tooltip: t('home.removePages.desc') },
|
{ displayText: t('home.removePages.title'), icon: BsFileEarmarkX, dest: "/nothing-here", tooltip: t('home.removePages.desc') },
|
||||||
{ displayText: t('home.pageLayout.title'), icon: BsGrid, dest: "/nothing-here", tooltip: t('home.pageLayout.desc') },
|
{ displayText: t('home.pageLayout.title'), icon: BsGrid, dest: "/page-operations/impose", tooltip: t('home.pageLayout.desc') },
|
||||||
{ displayText: t('home.scalePages.title'), icon: BsArrowsFullscreen, dest: "/nothing-here", tooltip: t('home.scalePages.desc') },
|
{ displayText: t('home.scalePages.title'), icon: BsArrowsFullscreen, dest: "/nothing-here", tooltip: t('home.scalePages.desc') },
|
||||||
{ displayText: t('home.autoSplitPDF.title'), icon: BsLayoutSplit, dest: "/nothing-here", tooltip: t('home.autoSplitPDF.desc') },
|
{ displayText: t('home.autoSplitPDF.title'), icon: BsLayoutSplit, dest: "/nothing-here", tooltip: t('home.autoSplitPDF.desc') },
|
||||||
{ displayText: t('home.adjust-contrast.title'), icon: BsPalette, dest: "/nothing-here", tooltip: t('home.adjust-contrast.desc') },
|
{ displayText: t('home.adjust-contrast.title'), icon: BsPalette, dest: "/nothing-here", tooltip: t('home.adjust-contrast.desc') },
|
||||||
@ -86,7 +86,7 @@ function NavBar() {
|
|||||||
]},
|
]},
|
||||||
{displayText: t('navbar.convert'), icon: BsArrowLeftRight, sublist: [
|
{displayText: t('navbar.convert'), icon: BsArrowLeftRight, sublist: [
|
||||||
{ displayText: t('home.imageToPdf.title'), icon: BsFileEarmarkImage, dest: "/dashboard", tooltip: t('home.imageToPdf.desc') },
|
{ displayText: t('home.imageToPdf.title'), icon: BsFileEarmarkImage, dest: "/dashboard", tooltip: t('home.imageToPdf.desc') },
|
||||||
{ displayText: t('home.fileToPDF.title'), icon: BsFileEarmark, dest: "/to-pdf", tooltip: t('home.fileToPDF.desc') },
|
{ displayText: t('home.fileToPDF.title'), icon: BsFileEarmark, dest: "/convert/file-to-pdf", tooltip: t('home.fileToPDF.desc') },
|
||||||
{ displayText: t('home.HTMLToPDF.title'), icon: BsFiletypeHtml, dest: "/nothing-here", tooltip: t('home.HTMLToPDF.desc') },
|
{ displayText: t('home.HTMLToPDF.title'), icon: BsFiletypeHtml, dest: "/nothing-here", tooltip: t('home.HTMLToPDF.desc') },
|
||||||
{ displayText: t('home.URLToPDF.title'), icon: BsLink, dest: "/nothing-here", tooltip: t('home.URLToPDF.desc') },
|
{ displayText: t('home.URLToPDF.title'), icon: BsLink, dest: "/nothing-here", tooltip: t('home.URLToPDF.desc') },
|
||||||
{ displayText: t('home.MarkdownToPDF.title'), icon: BsFiletypeMd, dest: "/nothing-here", tooltip: t('home.MarkdownToPDF.desc') },
|
{ displayText: t('home.MarkdownToPDF.title'), icon: BsFiletypeMd, dest: "/nothing-here", tooltip: t('home.MarkdownToPDF.desc') },
|
||||||
|
18
client-tauri/src/pages/page-operations/Impose.tsx
Normal file
18
client-tauri/src/pages/page-operations/Impose.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
import DynamicParameterFields from "../../components/DynamicParameterFields";
|
||||||
|
import { ImposeParamConstraints } from "@stirling-pdf/shared-operations/src/functions/impose";
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
function Impose() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>{t("pageLayout.header")}</h2>
|
||||||
|
<form>
|
||||||
|
<DynamicParameterFields constraints={ImposeParamConstraints}/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Impose;
|
@ -69,7 +69,7 @@ export class FieldConstraint {
|
|||||||
default:
|
default:
|
||||||
throw new Error(`UiConf type '${this.type}' not supported`)
|
throw new Error(`UiConf type '${this.type}' not supported`)
|
||||||
}
|
}
|
||||||
} else if (this.type instanceof FieldConstraint) {
|
} else if (this.type instanceof RecordConstraint) {
|
||||||
schema = this.type.toJoiSchema()
|
schema = this.type.toJoiSchema()
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`UiConf type '${this.type}' not supported`)
|
throw new Error(`UiConf type '${this.type}' not supported`)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
import { PdfFile, RepresentationType } from "../wrappers/PdfFile";
|
import { PdfFile, RepresentationType } from "../wrappers/PdfFile";
|
||||||
import { FieldConstraint, RecordConstraint } from '../dynamic-ui/OperatorConstraints'
|
import { FieldConstraint, RecordConstraint } from '../dynamic-ui/OperatorConstraints'
|
||||||
|
|
||||||
@ -10,9 +11,9 @@ export type ImposeParamsType = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const ImposeParamConstraints = new RecordConstraint({
|
export const ImposeParamConstraints = new RecordConstraint({
|
||||||
file: new FieldConstraint("display", "file.pdf", true, "hint"),
|
file: new FieldConstraint("display.key", "file.pdf", true, "hint.key"),
|
||||||
nup: new FieldConstraint("display", [2, 3, 4, 8, 9, 12, 16], true, "hint"),
|
nup: new FieldConstraint("display.key", [2, 3, 4, 8, 9, 12, 16], true, "hint.key"),
|
||||||
format: new FieldConstraint("display", "string", true, "hint"),
|
format: new FieldConstraint("display.key", ["A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","A10","Letter","Legal"], true, "hint.key"),
|
||||||
})
|
})
|
||||||
|
|
||||||
/** PDF-Imposition, PDF-N-Up: Put multiple pages of the input document into a single page of the output document. - see: {@link https://en.wikipedia.org/wiki/N-up} */
|
/** PDF-Imposition, PDF-N-Up: Put multiple pages of the input document into a single page of the output document. - see: {@link https://en.wikipedia.org/wiki/N-up} */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user