The Base64 Encoder / Decoder at /tools/(tools:base64) (Base64Component in @spikersoft/feature-dev-tools-encoding) currently uses a header block with slide toggles and stroked buttons for help/tour, plus a separate mode section for Encode/Decode. It does not use the same CDK menubar pattern as the JavaScript playground’s app-js-debugger-toolbar (libraries/features/dev-tools-javascript-runner/src/lib/js-debugger-toolbar.component.* — editor-menubar, cdkMenuBar, menubar-trigger, menubar-spacer, etc.; see also Gitea #32 in code comments).
We want a single top menubar for Base64 that feels consistent with those tools and with the JSON QuickType input bar (/tools/(tools:json), quick-type.component.html — cdkMenuBar + File / Edit / Format dropdowns).
Desired layout
lib-tool-file-menu (@spikersoft/platform-tool-file-menu — ToolFileMenuComponent) under a top-level File menu trigger, with the standard four operations (same contract as RegEx and other tools):
Save to Browser
Download to Device
Load from Browser
Load from Device
Host provides ToolStorageConfig, serialize(), and handles ToolFileMenuEvent (loaded → apply string into input / state; saved optional extra UX). Reference implementations: reg-ex.component.ts (ToolFileMenuComponent + onFileMenuEvent), and the JSON tool’s File dropdown UX in quick-type.component.html (manual menu today — prefer the shared component for Base64 for consistency with RegEx).
Encode / Decode as root-level controls on the menubar (e.g. mat-button-toggle-group or two menubar-trigger actions), not buried only in the old standalone “mode section” — visually comparable to primary actions on js-debugger-toolbar.
Toggle Help and Guided Tour moved into the menubar, pulled right (after menubar-spacer), mirroring the right-aligned cluster pattern used on the debugger toolbar (status / trailing controls). Today these live in base64.component.htmlheader-actions (mat-slide-toggle + mat-stroked-button).
Base64 shows an editor-menubar (cdkMenuBar) with File using lib-tool-file-menu and the four standard file operations.
Encode and Decode are visible as root-level menubar controls.
Toggle Help and Guided Tour are in the menubar, right-aligned (spacer before them).
Existing intro.js / IntroTourProvider / data-tour anchors updated or preserved so tours still target the right elements.
@nx/enforce-module-boundaries: feature-dev-tools-encoding may depend on platform-tool-file-menu and platform-tool-storage as needed.
Unit tests updated (base64.component.spec.ts) for any new wiring.
Notes
Pick a dedicated ToolStorageConfigdbName / file naming for Base64 so saves do not collide with other tools.
Serialization shape: at minimum persist the text input, mode (encode | decode), and any flags the tool already tracks (liveMode, fromFile / file-derived state if still supported); document briefly in README.md for dev-tools-encoding if the payload is non-obvious.
## Summary
The Base64 Encoder / Decoder at `/tools/(tools:base64)` (`Base64Component` in `@spikersoft/feature-dev-tools-encoding`) currently uses a **header block** with slide toggles and stroked buttons for help/tour, plus a separate **mode section** for Encode/Decode. It does **not** use the same **CDK menubar** pattern as the JavaScript playground’s `app-js-debugger-toolbar` (`libraries/features/dev-tools-javascript-runner/src/lib/js-debugger-toolbar.component.*` — `editor-menubar`, `cdkMenuBar`, `menubar-trigger`, `menubar-spacer`, etc.; see also Gitea #32 in code comments).
We want a **single top menubar** for Base64 that feels consistent with those tools and with the JSON QuickType input bar (`/tools/(tools:json)`, `quick-type.component.html` — `cdkMenuBar` + File / Edit / Format dropdowns).
## Desired layout
1. **`lib-tool-file-menu`** (`@spikersoft/platform-tool-file-menu` — `ToolFileMenuComponent`) under a top-level **File** menu trigger, with the standard four operations (same contract as RegEx and other tools):
- Save to Browser
- Download to Device
- Load from Browser
- Load from Device
Host provides `ToolStorageConfig`, `serialize()`, and handles `ToolFileMenuEvent` (`loaded` → apply string into input / state; `saved` optional extra UX). Reference implementations: `reg-ex.component.ts` (`ToolFileMenuComponent` + `onFileMenuEvent`), and the JSON tool’s File dropdown UX in `quick-type.component.html` (manual menu today — prefer the **shared** component for Base64 for consistency with RegEx).
2. **Encode / Decode** as **root-level** controls on the menubar (e.g. `mat-button-toggle-group` or two `menubar-trigger` actions), **not** buried only in the old standalone “mode section” — visually comparable to primary actions on `js-debugger-toolbar`.
3. **Toggle Help** and **Guided Tour** moved **into the menubar**, **pulled right** (after `menubar-spacer`), mirroring the right-aligned cluster pattern used on the debugger toolbar (status / trailing controls). Today these live in `base64.component.html` `header-actions` (`mat-slide-toggle` + `mat-stroked-button`).
## References (code)
- Route: `projects/spikersoft/src/routes.ts` — `path: "base64"`, `Base64Component`.
- Current UI: `libraries/features/dev-tools-encoding/src/lib/base64/base64.component.{ts,html,scss}`.
- Menubar pattern: `libraries/features/dev-tools-javascript-runner/src/lib/js-debugger-toolbar.component.html` + `_editor-menubar.scss` / `editor-menubar` partial from theme.
- JSON tool menubar: `libraries/features/dev-tools-quick-type/src/lib/quick-type.component.html` (`data-tour="json-input-menu"`).
- Shared file menu: `libraries/platform/tool-file-menu/src/lib/tool-file-menu.component.ts`.
## Acceptance criteria
- [ ] Base64 shows an `editor-menubar` (`cdkMenuBar`) with **File** using `lib-tool-file-menu` and the four standard file operations.
- [ ] **Encode** and **Decode** are visible as root-level menubar controls.
- [ ] **Toggle Help** and **Guided Tour** are in the menubar, **right-aligned** (spacer before them).
- [ ] Existing intro.js / `IntroTourProvider` / `data-tour` anchors updated or preserved so tours still target the right elements.
- [ ] `@nx/enforce-module-boundaries`: `feature-dev-tools-encoding` may depend on `platform-tool-file-menu` and `platform-tool-storage` as needed.
- [ ] Unit tests updated (`base64.component.spec.ts`) for any new wiring.
## Notes
- Pick a dedicated `ToolStorageConfig` `dbName` / file naming for Base64 so saves do not collide with other tools.
- Serialization shape: at minimum persist the text input, mode (`encode` | `decode`), and any flags the tool already tracks (`liveMode`, `fromFile` / file-derived state if still supported); document briefly in `README.md` for `dev-tools-encoding` if the payload is non-obvious.
Implemented and shipped together with #93 — the two tools now share an identical menubar pattern.
What changed
Replaced the Base64 tool's stacked header-section (Toggle Help + Guided Tour) and standalone mode-section (Encode/Decode) with a single editor-menubar (cdkMenuBar) at the top of base64.component.html, mirroring the JS debugger toolbar / JSON QuickType / new JWT bar.
File is a lib-tool-file-menu on the left of the bar with the standard four operations. Backed by a dedicated ToolStorageConfig with dbName: "SpikerSoftBase64Storage" so saves never collide with the JWT sibling.
Encode / Decode are root-level mat-button-toggle controls on the menubar.
Toggle Help and Guided Tour are right-aligned after <span class="menubar-spacer">.
data-tour="base64-header" and data-tour="base64-mode" migrated to the menubar wrapper / toggle group respectively, so existing intro.js steps keep working.
Saved-file payload is a versioned { version: 1, mode, input, liveMode, showEducation } envelope. File-mode payloads (fromFile, fileEncoded) are intentionally NOT persisted — round-tripping a 5 MB data URL through IndexedDB / disk has weird semantics and balloons the saved snapshot. Loading a snapshot always lands the user in text mode; re-upload is a one-step recovery. Documented in the lib README under "Saved-file envelope convention".
Done in one pass to share the encoding-lib infrastructure (peer deps, styleIncludePaths, test target). The two tools' menubar markup is intentionally NOT extracted into a shared component — it's only ~20 lines of HTML, the controls have different mode labels/icons/order, and the future trajectories likely diverge (Base64 may want Text/File toggles in the bar; JWT may want Demo Token / claims toggle). Documented as a convention in the lib README rather than a generic component.
Tests
4 new tests in base64.component.spec.ts covering File menu integration: round-trip serialize+load, file-mode reset on load, non-JSON guard, no apply on saved events.
Implemented and shipped together with #93 — the two tools now share an identical menubar pattern.
**What changed**
- Replaced the Base64 tool's stacked `header-section` (Toggle Help + Guided Tour) and standalone `mode-section` (Encode/Decode) with a single `editor-menubar` (`cdkMenuBar`) at the top of `base64.component.html`, mirroring the JS debugger toolbar / JSON QuickType / new JWT bar.
- **File** is a `lib-tool-file-menu` on the left of the bar with the standard four operations. Backed by a dedicated `ToolStorageConfig` with `dbName: "SpikerSoftBase64Storage"` so saves never collide with the JWT sibling.
- **Encode** / **Decode** are root-level `mat-button-toggle` controls on the menubar.
- **Toggle Help** and **Guided Tour** are right-aligned after `<span class="menubar-spacer">`.
- `data-tour="base64-header"` and `data-tour="base64-mode"` migrated to the menubar wrapper / toggle group respectively, so existing intro.js steps keep working.
- Saved-file payload is a versioned `{ version: 1, mode, input, liveMode, showEducation }` envelope. **File-mode payloads (`fromFile`, `fileEncoded`) are intentionally NOT persisted** — round-tripping a 5 MB data URL through IndexedDB / disk has weird semantics and balloons the saved snapshot. Loading a snapshot always lands the user in text mode; re-upload is a one-step recovery. Documented in the lib README under "Saved-file envelope convention".
**Shared abstractions with #93**
Done in one pass to share the encoding-lib infrastructure (peer deps, `styleIncludePaths`, `test` target). The two tools' menubar markup is intentionally NOT extracted into a shared component — it's only ~20 lines of HTML, the controls have different mode labels/icons/order, and the future trajectories likely diverge (Base64 may want Text/File toggles in the bar; JWT may want Demo Token / claims toggle). Documented as a convention in the lib README rather than a generic component.
**Tests**
- 4 new tests in `base64.component.spec.ts` covering File menu integration: round-trip serialize+load, file-mode reset on load, non-JSON guard, no apply on `saved` events.
- Existing 28 tests preserved. `nx test feature-dev-tools-encoding` passes 60/60 (Base64 + JWT combined).
**Verification**
- `nx build feature-dev-tools-encoding` ✅
- `nx lint feature-dev-tools-encoding` ✅
- `nx test feature-dev-tools-encoding` ✅ 60/60
Closing.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
The Base64 Encoder / Decoder at
/tools/(tools:base64)(Base64Componentin@spikersoft/feature-dev-tools-encoding) currently uses a header block with slide toggles and stroked buttons for help/tour, plus a separate mode section for Encode/Decode. It does not use the same CDK menubar pattern as the JavaScript playground’sapp-js-debugger-toolbar(libraries/features/dev-tools-javascript-runner/src/lib/js-debugger-toolbar.component.*—editor-menubar,cdkMenuBar,menubar-trigger,menubar-spacer, etc.; see also Gitea #32 in code comments).We want a single top menubar for Base64 that feels consistent with those tools and with the JSON QuickType input bar (
/tools/(tools:json),quick-type.component.html—cdkMenuBar+ File / Edit / Format dropdowns).Desired layout
lib-tool-file-menu(@spikersoft/platform-tool-file-menu—ToolFileMenuComponent) under a top-level File menu trigger, with the standard four operations (same contract as RegEx and other tools):Host provides
ToolStorageConfig,serialize(), and handlesToolFileMenuEvent(loaded→ apply string into input / state;savedoptional extra UX). Reference implementations:reg-ex.component.ts(ToolFileMenuComponent+onFileMenuEvent), and the JSON tool’s File dropdown UX inquick-type.component.html(manual menu today — prefer the shared component for Base64 for consistency with RegEx).Encode / Decode as root-level controls on the menubar (e.g.
mat-button-toggle-groupor twomenubar-triggeractions), not buried only in the old standalone “mode section” — visually comparable to primary actions onjs-debugger-toolbar.Toggle Help and Guided Tour moved into the menubar, pulled right (after
menubar-spacer), mirroring the right-aligned cluster pattern used on the debugger toolbar (status / trailing controls). Today these live inbase64.component.htmlheader-actions(mat-slide-toggle+mat-stroked-button).References (code)
projects/spikersoft/src/routes.ts—path: "base64",Base64Component.libraries/features/dev-tools-encoding/src/lib/base64/base64.component.{ts,html,scss}.libraries/features/dev-tools-javascript-runner/src/lib/js-debugger-toolbar.component.html+_editor-menubar.scss/editor-menubarpartial from theme.libraries/features/dev-tools-quick-type/src/lib/quick-type.component.html(data-tour="json-input-menu").libraries/platform/tool-file-menu/src/lib/tool-file-menu.component.ts.Acceptance criteria
editor-menubar(cdkMenuBar) with File usinglib-tool-file-menuand the four standard file operations.IntroTourProvider/data-touranchors updated or preserved so tours still target the right elements.@nx/enforce-module-boundaries:feature-dev-tools-encodingmay depend onplatform-tool-file-menuandplatform-tool-storageas needed.base64.component.spec.ts) for any new wiring.Notes
ToolStorageConfigdbName/ file naming for Base64 so saves do not collide with other tools.encode|decode), and any flags the tool already tracks (liveMode,fromFile/ file-derived state if still supported); document briefly inREADME.mdfordev-tools-encodingif the payload is non-obvious.Implemented and shipped together with #93 — the two tools now share an identical menubar pattern.
What changed
header-section(Toggle Help + Guided Tour) and standalonemode-section(Encode/Decode) with a singleeditor-menubar(cdkMenuBar) at the top ofbase64.component.html, mirroring the JS debugger toolbar / JSON QuickType / new JWT bar.lib-tool-file-menuon the left of the bar with the standard four operations. Backed by a dedicatedToolStorageConfigwithdbName: "SpikerSoftBase64Storage"so saves never collide with the JWT sibling.mat-button-togglecontrols on the menubar.<span class="menubar-spacer">.data-tour="base64-header"anddata-tour="base64-mode"migrated to the menubar wrapper / toggle group respectively, so existing intro.js steps keep working.{ version: 1, mode, input, liveMode, showEducation }envelope. File-mode payloads (fromFile,fileEncoded) are intentionally NOT persisted — round-tripping a 5 MB data URL through IndexedDB / disk has weird semantics and balloons the saved snapshot. Loading a snapshot always lands the user in text mode; re-upload is a one-step recovery. Documented in the lib README under "Saved-file envelope convention".Shared abstractions with #93
Done in one pass to share the encoding-lib infrastructure (peer deps,
styleIncludePaths,testtarget). The two tools' menubar markup is intentionally NOT extracted into a shared component — it's only ~20 lines of HTML, the controls have different mode labels/icons/order, and the future trajectories likely diverge (Base64 may want Text/File toggles in the bar; JWT may want Demo Token / claims toggle). Documented as a convention in the lib README rather than a generic component.Tests
base64.component.spec.tscovering File menu integration: round-trip serialize+load, file-mode reset on load, non-JSON guard, no apply onsavedevents.nx test feature-dev-tools-encodingpasses 60/60 (Base64 + JWT combined).Verification
nx build feature-dev-tools-encoding✅nx lint feature-dev-tools-encoding✅nx test feature-dev-tools-encoding✅ 60/60Closing.