Restructure/frontend editor (#6404)

## Move editor under `frontend/editor/`

Pure restructure: `frontend/` becomes the workspace, `frontend/editor/`
holds
  the PDF editor. 1775 file renames + 40 wiring edits. No logic changes.

  ### Why

`frontend/` is currently the editor — its `src/`, `public/`,
`src-tauri/`,
  config files all sit at the root. Promoting `frontend/` to a
workspace and putting the editor in a sibling folder leaves room for
future
apps to drop in alongside it, sharing one `package.json` /
`node_modules` /
  lint config / Storybook.

  ### What moves

  frontend/
  ├── editor/                ← NEW: everything editor-specific
  │   ├── src/               ← was frontend/src/
  │   ├── public/            ← was frontend/public/
  │   ├── src-tauri/         ← was frontend/src-tauri/
│ ├── index.html, vite.config.ts, vitest.config.ts, playwright.config.ts
  │   ├── tsconfig*.json, tailwind.config.js, postcss.config.js
  │   ├── scripts/
  │   ├── .env, .env.desktop, .env.saas
  │   └── DeveloperGuide.md
├── package.json, package-lock.json, node_modules/ ← workspace install
  ├── eslint.config.mjs, .prettierrc, .prettierignore ← shared tooling
  ├── .gitignore
  └── README.md

  ### Wiring edits (40 files)

  - `.taskfiles/frontend.yml`, `desktop.yml`, `e2e.yml`
  - `build.gradle`, `app/core/build.gradle`
- `eslint.config.mjs`, `frontend/package.json`, `.gitignore`,
`.prettierignore`
  - `docker/frontend/Dockerfile`
  - 8 `.github/workflows/*.yml`, plus `.github/dependabot.yml`,
    `.github/config/.files.yaml`, `.github/labeler-config-srvaroa.yml`
  - `scripts/translations/**`
- Docs: `AGENTS.md`, `CLAUDE.md`, `ADDING_TOOLS.md`,
`DeveloperGuide.md`,
`WINDOWS_SIGNING.md`, `devGuide/HowToAddNewLanguage.md`,
`frontend/README.md`,
    `frontend/editor/DeveloperGuide.md`

Plus 3 renamed + edited: `editor/vite.config.ts` (env path +
node_modules
  walk-up), `editor/scripts/setup-env.mts` (renamed from `.ts` for
`import.meta.url`), `editor/scripts/build-provisioner.mjs` (resolve
src-tauri
  relative to script).

  ### Verification

  | Check | Result |
  |---|---|
  | `task frontend:typecheck:all` (6 variants) | exit 0 |
  | `task frontend:lint` (eslint + dpdm) | exit 0 |
  | `task frontend:format:check` | exit 0 |
  | `task frontend:test` | 657 tests pass, 50 files |
| `task frontend:build:{core,proprietary,saas,desktop,prototypes}` | all
green |
| `task desktop:build` | full Tauri pipeline →
`Stirling-PDF_2.11.0_x64_en-US.msi` |
  | `playwright test --list --project=stubbed` | 172 tests discovered |

`task desktop:build` exercises the heaviest path — Rust + WiX + MSI
bundle
against the moved `editor/src-tauri/`. If anything in the restructure
was
  wrong it wouldn't have built.

  ### Test plan

  - [ ] `frontend-validation.yml` green
  - [ ] `e2e-stubbed.yml` green
  - [ ] `tauri-build.yml` green on at least one platform
  - [ ] `check_toml.yml` runs on a translation-touching PR

---------

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
Reece Browne
2026-05-22 13:40:34 +01:00
committed by GitHub
co-authored by Claude Opus 4.7
parent 48027ee9d6
commit 0a50e765b7
1820 changed files with 300 additions and 226 deletions
@@ -0,0 +1,59 @@
/* Cookie Consent Modal Styling - Ensure proper z-index */
/* Ensure cookie consent appears above everything */
#cc-main {
z-index: 999999 !important;
}
/* Additional styling if needed */
.cm-wrapper,
.pm-wrapper {
z-index: 999999 !important;
}
/* Dark mode styling */
.cc--darkmode .cm {
background: #2d2d2d !important;
color: #ffffff !important;
border-top: 1px solid #444 !important;
}
.cc--darkmode .pm {
background: #2d2d2d !important;
color: #ffffff !important;
}
.cc--darkmode .pm-overlay {
background: rgba(0, 0, 0, 0.7) !important;
}
/* Button styling */
.cc--darkmode .cm__btn {
background: #444 !important;
color: #ffffff !important;
border: 1px solid #666 !important;
}
.cc--darkmode .cm__btn:hover {
background: #555 !important;
}
.cc--darkmode .pm__btn {
background: #444 !important;
color: #ffffff !important;
border: 1px solid #666 !important;
}
.cc--darkmode .pm__btn:hover {
background: #555 !important;
}
/* Ensure ScrollArea doesn't interfere */
.mantine-ScrollArea-root {
position: relative !important;
}
/* Override any potential conflicts */
[data-mantine-color-scheme="dark"] #cc-main {
color: #ffffff !important;
}
+83
View File
@@ -0,0 +1,83 @@
html,
body {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
overscroll-behavior: none;
}
body {
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu",
"Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
img {
-webkit-user-drag: none;
user-drag: none;
}
code {
font-family:
source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
}
/* Suppress font visibility warnings for PDF.js embedded fonts */
@font-face {
font-family: "Adwaita Mono";
src: local("Adwaita Mono");
font-display: optional;
}
@font-face {
font-family: "Nimbus Mono PS";
src: local("Nimbus Mono PS");
font-display: optional;
}
/* CSS Variables */
:root {
--footer-height: 2rem;
}
/* Footer link styling - make buttons and links look identical */
.footer-link {
color: var(--mantine-color-gray-6);
text-decoration: none;
transition: color 0.2s ease;
border: none;
background: none;
cursor: pointer;
font-family: inherit;
font-size: inherit;
padding: 0;
}
.footer-link:hover {
color: var(--mantine-color-blue-8);
text-decoration: underline;
}
.stirling-link {
color: var(--mantine-color-blue-6);
text-decoration: none;
font-weight: 500;
transition: color 0.2s ease;
}
.stirling-link:hover {
color: var(--mantine-color-blue-8);
text-decoration: underline;
}
/* Viewer file tabs */
.viewer-file-tab {
justify-content: flex-start;
}
.viewer-file-tab[data-active] {
background-color: rgba(147, 197, 253, 0.5);
}
@@ -0,0 +1,345 @@
/* Rainbow Mode Styles - Easter Egg! */
@keyframes rainbowBackground {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
@keyframes rainbowBorder {
0% {
border-color: #ff0000;
box-shadow: 0 0 15px #ff0000;
}
14% {
border-color: #ff8800;
box-shadow: 0 0 15px #ff8800;
}
28% {
border-color: #ffff00;
box-shadow: 0 0 15px #ffff00;
}
42% {
border-color: #88ff00;
box-shadow: 0 0 15px #88ff00;
}
57% {
border-color: #00ff88;
box-shadow: 0 0 15px #00ff88;
}
71% {
border-color: #0088ff;
box-shadow: 0 0 15px #0088ff;
}
85% {
border-color: #8800ff;
box-shadow: 0 0 15px #8800ff;
}
100% {
border-color: #ff0000;
box-shadow: 0 0 15px #ff0000;
}
}
@keyframes rainbowText {
0% {
color: #ff0000;
text-shadow: 0 0 10px #ff0000;
}
14% {
color: #ff8800;
text-shadow: 0 0 10px #ff8800;
}
28% {
color: #ffff00;
text-shadow: 0 0 10px #ffff00;
}
42% {
color: #88ff00;
text-shadow: 0 0 10px #88ff00;
}
57% {
color: #00ff88;
text-shadow: 0 0 10px #00ff88;
}
71% {
color: #0088ff;
text-shadow: 0 0 10px #0088ff;
}
85% {
color: #8800ff;
text-shadow: 0 0 10px #8800ff;
}
100% {
color: #ff0000;
text-shadow: 0 0 10px #ff0000;
}
}
@keyframes rainbowPulse {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
}
/* Main rainbow theme class */
.rainbowMode {
background: linear-gradient(
-45deg,
#ff0000,
#ff8800,
#ffff00,
#88ff00,
#00ff88,
#00ffff,
#0088ff,
#8800ff,
#ff0088,
#ff0000
) !important;
background-size: 400% 400% !important;
animation: rainbowBackground 3s ease infinite !important;
color: white !important;
overflow-x: hidden;
}
/* Rainbow components */
.rainbowCard {
background: linear-gradient(
45deg,
#ff0000,
#ff8800,
#ffff00,
#88ff00,
#00ff88,
#00ffff,
#0088ff,
#8800ff,
#ff0088
) !important;
background-size: 400% 400% !important;
animation:
rainbowBackground 4s ease infinite,
rainbowBorder 2s linear infinite !important;
color: white !important;
border: 2px solid !important;
border-radius: 15px !important;
box-shadow: 0 0 20px rgba(255, 255, 255, 0.3) !important;
}
.rainbowButton {
background: linear-gradient(
45deg,
#ff0000,
#ff8800,
#ffff00,
#88ff00,
#00ff88,
#00ffff,
#0088ff,
#8800ff,
#ff0088
) !important;
background-size: 300% 300% !important;
animation:
rainbowBackground 2s ease infinite,
rainbowBorder 1s linear infinite !important;
border: 2px solid !important;
color: white !important;
border-radius: 8px !important;
transition: all 0.3s ease !important;
font-weight: bold !important;
}
.rainbowButton:hover {
transform: scale(1.05) !important;
animation:
rainbowBackground 1s ease infinite,
rainbowBorder 0.5s linear infinite,
rainbowPulse 0.5s ease infinite !important;
box-shadow: 0 0 25px rgba(255, 255, 255, 0.6) !important;
}
.rainbowInput {
background: linear-gradient(
90deg,
#ff0000,
#ff8800,
#ffff00,
#88ff00,
#00ff88,
#00ffff,
#0088ff,
#8800ff,
#ff0088
) !important;
background-size: 300% 300% !important;
animation:
rainbowBackground 2.5s ease infinite,
rainbowBorder 1.5s linear infinite !important;
border: 2px solid !important;
color: white !important;
border-radius: 8px !important;
}
.rainbowInput::placeholder {
color: rgba(255, 255, 255, 0.8) !important;
}
.rainbowText {
animation: rainbowText 3s linear infinite !important;
font-weight: bold !important;
text-shadow: 0 0 10px currentColor !important;
}
.rainbowSegmentedControl {
background: linear-gradient(
45deg,
#ff0000,
#ff8800,
#ffff00,
#88ff00,
#00ff88,
#00ffff,
#0088ff,
#8800ff,
#ff0088
) !important;
background-size: 400% 400% !important;
animation:
rainbowBackground 3s ease infinite,
rainbowBorder 2s linear infinite !important;
border: 2px solid !important;
border-radius: 12px !important;
padding: 4px !important;
}
.rainbowPaper {
background: linear-gradient(
90deg,
#00ffff,
#0088ff,
#8800ff,
#ff0088
) !important;
background-size: 100% 100% !important;
animation:
rainbowBackground 3.5s ease infinite,
rainbowBorder 2s linear infinite !important;
border: 2px solid !important;
color: white !important;
border-radius: 12px !important;
}
/* Easter egg notification */
.rainbowNotification {
position: fixed !important;
top: 20px !important;
right: 20px !important;
background: linear-gradient(
45deg,
#ffff00,
#88ff00,
#00ff88,
#00ffff
) !important;
background-size: 300% 300% !important;
animation:
rainbowBackground 1s ease infinite,
rainbowBorder 0.5s linear infinite !important;
color: white !important;
padding: 15px 20px !important;
border-radius: 25px !important;
font-weight: bold !important;
font-size: 16px !important;
z-index: 10000 !important;
border: 2px solid white !important;
box-shadow: 0 0 20px rgba(255, 255, 255, 0.8) !important;
user-select: none !important;
pointer-events: none !important;
}
/* Specific component overrides */
.rainbowMode [data-mantine-color-scheme] {
background: linear-gradient(
-45deg,
#ff0000,
#ff8800,
#ffff00,
#88ff00,
#00ff88,
#00ffff,
#0088ff,
#8800ff,
#ff0088,
#ff0000
) !important;
background-size: 400% 400% !important;
animation: rainbowBackground 3s ease infinite !important;
}
/* Make all buttons rainbow in rainbow mode */
.rainbowMode button {
background: linear-gradient(
45deg,
#ffff00,
#88ff00,
#00ff88,
#00ffff
) !important;
background-size: 100% 100% !important;
animation: rainbowBackground 2s ease infinite !important;
border: 2px solid !important;
animation:
rainbowBackground 2s ease infinite,
rainbowBorder 1.5s linear infinite !important;
color: white !important;
font-weight: bold !important;
}
/* Make all inputs rainbow in rainbow mode */
.rainbowMode input,
.rainbowMode select,
.rainbowMode textarea {
background: linear-gradient(
90deg,
#ffff00,
#88ff00,
#00ff88,
#00ffff
) !important;
background-size: 100% 100% !important;
animation: rainbowBackground 2.5s ease infinite !important;
border: 2px solid !important;
animation:
rainbowBackground 2.5s ease infinite,
rainbowBorder 1.5s linear infinite !important;
color: white !important;
}
/* Rainbow text class */
.rainbowText {
animation: rainbowText 3s linear infinite !important;
font-weight: bold !important;
text-shadow: 0 0 10px currentColor !important;
}
/* Make all text rainbow */
.rainbowMode h1,
.rainbowMode h2,
.rainbowMode h3,
.rainbowMode h4,
.rainbowMode h5,
.rainbowMode h6 {
animation: rainbowText 3s linear infinite !important;
font-weight: bold !important;
}
@@ -0,0 +1,24 @@
/* Import minimal theme variables */
@import "./theme.css";
@layer base {
@tailwind base;
}
@layer components {
@tailwind components;
}
@layer utilities {
@tailwind utilities;
}
@layer utilities {
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.no-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
}
File diff suppressed because it is too large Load Diff
+35
View File
@@ -0,0 +1,35 @@
// Centralized z-index constants for new usages added in this branch.
// Keep values identical to their original inline usages.
export const Z_INDEX_FULLSCREEN_SURFACE = 1000;
export const Z_INDEX_OVER_FULLSCREEN_SURFACE = 1300;
export const Z_ANALYTICS_MODAL = 1301;
// Config/Settings modal - should appear above analytics modal when navigating from onboarding
export const Z_INDEX_CONFIG_MODAL = 1400;
export const Z_INDEX_FILE_MANAGER_MODAL = 1200;
export const Z_INDEX_OVER_FILE_MANAGER_MODAL = 1300;
export const Z_INDEX_AUTOMATE_MODAL = 1100;
// Dropdowns/Popovers inside automation modals need to be above the modal
export const Z_INDEX_AUTOMATE_DROPDOWN = 1200;
// page editor Zindexes
export const Z_INDEX_HOVER_ACTION_MENU = 100;
export const Z_INDEX_SELECTION_BOX = 1000;
export const Z_INDEX_DROP_INDICATOR = 1001;
export const Z_INDEX_DRAG_BADGE = 1001;
// Modal that appears on top of config modal (e.g., restart confirmation, update modal)
export const Z_INDEX_OVER_CONFIG_MODAL = 2000;
// Sign-in modal — must appear above all app UI including config and analytics modals
export const Z_INDEX_SIGN_IN_MODAL = 9000;
// Toast notifications and error displays - Always on top (higher than rainbow theme at 10000)
export const Z_INDEX_TOAST = 10001;
// Signature preview overlays inside the PDF viewer
export const Z_INDEX_SIGNATURE_DRAG_BLOCKER = 999;
export const Z_INDEX_SIGNATURE_OVERLAY = 1000;
export const Z_INDEX_SIGNATURE_OVERLAY_HANDLE = 1001;
export const Z_INDEX_SIGNATURE_OVERLAY_DELETE = 1002;