diff --git a/client-tauri/src/App.tsx b/client-tauri/src/App.tsx index 94bb6007c..46494d33f 100644 --- a/client-tauri/src/App.tsx +++ b/client-tauri/src/App.tsx @@ -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() { } /> } /> } /> - } /> {/* Using path="*"" means "match anything", so this route acts like a catch-all for URLs that we don't have explicit routes for. */} } /> + }> + } /> + } /> + + }> + } /> + } /> + ); diff --git a/client-tauri/src/components/DynamicParameterFields.tsx b/client-tauri/src/components/DynamicParameterFields.tsx new file mode 100644 index 000000000..6832c6248 --- /dev/null +++ b/client-tauri/src/components/DynamicParameterFields.tsx @@ -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 = ({constraints, parentKeyPath=["DPF"]}) => { + const { t } = useTranslation(); + + return (<> + {Object.entries(constraints.record).map(([fieldName, value]) => { + console.log(fieldName, value) + const globallyUniqueId = joinKeyPath([...parentKeyPath, fieldName]); + return
+ + {fieldConstraintToElement(fieldName, parentKeyPath, globallyUniqueId, value)} +
+ })} + ); +} + +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 ( + + + {fieldConstraint.type.map((option) => )} + + ); + } else { + return
Error: Field type '{fieldConstraint.type}' not supported
+ } + } else if (typeof fieldConstraint.type == 'string') { + switch (fieldConstraint.type) { + case "file.pdf": + return ; + case "files.pdf": + return ; + case "string": + return ; + case "number": + return ; + default: + return
Error: Field type '{fieldConstraint.type}' not supported
+ } + } else if (fieldConstraint.type instanceof RecordConstraint) { + //return + return
Error: Field type 'RecordConstraint' not supported yet!
+ } + + return
Error: Field type '{fieldConstraint.type}' not supported
+} + +export default DynamicParameterFields; \ No newline at end of file diff --git a/client-tauri/src/components/NavBar.tsx b/client-tauri/src/components/NavBar.tsx index 7073910cb..4faca2c52 100644 --- a/client-tauri/src/components/NavBar.tsx +++ b/client-tauri/src/components/NavBar.tsx @@ -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') }, diff --git a/client-tauri/src/pages/page-operations/Impose.tsx b/client-tauri/src/pages/page-operations/Impose.tsx new file mode 100644 index 000000000..7957618a4 --- /dev/null +++ b/client-tauri/src/pages/page-operations/Impose.tsx @@ -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 ( +
+

{t("pageLayout.header")}

+
+ + +
+ ); +} + +export default Impose; diff --git a/shared-operations/src/dynamic-ui/OperatorConstraints.ts b/shared-operations/src/dynamic-ui/OperatorConstraints.ts index 7455ff7b1..363716aca 100644 --- a/shared-operations/src/dynamic-ui/OperatorConstraints.ts +++ b/shared-operations/src/dynamic-ui/OperatorConstraints.ts @@ -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`) diff --git a/shared-operations/src/functions/impose.ts b/shared-operations/src/functions/impose.ts index be3d752f2..a5a45f7fe 100644 --- a/shared-operations/src/functions/impose.ts +++ b/shared-operations/src/functions/impose.ts @@ -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} */