-
Notifications
You must be signed in to change notification settings - Fork 23
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
feat(stark-ui): implementation of the app sidebar #638
Conversation
@catlabs Could you please revert changes you made in the different package-lock.json files ? 😊 |
9645883
to
ea077f5
Compare
@@ -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 */ |
There was a problem hiding this comment.
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 { | ||
/** |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
showcase/src/app/app.component.html
Outdated
</div> | ||
</ng-container> | ||
<ng-container stark-app-sidenav-right> | ||
<div class="stark-app-sidenav-top"> |
There was a problem hiding this comment.
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
?
showcase/src/app/app.component.html
Outdated
<div class="stark-app-sidenav-top"> | ||
Top content | ||
</div> | ||
<div class="stark-app-sidenav-middle"> |
There was a problem hiding this comment.
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), |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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 | ||
*/ | ||
|
There was a problem hiding this comment.
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
ea077f5
to
8d01cec
Compare
There was a problem hiding this 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", () => { |
There was a problem hiding this comment.
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"; | ||
|
||
/** |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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] |
There was a problem hiding this comment.
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");
}
}
}
showcase/src/app/app.module.ts
Outdated
@@ -187,6 +190,7 @@ export const metaReducers: MetaReducer<State>[] = ENV !== "production" ? [logger | |||
providers: [ | |||
environment.ENV_PROVIDERS, | |||
APP_PROVIDERS, | |||
StarkAppSidebarService, |
There was a problem hiding this comment.
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 ? 😊
showcase/src/app/app.module.ts
Outdated
@@ -177,6 +179,7 @@ export const metaReducers: MetaReducer<State>[] = ENV !== "production" ? [logger | |||
NewsModule, | |||
StarkAppLogoModule, | |||
StarkAppLogoutModule, | |||
StarkAppSidebarModule, |
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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.
There was a problem hiding this 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"; |
There was a problem hiding this comment.
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"; |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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?
showcase/src/app/app.component.ts
Outdated
@@ -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; |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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?
showcase/src/app/app.component.html
Outdated
</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"> |
There was a problem hiding this comment.
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...
17b7382
to
6d4e72e
Compare
Repushed and rebased |
6d4e72e
to
ec279f0
Compare
I also change 2 things on the layout based on both Angular Material and Material design showcases:
To me, the look and feel is way better with those adaptation, especially with paragraphs :-) |
There was a problem hiding this 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>(); |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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 ;)
ce5fe2c
to
4a474c4
Compare
4a474c4
to
09eeeea
Compare
@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? |
ISSUES CLOSED: #592
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
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?