Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
63dcbc7
style: TT-332 include Tailwind in global style file
JosueOb Sep 2, 2021
5a5f6f9
feat: TT-332 dark mode implementation
JosueOb Sep 3, 2021
b017fbd
style: TT-332 color palette
JosueOb Sep 6, 2021
2d648d7
test: TT-332 unit test on the dark mode component
JosueOb Sep 6, 2021
1e23038
fix: TT-216 add tabIndex attribute to materialDatePicker and to Date …
bytesantiago Sep 7, 2021
13fd98a
chore(release): 1.50.5 [skip ci]nn
semantic-release-bot Sep 7, 2021
c63a8a0
refactor: TT-332 application of Azure toggle function to display dark…
JosueOb Sep 8, 2021
8e1ec7e
style: TT-332 TW prefix added to the color palette
JosueOb Sep 8, 2021
181bc76
refactor: TT-332 changes in sidebar and dark mode components
JosueOb Sep 8, 2021
704ba0e
fix: TT-334 keep the sidebar item selected when the page is refreshed…
JosueOb Sep 9, 2021
0125ac6
chore(release): 1.50.6 [skip ci]nn
semantic-release-bot Sep 9, 2021
5ecda54
refactor: TT-332 changes to the button to change the page theme
JosueOb Sep 10, 2021
f6fd309
test: TT-332 unit test to check if the user has the dark-mode feature…
JosueOb Sep 11, 2021
ff1ded3
style: TT-332 include Tailwind in global style file
JosueOb Sep 2, 2021
419ff2b
feat: TT-332 dark mode implementation
JosueOb Sep 3, 2021
c4ac6f7
style: TT-332 color palette
JosueOb Sep 6, 2021
57f96d7
test: TT-332 unit test on the dark mode component
JosueOb Sep 6, 2021
1507382
refactor: TT-332 application of Azure toggle function to display dark…
JosueOb Sep 8, 2021
18997af
style: TT-332 TW prefix added to the color palette
JosueOb Sep 8, 2021
1ed1c33
refactor: TT-332 changes in sidebar and dark mode components
JosueOb Sep 8, 2021
b99fa46
refactor: TT-332 changes to the button to change the page theme
JosueOb Sep 10, 2021
1e2e392
test: TT-332 unit test to check if the user has the dark-mode feature…
JosueOb Sep 11, 2021
b8705dd
refactor: TT-332 changes in the unit test description of the dark mod…
JosueOb Sep 13, 2021
95d1ed3
refactor: TT-332 changes in the unit test description of the dark mod…
JosueOb Sep 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ import { TechnologyReportComponent } from './modules/technology-report/pages/tec
import { CalendarComponent } from './modules/time-entries/components/calendar/calendar.component';
import { DropdownComponent } from './modules/shared/components/dropdown/dropdown.component';
import { NgSelectModule } from '@ng-select/ng-select';
import { DarkModeComponent } from './modules/shared/components/dark-mode/dark-mode.component';

const maskConfig: Partial<IConfig> = {
validation: false,
Expand Down Expand Up @@ -140,6 +141,7 @@ const maskConfig: Partial<IConfig> = {
TechnologyReportTableComponent,
CalendarComponent,
DropdownComponent,
DarkModeComponent,
],
imports: [
NgxMaskModule.forRoot(maskConfig),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<button
type="button"
class="p-2 transition duration-150 ease-in-out bg-whiteTW rounded-md hover:bg-grayTW-lightest dark:bg-grayTW-dark dark:hover:bg-grayTW-darker dark:hover:bg-gray-700 hover:text-gray-700 focus:outline-none focus:bg-grayTW-lightest dark:focus:bg-grayTW-darker"
(click)="changeToDarkOrLightTheme()"
*ngIf="isFeatureToggleDarkModeActive"
>
<div *ngIf="isDarkTheme(); then sunIcon; else moonIcon"></div>
<ng-template #moonIcon><img class="w-5 h-5" src="assets/icons/moon.svg" alt="moon icon" /></ng-template>
<ng-template #sunIcon><img class="w-5 h-5" src="assets/icons/sun.svg" alt="sun icon" /></ng-template>
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
import { of } from 'rxjs';
import { delay } from 'rxjs/operators';
import { FeatureToggleGeneralService } from '../../feature-toggles/feature-toggle-general/feature-toggle-general.service';
import { FeatureToggleModel } from '../../feature-toggles/feature-toggle.model';
import { FeatureFilterModel } from '../../feature-toggles/filters/feature-filter.model';
import { DarkModeComponent } from './dark-mode.component';

describe('DarkModeComponent', () => {
let component: DarkModeComponent;
let fixture: ComponentFixture<DarkModeComponent>;
let html: HTMLElement;
let featureToggleGeneralService: FeatureToggleGeneralService;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [DarkModeComponent],
}).compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(DarkModeComponent);
component = fixture.componentInstance;
html = document.documentElement;
featureToggleGeneralService = TestBed.inject(FeatureToggleGeneralService);
fixture.detectChanges();
});

afterEach(() => {
localStorage.removeItem('theme');
});

it('should be created', () => {
expect(component).toBeTruthy();
});

it('should be light the default theme', () => {
expect(component.theme).toEqual('light');
});

it('should change the value of the theme property if it exists in the local storage', () => {
localStorage.setItem('theme', 'dark');
component.checkThemeInLocalStorage();
expect(component.theme).toEqual('dark');
});

it('should be light theme if it does not exist in local storage', () => {
component.checkThemeInLocalStorage();
expect(component.theme).toEqual('light');
});

it('should be light theme if only the theme property exists in local storage and not its value', () => {
localStorage.setItem('theme', '');
component.checkThemeInLocalStorage();
expect(component.theme).toEqual('light');
});

it('should switch to dark theme if the theme property is light and vice versa', () => {
component.theme = component.setTheme();
expect(component.theme).toEqual('dark');
component.theme = component.setTheme();
expect(component.theme).toEqual('light');
});

it('should add the dark class in the html tag to apply dark mode', () => {
component.theme = 'dark';
component.addOrRemoveDarkMode();
fixture.detectChanges();
expect(html.classList.contains('dark')).toBe(true);
});

it('should not have dark class in the html tag when theme is light', () => {
component.addOrRemoveDarkMode();
fixture.detectChanges();
expect(component.theme).toEqual('light');
expect(html.classList.contains('dark')).toBe(false);
});

it('should change the value of the theme property, save it in the local storage and add the dark class to the HTML tag to change the theme', () => {
component.changeToDarkOrLightTheme();
fixture.detectChanges();
expect(component.theme).toEqual('dark');
expect(localStorage.getItem('theme')).toEqual('dark');
expect(html.classList.contains('dark')).toBe(true);
});

it('should be true the isFeatureToggleDarkModeActive property when the user has the dark-mode feature toggle enabled', fakeAsync(() => {
const filters : FeatureFilterModel[] = [];
const featureToggle: FeatureToggleModel = {name: 'dark-mode', enabled: true, filters};
spyOn(featureToggleGeneralService, 'getActivated').and.returnValue(of([featureToggle]).pipe(delay(1)));
component.ngOnInit();
tick(1);
expect(component.isFeatureToggleDarkModeActive).toBeTruthy();
}));

});
65 changes: 65 additions & 0 deletions src/app/modules/shared/components/dark-mode/dark-mode.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Component, OnInit } from '@angular/core';
import { FeatureToggle } from 'src/environments/enum';
import { FeatureToggleGeneralService } from '../../feature-toggles/feature-toggle-general/feature-toggle-general.service';

@Component({
selector: 'app-dark-mode',
templateUrl: './dark-mode.component.html',
})
export class DarkModeComponent implements OnInit {
public theme = 'light';
public isFeatureToggleDarkModeActive: boolean;

constructor(
private featureToggleGeneralService: FeatureToggleGeneralService
) {}

ngOnInit() {
this.featureToggleGeneralService.getActivated().subscribe((featuresToggles) => {
const darkModeToggle = featuresToggles.find( (item) => item.name === FeatureToggle.DARK_MODE);
this.isFeatureToggleDarkModeActive = darkModeToggle.enabled;
if (this.isFeatureToggleDarkModeActive) {
this.checkThemeInLocalStorage();
this.addOrRemoveDarkMode();
}
});
}

getLocalStorageTheme(): string {
return localStorage.getItem('theme') || 'light';
}

setLocalStorageTheme(theme: string): void {
localStorage.setItem('theme', theme);
}

checkThemeInLocalStorage(): void {
if ('theme' in localStorage) {
this.theme = this.getLocalStorageTheme();
} else {
this.setLocalStorageTheme(this.theme);
}
}

isDarkTheme(): boolean {
return this.theme === 'dark' ? true : false;
}

setTheme(): string {
return this.isDarkTheme() ? 'light' : 'dark';
}

addOrRemoveDarkMode(): void {
if (this.isDarkTheme()) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}

changeToDarkOrLightTheme(): void {
this.theme = this.setTheme();
this.setLocalStorageTheme(this.theme);
this.addOrRemoveDarkMode();
}
}
21 changes: 13 additions & 8 deletions src/app/modules/shared/components/sidebar/sidebar.component.html
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
<div class="d-flex" id="wrapper">
<div class="bg-light border-right" id="sidebar-wrapper">
<div class="d-flex bg-grayTW-lightest dark:bg-grayTW-darker dark:text-whiteTW" id="wrapper">
<div class="border-right bg-whiteTW dark:bg-grayTW-dark" id="sidebar-wrapper">
<div class="sidebar-heading" style="text-align: center">
<img src="assets/img/ioet.png" width="90" height="auto" style="padding-top: 2rem; padding-bottom: 2rem;" alt="logo" />
</div>
<div class="list-group list-group-flush">
<div class="list-group list-group-flush bg-whiteTW dark:bg-grayTW-darker">
<a
*ngFor="let item of itemsSidebar"
[routerLink]="item.route"
routerLinkActive=""
class="list-group-item list-group-item-action bg-light"
class="list-group-item list-group-item-action bg-whiteTW dark:bg-grayTW-dark dark:text-whiteTW"
[ngClass]="{active: item.active}"
>
<i class="{{ item.icon }}"></i> {{ item.text }}
</a>
</div>
</div>
<div id="page-content-wrapper">
<nav class="navbar navbar-expand-lg navbar-light border-bottom">
<button class="btn btn-primary" id="menu-toggle">
<nav class="navbar navbar-expand-lg navbar-light border-bottom bg-whiteTW dark:bg-grayTW-dark">
<button class="btn bg-primaryTW hover:bg-primaryTW-dark text-whiteTW hover:text-whiteTW" id="menu-toggle">
Toggle Menu
</button>
<div class="dark-mode-toggle">
<app-dark-mode></app-dark-mode>
</div>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
Expand All @@ -30,9 +33,11 @@
</div>
</nav>
<div class="container-fluid px-0 full-height">
<div class="content_app h-100">
<div class="content_app h-100">
<div class="m-1 p-5 rounded-md bg-whiteTW dark:bg-grayTW-dark">
<router-outlet></router-outlet>
</div>
</div>
</div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ body {
font-weight: bold;
text-decoration: underline;
border-color: $primary;
background-color: transparent;
}

.full-height {
Expand All @@ -62,3 +63,9 @@ body {
height: -o-calc(100vh - 12vh);
height: calc(100vh - 12vh);
}

.dark-mode-toggle{
Copy link
Collaborator

Choose a reason for hiding this comment

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

add a space after .dark-mode-toggle

.dark-mode-toggle {

position: absolute;
left: 50%;
transform: translateX(-50%);
}
8 changes: 8 additions & 0 deletions src/assets/icons/moon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions src/assets/icons/sun.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions src/environments/enum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export enum FeatureToggle {
SWITCH_GROUP = 'switch-group',
TIME_TRACKER_CALENDAR = 'time-tracker-calendar'
SWITCH_GROUP = 'switch-group',
TIME_TRACKER_CALENDAR = 'time-tracker-calendar',
DARK_MODE = 'dark-mode',
}
4 changes: 4 additions & 0 deletions src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
@import './styles/colors.scss';
@import '../node_modules/angular-calendar/css/angular-calendar.css';

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

html,
body {
font-family: 'Roboto', sans-serif;
Expand Down
Loading