mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-14 10:34:06 +02:00
Switch key areas to lazily import to improve Vite chunk size (#6278)
# Description of Changes Vite currently warns that when it's bundling our code that the chunk size is way too high because most of the imports are static so it can't split them into smaller chunks. This PR changes a few key areas to use lazy imports to try and make the chunks as small as possible with minimal code changes. Vite's warnings kick in at minified chunks being >500kB, and we've got a little way to go still to reach that, but we can keep chipping away at this and I'd rather get the biggest wins done now. I've also included Lighthouse scores because there's been discussion about improving ours recently. It's not the aim of this PR to improve it, but it's nice that it makes it a little better. ## Current main chunks Build split into 12 chunks. Largest chunk in build is: ``` [frontend:build] dist/assets/index-B6JiWDxZ.js 5,175.51 kB │ gzip: 1,495.85 kB ``` <img width="1442" height="775" alt="image" src="https://github.com/user-attachments/assets/b0e8a3fa-4ef3-4ccd-8c1d-bfed2d99bd27" /> Lighthouse score: <img width="423" height="146" alt="before" src="https://github.com/user-attachments/assets/c62056e8-2e77-49a6-a1ae-f08ec8021fb3" /> ## This PR's chunks Build split into 176 chunks. Largest chunk in build is: ``` [frontend:build] dist/assets/index-qCgeCY4B.js 2,878.54 kB │ gzip: 861.03 kB ``` <img width="1447" height="776" alt="image" src="https://github.com/user-attachments/assets/8d0c3cf0-cc25-41c3-b114-4940d3e99349" /> Lighthouse score: <img width="402" height="145" alt="after" src="https://github.com/user-attachments/assets/99a26eb3-bd15-4b92-bf22-82b58b458f52" /> --------- Co-authored-by: EthanHealy01 <[email protected]>
This commit is contained in:
co-authored by
EthanHealy01
parent
51f5345151
commit
3fe8adc5cb
Generated
+341
@@ -117,6 +117,7 @@
|
||||
"postcss-simple-vars": "^7.0.1",
|
||||
"prettier": "^3.8.1",
|
||||
"puppeteer": "^24.25.0",
|
||||
"rollup-plugin-visualizer": "^7.0.1",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "^5.9.2",
|
||||
"typescript-eslint": "^8.44.1",
|
||||
@@ -6256,6 +6257,22 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/bundle-name": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
|
||||
"integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"run-applescript": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/byte-counter": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/byte-counter/-/byte-counter-0.1.0.tgz",
|
||||
@@ -7325,6 +7342,36 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/default-browser": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz",
|
||||
"integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bundle-name": "^4.1.0",
|
||||
"default-browser-id": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/default-browser-id": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz",
|
||||
"integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/defaults": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
|
||||
@@ -7338,6 +7385,19 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/define-lazy-prop": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
|
||||
"integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/degenerator": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
|
||||
@@ -9179,6 +9239,22 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-docker": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
|
||||
"integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"is-docker": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
@@ -9212,6 +9288,38 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-in-ssh": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz",
|
||||
"integrity": "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-inside-container": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
|
||||
"integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-docker": "^3.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"is-inside-container": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-interactive": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
|
||||
@@ -9314,6 +9422,22 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-wsl": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz",
|
||||
"integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-inside-container": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
@@ -10525,6 +10649,27 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/open": {
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/open/-/open-11.0.0.tgz",
|
||||
"integrity": "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"default-browser": "^5.4.0",
|
||||
"define-lazy-prop": "^3.0.0",
|
||||
"is-in-ssh": "^1.0.0",
|
||||
"is-inside-container": "^1.0.0",
|
||||
"powershell-utils": "^0.1.0",
|
||||
"wsl-utils": "^0.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/optionator": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
||||
@@ -11309,6 +11454,19 @@
|
||||
"web-vitals": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/powershell-utils": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz",
|
||||
"integrity": "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/preact": {
|
||||
"version": "10.29.0",
|
||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.29.0.tgz",
|
||||
@@ -12407,6 +12565,172 @@
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-7.0.1.tgz",
|
||||
"integrity": "sha512-UJUT4+1Ho4OcWmPYU3sYXgUqI8B8Ayfe06MX7y0qCJ1K8aGoKtR/NDd/2nZqM7ADkrzny+I99Ul7GgyoiVNAgg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"open": "^11.0.0",
|
||||
"picomatch": "^4.0.2",
|
||||
"source-map": "^0.7.4",
|
||||
"yargs": "^18.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"rollup-plugin-visualizer": "dist/bin/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rolldown": "1.x || ^1.0.0-beta || ^1.0.0-rc",
|
||||
"rollup": "2.x || 3.x || 4.x"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rolldown": {
|
||||
"optional": true
|
||||
},
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/ansi-styles": {
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
|
||||
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/cliui": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz",
|
||||
"integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^7.2.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"wrap-ansi": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/emoji-regex": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
|
||||
"integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/picomatch": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/source-map": {
|
||||
"version": "0.7.6",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
|
||||
"integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/string-width": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
|
||||
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^10.3.0",
|
||||
"get-east-asian-width": "^1.0.0",
|
||||
"strip-ansi": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/wrap-ansi": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
|
||||
"integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.2.1",
|
||||
"string-width": "^7.0.0",
|
||||
"strip-ansi": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/yargs": {
|
||||
"version": "18.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz",
|
||||
"integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^9.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"string-width": "^7.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^22.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=23"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/yargs-parser": {
|
||||
"version": "22.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz",
|
||||
"integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=23"
|
||||
}
|
||||
},
|
||||
"node_modules/run-applescript": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
|
||||
"integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/rw": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
|
||||
@@ -14389,6 +14713,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/wsl-utils": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.3.1.tgz",
|
||||
"integrity": "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-wsl": "^3.1.0",
|
||||
"powershell-utils": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/xml-name-validator": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
"postcss-simple-vars": "^7.0.1",
|
||||
"prettier": "^3.8.1",
|
||||
"puppeteer": "^24.25.0",
|
||||
"rollup-plugin-visualizer": "^7.0.1",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "^5.9.2",
|
||||
"typescript-eslint": "^8.44.1",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useCallback } from "react";
|
||||
import { Box } from "@mantine/core";
|
||||
import { Suspense, lazy, useCallback } from "react";
|
||||
import { Box, Loader, Center } from "@mantine/core";
|
||||
import { useRainbowThemeContext } from "@app/components/shared/RainbowThemeProvider";
|
||||
import { useToolWorkflow } from "@app/contexts/ToolWorkflowContext";
|
||||
import { useFileHandler } from "@app/hooks/useFileHandler";
|
||||
@@ -16,14 +16,20 @@ import { FileId } from "@app/types/file";
|
||||
import styles from "@app/components/layout/Workbench.module.css";
|
||||
|
||||
import TopControls from "@app/components/shared/TopControls";
|
||||
import FileEditor from "@app/components/fileEditor/FileEditor";
|
||||
import PageEditor from "@app/components/pageEditor/PageEditor";
|
||||
import PageEditorControls from "@app/components/pageEditor/PageEditorControls";
|
||||
import Viewer from "@app/components/viewer/Viewer";
|
||||
import LandingPage from "@app/components/shared/LandingPage";
|
||||
import Footer from "@app/components/shared/Footer";
|
||||
import DismissAllErrorsButton from "@app/components/shared/DismissAllErrorsButton";
|
||||
|
||||
// Workbench panels are loaded on demand. Viewer pulls in pdfjs-dist and the
|
||||
// full @embedpdf plugin set; FileEditor/PageEditor are only needed once a file
|
||||
// is open. Lazy-loading keeps all of that out of the initial bundle.
|
||||
const FileEditor = lazy(() => import("@app/components/fileEditor/FileEditor"));
|
||||
const PageEditor = lazy(() => import("@app/components/pageEditor/PageEditor"));
|
||||
const PageEditorControls = lazy(
|
||||
() => import("@app/components/pageEditor/PageEditorControls"),
|
||||
);
|
||||
const Viewer = lazy(() => import("@app/components/viewer/Viewer"));
|
||||
|
||||
// No props needed - component uses contexts directly
|
||||
export default function Workbench() {
|
||||
const { isRainbowMode } = useRainbowThemeContext();
|
||||
@@ -236,7 +242,15 @@ export default function Workbench() {
|
||||
...(currentView === "pageEditor" && { height: 0 }),
|
||||
}}
|
||||
>
|
||||
{renderMainContent()}
|
||||
<Suspense
|
||||
fallback={
|
||||
<Center style={{ height: "100%" }}>
|
||||
<Loader />
|
||||
</Center>
|
||||
}
|
||||
>
|
||||
{renderMainContent()}
|
||||
</Suspense>
|
||||
</Box>
|
||||
|
||||
<Footer
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Suspense, lazy, useEffect, useState } from "react";
|
||||
|
||||
// AppConfigModal pulls in the entire settings UI tree (admin sections,
|
||||
// account, supabase auth flows, etc.). We defer loading until the user first
|
||||
// opens the modal, then keep it mounted so the close animation runs.
|
||||
const AppConfigModal = lazy(
|
||||
() => import("@app/components/shared/AppConfigModal"),
|
||||
);
|
||||
|
||||
interface AppConfigModalLazyProps {
|
||||
opened: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export default function AppConfigModalLazy({
|
||||
opened,
|
||||
onClose,
|
||||
}: AppConfigModalLazyProps) {
|
||||
const [shouldMount, setShouldMount] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (opened) setShouldMount(true);
|
||||
}, [opened]);
|
||||
|
||||
if (!shouldMount) return null;
|
||||
|
||||
return (
|
||||
<Suspense fallback={null}>
|
||||
<AppConfigModal opened={opened} onClose={onClose} />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
@@ -30,7 +30,7 @@ import "@app/components/shared/quickAccessBar/QuickAccessBar.css";
|
||||
import { Tooltip } from "@app/components/shared/Tooltip";
|
||||
import AllToolsNavButton from "@app/components/shared/AllToolsNavButton";
|
||||
import ActiveToolButton from "@app/components/shared/quickAccessBar/ActiveToolButton";
|
||||
import AppConfigModal from "@app/components/shared/AppConfigModal";
|
||||
import AppConfigModal from "@app/components/shared/AppConfigModalLazy";
|
||||
import { useAppConfig } from "@app/contexts/AppConfigContext";
|
||||
import { useGroupSigningEnabled } from "@app/hooks/useGroupSigningEnabled";
|
||||
import { useSharingEnabled } from "@app/hooks/useSharingEnabled";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect, useCallback, useRef } from "react";
|
||||
import { lazy, useState, useEffect, useCallback, useRef } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Drawer } from "@mantine/core";
|
||||
@@ -23,8 +23,15 @@ import {
|
||||
import { useFileSelection } from "@app/contexts/file/fileHooks";
|
||||
import { fileStorage } from "@app/services/fileStorage";
|
||||
import { useFileActions } from "@app/contexts/FileContext";
|
||||
import SignRequestWorkbenchView from "@app/components/tools/certSign/SignRequestWorkbenchView";
|
||||
import SessionDetailWorkbenchView from "@app/components/tools/certSign/SessionDetailWorkbenchView";
|
||||
// These workbench views pull in the PDF viewer / pdfium / @embedpdf chain, so
|
||||
// they are loaded on demand when the certSign collab feature actually opens
|
||||
// one of them. Workbench wraps custom views in <Suspense>.
|
||||
const SignRequestWorkbenchView = lazy(
|
||||
() => import("@app/components/tools/certSign/SignRequestWorkbenchView"),
|
||||
);
|
||||
const SessionDetailWorkbenchView = lazy(
|
||||
() => import("@app/components/tools/certSign/SessionDetailWorkbenchView"),
|
||||
);
|
||||
import { Z_INDEX_OVER_FULLSCREEN_SURFACE } from "@app/styles/zIndex";
|
||||
|
||||
export const SIGN_REQUEST_WORKBENCH_TYPE =
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { Suspense, useState, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Modal, Title, Button, Group, Stack, Text, Alert } from "@mantine/core";
|
||||
import {
|
||||
Modal,
|
||||
Title,
|
||||
Button,
|
||||
Group,
|
||||
Stack,
|
||||
Text,
|
||||
Alert,
|
||||
Loader,
|
||||
} from "@mantine/core";
|
||||
import { Z_INDEX_AUTOMATE_MODAL } from "@app/styles/zIndex";
|
||||
import SettingsIcon from "@mui/icons-material/Settings";
|
||||
import CheckIcon from "@mui/icons-material/Check";
|
||||
@@ -124,7 +133,9 @@ export default function ToolConfigurationModal({
|
||||
<div
|
||||
style={{ maxHeight: "60vh", overflowY: "auto", overflowX: "hidden" }}
|
||||
>
|
||||
{renderToolSettings()}
|
||||
<Suspense fallback={<Loader size="sm" />}>
|
||||
{renderToolSettings()}
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
<Group justify="flex-end" gap="sm">
|
||||
|
||||
@@ -1,19 +1,8 @@
|
||||
import { useMemo } from "react";
|
||||
import { lazy, useMemo } from "react";
|
||||
import LocalIcon from "@app/components/shared/LocalIcon";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { devApiLink } from "@app/constants/links";
|
||||
import SplitPdfPanel from "@app/tools/Split";
|
||||
import CompressPdfPanel from "@app/tools/Compress";
|
||||
import OCRPanel from "@app/tools/OCR";
|
||||
import ConvertPanel from "@app/tools/Convert";
|
||||
import Sanitize from "@app/tools/Sanitize";
|
||||
import AddPassword from "@app/tools/AddPassword";
|
||||
import ChangePermissions from "@app/tools/ChangePermissions";
|
||||
import RemoveBlanks from "@app/tools/RemoveBlanks";
|
||||
import RemovePages from "@app/tools/RemovePages";
|
||||
import ReorganizePages from "@app/tools/ReorganizePages";
|
||||
import { reorganizePagesOperationConfig } from "@app/hooks/tools/reorganizePages/useReorganizePagesOperation";
|
||||
import RemovePassword from "@app/tools/RemovePassword";
|
||||
import {
|
||||
SubcategoryId,
|
||||
ToolCategoryId,
|
||||
@@ -23,37 +12,9 @@ import {
|
||||
LinkToolRegistry,
|
||||
} from "@app/data/toolsTaxonomy";
|
||||
import { isSuperToolId, isLinkToolId } from "@app/types/toolId";
|
||||
import AdjustContrast from "@app/tools/AdjustContrast";
|
||||
import AdjustContrastSingleStepSettings from "@app/components/tools/adjustContrast/AdjustContrastSingleStepSettings";
|
||||
import { adjustContrastOperationConfig } from "@app/hooks/tools/adjustContrast/useAdjustContrastOperation";
|
||||
import { getSynonyms } from "@app/utils/toolSynonyms";
|
||||
import { useProprietaryToolRegistry } from "@app/data/useProprietaryToolRegistry";
|
||||
import GetPdfInfo from "@app/tools/GetPdfInfo";
|
||||
import AddWatermark from "@app/tools/AddWatermark";
|
||||
import AddStamp from "@app/tools/AddStamp";
|
||||
import AddAttachments from "@app/tools/AddAttachments";
|
||||
import Merge from "@app/tools/Merge";
|
||||
import EditTableOfContents from "@app/tools/EditTableOfContents";
|
||||
import Repair from "@app/tools/Repair";
|
||||
import AutoRename from "@app/tools/AutoRename";
|
||||
import SingleLargePage from "@app/tools/SingleLargePage";
|
||||
import PageLayout from "@app/tools/PageLayout";
|
||||
import UnlockPdfForms from "@app/tools/UnlockPdfForms";
|
||||
import FormFill from "@app/tools/formFill/FormFill";
|
||||
import RemoveCertificateSign from "@app/tools/RemoveCertificateSign";
|
||||
import RemoveImage from "@app/tools/RemoveImage";
|
||||
import CertSign from "@app/tools/CertSign";
|
||||
import TimestampPdf from "@app/tools/TimestampPdf";
|
||||
import BookletImposition from "@app/tools/BookletImposition";
|
||||
import Flatten from "@app/tools/Flatten";
|
||||
import Rotate from "@app/tools/Rotate";
|
||||
import PdfTextEditor from "@app/tools/pdfTextEditor/PdfTextEditor";
|
||||
import ChangeMetadata from "@app/tools/ChangeMetadata";
|
||||
import Crop from "@app/tools/Crop";
|
||||
import Sign from "@app/tools/Sign";
|
||||
import AddText from "@app/tools/AddText";
|
||||
import AddImage from "@app/tools/AddImage";
|
||||
import Annotate from "@app/tools/Annotate";
|
||||
import { compressOperationConfig } from "@app/hooks/tools/compress/useCompressOperation";
|
||||
import { splitOperationConfig } from "@app/hooks/tools/split/useSplitOperation";
|
||||
import { addPasswordOperationConfig } from "@app/hooks/tools/addPassword/useAddPasswordOperation";
|
||||
@@ -93,50 +54,7 @@ import { scannerImageSplitOperationConfig } from "@app/hooks/tools/scannerImageS
|
||||
import { addPageNumbersOperationConfig } from "@app/components/tools/addPageNumbers/useAddPageNumbersOperation";
|
||||
import { extractPagesOperationConfig } from "@app/hooks/tools/extractPages/useExtractPagesOperation";
|
||||
import { ENDPOINTS as SPLIT_ENDPOINT_NAMES } from "@app/constants/splitConstants";
|
||||
import CompressSettings from "@app/components/tools/compress/CompressSettings";
|
||||
import AddPasswordSettings from "@app/components/tools/addPassword/AddPasswordSettings";
|
||||
import RemovePasswordSettings from "@app/components/tools/removePassword/RemovePasswordSettings";
|
||||
import SanitizeSettings from "@app/components/tools/sanitize/SanitizeSettings";
|
||||
import AddWatermarkSingleStepSettings from "@app/components/tools/addWatermark/AddWatermarkSingleStepSettings";
|
||||
import OCRSettings from "@app/components/tools/ocr/OCRSettings";
|
||||
import ConvertSettings from "@app/components/tools/convert/ConvertSettings";
|
||||
import ChangePermissionsSettings from "@app/components/tools/changePermissions/ChangePermissionsSettings";
|
||||
import BookletImpositionSettings from "@app/components/tools/bookletImposition/BookletImpositionSettings";
|
||||
import FlattenSettings from "@app/components/tools/flatten/FlattenSettings";
|
||||
import RedactSingleStepSettings from "@app/components/tools/redact/RedactSingleStepSettings";
|
||||
import Redact from "@app/tools/Redact";
|
||||
import AdjustPageScale from "@app/tools/AdjustPageScale";
|
||||
import ReplaceColor from "@app/tools/ReplaceColor";
|
||||
import ScannerImageSplit from "@app/tools/ScannerImageSplit";
|
||||
import OverlayPdfs from "@app/tools/OverlayPdfs";
|
||||
import { ToolId } from "@app/types/toolId";
|
||||
import MergeSettings from "@app/components/tools/merge/MergeSettings";
|
||||
import AdjustPageScaleSettings from "@app/components/tools/adjustPageScale/AdjustPageScaleSettings";
|
||||
import ScannerImageSplitSettings from "@app/components/tools/scannerImageSplit/ScannerImageSplitSettings";
|
||||
import ChangeMetadataSingleStep from "@app/components/tools/changeMetadata/ChangeMetadataSingleStep";
|
||||
import SignSettings from "@app/components/tools/sign/SignSettings";
|
||||
import AddPageNumbers from "@app/tools/AddPageNumbers";
|
||||
import RemoveAnnotations from "@app/tools/RemoveAnnotations";
|
||||
import PageLayoutSettings from "@app/components/tools/pageLayout/PageLayoutSettings";
|
||||
import ExtractImages from "@app/tools/ExtractImages";
|
||||
import ExtractPages from "@app/tools/ExtractPages";
|
||||
import ExtractImagesSettings from "@app/components/tools/extractImages/ExtractImagesSettings";
|
||||
import ExtractPagesSettings from "@app/components/tools/extractPages/ExtractPagesSettings";
|
||||
import ReplaceColorSettings from "@app/components/tools/replaceColor/ReplaceColorSettings";
|
||||
import AddStampAutomationSettings from "@app/components/tools/addStamp/AddStampAutomationSettings";
|
||||
import CertSignAutomationSettings from "@app/components/tools/certSign/CertSignAutomationSettings";
|
||||
import CropAutomationSettings from "@app/components/tools/crop/CropAutomationSettings";
|
||||
import RotateAutomationSettings from "@app/components/tools/rotate/RotateAutomationSettings";
|
||||
import SplitAutomationSettings from "@app/components/tools/split/SplitAutomationSettings";
|
||||
import AddAttachmentsSettings from "@app/components/tools/addAttachments/AddAttachmentsSettings";
|
||||
import RemovePagesSettings from "@app/components/tools/removePages/RemovePagesSettings";
|
||||
import RemoveBlanksSettings from "@app/components/tools/removeBlanks/RemoveBlanksSettings";
|
||||
import AddPageNumbersAutomationSettings from "@app/components/tools/addPageNumbers/AddPageNumbersAutomationSettings";
|
||||
import OverlayPdfsSettings from "@app/components/tools/overlayPdfs/OverlayPdfsSettings";
|
||||
import ValidateSignature from "@app/tools/ValidateSignature";
|
||||
import ShowJS from "@app/tools/ShowJS";
|
||||
import Automate from "@app/tools/Automate";
|
||||
import Compare from "@app/tools/Compare";
|
||||
import { CONVERT_SUPPORTED_FORMATS } from "@app/constants/convertSupportedFornats";
|
||||
|
||||
export interface TranslatedToolCatalog {
|
||||
@@ -170,7 +88,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.pdfTextEditor.title", "PDF Text Editor"),
|
||||
component: PdfTextEditor,
|
||||
component: lazy(() => import("@app/tools/pdfTextEditor/PdfTextEditor")),
|
||||
description: t(
|
||||
"home.pdfTextEditor.desc",
|
||||
"Review and edit text and images in PDFs with grouped text editing and PDF regeneration",
|
||||
@@ -216,7 +134,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.merge.title", "Merge"),
|
||||
component: Merge,
|
||||
component: lazy(() => import("@app/tools/Merge")),
|
||||
description: t(
|
||||
"home.merge.desc",
|
||||
"Merge multiple PDFs into a single document",
|
||||
@@ -226,7 +144,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["merge-pdfs"],
|
||||
operationConfig: mergeOperationConfig,
|
||||
automationSettings: MergeSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/merge/MergeSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "merge"),
|
||||
},
|
||||
// Signing
|
||||
@@ -239,7 +159,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.certSign.title", "Certificate Sign"),
|
||||
component: CertSign,
|
||||
component: lazy(() => import("@app/tools/CertSign")),
|
||||
description: t(
|
||||
"home.certSign.desc",
|
||||
"Sign PDF documents using digital certificates",
|
||||
@@ -250,14 +170,17 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["cert-sign"],
|
||||
operationConfig: certSignOperationConfig,
|
||||
automationSettings: CertSignAutomationSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/certSign/CertSignAutomationSettings"),
|
||||
),
|
||||
},
|
||||
timestampPdf: {
|
||||
icon: (
|
||||
<LocalIcon icon="schedule-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.timestampPdf.title", "Timestamp PDF"),
|
||||
component: TimestampPdf,
|
||||
component: lazy(() => import("@app/tools/TimestampPdf")),
|
||||
description: t(
|
||||
"home.timestampPdf.desc",
|
||||
"Add an RFC 3161 document timestamp to prove when your PDF existed",
|
||||
@@ -275,7 +198,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="signature-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.sign.title", "Sign"),
|
||||
component: Sign,
|
||||
component: lazy(() => import("@app/tools/Sign")),
|
||||
description: t(
|
||||
"home.sign.desc",
|
||||
"Adds signature to PDF by drawing, text or image",
|
||||
@@ -284,7 +207,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
subcategoryId: SubcategoryId.SIGNING,
|
||||
endpoints: ["sign"],
|
||||
operationConfig: signOperationConfig,
|
||||
automationSettings: SignSettings, // TODO:: not all settings shown, suggested next tools shown
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/sign/SignSettings"),
|
||||
), // TODO:: not all settings shown, suggested next tools shown
|
||||
synonyms: getSynonyms(t, "sign"),
|
||||
supportsAutomate: false, //TODO make support Sign
|
||||
},
|
||||
@@ -297,7 +222,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.addText.title", "Add Text"),
|
||||
component: AddText,
|
||||
component: lazy(() => import("@app/tools/AddText")),
|
||||
description: t(
|
||||
"home.addText.desc",
|
||||
"Add custom text anywhere in your PDF",
|
||||
@@ -313,7 +238,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
addImage: {
|
||||
icon: <LocalIcon icon="image-rounded" width="1.5rem" height="1.5rem" />,
|
||||
name: t("home.addImage.title", "Add Image"),
|
||||
component: AddImage,
|
||||
component: lazy(() => import("@app/tools/AddImage")),
|
||||
description: t("home.addImage.desc", "Add images anywhere in your PDF"),
|
||||
categoryId: ToolCategoryId.STANDARD_TOOLS,
|
||||
subcategoryId: SubcategoryId.GENERAL,
|
||||
@@ -326,7 +251,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
annotate: {
|
||||
icon: <LocalIcon icon="edit" width="1.5rem" height="1.5rem" />,
|
||||
name: t("home.annotate.title", "Annotate"),
|
||||
component: Annotate,
|
||||
component: lazy(() => import("@app/tools/Annotate")),
|
||||
description: t(
|
||||
"home.annotate.desc",
|
||||
"Highlight, draw, add notes, and shapes directly in the viewer",
|
||||
@@ -348,7 +273,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="password-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.addPassword.title", "Add Password"),
|
||||
component: AddPassword,
|
||||
component: lazy(() => import("@app/tools/AddPassword")),
|
||||
description: t(
|
||||
"home.addPassword.desc",
|
||||
"Add password protection and restrictions to PDF files",
|
||||
@@ -358,7 +283,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["add-password"],
|
||||
operationConfig: addPasswordOperationConfig,
|
||||
automationSettings: AddPasswordSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/addPassword/AddPasswordSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "addPassword"),
|
||||
},
|
||||
watermark: {
|
||||
@@ -370,7 +297,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.watermark.title", "Add Watermark"),
|
||||
component: AddWatermark,
|
||||
component: lazy(() => import("@app/tools/AddWatermark")),
|
||||
maxFiles: -1,
|
||||
description: t(
|
||||
"home.watermark.desc",
|
||||
@@ -380,7 +307,10 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
subcategoryId: SubcategoryId.DOCUMENT_SECURITY,
|
||||
endpoints: ["add-watermark"],
|
||||
operationConfig: addWatermarkOperationConfig,
|
||||
automationSettings: AddWatermarkSingleStepSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/addWatermark/AddWatermarkSingleStepSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "watermark"),
|
||||
},
|
||||
addStamp: {
|
||||
@@ -388,7 +318,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="approval-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.addStamp.title", "Add Stamp to PDF"),
|
||||
component: AddStamp,
|
||||
component: lazy(() => import("@app/tools/AddStamp")),
|
||||
description: t(
|
||||
"home.addStamp.desc",
|
||||
"Add text or add image stamps at set locations",
|
||||
@@ -399,7 +329,10 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["add-stamp"],
|
||||
operationConfig: addStampOperationConfig,
|
||||
automationSettings: AddStampAutomationSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/addStamp/AddStampAutomationSettings"),
|
||||
),
|
||||
},
|
||||
sanitize: {
|
||||
icon: (
|
||||
@@ -410,7 +343,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.sanitize.title", "Sanitize"),
|
||||
component: Sanitize,
|
||||
component: lazy(() => import("@app/tools/Sanitize")),
|
||||
maxFiles: -1,
|
||||
categoryId: ToolCategoryId.STANDARD_TOOLS,
|
||||
subcategoryId: SubcategoryId.DOCUMENT_SECURITY,
|
||||
@@ -420,7 +353,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
),
|
||||
endpoints: ["sanitize-pdf"],
|
||||
operationConfig: sanitizeOperationConfig,
|
||||
automationSettings: SanitizeSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/sanitize/SanitizeSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "sanitize"),
|
||||
},
|
||||
flatten: {
|
||||
@@ -432,7 +367,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.flatten.title", "Flatten"),
|
||||
component: Flatten,
|
||||
component: lazy(() => import("@app/tools/Flatten")),
|
||||
description: t(
|
||||
"home.flatten.desc",
|
||||
"Remove all interactive elements and forms from a PDF",
|
||||
@@ -442,7 +377,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["flatten"],
|
||||
operationConfig: flattenOperationConfig,
|
||||
automationSettings: FlattenSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/flatten/FlattenSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "flatten"),
|
||||
},
|
||||
unlockPDFForms: {
|
||||
@@ -454,7 +391,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.unlockPDFForms.title", "Unlock PDF Forms"),
|
||||
component: UnlockPdfForms,
|
||||
component: lazy(() => import("@app/tools/UnlockPdfForms")),
|
||||
description: t(
|
||||
"home.unlockPDFForms.desc",
|
||||
"Remove read-only property of form fields in a PDF document.",
|
||||
@@ -476,7 +413,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.formFill.title", "Fill Form"),
|
||||
component: FormFill,
|
||||
component: lazy(() => import("@app/tools/formFill/FormFill")),
|
||||
description: t(
|
||||
"home.formFill.desc",
|
||||
"Fill PDF form fields interactively with a visual editor",
|
||||
@@ -492,7 +429,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
changePermissions: {
|
||||
icon: <LocalIcon icon="lock-outline" width="1.5rem" height="1.5rem" />,
|
||||
name: t("home.changePermissions.title", "Change Permissions"),
|
||||
component: ChangePermissions,
|
||||
component: lazy(() => import("@app/tools/ChangePermissions")),
|
||||
description: t(
|
||||
"home.changePermissions.desc",
|
||||
"Change document restrictions and permissions",
|
||||
@@ -502,7 +439,10 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["add-password"],
|
||||
operationConfig: changePermissionsOperationConfig,
|
||||
automationSettings: ChangePermissionsSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/changePermissions/ChangePermissionsSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "changePermissions"),
|
||||
},
|
||||
getPdfInfo: {
|
||||
@@ -510,7 +450,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="fact-check-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.getPdfInfo.title", "Get ALL Info on PDF"),
|
||||
component: GetPdfInfo,
|
||||
component: lazy(() => import("@app/tools/GetPdfInfo")),
|
||||
description: t(
|
||||
"home.getPdfInfo.desc",
|
||||
"Grabs any and all information possible on PDFs",
|
||||
@@ -528,7 +468,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="verified-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.validateSignature.title", "Validate PDF Signature"),
|
||||
component: ValidateSignature,
|
||||
component: lazy(() => import("@app/tools/ValidateSignature")),
|
||||
description: t(
|
||||
"home.validateSignature.desc",
|
||||
"Verify digital signatures and certificates in PDF documents",
|
||||
@@ -566,7 +506,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="assignment-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.changeMetadata.title", "Change Metadata"),
|
||||
component: ChangeMetadata,
|
||||
component: lazy(() => import("@app/tools/ChangeMetadata")),
|
||||
description: t(
|
||||
"home.changeMetadata.desc",
|
||||
"Change/Remove/Add metadata from a PDF document",
|
||||
@@ -576,13 +516,16 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["update-metadata"],
|
||||
operationConfig: changeMetadataOperationConfig,
|
||||
automationSettings: ChangeMetadataSingleStep,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/changeMetadata/ChangeMetadataSingleStep"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "changeMetadata"),
|
||||
},
|
||||
editTableOfContents: {
|
||||
icon: <LocalIcon icon="toc-rounded" width="1.5rem" height="1.5rem" />,
|
||||
name: t("home.editTableOfContents.title", "Edit Table of Contents"),
|
||||
component: EditTableOfContents,
|
||||
component: lazy(() => import("@app/tools/EditTableOfContents")),
|
||||
description: t(
|
||||
"home.editTableOfContents.desc",
|
||||
"Add or edit bookmarks and table of contents in PDF documents",
|
||||
@@ -601,7 +544,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
crop: {
|
||||
icon: <LocalIcon icon="crop-rounded" width="1.5rem" height="1.5rem" />,
|
||||
name: t("home.crop.title", "Crop PDF"),
|
||||
component: Crop,
|
||||
component: lazy(() => import("@app/tools/Crop")),
|
||||
description: t(
|
||||
"home.crop.desc",
|
||||
"Crop a PDF to reduce its size (maintains text!)",
|
||||
@@ -611,7 +554,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["crop"],
|
||||
operationConfig: cropOperationConfig,
|
||||
automationSettings: CropAutomationSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/crop/CropAutomationSettings"),
|
||||
),
|
||||
},
|
||||
rotate: {
|
||||
icon: (
|
||||
@@ -622,14 +567,16 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.rotate.title", "Rotate"),
|
||||
component: Rotate,
|
||||
component: lazy(() => import("@app/tools/Rotate")),
|
||||
description: t("home.rotate.desc", "Easily rotate your PDFs."),
|
||||
categoryId: ToolCategoryId.STANDARD_TOOLS,
|
||||
subcategoryId: SubcategoryId.PAGE_FORMATTING,
|
||||
maxFiles: -1,
|
||||
endpoints: ["rotate-pdf"],
|
||||
operationConfig: rotateOperationConfig,
|
||||
automationSettings: RotateAutomationSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/rotate/RotateAutomationSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "rotate"),
|
||||
},
|
||||
split: {
|
||||
@@ -641,13 +588,15 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.split.title", "Split"),
|
||||
component: SplitPdfPanel,
|
||||
component: lazy(() => import("@app/tools/Split")),
|
||||
description: t("home.split.desc", "Split PDFs into multiple documents"),
|
||||
categoryId: ToolCategoryId.STANDARD_TOOLS,
|
||||
subcategoryId: SubcategoryId.PAGE_FORMATTING,
|
||||
endpoints: Array.from(new Set(Object.values(SPLIT_ENDPOINT_NAMES))),
|
||||
operationConfig: splitOperationConfig,
|
||||
automationSettings: SplitAutomationSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/split/SplitAutomationSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "split"),
|
||||
},
|
||||
reorganizePages: {
|
||||
@@ -655,7 +604,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="move-down-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.reorganizePages.title", "Reorganize Pages"),
|
||||
component: ReorganizePages,
|
||||
component: lazy(() => import("@app/tools/ReorganizePages")),
|
||||
description: t(
|
||||
"home.reorganizePages.desc",
|
||||
"Rearrange, duplicate, or delete PDF pages with visual drag-and-drop control.",
|
||||
@@ -672,7 +621,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="crop-free-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.scalePages.title", "Adjust page size/scale"),
|
||||
component: AdjustPageScale,
|
||||
component: lazy(() => import("@app/tools/AdjustPageScale")),
|
||||
description: t(
|
||||
"home.scalePages.desc",
|
||||
"Change the size/scale of a page and/or its contents.",
|
||||
@@ -682,20 +631,26 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["scale-pages"],
|
||||
operationConfig: adjustPageScaleOperationConfig,
|
||||
automationSettings: AdjustPageScaleSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/adjustPageScale/AdjustPageScaleSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "scalePages"),
|
||||
},
|
||||
addPageNumbers: {
|
||||
icon: <LocalIcon icon="123-rounded" width="1.5rem" height="1.5rem" />,
|
||||
name: t("home.addPageNumbers.title", "Add Page Numbers"),
|
||||
component: AddPageNumbers,
|
||||
component: lazy(() => import("@app/tools/AddPageNumbers")),
|
||||
description: t(
|
||||
"home.addPageNumbers.desc",
|
||||
"Add Page numbers throughout a document in a set location",
|
||||
),
|
||||
categoryId: ToolCategoryId.STANDARD_TOOLS,
|
||||
subcategoryId: SubcategoryId.PAGE_FORMATTING,
|
||||
automationSettings: AddPageNumbersAutomationSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/addPageNumbers/AddPageNumbersAutomationSettings"),
|
||||
),
|
||||
maxFiles: -1,
|
||||
endpoints: ["add-page-numbers"],
|
||||
operationConfig: addPageNumbersOperationConfig,
|
||||
@@ -706,7 +661,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="dashboard-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.pageLayout.title", "Multi-Page Layout"),
|
||||
component: PageLayout,
|
||||
component: lazy(() => import("@app/tools/PageLayout")),
|
||||
description: t(
|
||||
"home.pageLayout.desc",
|
||||
"Merge multiple pages of a PDF document into a single page",
|
||||
@@ -715,7 +670,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
subcategoryId: SubcategoryId.PAGE_FORMATTING,
|
||||
maxFiles: -1,
|
||||
endpoints: ["multi-page-layout"],
|
||||
automationSettings: PageLayoutSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/pageLayout/PageLayoutSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "pageLayout"),
|
||||
},
|
||||
bookletImposition: {
|
||||
@@ -723,9 +680,12 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="menu-book-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.bookletImposition.title", "Booklet Imposition"),
|
||||
component: BookletImposition,
|
||||
component: lazy(() => import("@app/tools/BookletImposition")),
|
||||
operationConfig: bookletImpositionOperationConfig,
|
||||
automationSettings: BookletImpositionSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/bookletImposition/BookletImpositionSettings"),
|
||||
),
|
||||
description: t(
|
||||
"home.bookletImposition.desc",
|
||||
"Create booklets with proper page ordering and multi-page layout for printing and binding",
|
||||
@@ -743,7 +703,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.pdfToSinglePage.title", "PDF to Single Large Page"),
|
||||
component: SingleLargePage,
|
||||
component: lazy(() => import("@app/tools/SingleLargePage")),
|
||||
|
||||
description: t(
|
||||
"home.pdfToSinglePage.desc",
|
||||
@@ -762,7 +722,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="attachment-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.addAttachments.title", "Add Attachments"),
|
||||
component: AddAttachments,
|
||||
component: lazy(() => import("@app/tools/AddAttachments")),
|
||||
description: t(
|
||||
"home.addAttachments.desc",
|
||||
"Add or remove embedded files (attachments) to/from a PDF",
|
||||
@@ -773,7 +733,10 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: 1,
|
||||
endpoints: ["add-attachments"],
|
||||
operationConfig: addAttachmentsOperationConfig,
|
||||
automationSettings: AddAttachmentsSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/addAttachments/AddAttachmentsSettings"),
|
||||
),
|
||||
},
|
||||
|
||||
// Extraction
|
||||
@@ -783,7 +746,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="upload-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.extractPages.title", "Extract Pages"),
|
||||
component: ExtractPages,
|
||||
component: lazy(() => import("@app/tools/ExtractPages")),
|
||||
description: t(
|
||||
"home.extractPages.desc",
|
||||
"Extract specific pages from a PDF document",
|
||||
@@ -791,7 +754,10 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
categoryId: ToolCategoryId.STANDARD_TOOLS,
|
||||
subcategoryId: SubcategoryId.EXTRACTION,
|
||||
synonyms: getSynonyms(t, "extractPages"),
|
||||
automationSettings: ExtractPagesSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/extractPages/ExtractPagesSettings"),
|
||||
),
|
||||
operationConfig: extractPagesOperationConfig,
|
||||
endpoints: ["rearrange-pages"],
|
||||
},
|
||||
@@ -804,7 +770,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.extractImages.title", "Extract Images"),
|
||||
component: ExtractImages,
|
||||
component: lazy(() => import("@app/tools/ExtractImages")),
|
||||
description: t(
|
||||
"home.extractImages.desc",
|
||||
"Extract images from PDF documents",
|
||||
@@ -814,7 +780,10 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["extract-images"],
|
||||
operationConfig: extractImagesOperationConfig,
|
||||
automationSettings: ExtractImagesSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/extractImages/ExtractImagesSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "extractImages"),
|
||||
},
|
||||
|
||||
@@ -829,7 +798,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.removePages.title", "Remove Pages"),
|
||||
component: RemovePages,
|
||||
component: lazy(() => import("@app/tools/RemovePages")),
|
||||
description: t(
|
||||
"home.removePages.desc",
|
||||
"Remove specific pages from a PDF document",
|
||||
@@ -840,7 +809,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
endpoints: ["remove-pages"],
|
||||
synonyms: getSynonyms(t, "removePages"),
|
||||
operationConfig: removePagesOperationConfig,
|
||||
automationSettings: RemovePagesSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/removePages/RemovePagesSettings"),
|
||||
),
|
||||
},
|
||||
removeBlanks: {
|
||||
icon: (
|
||||
@@ -851,7 +822,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.removeBlanks.title", "Remove Blank Pages"),
|
||||
component: RemoveBlanks,
|
||||
component: lazy(() => import("@app/tools/RemoveBlanks")),
|
||||
description: t(
|
||||
"home.removeBlanks.desc",
|
||||
"Remove blank pages from PDF documents",
|
||||
@@ -862,7 +833,10 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
endpoints: ["remove-blanks"],
|
||||
synonyms: getSynonyms(t, "removeBlanks"),
|
||||
operationConfig: removeBlanksOperationConfig,
|
||||
automationSettings: RemoveBlanksSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/removeBlanks/RemoveBlanksSettings"),
|
||||
),
|
||||
},
|
||||
removeAnnotations: {
|
||||
icon: (
|
||||
@@ -873,7 +847,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.removeAnnotations.title", "Remove Annotations"),
|
||||
component: RemoveAnnotations,
|
||||
component: lazy(() => import("@app/tools/RemoveAnnotations")),
|
||||
description: t(
|
||||
"home.removeAnnotations.desc",
|
||||
"Remove annotations and comments from PDF documents",
|
||||
@@ -895,7 +869,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.removeImage.title", "Remove Images"),
|
||||
component: RemoveImage,
|
||||
component: lazy(() => import("@app/tools/RemoveImage")),
|
||||
description: t(
|
||||
"home.removeImage.desc",
|
||||
"Remove all images from a PDF document",
|
||||
@@ -917,7 +891,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.removePassword.title", "Remove Password"),
|
||||
component: RemovePassword,
|
||||
component: lazy(() => import("@app/tools/RemovePassword")),
|
||||
description: t(
|
||||
"home.removePassword.desc",
|
||||
"Remove password protection from PDF documents",
|
||||
@@ -927,7 +901,10 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
endpoints: ["remove-password"],
|
||||
maxFiles: -1,
|
||||
operationConfig: removePasswordOperationConfig,
|
||||
automationSettings: RemovePasswordSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/removePassword/RemovePasswordSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "removePassword"),
|
||||
},
|
||||
removeCertSign: {
|
||||
@@ -939,7 +916,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.removeCertSign.title", "Remove Certificate Sign"),
|
||||
component: RemoveCertificateSign,
|
||||
component: lazy(() => import("@app/tools/RemoveCertificateSign")),
|
||||
description: t(
|
||||
"home.removeCertSign.desc",
|
||||
"Remove digital signature from PDF documents",
|
||||
@@ -960,7 +937,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="automation-outline" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.automate.title", "Automate"),
|
||||
component: Automate,
|
||||
component: lazy(() => import("@app/tools/Automate")),
|
||||
description: t(
|
||||
"home.automate.desc",
|
||||
"Build multi-step workflows by chaining together PDF actions. Ideal for recurring tasks.",
|
||||
@@ -978,7 +955,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="match-word-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.autoRename.title", "Auto Rename PDF File"),
|
||||
component: AutoRename,
|
||||
component: lazy(() => import("@app/tools/AutoRename")),
|
||||
maxFiles: -1,
|
||||
endpoints: ["auto-rename"],
|
||||
operationConfig: autoRenameOperationConfig,
|
||||
@@ -996,7 +973,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
adjustContrast: {
|
||||
icon: <LocalIcon icon="palette" width="1.5rem" height="1.5rem" />,
|
||||
name: t("home.adjustContrast.title", "Adjust Colors/Contrast"),
|
||||
component: AdjustContrast,
|
||||
component: lazy(() => import("@app/tools/AdjustContrast")),
|
||||
description: t(
|
||||
"home.adjustContrast.desc",
|
||||
"Adjust colors and contrast of PDF documents",
|
||||
@@ -1006,7 +983,10 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["adjust-contrast"],
|
||||
operationConfig: adjustContrastOperationConfig,
|
||||
automationSettings: AdjustContrastSingleStepSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/adjustContrast/AdjustContrastSingleStepSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "adjustContrast"),
|
||||
},
|
||||
repair: {
|
||||
@@ -1018,7 +998,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.repair.title", "Repair"),
|
||||
component: Repair,
|
||||
component: lazy(() => import("@app/tools/Repair")),
|
||||
description: t(
|
||||
"home.repair.desc",
|
||||
"Repair corrupted or damaged PDF files",
|
||||
@@ -1039,7 +1019,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
"home.scannerImageSplit.title",
|
||||
"Detect & Split Scanned Photos",
|
||||
),
|
||||
component: ScannerImageSplit,
|
||||
component: lazy(() => import("@app/tools/ScannerImageSplit")),
|
||||
description: t(
|
||||
"home.scannerImageSplit.desc",
|
||||
"Detect and split scanned photos into separate pages",
|
||||
@@ -1049,7 +1029,10 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["extract-image-scans"],
|
||||
operationConfig: scannerImageSplitOperationConfig,
|
||||
automationSettings: ScannerImageSplitSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/scannerImageSplit/ScannerImageSplitSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "ScannerImageSplit"),
|
||||
},
|
||||
overlayPdfs: {
|
||||
@@ -1057,7 +1040,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="layers-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.overlay-pdfs.title", "Overlay PDFs"),
|
||||
component: OverlayPdfs,
|
||||
component: lazy(() => import("@app/tools/OverlayPdfs")),
|
||||
description: t(
|
||||
"home.overlay-pdfs.desc",
|
||||
"Overlay one PDF on top of another",
|
||||
@@ -1067,7 +1050,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
endpoints: ["overlay-pdf"],
|
||||
operationConfig: overlayPdfsOperationConfig,
|
||||
synonyms: getSynonyms(t, "overlay-pdfs"),
|
||||
automationSettings: OverlayPdfsSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/overlayPdfs/OverlayPdfsSettings"),
|
||||
),
|
||||
},
|
||||
replaceColor: {
|
||||
icon: (
|
||||
@@ -1078,7 +1063,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.replaceColor.title", "Replace & Invert Color"),
|
||||
component: ReplaceColor,
|
||||
component: lazy(() => import("@app/tools/ReplaceColor")),
|
||||
description: t(
|
||||
"home.replaceColor.desc",
|
||||
"Replace or invert colors in PDF documents",
|
||||
@@ -1088,7 +1073,10 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["replace-invert-pdf"],
|
||||
operationConfig: replaceColorOperationConfig,
|
||||
automationSettings: ReplaceColorSettings,
|
||||
automationSettings: lazy(
|
||||
() =>
|
||||
import("@app/components/tools/replaceColor/ReplaceColorSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "replaceColor"),
|
||||
},
|
||||
scannerEffect: {
|
||||
@@ -1115,7 +1103,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="javascript-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.showJS.title", "Show JavaScript"),
|
||||
component: ShowJS,
|
||||
component: lazy(() => import("@app/tools/ShowJS")),
|
||||
description: t(
|
||||
"home.showJS.desc",
|
||||
"Extract and display JavaScript code from PDF documents",
|
||||
@@ -1221,7 +1209,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="compare-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.compare.title", "Compare"),
|
||||
component: Compare,
|
||||
component: lazy(() => import("@app/tools/Compare")),
|
||||
description: t(
|
||||
"home.compare.desc",
|
||||
"Compare two PDF documents and highlight differences",
|
||||
@@ -1244,7 +1232,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.compress.title", "Compress"),
|
||||
component: CompressPdfPanel,
|
||||
component: lazy(() => import("@app/tools/Compress")),
|
||||
description: t(
|
||||
"home.compress.desc",
|
||||
"Compress PDFs to reduce their file size.",
|
||||
@@ -1254,7 +1242,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["compress-pdf"],
|
||||
operationConfig: compressOperationConfig,
|
||||
automationSettings: CompressSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/compress/CompressSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "compress"),
|
||||
},
|
||||
convert: {
|
||||
@@ -1262,7 +1252,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
<LocalIcon icon="sync-alt-rounded" width="1.5rem" height="1.5rem" />
|
||||
),
|
||||
name: t("home.convert.title", "Convert"),
|
||||
component: ConvertPanel,
|
||||
component: lazy(() => import("@app/tools/Convert")),
|
||||
description: t(
|
||||
"home.convert.desc",
|
||||
"Convert files to and from PDF format",
|
||||
@@ -1291,7 +1281,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
],
|
||||
|
||||
operationConfig: convertOperationConfig,
|
||||
automationSettings: ConvertSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/convert/ConvertSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "convert"),
|
||||
},
|
||||
|
||||
@@ -1304,7 +1296,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.ocr.title", "OCR"),
|
||||
component: OCRPanel,
|
||||
component: lazy(() => import("@app/tools/OCR")),
|
||||
description: t(
|
||||
"home.ocr.desc",
|
||||
"Extract text from scanned PDFs using Optical Character Recognition",
|
||||
@@ -1314,7 +1306,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["ocr-pdf"],
|
||||
operationConfig: ocrOperationConfig,
|
||||
automationSettings: OCRSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/ocr/OCRSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "ocr"),
|
||||
},
|
||||
redact: {
|
||||
@@ -1326,7 +1320,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
/>
|
||||
),
|
||||
name: t("home.redact.title", "Redact"),
|
||||
component: Redact,
|
||||
component: lazy(() => import("@app/tools/Redact")),
|
||||
description: t(
|
||||
"home.redact.desc",
|
||||
"Permanently remove sensitive information from PDF documents",
|
||||
@@ -1336,7 +1330,9 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
maxFiles: -1,
|
||||
endpoints: ["auto-redact"],
|
||||
operationConfig: redactOperationConfig,
|
||||
automationSettings: RedactSingleStepSettings,
|
||||
automationSettings: lazy(
|
||||
() => import("@app/components/tools/redact/RedactSingleStepSettings"),
|
||||
),
|
||||
synonyms: getSynonyms(t, "redact"),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -24,7 +24,7 @@ import RightRail from "@app/components/shared/RightRail";
|
||||
import FileManager from "@app/components/FileManager";
|
||||
import LocalIcon from "@app/components/shared/LocalIcon";
|
||||
import { useFilesModalContext } from "@app/contexts/FilesModalContext";
|
||||
import AppConfigModal from "@app/components/shared/AppConfigModal";
|
||||
import AppConfigModal from "@app/components/shared/AppConfigModalLazy";
|
||||
import { getStartupNavigationAction } from "@app/utils/homePageNavigation";
|
||||
import { HomePageExtensions } from "@app/components/home/HomePageExtensions";
|
||||
|
||||
|
||||
+23
-7
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { Suspense, lazy, useState, useEffect } from "react";
|
||||
import { isAxiosError } from "axios";
|
||||
import {
|
||||
Tabs,
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
Text,
|
||||
Button,
|
||||
Accordion,
|
||||
Center,
|
||||
} from "@mantine/core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@@ -16,7 +17,14 @@ import auditService, {
|
||||
} from "@app/services/auditService";
|
||||
import AuditSystemStatus from "@app/components/shared/config/configSections/audit/AuditSystemStatus";
|
||||
import AuditStatsCards from "@app/components/shared/config/configSections/audit/AuditStatsCards";
|
||||
import AuditChartsSection from "@app/components/shared/config/configSections/audit/AuditChartsSection";
|
||||
|
||||
// AuditChartsSection pulls in recharts (~200 kB gzip). It's only rendered when
|
||||
// the user expands the "Events Over Time" accordion on this page, so we keep
|
||||
// the rest of the audit page eager and lazy-load just the charts.
|
||||
const AuditChartsSection = lazy(
|
||||
() =>
|
||||
import("@app/components/shared/config/configSections/audit/AuditChartsSection"),
|
||||
);
|
||||
import AuditEventsTable from "@app/components/shared/config/configSections/audit/AuditEventsTable";
|
||||
import AuditExportSection from "@app/components/shared/config/configSections/audit/AuditExportSection";
|
||||
import AuditClearDataSection from "@app/components/shared/config/configSections/audit/AuditClearDataSection";
|
||||
@@ -217,11 +225,19 @@ const AdminAuditSection: React.FC = () => {
|
||||
{t("audit.charts.overTime", "Events Over Time")}
|
||||
</Accordion.Control>
|
||||
<Accordion.Panel>
|
||||
<AuditChartsSection
|
||||
loginEnabled={isEnabled}
|
||||
timePeriod={timePeriod}
|
||||
onTimePeriodChange={setTimePeriod}
|
||||
/>
|
||||
<Suspense
|
||||
fallback={
|
||||
<Center style={{ padding: "2rem" }}>
|
||||
<Loader />
|
||||
</Center>
|
||||
}
|
||||
>
|
||||
<AuditChartsSection
|
||||
loginEnabled={isEnabled}
|
||||
timePeriod={timePeriod}
|
||||
onTimePeriodChange={setTimePeriod}
|
||||
/>
|
||||
</Suspense>
|
||||
</Accordion.Panel>
|
||||
</Accordion.Item>
|
||||
</Accordion>
|
||||
|
||||
+15
-2
@@ -1,4 +1,4 @@
|
||||
import { defineConfig, loadEnv } from "vite";
|
||||
import { defineConfig, loadEnv, type PluginOption } from "vite";
|
||||
import react from "@vitejs/plugin-react-swc";
|
||||
import tsconfigPaths from "vite-tsconfig-paths";
|
||||
import { viteStaticCopy } from "vite-plugin-static-copy";
|
||||
@@ -20,7 +20,7 @@ const TSCONFIG_MAP: Record<BuildMode, string> = {
|
||||
prototypes: "./tsconfig.prototypes.vite.json",
|
||||
};
|
||||
|
||||
export default defineConfig(({ mode }) => {
|
||||
export default defineConfig(async ({ mode }) => {
|
||||
// Load env file based on `mode` in the current working directory.
|
||||
// Set the third parameter to '' to load all env regardless of the
|
||||
// `VITE_` prefix.
|
||||
@@ -55,6 +55,19 @@ export default defineConfig(({ mode }) => {
|
||||
tsconfigPaths({
|
||||
projects: [tsconfigProject],
|
||||
}),
|
||||
// Set ANALYZE=true to emit dist/stats.html (treemap) alongside the
|
||||
// build; rollup-plugin-visualizer is ESM-only so we import dynamically.
|
||||
...(process.env.ANALYZE === "true"
|
||||
? [
|
||||
(await import("rollup-plugin-visualizer")).visualizer({
|
||||
filename: "dist/stats.html",
|
||||
template: "treemap",
|
||||
gzipSize: true,
|
||||
brotliSize: true,
|
||||
emitFile: false,
|
||||
}) as PluginOption,
|
||||
]
|
||||
: []),
|
||||
viteStaticCopy({
|
||||
targets: [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user