Skip to content

feat: Adicionei a nova feature de dark-mode#669

Open
Marcio-Carvalho27 wants to merge 1 commit into
brmodeloweb:mainfrom
Marcio-Carvalho27:feature/dark-mode
Open

feat: Adicionei a nova feature de dark-mode#669
Marcio-Carvalho27 wants to merge 1 commit into
brmodeloweb:mainfrom
Marcio-Carvalho27:feature/dark-mode

Conversation

@Marcio-Carvalho27
Copy link
Copy Markdown

@Marcio-Carvalho27 Marcio-Carvalho27 commented May 6, 2026

Dark Mode

Resumo

Este PR adiciona suporte a dark mode na aplicação e um seletor de tema no menu de perfil do usuário.

O que foi feito

  • Criação de um ThemeService para salvar o tema selecionado no localStorage;
  • Registro do serviço no módulo principal da aplicação;
  • Aplicação automática do tema salvo ao iniciar a aplicação;
  • Adição de um seletor claro/escuro no dropdown do perfil;
  • Inclusão das traduções em português e inglês;
  • Ajustes de estilos para dark mode em:
    • navbar;
    • dropdowns;
    • modais;
    • tabelas;
    • formulários;
    • workspace do editor.
  • Ajustes visuais nos diagramas do modelo conceitual e lógico para melhorar contraste e legibilidade no tema escuro.

Arquivos alterados

  • app/angular/service/themeService.js
  • app/angular/index.js
  • app/angular/components/dropdownIcon.js
  • app/angular/components/dropdownIcon.html
  • app/i18n/languages/pt_BR.js
  • app/i18n/languages/en.js
  • app/sass/colors.scss
  • app/sass/mainHeader.scss
  • app/sass/structure.scss
  • app/sass/joint-custom.scss

Validação

  • Executado npx webpack --progress --color;
  • Compilação concluída sem erros.

Observações

  • O tema selecionado é salvo usando a chave brmw-theme;
  • O dark mode utiliza a classe theme-dark no body, sem alterar o comportamento atual do tema claro.

Summary by CodeRabbit

  • New Features
    • Added Light and Dark theme selector to the application dropdown menu with automatic persistence of user theme preference
    • Selected theme is applied immediately and automatically restored when the application starts
    • Implemented comprehensive dark mode styling across the entire interface including dialogs, forms, diagrams, and interactive elements using an HSL-based design token system

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

📝 Walkthrough

Walkthrough

This PR adds a theme system enabling users to select between Light and Dark modes. It introduces a ThemeService for theme persistence and application, integrates theme selection UI into the dropdown menu, applies dark-theme styling across components, and provides localized UI labels.

Changes

Theme System Implementation

Layer / File(s) Summary
Service Foundation
app/angular/service/themeService.js
New ThemeService manages theme state with localStorage persistence. Exposes getTheme(), applyTheme(theme), and toggleTheme() methods that toggle body CSS classes (theme-dark/theme-light) and persist the selection.
Component Integration
app/angular/components/dropdownIcon.js, app/angular/components/dropdownIcon.html
dropdownIcon controller injects ThemeService, initializes theme property, and adds setTheme(theme) method. Template adds Light/Dark theme options in dropdown with active-state highlighting and separating divider.
Module Initialization
app/angular/index.js
Registers themeService dependency and updates app.run block to inject ThemeService and apply the current theme at startup.
Dark Theme Styling
app/sass/colors.scss, app/sass/structure.scss
Define body.theme-dark color variable overrides (brand, borders, grayscale, accents) and component-specific styles (dropdowns, modals, tables, forms, editors) for dark mode appearance.
Component-Specific Dark Styling
app/sass/joint-custom.scss, app/sass/mainHeader.scss
JointJS diagram components and theme menu UI (.theme-menu-item, .theme-toggle, .active button states) styled for dark theme; menu layout uses CSS grid.
Localization
app/i18n/languages/en.js, app/i18n/languages/pt_BR.js
Add English and Portuguese translations for Theme, Light, and Dark UI labels; correct English Color label entry.

Sequence Diagram

sequenceDiagram
    actor User
    participant UI as DropdownIcon Component
    participant Service as ThemeService
    participant Storage as localStorage
    participant DOM as Document Body

    User->>UI: Click "Light" or "Dark" button
    UI->>Service: setTheme('light'/'dark')
    Service->>Storage: Write to 'brmw-theme' key
    Service->>DOM: Toggle theme-light/theme-dark class
    DOM->>DOM: Apply dark theme CSS variables & styles
    Service-->>UI: Return updated theme
    UI->>UI: Update active button state
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A rabbit hops through light and dark,
Themes dance where colors leave their mark,
Service stores what hearts prefer,
Light by day, dark when stars occur!
✨🌙

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The PR title mentions 'dark-mode' which is the main feature, but uses vague phrasing ('Adicionei a nova feature') that lacks specificity and doesn't clearly summarize the changes. Improve the title to be more specific and descriptive in English. Example: 'feat: Add dark mode theme support with localStorage persistence' or similar, focusing on the key technical change.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
app/angular/service/themeService.js (1)

28-31: toggleTheme() lacks state sync with dropdown controller

toggleTheme() is defined in the service but not currently called elsewhere in the codebase. However, the method exposes a design vulnerability: if invoked from outside the component (e.g., a future keyboard shortcut handler), it will apply the new theme to the DOM without updating ctrl.theme in dropdownIcon.js, causing the dropdown highlight to display stale state. While this is not a live bug today, the exported method should either be removed or updated to sync ctrl.theme when the theme changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/angular/service/themeService.js` around lines 28 - 31, toggleTheme
currently applies the new theme to the DOM but doesn't update dropdownIcon's
ctrl.theme, risking stale UI; either remove toggleTheme from the service or
change it to synchronise state by notifying listeners after applying the theme.
Fix by modifying service.toggleTheme (using service.getTheme and
service.applyTheme) to emit a theme change notification (e.g.
$rootScope.$broadcast('theme:changed', nextTheme) or call a registered callback)
immediately after applyTheme resolves, and update dropdownIcon.js to listen for
that 'theme:changed' event and set ctrl.theme accordingly; alternatively make
toggleTheme accept an optional callback to update ctrl.theme and call it with
nextTheme.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/angular/components/dropdownIcon.html`:
- Around line 9-22: The two theme toggle buttons (the elements using
$ctrl.setTheme(...) and ng-class that checks $ctrl.theme) lack an ARIA pressed
state; update both button elements to emit aria-pressed reflecting whether
$ctrl.theme equals 'light' or 'dark' (use ng-attr-aria-pressed with an
expression that produces "true"/"false") so screen readers can announce the
active toggle while leaving existing ng-class and $ctrl.setTheme intact.

In `@app/angular/service/themeService.js`:
- Around line 13-15: getTheme() currently returns any string stored under
storageKey which can initialize ctrl.theme to invalid values; update
service.getTheme to validate the retrieved value against the allowed themes
(themes.light and themes.dark) and return a safe default (e.g., themes.light)
when the stored value is not one of those two, ensuring components like
dropdownIcon.js (ctrl.theme) only receive "light" or "dark".

---

Nitpick comments:
In `@app/angular/service/themeService.js`:
- Around line 28-31: toggleTheme currently applies the new theme to the DOM but
doesn't update dropdownIcon's ctrl.theme, risking stale UI; either remove
toggleTheme from the service or change it to synchronise state by notifying
listeners after applying the theme. Fix by modifying service.toggleTheme (using
service.getTheme and service.applyTheme) to emit a theme change notification
(e.g. $rootScope.$broadcast('theme:changed', nextTheme) or call a registered
callback) immediately after applyTheme resolves, and update dropdownIcon.js to
listen for that 'theme:changed' event and set ctrl.theme accordingly;
alternatively make toggleTheme accept an optional callback to update ctrl.theme
and call it with nextTheme.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 27b0b660-5f2a-4757-994b-15aac7711a0e

📥 Commits

Reviewing files that changed from the base of the PR and between b6138fe and 69e760d.

📒 Files selected for processing (10)
  • app/angular/components/dropdownIcon.html
  • app/angular/components/dropdownIcon.js
  • app/angular/index.js
  • app/angular/service/themeService.js
  • app/i18n/languages/en.js
  • app/i18n/languages/pt_BR.js
  • app/sass/colors.scss
  • app/sass/joint-custom.scss
  • app/sass/mainHeader.scss
  • app/sass/structure.scss

Comment on lines +9 to +22
<button
type="button"
ng-class="{active: $ctrl.theme === 'light'}"
ng-click="$ctrl.setTheme('light')"
>
{{ 'Light' | translate }}
</button>
<button
type="button"
ng-class="{active: $ctrl.theme === 'dark'}"
ng-click="$ctrl.setTheme('dark')"
>
{{ 'Dark' | translate }}
</button>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add aria-pressed so screen readers can announce the active theme.

Per the WAI-ARIA Authoring Practices Guide, if the button is a toggle button, it must carry an aria-pressed state. Currently only the visual .active class communicates which theme is selected; state changes fail completely when you rely on visual-only indicators like colour changes.

♿ Proposed fix — add aria-pressed to both buttons
 				<button
 					type="button"
 					ng-class="{active: $ctrl.theme === 'light'}"
+					ng-attr-aria-pressed="{{ $ctrl.theme === 'light' }}"
 					ng-click="$ctrl.setTheme('light')"
 				>
 					{{ 'Light' | translate }}
 				</button>
 				<button
 					type="button"
 					ng-class="{active: $ctrl.theme === 'dark'}"
+					ng-attr-aria-pressed="{{ $ctrl.theme === 'dark' }}"
 					ng-click="$ctrl.setTheme('dark')"
 				>
 					{{ 'Dark' | translate }}
 				</button>

ng-attr-aria-pressed is used instead of aria-pressed directly to emit the attribute with the correct boolean string ("true" / "false"), which AngularJS expression interpolation alone would leave as the JS boolean value.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<button
type="button"
ng-class="{active: $ctrl.theme === 'light'}"
ng-click="$ctrl.setTheme('light')"
>
{{ 'Light' | translate }}
</button>
<button
type="button"
ng-class="{active: $ctrl.theme === 'dark'}"
ng-click="$ctrl.setTheme('dark')"
>
{{ 'Dark' | translate }}
</button>
<button
type="button"
ng-class="{active: $ctrl.theme === 'light'}"
ng-attr-aria-pressed="{{ $ctrl.theme === 'light' }}"
ng-click="$ctrl.setTheme('light')"
>
{{ 'Light' | translate }}
</button>
<button
type="button"
ng-class="{active: $ctrl.theme === 'dark'}"
ng-attr-aria-pressed="{{ $ctrl.theme === 'dark' }}"
ng-click="$ctrl.setTheme('dark')"
>
{{ 'Dark' | translate }}
</button>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/angular/components/dropdownIcon.html` around lines 9 - 22, The two theme
toggle buttons (the elements using $ctrl.setTheme(...) and ng-class that checks
$ctrl.theme) lack an ARIA pressed state; update both button elements to emit
aria-pressed reflecting whether $ctrl.theme equals 'light' or 'dark' (use
ng-attr-aria-pressed with an expression that produces "true"/"false") so screen
readers can announce the active toggle while leaving existing ng-class and
$ctrl.setTheme intact.

Comment on lines +13 to +15
service.getTheme = () => {
return $window.localStorage.getItem(storageKey) || themes.light;
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

getTheme() returns an unvalidated localStorage value

If localStorage["brmw-theme"] holds anything other than "light" or "dark" (e.g., manual tampering or a future migration), ctrl.theme is initialized to that arbitrary string in dropdownIcon.js line 8. The dropdown ng-class comparison will silently match nothing, leaving both options un-highlighted even though applyTheme at startup normalizes and correctly sets the body class.

🛡️ Proposed fix — validate against known themes
 service.getTheme = () => {
-  return $window.localStorage.getItem(storageKey) || themes.light;
+  const stored = $window.localStorage.getItem(storageKey);
+  return Object.values(themes).includes(stored) ? stored : themes.light;
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
service.getTheme = () => {
return $window.localStorage.getItem(storageKey) || themes.light;
};
service.getTheme = () => {
const stored = $window.localStorage.getItem(storageKey);
return Object.values(themes).includes(stored) ? stored : themes.light;
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/angular/service/themeService.js` around lines 13 - 15, getTheme()
currently returns any string stored under storageKey which can initialize
ctrl.theme to invalid values; update service.getTheme to validate the retrieved
value against the allowed themes (themes.light and themes.dark) and return a
safe default (e.g., themes.light) when the stored value is not one of those two,
ensuring components like dropdownIcon.js (ctrl.theme) only receive "light" or
"dark".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant