Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(stark-ui): implementation of the app sidebar #638

Merged
merged 1 commit into from
Sep 6, 2018

Conversation

catlabs
Copy link
Contributor

@catlabs catlabs commented Aug 27, 2018

ISSUES CLOSED: #592

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

[ ] Bugfix
[x] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Documentation content changes
[ ] Other... Please describe:

What is the current behavior?

Issue Number: #592 #569 #534

What is the new behavior?

Implementation of the 2 app sidebars
Note: Only 2 sidebars are allowed in material: angular/components#1514

Does this PR introduce a breaking change?

[ ] Yes
[x] No

@coveralls
Copy link

coveralls commented Aug 27, 2018

Coverage Status

Coverage decreased (-0.1%) to 92.4% when pulling 09eeeea on catlabs:feature/sidebar into a444bb0 on NationalBankBelgium:master.

@SuperITMan
Copy link
Member

@catlabs Could you please revert changes you made in the different package-lock.json files ? 😊

@catlabs catlabs force-pushed the feature/sidebar branch 2 times, most recently from 9645883 to ea077f5 Compare August 29, 2018 07:15
@@ -11,3 +11,24 @@
color: map-get($mat-light-theme-foreground, disabled-button);
}
}

/* TODO: This code soul be moved when the app menu is implemented */
Copy link
Member

Choose a reason for hiding this comment

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

typo issue --> "This code should be ..."

encapsulation: ViewEncapsulation.None
})
export class StarkAppSidebarComponent implements OnDestroy {
/**
Copy link
Member

Choose a reason for hiding this comment

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

Could you please add the following piece of code below ?

/**
 * Adds class="stark-app-sidebar" attribute on the host component
 */
@HostBinding("class")
public class: string = componentName;

/* ============================================================================== */
/* stark-ui: src/modules/app-sidebar/components/_app-sidebar.component.scss */

stark-app-sidebar {
Copy link
Member

Choose a reason for hiding this comment

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

As proposed below, if we define a class for the component, it would be maybe better to use the class .stark-app-sidebar instead of the tag.

</div>
</ng-container>
<ng-container stark-app-sidenav-right>
<div class="stark-app-sidenav-top">
Copy link
Member

Choose a reason for hiding this comment

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

As we discussed, could you please adapt this element by adding those classes: m1 center ?

<div class="stark-app-sidenav-top">
Top content
</div>
<div class="stark-app-sidenav-middle">
Copy link
Member

Choose a reason for hiding this comment

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

As we discussed, could you please adapt this element by adding those classes: m1 center ?

break;
case "right":
from(this.appSidenavRight.open()).subscribe(
(result: MatDrawerToggleResult) => this.logger.debug("right sidebar " + result),
Copy link
Member

Choose a reason for hiding this comment

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

Could you please adapt the debug message to be more explicit about the origin of the message ?

this.logger.debug(componentName + ": right sidenav " + result)

case "left":
from(this.appSidenavLeft.open()).subscribe(
(result: MatDrawerToggleResult) => this.logger.debug("left sidenav " + result),
(error: Error) => this.logger.warn(error)
Copy link
Member

Choose a reason for hiding this comment

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

Could you please adapt the debug message to be more explicit about the origin of the message ?

this.logger.warn(componentName + ": ", error)

case "right":
from(this.appSidenavRight.open()).subscribe(
(result: MatDrawerToggleResult) => this.logger.debug("right sidebar " + result),
(error: Error) => this.logger.warn(error)
Copy link
Member

Choose a reason for hiding this comment

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

Could you please adapt the debug message to be more explicit about the origin of the message ?

this.logger.warn(componentName + ": ", error)

* StarkAppSidebarService service
*/
@Injectable()
export class StarkAppSidebarService {
Copy link
Member

Choose a reason for hiding this comment

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

In Stark-Core we have an interface beside the the service implementation everytime.
Could you please do the same here ?

/**
* Subject emitting sidebar close events
*/

Copy link
Member

Choose a reason for hiding this comment

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

Normally the comments should be glued to the variable/method it describes

Copy link
Member

@SuperITMan SuperITMan left a comment

Choose a reason for hiding this comment

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

Could you please also provide a mock implementation of StarkAppSidebarService, as we have in stark-core ?

import { StarkAppSidebarOpenEvent } from "./app-sidebar-open-event.intf";
import createSpy = jasmine.createSpy;

describe("ValueService", () => {
Copy link
Member

Choose a reason for hiding this comment

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

Small issue here, it should be "AppSidebarService" instead of "ValueService"

import { Observable } from "rxjs";
import { StarkAppSidebarOpenEvent } from "./app-sidebar-open-event.intf";

/**
Copy link
Member

Choose a reason for hiding this comment

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

Could you please provide a name and an injection token as we have in stark-core ?

/**
 * The name of the service in case an injection is needed
 */
export const starkAppSidebarServiceName: string = "StarkAppSidebarService";
/**
 * The InjectionToken version of the service name
 */
export const STARK_APP_SIDEBAR_SERVICE: InjectionToken<StarkAppSidebarService> = new InjectionToken<StarkAppSidebarService>(starkAppSidebarServiceName);

* Service to fetch the user profile from the REST API.
* In Development, it can also be used to set the user profile manually.
*/
export interface StarkAppSidebarServiceIntf {
Copy link
Member

Choose a reason for hiding this comment

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

Could you please change the name of the interface to StarkAppSidebarService ?

* StarkAppSidebarService service
*/
@Injectable()
export class StarkAppSidebarService implements StarkAppSidebarServiceIntf {
Copy link
Member

Choose a reason for hiding this comment

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

Could you please change the name of the class to StarkAppSidebarServiceImpl

Copy link
Member

Choose a reason for hiding this comment

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

Could you please add a constructor and inject @Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService in it ?
And then, do this inside:

public constructor(@Inject(STARK_LOGGING_SERVICE) public logger) {
    this.logger.debug(starkAppSidebarServiceName + " loaded");
}

declarations: [StarkAppSidebarComponent],
imports: [CommonModule, MatSidenavModule],
exports: [StarkAppSidebarComponent],
providers: [StarkAppSidebarService]
Copy link
Member

Choose a reason for hiding this comment

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

Could you please adapt the declaration of the module like this:

@NgModule({
        declarations: [StarkAppSidebarComponent],
	imports: [CommonModule, MatSidenavModule],
        exports: [StarkAppSidebarComponent]
})
export class StarkAppSidebarModule {
	/**
	 * Instantiates the services only once since they should be singletons
	 * so the forRoot() should be called only by the AppModule
	 * @link https://angular.io/guide/singleton-services#forroot
	 * @returns a module with providers
	 */
	public static forRoot(): ModuleWithProviders {
		return {
			ngModule: StarkAppSidebarModule,
			providers: [{ provide: STARK_APP_SIDEBAR_SERVICE, useClass: StarkAppSidebarServiceImpl }]
		};
	}

	/**
	 * Prevents this module from being re-imported
	 * @link https://angular.io/guide/singleton-services#prevent-reimport-of-the-coremodule
	 * @param parentModule - the parent module
	 */
	public constructor(
		@Optional()
		@SkipSelf()
		parentModule: StarkAppSidebarModule
	) {
		if (parentModule) {
			throw new Error("StarkAppSidebarModule is already loaded. Import it in the AppModule only");
		}
	}
}

@@ -187,6 +190,7 @@ export const metaReducers: MetaReducer<State>[] = ENV !== "production" ? [logger
providers: [
environment.ENV_PROVIDERS,
APP_PROVIDERS,
StarkAppSidebarService,
Copy link
Member

Choose a reason for hiding this comment

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

Could you please remove this line since it won't be used as this anymore ? 😊

@@ -177,6 +179,7 @@ export const metaReducers: MetaReducer<State>[] = ENV !== "production" ? [logger
NewsModule,
StarkAppLogoModule,
StarkAppLogoutModule,
StarkAppSidebarModule,
Copy link
Member

Choose a reason for hiding this comment

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

Could you please adapt this to StarkAppSidebarModule.forRoot() ?

@@ -0,0 +1,3 @@
<example-viewer [extensions]="['HTML']" filesPath="sidebar/regular" exampleTitle="SHOWCASE.DEMO.SIDEBAR.TITLE">
<p translate>SHOWCASE.DEMO.SIDEBAR.INTRO</p>
Copy link
Member

Choose a reason for hiding this comment

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

Could you please provide an example with calls to the sidebarService ?
You could provide 3 examples, one for each sidebar.

Copy link
Collaborator

@christophercr christophercr left a comment

Choose a reason for hiding this comment

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

Some remarks... and I think the PR should be rebased...

@@ -2,6 +2,8 @@ export * from "./modules/action-bar";
export * from "./modules/app-logo";
export * from "./modules/app-logout";
export * from "./modules/breadcrumb";
export * from "./modules/app-sidebar";
export * from "./modules/keyboard-directives";
Copy link
Collaborator

Choose a reason for hiding this comment

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

This line is duplicated: "keyboard-directives"

* Mode for the left sidebar: either the menu is shown or the regular sidebar
*/
@Input()
public sidenavLeftMode: "regular" | "menu";
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you create a custom type for these? That way you can re-use them in the StarkAppSidebarOpenEvent interface ;)

* Component lifecycle OnDestroy hook
* Prevent memory leak when component destroyed
*/
public ngOnDestroy(): void {
Copy link
Collaborator

Choose a reason for hiding this comment

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

As a convention we put the Angular lifecycle hooks right after the constructor method and in chronological order, this means that the ngOnInit is placed before the ngOnDestriy. This way is easier to find them ;)

<ng-content select="[stark-app-sidenav-menu]"></ng-content>
</ng-container>
</mat-sidenav>
<mat-sidenav #appSidenavRight class="stark-app-sidenav-right" closed mode="over" position="end" [fixedInViewport]="true"
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is the attribute "closed" used for? Is it really needed here? Shouldn't we close/open the sidebar programatically instead?

@@ -19,12 +20,35 @@ import { STARK_LOGGING_SERVICE, StarkLoggingService } from "@nationalbankbelgium
export class AppComponent implements OnInit {
public appState: AppState;

public constructor(appState: AppState, @Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService) {
@ViewChild("appSideBar")
public appSidebar: StarkAppSidebarComponent;
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems this variable is never used... or am I missing something?

closeSidebars();
});
service.close();
expect(closeSidebars).toHaveBeenCalled();
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can use the "toHaveBeenCalledTimes(1)" matcher to be more explicit and to be sure it was called only once

@@ -0,0 +1,20 @@
<mat-sidenav-container #appSidenavContainer>
<mat-sidenav #appSidenavLeft class="stark-app-sidenav-left" [ngClass]="{'stark-app-sidenav-menu': sidenavLeftMode==='menu'}" closed mode="over" [fixedInViewport]="true"
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is the attribute "closed" used for? Is it really needed here? Shouldn't we close/open the sidebar programatically instead?

</a>
<a mat-list-item uiSref="stark-header" uiSrefActive="active">
<span matLine>Stark header</span>
</a>
<a mat-list-item uiSref="demo-table" uiSrefActive="active">
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you move this item right after the demo-sidebar item? We should keep them in alphabetical order...

@catlabs catlabs force-pushed the feature/sidebar branch 3 times, most recently from 17b7382 to 6d4e72e Compare September 5, 2018 08:24
@catlabs
Copy link
Contributor Author

catlabs commented Sep 5, 2018

Repushed and rebased

@catlabs
Copy link
Contributor Author

catlabs commented Sep 5, 2018

I also change 2 things on the layout based on both Angular Material and Material design showcases:

  • header take now the full width on desktop
  • the main content has a x padding of 70px on smaller screen, on big screen the max width of the content is 940px

To me, the look and feel is way better with those adaptation, especially with paragraphs :-)

Copy link
Collaborator

@christophercr christophercr left a comment

Choose a reason for hiding this comment

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

Small remarks


public openSidebar$: Observable<StarkAppSidebarOpenEvent> = this.openSidebarSource.asObservable();

private closeSidebarSource: Subject<void> = new Subject<void>();
Copy link
Collaborator

Choose a reason for hiding this comment

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

This property should also be "protected" right?

}

.stark-app-sidenav-left {
width: 150px;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Isn't 150px too small for the left sidebar? Could we put at least 200px as we do for the menu?

@@ -0,0 +1,5 @@
<example-viewer [extensions]="['HTML', 'TS']" filesPath="sidebar/regular" exampleTitle="SHOWCASE.DEMO.SIDEBAR.TITLE">
<button color="primary" mat-raised-button mat-button (click)="openMenu()" translate>{{ 'SHOWCASE.DEMO.SIDEBAR.OPEN_MENU' | translate }}</button>
Copy link
Collaborator

Choose a reason for hiding this comment

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

The "translate" feature is used twice: as a directive and as a pipe. You can simply use the directive ;)

@@ -0,0 +1,5 @@
<example-viewer [extensions]="['HTML', 'TS']" filesPath="sidebar/regular" exampleTitle="SHOWCASE.DEMO.SIDEBAR.TITLE">
<button color="primary" mat-raised-button mat-button (click)="openMenu()" translate>{{ 'SHOWCASE.DEMO.SIDEBAR.OPEN_MENU' | translate }}</button>
<button color="primary" mat-raised-button mat-button (click)="openLeftSidebar()" translate>{{ 'SHOWCASE.DEMO.SIDEBAR.OPEN_LEFT' | translate }}</button>
Copy link
Collaborator

Choose a reason for hiding this comment

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

The "translate" feature is used twice: as a directive and as a pipe. You can simply use the directive ;)

<example-viewer [extensions]="['HTML', 'TS']" filesPath="sidebar/regular" exampleTitle="SHOWCASE.DEMO.SIDEBAR.TITLE">
<button color="primary" mat-raised-button mat-button (click)="openMenu()" translate>{{ 'SHOWCASE.DEMO.SIDEBAR.OPEN_MENU' | translate }}</button>
<button color="primary" mat-raised-button mat-button (click)="openLeftSidebar()" translate>{{ 'SHOWCASE.DEMO.SIDEBAR.OPEN_LEFT' | translate }}</button>
<button color="primary" mat-raised-button mat-button (click)="openRightSidebar()" translate>{{ 'SHOWCASE.DEMO.SIDEBAR.OPEN_RIGHT' | translate }}</button>
Copy link
Collaborator

Choose a reason for hiding this comment

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

The "translate" feature is used twice: as a directive and as a pipe. You can simply use the directive ;)

@catlabs catlabs force-pushed the feature/sidebar branch 3 times, most recently from ce5fe2c to 4a474c4 Compare September 6, 2018 14:51
@christophercr
Copy link
Collaborator

@SuperITMan for your info, I've reviewed this PR and everything seems OK now so I will merge it. This way I can release a new version today so the showcase will look better now ;)

In any case, if you find any issue after reviewing this again, we can create another issue to track it ok?

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

Successfully merging this pull request may close these issues.

ui: sidebar/menu - implement component/module
4 participants