Commit Graph
613 Commits
Author SHA1 Message Date
EthanHealy01andGitHub 23dc03832f Fixes/tour and desktop improvements (#6320)
Added back the desktop file isDirty indicator
<img width="414" height="385" alt="Screenshot 2026-05-07 at 1 36 19 PM"
src="https://github.com/user-attachments/assets/d2d79c46-469d-4bb2-9540-e86183dcd372"
/>

Also added back the tours and added tests to ensure we don't delete
parts of them in future by mistake
<img width="2056" height="1069" alt="Screenshot 2026-05-07 at 1 36
31 PM"
src="https://github.com/user-attachments/assets/987741a0-01aa-4a0e-9e06-584a52cc1e43"
/>
<img width="2056" height="1066" alt="Screenshot 2026-05-07 at 1 36
43 PM"
src="https://github.com/user-attachments/assets/48ea369c-816c-485d-889a-6ecce71b1855"
/>
2026-05-07 16:19:55 +01:00
EthanHealy01andGitHub b5f11c4efe Fixes to UI redesign staging (#6315)
- Upgrade banner is thinner
- Full screen tools list removed the button to toggle the setting and
minimize the view
- Language selector button fixed in dark mode
- Consolidation to thumbnail logic and improved rendering of fallback
thumbnails for non PDF/non image files
- Changed icons in the left side file selector to match design spec more
- Changed file picker modal to use the same icons as fallbacks as the
left sidebar file picker and the active files
- Added scrollbar to the left sidebar files list
2026-05-06 16:45:21 +01:00
EthanHealy01andGitHub cec414d11b Merge branch 'main' into UIRedesignStaging 2026-05-06 01:23:48 +01:00
ed56490f93 Fix move button on multitool (#6291)
Hitting move button twice on multitool didn't work

---------

Co-authored-by: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com>
2026-05-05 20:46:47 +00:00
EthanHealy01 5ca7e35ba9 linter 2026-05-05 19:18:32 +01:00
EthanHealy01 14834723c9 forgot import 2026-05-05 18:54:15 +01:00
EthanHealy01 1d18b3db1a merge main 2026-05-05 18:49:48 +01:00
James BruntonandGitHub 95c39b4648 Fix missing desktop save indicator on files (#6310)
# Description of Changes
Save indicator stopped showing up after #6050, which fixed the missing
truncation on filenames, but accidentally bypassed the save indicator
component at the same time. This PR puts the component back in and makes
it support truncation so we can have both.

<img width="586" height="166" alt="image"
src="https://github.com/user-attachments/assets/529c3dcb-ee00-4a6d-ae53-ef8657204369"
/>
2026-05-05 11:19:11 +00:00
EthanHealy01 93ab2b4805 merge main 2026-05-05 11:54:46 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Anthony Stirling
4ab7d3b3ae build(deps): bump the mui group across 1 directory with 2 updates (#6301)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2026-05-05 10:53:16 +01:00
EthanHealy01 54805896d6 Merge remote-tracking branch 'origin/main' into UIRedesignStaging 2026-05-01 18:54:21 +01:00
3fe8adc5cb 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 <80844253+EthanHealy01@users.noreply.github.com>
2026-05-01 15:21:06 +00:00
EthanHealy01 0a73467ce5 Revert "fix: viewer stays on signed file instead of jumping to file A after tool run"
This reverts commit df056a8f2d.
2026-05-01 14:35:11 +01:00
EthanHealy01 df056a8f2d fix: viewer stays on signed file instead of jumping to file A after tool run
Remove the useEffect that cleared activeFileId when its file left the workbench.
That effect raced with tool operations: CONSUME_FILES atomically removes the input
and adds the output in one dispatch, but the clearing effect fired between the
dispatch and the tool's setActiveFileId(newId) call, clobbering the correct new ID
with null. activeFileIndex already falls back to 0 for stale/null IDs, so the
clearing effect was not needed for correctness.
2026-05-01 14:32:48 +01:00
EthanHealy01 34d9baa1be fix: move close icon from hamburger to search icon when search is active 2026-05-01 14:23:15 +01:00
EthanHealy01 178c3c3331 prettier 2026-05-01 14:04:33 +01:00
EthanHealy01 39e0fb630c fix: stay on multi-tool after first file upload
getStartupNavigationAction was unconditionally redirecting to viewer/
fileEditor on 0→N file transitions, overriding the multi-tool workbench.
Exempt multiTool the same way pdfTextEditor already is.
2026-05-01 12:17:14 +01:00
EthanHealy01andGitHub ed7a9d1a01 Merge branch 'main' into UIRedesignStaging 2026-05-01 12:10:38 +01:00
EthanHealy01 be69d071bc test(e2e): fix Firefox toggle click in settings spec
Click the visible label wrapper instead of force-clicking the hidden
checkbox input, which Firefox does not register as a state change.
2026-05-01 12:07:55 +01:00
EthanHealy01 a8671ec1f7 test(e2e): fix all stubbed Playwright test failures
Updated stubbed specs to match the redesigned UI: fixed locators for
WorkbenchBar buttons, FileSidebar search, navigation, settings dialog,
language selector, and in-document PDF search. All 130 stubbed tests
now pass (7 intentional skips for build-conditional features).
2026-05-01 10:55:19 +01:00
86774d556e Pdf comment agent (#6196)
Co-authored-by: James Brunton <jbrunton96@gmail.com>
2026-05-01 10:19:38 +01:00
EthanHealy01 67fc78b6df Fix lint, formatting, and TOML parse errors post-merge
- Remove unused meta variable and getFileTypeMeta import from NonPdfViewer
- Fix TOML: move compare.edited.selectBaseFirst and compare.swap.label from
  dotted-key form in [compare] to their proper subsections
- Run Prettier on 7 files flagged by format check
2026-04-30 21:29:11 +01:00
EthanHealy01 b5b4bbc46b Merge branch 'main' into UIRedesignStaging
Resolved conflict in en-GB/translation.toml:
- Accept main's reorganised/alphabetised structure
- Restore UIRedesign wording (checked/add vs selected/select terminology)
- Add sections new to UIRedesign: fileSelectorPicker, fileSidebar, workbenchBar
- Add missing keys: rightRail.closeAll/share, tool.filesLoading/filesLoadingProgress,
  settings.general theme/language keys, fileEditor.pageCount, encryptedPdfUnlock viewer keys
2026-04-30 21:24:27 +01:00
EthanHealy01 849899f58c Merge remote-tracking branch 'origin/UIRedesignStaging' into UIRedesignStaging 2026-04-30 21:17:08 +01:00
EthanHealy01 a42fdfad00 UI redesign: multi-tool mode, workbench bar animation, PDFium rendering fixes
- Add multi-tool mode support across FileSidebar, FilesModalContext, PageEditorContext,
  WorkbenchBar, and ToolWorkflowContext — adding files stays in pageEditor view and
  auto-selects files; left panel hides/shows on workbench switch
- Animate WorkbenchBar in/out via CSS grid-template-rows trick when files are added/removed;
  suppress initial transition with rAF flag
- Fix PDFium pixel format (RGBA not BGRA) and rotation logic (effective dims already
  post-rotation; counter-rotate when applyRotation=false)
- Fix PageEditor flash of "No PDF files loaded" by checking file context directly
- Redesign AddFileCard: solid border, rounded corners, shadow hover, focus-visible ring
- Show AddFileCard in FileEditor empty state instead of text stack
- Add date grouping helpers (today/yesterday/thisWeek/thisMonth/older) to FileSidebar
- Redesign FilePdfIcon: solid filled with folded corner, red colour
- Simplify NonPdfBanner: remove file-type badge, keep only convert-to-PDF button
- Fix thumbnail precedence in useToolOperation (prefer metadata.thumbnailUrl)
- Fix fileActions stub dispatch to trigger selector re-render after ADD_FILES
- Switch Annotate to useAllFiles and Automate/AutomationRun to useViewScopedFiles
2026-04-30 21:16:58 +01:00
Anthony StirlingandGitHub d8c1ffa8ef fix stubs playwright (#6274) 2026-04-30 12:37:15 +01:00
a26b15b1fe Lazy load open cv (#6236)
Co-authored-by: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com>
2026-04-28 17:36:34 +01:00
ConnorYohandGitHub 4e4918b91e fix(workflow): stop leaking peer share tokens from participant session API (#6241) 2026-04-28 17:36:20 +01:00
Anthony StirlingandGitHub 12a00fe9c5 bug fixes for some desktop tools (#6246) 2026-04-28 17:24:56 +01:00
Anthony StirlingandGitHub 8daee7303d playwright (#6025) 2026-04-27 11:35:50 +01:00
James BruntonandGitHub 1e3da14081 Change frontend .env files to be committed and have .env.*.local overrides (#6207) 2026-04-25 13:09:59 +01:00
LudyandGitHub 9890d6a7de fix: skip translation key extraction for files without i18n usage (#6221) 2026-04-25 13:08:24 +01:00
EthanHealy01andGitHub 770577edb6 Merge branch 'main' into UIRedesignStaging 2026-04-24 11:00:53 +01:00
EthanHealy01 eaed8feb42 aikido change requests 2026-04-23 18:59:36 +01:00
EthanHealy01andGitHub 7c42d8018a make clicking on comments open the comments sidebar and more (#6174)
make clicking on comments open the comments sidebar and add a button to
create comments into the empty state of the comments sidebar
<img width="2056" height="1081" alt="Screenshot 2026-04-23 at 12 39
50 PM"
src="https://github.com/user-attachments/assets/6f15484d-d04f-4900-92c6-b2cc397d6d08"
/>

<img width="627" height="396" alt="Screenshot 2026-04-23 at 12 40 06 PM"
src="https://github.com/user-attachments/assets/509e5526-0082-4fc6-a98f-829bb4c1baf2"
/>
2026-04-23 17:22:47 +01:00
c294e9b2cb fix file sharing bug (#6161)
# Description of Changes

Fixes share-link navigation for SSO users. Reported on v2.9.2 with
`SSOAutoLogin: true`: clicking a `/share/<token>` link in an email
redirected the user to the home page after SSO instead of the shared
file.

## Root cause

Three compounding issues had to be fixed together; the first was the
initial symptom but the other two only surfaced during live
verification.

1. **Spring Security blocked `/share/<token>` for unauthenticated
users.** The route wasn't in `RequestUriUtils.isPublicAuthEndpoint`, so
the server 302'd straight to `/login` before React could load
`ShareLinkPage`. The share URL was lost because `NullRequestCache` is
configured and never persisted the original destination.

2. **`httpErrorHandler` full-page-redirected to `/login?from=<path>` on
any unhandled 401** (fired by `LicenseContext`, `AppConfig`, etc. during
normal ShareLinkPage mount). That *did* preserve the return path — but
**Spring Security strips query strings from `/login`** (302 to bare
`/login`), so `?from=` never reached React. Confirmed via `curl -i
http://localhost:8080/login?from=xyz` → `Location: /login`.

3. **`AuthCallback.tsx` unconditionally `navigate("/")`** after the
SAML/OAuth round-trip, discarding any intended destination.

## Fix

**Backend** — make `/share/<token>` a public SPA bootstrap, data APIs
stay protected:
- `RequestUriUtils.isPublicAuthEndpoint` — permits `^/share/[^/]+/?$`
(tight regex, single token segment only; `/share/<token>/anything` stays
protected).
- `ReactRoutingController` — dedicated `@GetMapping("/share/{token}")`
mirroring `/auth/callback`.
- `/api/v1/storage/share-links/**` remains behind Spring Security with
its existing `canAccessShareLink` check.

**Frontend** — persist the return path across full-page redirects via
`sessionStorage` (same-origin, survives the SSO round-trip):
- `httpErrorHandler.ts` — stashes current pathname to
`stirling_post_login_path` before the 401 → `/login` redirect.
- `springAuthClient.ts` — new `isSafePostLoginRedirect` /
`setPostLoginRedirectPath` / `consumePostLoginRedirectPath` helpers
(rejects protocol-relative URLs and auth-plumbing paths to guard against
open-redirect abuse).
- `Login.tsx` — on explicit user sign-in, read path from
`location.state` or `?from=` query and stash it; don't clobber an
already-stashed value.
- `AuthCallback.tsx` — consume the stashed path (single-use) and
`navigate(target)` instead of always `/`.


---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.

---------

Co-authored-by: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com>
2026-04-23 14:52:25 +01:00
EthanHealy01andGitHub 3b24b3479a Merge branch 'main' into UIRedesignStaging 2026-04-23 13:05:14 +01:00
Anthony StirlingandGitHub 611d7577a3 Version bump to 2.10.0 (#6168) 2026-04-23 11:54:47 +01:00
Anthony StirlingandGitHub 1d5b47fa9b fix edge translation bug (#6158) 2026-04-22 16:31:43 +01:00
Anthony StirlingandGitHub d71a2c3d81 FixThumbnailRegeneration (#6134) 2026-04-22 14:33:38 +01:00
EthanHealy01 fd1cf4468e prettier 2026-04-21 22:38:27 +01:00
EthanHealy01 04c5fbc590 change stuff for playwright test and remove test for drag and drop compare upload which no longer exists 2026-04-21 21:26:19 +01:00
EthanHealy01andGitHub d2f28e07ea Merge branch 'main' into UIRedesignStaging 2026-04-21 18:50:19 +01:00
EthanHealy01 2843418fb7 frontend validatoin 2026-04-21 18:47:23 +01:00
EthanHealy01 53377da75d test 2026-04-21 18:09:22 +01:00
EthanHealy01 93b1669f63 Merge branch 'main' of https://github.com/Stirling-Tools/Stirling-PDF into UIRedesignStaging 2026-04-21 16:35:51 +01:00
James BruntonandGitHub 2a856fbc19 Allow chat history to be sent to AI engine (#6128)
# Description of Changes
Add an extra parameter to every agent to receive the conversation
history in addition to the current message. This will make it possible
to answer followup questions from the AI without needing to give full
context in your message.
2026-04-21 15:03:10 +00:00
EthanHealy01andGitHub 7dc164453b UIUX/UI redesign (#6107)
# PR: feature/UIRedesign → UIRedesignStaging

## Overview

Major layout restructure: the old right-rail icon column and top
file-tab strip are replaced by a new horizontal `WorkbenchBar` and a new
persistent `FileSidebar` on the left. Alongside those headline changes,
a range of bugs are fixed around viewer state, file management, and
thumbnail caching.

---

## Changes

### 1. Page layout restructured

**Before:** `QuickAccessBar` above content, `ToolPanel` on the left,
`RightRail` vertical icon column on the right.

**After:** `FileSidebar` on the left, `WorkbenchBar` across the top,
`ToolPanel` on the right. The right rail is gone.

---

### 2. `FileSidebar` — new persistent left sidebar

**Why:** The only way to see saved files was opening the file manager
modal. The sidebar gives quick access to everything in IndexedDB without
a modal.

**Before:** No persistent sidebar. Files managed exclusively via the
modal.

**After:**
- Collapsible strip on the left (collapses to a narrow icon strip,
expands to a file list).
- Shows all saved files, sorted by last modified. Files not yet
persisted to IndexedDB also appear.
- Click a file to toggle it on/off the workbench. If the file is open in
the viewer with unsaved changes, the save prompt fires first.
- Search bar filters by filename.
- Add files from computer or Google Drive directly from the sidebar.
- Thumbnail appears on hover, loaded lazily and cached for future
visits.
- The currently-viewed file is pinned at the top of the list with a
green highlight.
- List updates automatically when files are added or deleted anywhere in
the app.

---

### 3. `WorkbenchBar` replaces `TopControls` + `RightRail`

**Why:** `TopControls` only showed when files existed and only displayed
file tabs. The right rail was a separate vertical column. Neither gave a
coherent home for view switching, tool actions, and file operations.

**Before:** File tabs in a strip at the top; download/close/view buttons
in a separate vertical column on the right.

**After:**
- Always visible bar across the top.
- Left: Viewer / Active Files view switcher (hidden when no files are
open).
- Centre: Tool-specific action buttons (the same buttons that previously
lived in the right rail), plus zoom controls when in viewer mode.
- Right: Print (viewer only), Close (closes the current file in viewer
mode, closes all files in file editor mode), Download, Save As.
- Adapts to narrow widths by wrapping into two rows.


---

### 4. Viewer — active file never loses track after tool operations

**Why:** After running a tool on a file, the viewer would sometimes jump
to showing a different file.

**Before:** The "active file index" and "active file ID" were tracked as
two separate pieces of state that could desync when files were reordered
after a tool ran.

**After:** The index is always derived from the ID, so they can never
disagree. The viewer stays on the correct file after any operation.


### 5. Auto-navigate after file upload

**Before:** After uploading files via the modal, the user was left on
whatever view was active — no automatic navigation.

**After:** Single file uploaded → navigates to viewer. Multiple files
uploaded → navigates to Active Files.

---

### 6. Run button shows loading progress while files are still loading

**Why:** Opening a tool immediately after uploading many files could
silently skip files that hadn't finished loading yet.

**Before:** Run button was enabled immediately; files still being loaded
from storage were silently skipped.

**After:** While files are loading, the run button is replaced with a
disabled progress indicator. For multiple pending files it shows "2 / 5
files loading…". Once all files are ready, the button becomes active.

---

### 7. Bulk delete in file manager

**Why:** Deleting many files at once was slow and caused visible flicker
as each file was removed one by one.

**Before:** Each selected file went through the full single-delete flow
sequentially.

**After:** Local files are deleted in a single batch operation — one UI
update, one IndexedDB transaction. Server-connected files still go
through the sequential flow since each may need a confirmation prompt.

---

### 8. Deselecting a dirty file in the modal no longer removes it from
the workbench

**Before:** Deselecting a file in the file manager and clicking "Open"
would remove it from the workbench even if it had unsaved changes.

**After:** Files with unsaved changes are skipped when removing
deselected files.

---

### 9. File manager — "Close all files" button

**Before:** With nothing selected in the file manager, the "Open File"
button was disabled.

**After:** When nothing is selected but files are open, the button
changes to "Close all files" and becomes enabled.

---

### 10. File picker — search and hover thumbnails

**Before:** No way to filter the file list in the picker dropdown. No
visual preview.

**After:** Search input filters files by name. Hovering a row shows a
thumbnail preview.

---

### 11. Pan and ruler modes are now mutually exclusive

**Before:** Enabling the pan tool while the ruler was active left the
ruler in a broken state, and vice versa.

**After:** Activating either tool automatically deactivates the other.

---

### 12. Tool icons switched to outline style

All tool icons in the picker are now the outline variant instead of the
filled/solid variant, for a lighter, more consistent look.

---

### 13. Settings — language and theme options added to General settings

Language and theme (light/dark) controls are now available in Settings →
General.

---

## Test Script

---

### Sidebar and file management

1. **Sidebar toggle:** Confirm the left sidebar strip is visible on
load. Click expand — confirm the file list appears. Click collapse —
confirm it shrinks back to the strip.
2. **Upload and see files:** Upload 3 PDFs. Confirm all three appear in
the sidebar list without needing to open any modal.
3. **Sidebar search:** Type part of a filename in the sidebar search
box. Confirm the list filters. Clear it — confirm all files return.
4. **Toggle files on workbench from sidebar:** Click a file in the
sidebar that isn't on the workbench — confirm it opens. Click it again —
confirm it closes.
5. **Save prompt via sidebar:** Open a file in the viewer and make a
change (e.g. annotate). Click that file in the sidebar to close it —
confirm the unsaved-changes save prompt appears.
6. **Thumbnail on hover:** Hover a file row in the sidebar — confirm a
thumbnail preview appears.
7. **Currently viewed file pinned:** With multiple files open, confirm
the one you're viewing is highlighted at the top of the sidebar list.
8. **Sidebar reflects deletions:** Delete a file via the file manager
modal. Confirm the sidebar updates automatically without a page reload.

---

### Workbench bar

9. **No files state:** With no files open, confirm the workbench bar is
visible but no view tabs are shown.
10. **View tabs appear:** Upload a file — confirm "Viewer" and "Active
Files" tabs appear. Switch between them.
11. **Close button behaviour:** In Active Files with multiple files,
click Close — confirm all files close. Open a single file in viewer
mode, click Close — confirm only that file closes.
12. **Download:** Open a file in the viewer, click Download — confirm
the file saves.
13. **Zoom controls in viewer:** Confirm zoom in/out and a slider appear
in the bar's centre when in viewer mode. Drag the slider — confirm the
PDF zooms live. Switch to Active Files — confirm the controls disappear.

---

### Tool panel

14. **Collapse/expand:** Collapse the tool panel. Confirm a narrow strip
remains (not blank space). Click the expand icon — panel opens. Collapse
again, click the search icon — confirm the panel opens with the search
field already focused.
15. **Back button in tool:** Open a tool (e.g. Compress). Confirm the
search bar icon changes to a back arrow. Click it — confirm you return
to the tool list.
16. **Viewer tool mini bar:** Open a PDF in the viewer. Confirm a mini
toolbar appears at the top of the panel with viewer-specific buttons
(annotate, redact, form fill, etc.). Switch to Active Files — confirm it
disappears.

---

### Running tools with files loading

17. **Loading indicator on run button:** Upload 5+ PDFs and immediately
open a tool (e.g. Compress or Merge). If files are still loading,
confirm the run button shows a loading progress indicator and is
disabled. Wait until loading finishes — confirm the button becomes
active.

---

### Viewer correctness

18. **Active file stays put after tool run:** Open 3 PDFs. Navigate to
file #2 in the viewer. Run a tool (e.g. rotate) on file #2. Confirm the
viewer stays on file #2 after the operation completes.
19. **Pan / ruler mutual exclusion:** Open a PDF. Enable pan. Enable the
ruler — confirm pan turns off. Re-enable pan — confirm the ruler turns
off.

---

### File manager

20. **Bulk delete:** Open the file manager, select 3+ local files, click
Delete Selected. Confirm all disappear in one go with no flicker, and
the sidebar updates.
21. **Dirty file not removed on deselect:** Open a PDF, make a change.
Open the file manager, deselect that file, click Open. Confirm the file
is still on the workbench.
22. **Close all from modal:** Have files open. Open the file manager,
deselect everything — confirm the button changes to "Close all files".
Click it — confirm all files close.

---

### File picker (inside tools)

23. **Search in picker:** Open a tool with a file picker (e.g. Merge,
Compare). Open the picker dropdown. Type a partial name — confirm the
list filters. Hover a row — confirm a thumbnail appears.

---

### Other flows

24. **Auto-navigate after upload:** Upload a single PDF via the modal —
confirm you land in the viewer. Upload multiple at once — confirm you
land in Active Files.
25. **Landscape PDF aspect ratio:** Upload a landscape PDF. In Active
Files view, confirm its thumbnail card is wider than tall.
26. **Compare tool clear label:** Open the Compare tool. Click to clear
the selection. Confirm the confirm button reads "Clear Selected".
27. **Settings — language and theme:** Open Settings → General. Confirm
Language and Theme controls exist. Toggle theme — confirm it switches.
28. **Tool icons:** Open the tool picker and confirm all tool icons use
the outline/unfilled style.


<img width="2056" height="1077" alt="Screenshot 2026-04-14 at 5 08
36 PM"
src="https://github.com/user-attachments/assets/b68243cb-70f6-4aac-b4e8-76ca6c617be2"
/>

<img width="2056" height="1080" alt="Screenshot 2026-04-14 at 5 08
51 PM"
src="https://github.com/user-attachments/assets/b3c1525b-6f30-4abc-b85a-ce2368e376c7"
/>

<img width="2056" height="1081" alt="Screenshot 2026-04-14 at 5 09
10 PM"
src="https://github.com/user-attachments/assets/894bb5a4-dd4b-49ae-a7da-2ee343c6c656"
/>

<img width="2056" height="1080" alt="Screenshot 2026-04-14 at 5 09
31 PM"
src="https://github.com/user-attachments/assets/9d4dd1e4-026d-4736-891d-0ae6647318d4"
/>
2026-04-21 15:48:02 +01:00
66a75b1f28 Add pixel comparison mode to Compare tool (#6109)
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
Co-authored-by: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com>
2026-04-20 19:31:07 +01:00
e5767ed58b Change AI engine to execute tools in Java instead of on frontend (#6116)
# Description of Changes
Redesign AI engine so that it autogenerates the `tool_models.py` file
from the OpenAPI spec so the Python has access to the Java API
parameters and the full list of Java tools that it can run. CI ensures
that whenever someone modifies a tool endpoint that the AI enigne tool
models get updated as well (the dev gets told to run `task
engine:tool-models`).

There's loads of advantages to having the Java be the one that actually
executes the tools, rather than the frontend as it was previously set up
to theoretically use:
- The AI gets much better descriptions of the params from the API docs
- It'll be usable headless in the future so a Java daemon could run to
execute ops on files in a folder without the need for the UI to run
- The Java already has all the logic it needs to execute the tools 
- We don't need to parse the TypeScript to find the API (which is hard
because the TS wasn't designed to be computer-read to extract the API)

I've also hooked up the prototype frontend to ensure it's working
properly, and have built it in a way that all the tool names can be
translated properly, which was always an issue with previous prototypes
of this.

---------

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
Co-authored-by: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com>
2026-04-20 15:57:11 +01:00