mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-17 11:45:05 +02:00
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:
co-authored by
Claude Opus 4.7
parent
48027ee9d6
commit
0a50e765b7
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
Reference in New Issue
Block a user