diff --git a/CLAUDE.md b/CLAUDE.md index aacb70d..2ae3a8e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,57 +1,84 @@ -# Jey Theme +# CLAUDE.md -Frappe theme override app. Custom UI/UX for ERPNext desk. +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## What this app is + +Frappe/ERPNext v15 app that does three things: +1. Overrides the desk UI with a multi-theme visual system (CSS + JS bundle). +2. Hides the **Quality Management** and **Subcontracting** modules app-wide (URL/API/bootinfo/permissions). +3. Maintains a custom **Taxes Az** workspace on every migrate. + +Installed into `frappe-bench` as a normal app. Python code is at `jey_theme/` (Frappe app package). Frontend assets live at `jey_theme/public/{css,js}`. + +## Commands + +Run from `frappe-bench/` (the bench root), not this app dir. + +- `bench build --app jey_theme` — rebuild JS bundle after editing `jey_theme/public/js/jey_theme.js`. +- CSS-only changes: no build needed, just hard-reload the browser. +- `bench migrate` — runs the `after_migrate` hook that rebuilds the Taxes Az workspace from `setup/taxes_workspace.py`. +- `bench execute jey_theme.setup.taxes_workspace.setup` — re-run the workspace setup without a full migrate. +- `bench restart` — reload Python workers after editing `access_control.py` or `hooks.py`. +- No test suite, no linter config in this repo. ## Architecture -### Multi-theme system +### Python: access control (`jey_theme/access_control.py` + `hooks.py`) -The app supports multiple visual themes via `data-jey-theme` attribute on ``. +Goal: make blocked modules invisible and unreachable for every user, including Administrator. -- Themes: **chrome** (metallic rings), **modern** (frosted glass) -- Theme is stored in `localStorage("jey-theme")` and set on page load -- Default theme: `chrome` -- No dark/light variants — each theme is self-contained -- Switching themes rebuilds icon DOM with per-theme SVGs +- `BLOCKED_MODULES` / `BLOCKED_DOCTYPES_EXTRA` — edit these frozensets to change what's blocked. +- Three defense layers wired in `hooks.py`: + - `before_request` — blocks `/api/resource/`, `/app/`, and form_dict-based calls at the HTTP boundary (catches Administrator, who bypasses `has_permission`). + - `has_permission = {"*": ...}` — per-doc deny for non-admin users who have role access. + - `extend_bootinfo` — strips blocked items from `allowed_modules`, `modules`, `user.can_*`, `workspaces.pages`, `workspace_sidebar_item`, `module_wise_workspaces`, `app_data`, `desktop_icons`, etc., so the client router/sidebar never sees them. +- Slug/doctype/workspace sets are cached on `frappe.local` per-request. +- When adding a new block vector: extend `extend_bootinfo` rather than relying only on `has_permission`, because the client has many independent boot-derived UIs. -### File structure +### Python: Taxes Az workspace (`jey_theme/setup/taxes_workspace.py`) -``` -css/ - shared.css — checkboxes, icon animations, base desktop-icon sizing, theme switcher UI - theme_chrome.css — chrome theme visuals - theme_modern.css — modern theme visuals -js/ - jey_theme.js — theme init, per-theme icon maps (THEME_ICONS), DOM building, theme switcher override -public/html/ - erpnext_chrome_menu_v2(15).html — reference design for chrome theme -``` +Idempotent setup run via `after_migrate`. -### Adding a new theme +- Builds a `Workspace` named **Taxes Az** with three cards (Declarations, Setup, Tools), a `Workspace Sidebar` listing every taxes_az doctype, and a `Desktop Icon` that routes via the sidebar. +- The doctype list is a **static snapshot** in `DECLARATIONS_DOCTYPES` / `SETUP_DOCTYPES` / `TOOLS_DOCTYPES`. Adding a DocType to the `taxes_az` app does NOT auto-include it — append to the tuple and re-migrate. +- `_cleanup_obsolete()` removes legacy docs owned by this app (currently `"Taxes"`). Only touches records where `app == "jey_theme"` — never deletes ERPNext/other-app docs. -1. Create `css/theme_mytheme.css` with `[data-jey-theme="mytheme"]` selectors -2. Prefix keyframes with theme name: `jey-mytheme-*` -3. Add icon set in `THEME_ICONS.mytheme` in `jey_theme.js` (falls back to chrome icons if key missing) -4. Add entry to `JEY_THEMES` array in the switcher section -5. Add CSS file to `app_include_css` list in `hooks.py` +### Frontend: multi-theme system -### Theme scope +Bundle entry: `jey_theme/public/js/jey_theme.js`. CSS: `jey_theme/public/css/{shared,theme_chrome,theme_modern}.css`. All four are loaded via `app_include_css` / `app_include_js` in `hooks.py` for both desk and web contexts. -Themes can change **everything** — not just icons: -- CSS (`[data-jey-theme="..."]`): layout, positioning, colors, fonts, visibility, animations — any element on any page -- JS (`jeyRebuildIcons` / theme switch hooks): DOM restructuring, moving elements between containers, adding/removing components -- Per-theme SVG icon sets, per-theme DOM structure — all supported +- Theme selector lives in `data-jey-theme` on ``, stored in `localStorage("jey-theme")`. Default: `chrome`. Set before first paint by an IIFE at the top of `jey_theme.js`. +- Themes supported: **chrome** (metallic rings), **modern** (frosted glass). No dark/light variants — each theme is self-contained. +- Theme-specific CSS MUST be wrapped in `[data-jey-theme="themename"]`. Keyframes MUST be prefixed `jey--*` to avoid cross-theme name collisions. +- Shared CSS (checkboxes, icon base sizing, switcher UI, column-resize rules) lives in `shared.css` without theme selectors. -### Desktop icons +### Frontend: per-theme icons -- JS replaces `` with inline `` per current theme -- Each theme has its own `THEME_ICONS[themeName]` map with unique SVG paths -- Folder icons (`.folder-icon`) are converted to regular themed icons -- SVGs can have `cls` (e.g. `ico-buying`) for shared animations -- On theme switch, `jeyRebuildIcons()` tears down and rebuilds all icon DOM +- `THEME_ICONS[themeName]` in `jey_theme.js` maps icon keys to inline SVG path strings. Missing keys fall back to `THEME_ICONS.chrome`, then `_fallback`. +- JS replaces `` / `.folder-icon` with inline `` per current theme. +- `window.jeyRebuildIcons()` tears down and rebuilds all icon DOM — called on theme switch. +- SVGs may carry a `cls` (e.g. `ico-buying`) for shared CSS animations. + +### Frontend: early-paint tricks in `jey_theme.js` + +The top IIFE runs before paint to avoid FOUC: +- Sets `data-jey-theme` immediately. +- Defaults `container_fullwidth = "true"` on fresh install. +- Reads all `jey-col-widths::` localStorage keys and injects a `