Added OperatorConstraints UI generator

This commit is contained in:
Saud Fatayerji 2023-11-19 20:09:53 +03:00
parent d73a61ae3d
commit 42904788bf
6 changed files with 97 additions and 7 deletions

View File

@ -5,6 +5,7 @@ import Home from "./pages/Home";
import About from "./pages/About";
import Dashboard from "./pages/Dashboard";
import ToPdf from "./pages/convert/ToPdf"
import Impose from "./pages/page-operations/Impose"
import NoMatch from "./pages/NoMatch";
import NavBar from "./components/NavBar";
@ -39,13 +40,20 @@ export default function App() {
<Route index element={<Home />} />
<Route path="about" element={<About />} />
<Route path="dashboard" element={<Dashboard />} />
<Route path="to-pdf" element={<ToPdf />} />
{/* 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="/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>
</Suspense>
);

View 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;

View File

@ -76,7 +76,7 @@ function NavBar() {
{ 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.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.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') },
@ -86,7 +86,7 @@ function NavBar() {
]},
{displayText: t('navbar.convert'), icon: BsArrowLeftRight, sublist: [
{ 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.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') },

View 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;

View File

@ -69,7 +69,7 @@ export class FieldConstraint {
default:
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()
} else {
throw new Error(`UiConf type '${this.type}' not supported`)

View File

@ -1,3 +1,4 @@
import { PdfFile, RepresentationType } from "../wrappers/PdfFile";
import { FieldConstraint, RecordConstraint } from '../dynamic-ui/OperatorConstraints'
@ -10,9 +11,9 @@ export type ImposeParamsType = {
}
export const ImposeParamConstraints = new RecordConstraint({
file: new FieldConstraint("display", "file.pdf", true, "hint"),
nup: new FieldConstraint("display", [2, 3, 4, 8, 9, 12, 16], true, "hint"),
format: new FieldConstraint("display", "string", true, "hint"),
file: new FieldConstraint("display.key", "file.pdf", true, "hint.key"),
nup: new FieldConstraint("display.key", [2, 3, 4, 8, 9, 12, 16], true, "hint.key"),
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} */