diff --git a/apps/daffio/package.json b/apps/daffio/package.json index e1dc5875a4..44cee9bde2 100644 --- a/apps/daffio/package.json +++ b/apps/daffio/package.json @@ -40,6 +40,7 @@ "@daffodil/design": "0.0.0-PLACEHOLDER", "@daffodil/router": "0.0.0-PLACEHOLDER", "@daffodil/tools-dgeni": "0.0.0-PLACEHOLDER", - "@daffodil/theme-switch": "0.0.0-PLACEHOLDER" + "@daffodil/theme-switch": "0.0.0-PLACEHOLDER", + "@ngrx/component": "0.0.0-PLACEHOLDER" } } diff --git a/apps/daffio/src/app/app-routing.module.ts b/apps/daffio/src/app/app-routing.module.ts index 4218691bc1..def35ff258 100644 --- a/apps/daffio/src/app/app-routing.module.ts +++ b/apps/daffio/src/app/app-routing.module.ts @@ -14,6 +14,7 @@ import { DaffioDocsSidebarContentComponent } from './core/sidebar/components/doc import { DaffioMarketingSidebarContentComponent } from './core/sidebar/components/marketing-sidebar-content/marketing-sidebar-content.component'; import { DaffioSidebarFooterComponent } from './core/sidebar/components/sidebar-footer/sidebar-footer.component'; import { DaffioSidebarHeaderComponent } from './core/sidebar/components/sidebar-header/sidebar-header.component'; +import { DaffioDocsSidebarContainer } from './core/sidebar/containers/docs-sidebar/docs-sidebar.component'; import { TemplateComponent } from './core/template/template.component'; import { DaffioRouterNamedViewsEnum } from './named-views/models/named-views.enum'; @@ -39,12 +40,10 @@ export const appRoutes: Routes = [ }, }, }, - { path: '', children: [ { path: 'api', loadChildren: () => import('./api/api.module').then(m => m.DaffioApiModule) }, - { path: 'guides', loadChildren: () => import('./guides/guides.module').then(m => m.DaffioGuidesModule) }, ], data: { daffNamedViews: { @@ -56,6 +55,20 @@ export const appRoutes: Routes = [ }, }, }, + { + path: '', + children: [ + { path: 'guides', loadChildren: () => import('./guides/guides.module').then(m => m.DaffioGuidesModule) }, + ], + data: { + daffNamedViews: { + [DaffioRouterNamedViewsEnum.NAV]: DaffioDocsHeaderContainer, + [DaffioRouterNamedViewsEnum.SIDEBARHEADER]: DaffioSidebarHeaderComponent, + [DaffioRouterNamedViewsEnum.SIDEBARCONTENT]: DaffioDocsSidebarContainer, + [DaffioRouterNamedViewsEnum.SIDEBARFOOTER]: DaffioSidebarFooterComponent, + }, + }, + }, ], }, { diff --git a/apps/daffio/src/app/app.module.ts b/apps/daffio/src/app/app.module.ts index ed4c08bd2e..7e72f0c2d5 100644 --- a/apps/daffio/src/app/app.module.ts +++ b/apps/daffio/src/app/app.module.ts @@ -23,6 +23,7 @@ import { DaffioDocsSidebarContentComponentModule } from './core/sidebar/componen import { DaffioMarketingSidebarContentComponentModule } from './core/sidebar/components/marketing-sidebar-content/marketing-sidebar-content.module'; import { DaffioSidebarFooterComponentModule } from './core/sidebar/components/sidebar-footer/sidebar-footer.module'; import { DaffioSidebarHeaderComponentModule } from './core/sidebar/components/sidebar-header/sidebar-header.module'; +import { DaffioDocsSidebarContainerModule } from './core/sidebar/containers/docs-sidebar/docs-sidebar.module'; import { TemplateModule } from './core/template/template.module'; import { environment } from '../environments/environment'; @@ -44,6 +45,7 @@ import { environment } from '../environments/environment'; DaffioSidebarFooterComponentModule, DaffioSimpleFooterComponentModule, DaffioMarketingFooterComponentModule, + DaffioDocsSidebarContainerModule, //Make sure this loads after Router and Store StoreRouterConnectingModule.forRoot({ serializer: FullRouterStateSerializer, diff --git a/apps/daffio/src/app/core/sidebar/actions/sidebar.actions.ts b/apps/daffio/src/app/core/sidebar/actions/sidebar.actions.ts index 948cf1ec26..0cddd1a449 100644 --- a/apps/daffio/src/app/core/sidebar/actions/sidebar.actions.ts +++ b/apps/daffio/src/app/core/sidebar/actions/sidebar.actions.ts @@ -14,10 +14,14 @@ export enum SidebarActionTypes { export class ToggleSidebar implements Action { readonly type = SidebarActionTypes.ToggleSidebarAction; + + constructor(public payload?: string) {} } export class OpenSidebar implements Action { readonly type = SidebarActionTypes.OpenSidebarAction; + + constructor(public payload?: string) {} } export class CloseSidebar implements Action { @@ -27,22 +31,21 @@ export class CloseSidebar implements Action { export class SetSidebarVisibility implements Action { readonly type = SidebarActionTypes.SetSidebarVisibilityAction; - constructor(public payload: boolean){} + constructor(public payload: boolean) {} } export class SetSidebarState implements Action { readonly type = SidebarActionTypes.SetSidebarStateAction; - constructor(public payload: { mode?: DaffSidebarMode; open?: boolean }){} + constructor(public payload: { mode?: DaffSidebarMode; open?: boolean; kind?: string }) {} } export class SetSidebarMode implements Action { readonly type = SidebarActionTypes.SetSidebarModeAction; - constructor(public payload: DaffSidebarMode){} + constructor(public payload: DaffSidebarMode) {} } - export class ResetMode implements Action { readonly type = SidebarActionTypes.ResetModeAction; } diff --git a/apps/daffio/src/app/core/sidebar/containers/docs-sidebar/docs-sidebar.component.html b/apps/daffio/src/app/core/sidebar/containers/docs-sidebar/docs-sidebar.component.html new file mode 100644 index 0000000000..bd64d62e6f --- /dev/null +++ b/apps/daffio/src/app/core/sidebar/containers/docs-sidebar/docs-sidebar.component.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/apps/daffio/src/app/core/sidebar/containers/docs-sidebar/docs-sidebar.component.spec.ts b/apps/daffio/src/app/core/sidebar/containers/docs-sidebar/docs-sidebar.component.spec.ts new file mode 100644 index 0000000000..d9c2ebf3f6 --- /dev/null +++ b/apps/daffio/src/app/core/sidebar/containers/docs-sidebar/docs-sidebar.component.spec.ts @@ -0,0 +1,149 @@ +import { + BreakpointObserver, + BreakpointState, +} from '@angular/cdk/layout'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { + ComponentFixture, + TestBed, + waitForAsync, +} from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { RouterTestingModule } from '@angular/router/testing'; +import { LetModule } from '@ngrx/component'; +import { + MockStore, + provideMockStore, +} from '@ngrx/store/testing'; +import { DaffioDocsPackagesListContainerModule } from 'apps/daffio/src/app/guides/containers/packages-list/packages-list.module'; +import { BehaviorSubject } from 'rxjs'; + +import { DaffBreakpoints } from '@daffodil/design'; + +import { + DAFFIO_DOCS_CONTENT_SIDEBAR_KIND, + DaffioDocsSidebarContainer, +} from './docs-sidebar.component'; +import { DaffioDocsSidebarContentComponentModule } from '../../components/docs-sidebar-content/docs-sidebar-content.module'; +import { selectSidebarKind } from '../../reducers'; + +describe('DaffioDocsSidebarContainer', () => { + let component: DaffioDocsSidebarContainer; + let fixture: ComponentFixture; + let store: MockStore; + let breakpointSpy: jasmine.SpyObj; + let breakpointState: BehaviorSubject; + + beforeEach(waitForAsync(() => { + breakpointSpy = jasmine.createSpyObj('BreakpointObserver', ['observe']); + + TestBed.configureTestingModule({ + imports: [ + LetModule, + RouterTestingModule, + HttpClientTestingModule, + DaffioDocsPackagesListContainerModule, + DaffioDocsSidebarContentComponentModule, + ], + declarations: [ + DaffioDocsSidebarContainer, + ], + providers: [ + provideMockStore(), + { + provide: BreakpointObserver, + useValue: breakpointSpy, + }, + ], + }) + .compileComponents(); + })); + + beforeEach(() => { + store = TestBed.inject(MockStore); + breakpointState = new BehaviorSubject({ matches: false, breakpoints: {}}); + breakpointSpy.observe.withArgs(DaffBreakpoints.BIG_TABLET).and.returnValue(breakpointState); + store.overrideSelector(selectSidebarKind, undefined); + + fixture = TestBed.createComponent(DaffioDocsSidebarContainer); + component = fixture.componentInstance; + + fixture.detectChanges(); + }); + + afterEach(() => { + store.resetSelectors(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('when the breakpoint is big tablet', () => { + beforeEach(() => { + breakpointState.next({ + matches: true, + breakpoints: {}, + }); + fixture.detectChanges(); + }); + + describe('and when the sidebar kind is unset', () => { + beforeEach(() => { + store.overrideSelector(selectSidebarKind, undefined); + store.setState({}); + fixture.detectChanges(); + }); + + it('should render ', () => { + expect(fixture.debugElement.query(By.css('daffio-docs-packages-list-container'))).toBeTruthy(); + }); + }); + + describe('and when the sidebar kind is content', () => { + beforeEach(() => { + store.overrideSelector(selectSidebarKind, DAFFIO_DOCS_CONTENT_SIDEBAR_KIND); + store.setState({}); + fixture.detectChanges(); + }); + + it('should render ', () => { + expect(fixture.debugElement.query(By.css('daffio-docs-packages-list-container'))).toBeTruthy(); + }); + }); + }); + + describe('when the breakpoint is not big tablet', () => { + beforeEach(() => { + breakpointState.next({ + matches: false, + breakpoints: {}, + }); + fixture.detectChanges(); + }); + + describe('and when the sidebar kind is unset', () => { + beforeEach(() => { + store.overrideSelector(selectSidebarKind, undefined); + store.setState({}); + fixture.detectChanges(); + }); + + it('should render ', () => { + expect(fixture.debugElement.query(By.css('daffio-docs-sidebar-content'))).toBeTruthy(); + }); + }); + + describe('and when the sidebar kind is content', () => { + beforeEach(() => { + store.overrideSelector(selectSidebarKind, DAFFIO_DOCS_CONTENT_SIDEBAR_KIND); + store.setState({}); + fixture.detectChanges(); + }); + + it('should render ', () => { + expect(fixture.debugElement.query(By.css('daffio-docs-packages-list-container'))).toBeTruthy(); + }); + }); + }); +}); diff --git a/apps/daffio/src/app/core/sidebar/containers/docs-sidebar/docs-sidebar.component.ts b/apps/daffio/src/app/core/sidebar/containers/docs-sidebar/docs-sidebar.component.ts new file mode 100644 index 0000000000..1d1893092a --- /dev/null +++ b/apps/daffio/src/app/core/sidebar/containers/docs-sidebar/docs-sidebar.component.ts @@ -0,0 +1,48 @@ +import { BreakpointObserver } from '@angular/cdk/layout'; +import { + ChangeDetectionStrategy, + Component, + OnInit, +} from '@angular/core'; +import { + select, + Store, +} from '@ngrx/store'; +import { + Observable, + map, +} from 'rxjs'; + +import { DaffBreakpoints } from '@daffodil/design'; + +import { selectSidebarKind } from '../../reducers'; + +export const DAFFIO_DOCS_CONTENT_SIDEBAR_KIND = 'content'; + +/** + * @private + * This component stores all of the sidebars within daff.io/docs + */ +@Component({ + selector: 'daffio-docs-sidebar-container', + templateUrl: './docs-sidebar.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class DaffioDocsSidebarContainer implements OnInit { + contentSidebarKind = DAFFIO_DOCS_CONTENT_SIDEBAR_KIND; + + constructor( + private store: Store, + private breakpointObserver: BreakpointObserver, + ) {} + + sidebarKind$: Observable; + isBigTablet$: Observable; + + ngOnInit() { + this.isBigTablet$ = this.breakpointObserver.observe(DaffBreakpoints.BIG_TABLET).pipe( + map(({ matches }) => matches), + ); + this.sidebarKind$ = this.store.pipe(select(selectSidebarKind)); + } +} diff --git a/apps/daffio/src/app/core/sidebar/containers/docs-sidebar/docs-sidebar.module.ts b/apps/daffio/src/app/core/sidebar/containers/docs-sidebar/docs-sidebar.module.ts new file mode 100644 index 0000000000..5d4066c79a --- /dev/null +++ b/apps/daffio/src/app/core/sidebar/containers/docs-sidebar/docs-sidebar.module.ts @@ -0,0 +1,26 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { LetModule } from '@ngrx/component'; +import { DaffioDocsPackagesListContainerModule } from 'apps/daffio/src/app/guides/containers/packages-list/packages-list.module'; + +import { DaffioDocsSidebarContainer } from './docs-sidebar.component'; +import { DaffioDocsSidebarContentComponentModule } from '../../components/docs-sidebar-content/docs-sidebar-content.module'; + +@NgModule({ + imports: [ + CommonModule, + RouterModule, + LetModule, + + DaffioDocsPackagesListContainerModule, + DaffioDocsSidebarContentComponentModule, + ], + declarations: [ + DaffioDocsSidebarContainer, + ], + exports: [ + DaffioDocsSidebarContainer, + ], +}) +export class DaffioDocsSidebarContainerModule {} diff --git a/apps/daffio/src/app/core/sidebar/containers/sidebar-viewport/sidebar-viewport-theme.scss b/apps/daffio/src/app/core/sidebar/containers/sidebar-viewport/sidebar-viewport-theme.scss deleted file mode 100644 index be1edd8db0..0000000000 --- a/apps/daffio/src/app/core/sidebar/containers/sidebar-viewport/sidebar-viewport-theme.scss +++ /dev/null @@ -1,19 +0,0 @@ -@use 'sass:map'; -@use 'theme' as daff-theme; - -@mixin daffio-sidebar-viewport-theme($theme) { - $neutral: daff-theme.daff-map-deep-get($theme, 'core.neutral'); - $base: daff-theme.daff-map-deep-get($theme, 'core.base'); - $base-contrast: daff-theme.daff-map-deep-get($theme, 'core.base-contrast'); - $primary: map.get($theme, primary); - - .daffio-sidebar-viewport { - &__get-started { - background: daff-theme.daff-illuminate($base, $neutral, 2); - - &:hover { - background: daff-theme.daff-illuminate($base, $neutral, 3); - } - } - } -} \ No newline at end of file diff --git a/apps/daffio/src/app/core/sidebar/containers/sidebar-viewport/sidebar-viewport.component.spec.ts b/apps/daffio/src/app/core/sidebar/containers/sidebar-viewport/sidebar-viewport.component.spec.ts index dcb2d557d8..65582a77b4 100644 --- a/apps/daffio/src/app/core/sidebar/containers/sidebar-viewport/sidebar-viewport.component.spec.ts +++ b/apps/daffio/src/app/core/sidebar/containers/sidebar-viewport/sidebar-viewport.component.spec.ts @@ -1,4 +1,5 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { Component } from '@angular/core'; import { ComponentFixture, TestBed, @@ -8,22 +9,31 @@ import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { RouterTestingModule } from '@angular/router/testing'; import { - Store, - StoreModule, - combineReducers, -} from '@ngrx/store'; + MockStore, + provideMockStore, +} from '@ngrx/store/testing'; import { cold } from 'jasmine-marbles'; +import { BehaviorSubject } from 'rxjs'; import { DaffSidebarModule, DaffSidebarViewportComponent, DaffSidebarComponent, + DaffSidebarModeEnum, } from '@daffodil/design/sidebar'; +import { + DaffRouterNamedViewService, + DaffRouterNamedViews, +} from '@daffodil/router'; import { DaffioSidebarViewportContainer } from './sidebar-viewport.component'; +import { DaffioRouterNamedViewsEnum } from '../../../../named-views/models/named-views.enum'; import { CloseSidebar } from '../../actions/sidebar.actions'; import * as fromSidebar from '../../reducers/index'; +@Component({ template: '' }) +class TestComponent {} + describe('DaffioSidebarViewportContainer', () => { let component: DaffioSidebarViewportContainer; let fixture: ComponentFixture; @@ -31,14 +41,16 @@ describe('DaffioSidebarViewportContainer', () => { let daffSidebarViewport: DaffSidebarViewportComponent; let daffSidebar: DaffSidebarComponent; - let store: Store; + let store: MockStore; + let namedViewServiceSpy: jasmine.SpyObj; + let namedViews: BehaviorSubject; beforeEach(waitForAsync(() => { + namedViews = new BehaviorSubject({}); + namedViewServiceSpy = jasmine.createSpyObj('DaffRouterNamedViewService', {}, { namedViews$: namedViews }); + TestBed.configureTestingModule({ imports: [ - StoreModule.forRoot({ - daffioSidebar: combineReducers(fromSidebar.reducers), - }), RouterTestingModule, NoopAnimationsModule, DaffSidebarModule, @@ -46,6 +58,14 @@ describe('DaffioSidebarViewportContainer', () => { ], declarations: [ DaffioSidebarViewportContainer, + TestComponent, + ], + providers: [ + { + provide: DaffRouterNamedViewService, + useValue: namedViewServiceSpy, + }, + provideMockStore(), ], }) .compileComponents(); @@ -54,20 +74,23 @@ describe('DaffioSidebarViewportContainer', () => { beforeEach(() => { fixture = TestBed.createComponent(DaffioSidebarViewportContainer); component = fixture.componentInstance; - store = TestBed.inject(Store); + store = TestBed.inject(MockStore); spyOn(store, 'dispatch'); + store.overrideSelector(fromSidebar.selectShowSidebar, false); + store.overrideSelector(fromSidebar.selectSidebarMode, DaffSidebarModeEnum.Side); + store.setState({}); fixture.detectChanges(); daffSidebar = fixture.debugElement.query(By.css('daff-sidebar')).componentInstance; daffSidebarViewport = fixture.debugElement.query(By.css('daff-sidebar-viewport')).componentInstance; }); - it('should create', () => { - expect(component).toBeTruthy(); + afterEach(() => { + store.resetSelectors(); }); - it('should set the `daff-sidebar` mode to the default initialState (push)', () => { - expect(daffSidebar.mode).toEqual('under'); + it('should create', () => { + expect(component).toBeTruthy(); }); describe('when the `daff-sidebar-viewport` emits `backdropClicked`', () => { @@ -106,4 +129,96 @@ describe('DaffioSidebarViewportContainer', () => { }); }); }); + + describe('when there is a named view for the sidebar header', () => { + beforeEach(() => { + namedViews.next({ + [DaffioRouterNamedViewsEnum.SIDEBARHEADER]: TestComponent, + }); + fixture.detectChanges(); + }); + + it('should render the sidebar header', () => { + const sidebarHeader = fixture.debugElement.query(By.css('daff-sidebar-header')); + expect(sidebarHeader).toBeTruthy(); + }); + }); + + describe('when there is not a named view for the sidebar header', () => { + beforeEach(() => { + namedViews.next({}); + fixture.detectChanges(); + }); + + it('should not render the sidebar header', () => { + const sidebarHeader = fixture.debugElement.query(By.css('daff-sidebar-header')); + expect(sidebarHeader).toBeFalsy(); + }); + }); + + describe('when there is a named view for the sidebar footer', () => { + beforeEach(() => { + namedViews.next({ + [DaffioRouterNamedViewsEnum.SIDEBARFOOTER]: TestComponent, + }); + fixture.detectChanges(); + }); + + it('should render the sidebar footer', () => { + const sidebarFooter = fixture.debugElement.query(By.css('daff-sidebar-footer')); + expect(sidebarFooter).toBeTruthy(); + }); + }); + + describe('when there is not a named view for the sidebar footer', () => { + beforeEach(() => { + namedViews.next({}); + fixture.detectChanges(); + }); + + it('should not render the sidebar footer', () => { + const sidebarFooter = fixture.debugElement.query(By.css('daff-sidebar-footer')); + expect(sidebarFooter).toBeFalsy(); + }); + }); + + describe('when the sidebar mode is side-fixed', () => { + beforeEach(() => { + store.overrideSelector(fromSidebar.selectSidebarMode, DaffSidebarModeEnum.SideFixed); + store.setState({}); + fixture.detectChanges(); + }); + + it('should not render the sidebar header', () => { + const sidebarHeader = fixture.debugElement.query(By.css('daff-sidebar-header')); + expect(sidebarHeader).toBeFalsy(); + }); + + it('should not render the sidebar footer', () => { + const sidebarFooter = fixture.debugElement.query(By.css('daff-sidebar-footer')); + expect(sidebarFooter).toBeFalsy(); + }); + }); + + describe('when the sidebar mode is not side-fixed and there are named views for the header and footer', () => { + beforeEach(() => { + store.overrideSelector(fromSidebar.selectSidebarMode, DaffSidebarModeEnum.Side); + store.setState({}); + namedViews.next({ + [DaffioRouterNamedViewsEnum.SIDEBARHEADER]: TestComponent, + [DaffioRouterNamedViewsEnum.SIDEBARFOOTER]: TestComponent, + }); + fixture.detectChanges(); + }); + + it('should render the sidebar header', () => { + const sidebarHeader = fixture.debugElement.query(By.css('daff-sidebar-header')); + expect(sidebarHeader).toBeTruthy(); + }); + + it('should render the sidebar footer', () => { + const sidebarFooter = fixture.debugElement.query(By.css('daff-sidebar-footer')); + expect(sidebarFooter).toBeTruthy(); + }); + }); }); diff --git a/apps/daffio/src/app/core/sidebar/containers/sidebar-viewport/sidebar-viewport.component.ts b/apps/daffio/src/app/core/sidebar/containers/sidebar-viewport/sidebar-viewport.component.ts index 8d8c2ee382..f14156faa7 100644 --- a/apps/daffio/src/app/core/sidebar/containers/sidebar-viewport/sidebar-viewport.component.ts +++ b/apps/daffio/src/app/core/sidebar/containers/sidebar-viewport/sidebar-viewport.component.ts @@ -8,11 +8,15 @@ import { select, } from '@ngrx/store'; import { + combineLatest, map, Observable, } from 'rxjs'; -import { DaffSidebarMode } from '@daffodil/design/sidebar'; +import { + DaffSidebarMode, + DaffSidebarModeEnum, +} from '@daffodil/design/sidebar'; import { DaffRouterNamedViewService } from '@daffodil/router'; import { DaffioRouterNamedViewsEnum } from '../../../../named-views/models/named-views.enum'; @@ -38,13 +42,24 @@ export class DaffioSidebarViewportContainer implements OnInit { ngOnInit() { this.showSidebar$ = this.store.pipe(select(fromDaffioSidebar.selectShowSidebar)); this.mode$ = this.store.pipe(select(fromDaffioSidebar.selectSidebarMode)); - this.showSidebarHeader$ = this.namedViewService.namedViews$.pipe(map((namedViews) => !!namedViews[this.sidebarHeaderNamedView])); - this.showSidebarFooter$ = this.namedViewService.namedViews$.pipe(map((namedViews) => !!namedViews[this.sidebarFooterNamedView])); + this.showSidebarHeader$ = combineLatest([ + this.namedViewService.namedViews$, + this.mode$, + ]).pipe( + map(([namedViews, mode]) => !!namedViews[this.sidebarHeaderNamedView] && mode !== DaffSidebarModeEnum.SideFixed), + ); + this.showSidebarFooter$ = combineLatest([ + this.namedViewService.namedViews$, + this.mode$, + ]).pipe( + map(([namedViews, mode]) => !!namedViews[this.sidebarFooterNamedView] && mode !== DaffSidebarModeEnum.SideFixed), + ); } constructor( private store: Store, - private namedViewService: DaffRouterNamedViewService) { } + private namedViewService: DaffRouterNamedViewService, + ) { } close() { this.store.dispatch(new CloseSidebar()); diff --git a/apps/daffio/src/app/core/sidebar/effects/sidebar-routing-mode.effects.ts b/apps/daffio/src/app/core/sidebar/effects/sidebar-routing-mode.effects.ts index 76b71c467f..e0d2582405 100644 --- a/apps/daffio/src/app/core/sidebar/effects/sidebar-routing-mode.effects.ts +++ b/apps/daffio/src/app/core/sidebar/effects/sidebar-routing-mode.effects.ts @@ -29,10 +29,10 @@ export class DaffioSidebarRoutingModeEffects { private breakpointsObserver: BreakpointObserver, ) { } - changeModeWhenVisitingConfiguredRoute$ = createEffect(() => (): Observable => combineLatest( + changeModeWhenVisitingConfiguredRoute$ = createEffect(() => (): Observable => combineLatest([ this.actions$.pipe(ofType(ROUTER_NAVIGATED)), this.breakpointsObserver.observe(DaffBreakpoints.BIG_TABLET), - ).pipe( + ]).pipe( map(([action, state]) => { const mode = computeDeepestSidebarMode(action.payload.routerState.root); if(state.matches && mode){ diff --git a/apps/daffio/src/app/core/sidebar/reducers/index.ts b/apps/daffio/src/app/core/sidebar/reducers/index.ts index f903265d01..bd8627f128 100644 --- a/apps/daffio/src/app/core/sidebar/reducers/index.ts +++ b/apps/daffio/src/app/core/sidebar/reducers/index.ts @@ -40,6 +40,11 @@ export const selectShowSidebar: MemoizedSelector, boolean> = fromDaffioSidebar.getShowSidebar, ); +export const selectSidebarKind: MemoizedSelector, string> = createSelector( + daffioSidebarStateSelector, + fromDaffioSidebar.getKind, +); + export const selectSidebarMode: MemoizedSelector, DaffSidebarMode> = createSelector( daffioSidebarStateSelector, fromDaffioSidebar.getMode, diff --git a/apps/daffio/src/app/core/sidebar/reducers/sidebar.reducer.ts b/apps/daffio/src/app/core/sidebar/reducers/sidebar.reducer.ts index 512ee207f5..fb5398bf73 100644 --- a/apps/daffio/src/app/core/sidebar/reducers/sidebar.reducer.ts +++ b/apps/daffio/src/app/core/sidebar/reducers/sidebar.reducer.ts @@ -8,6 +8,7 @@ import { export interface State { showSidebar: boolean; mode: DaffSidebarMode; + kind?: string; } export const initialState: State = { @@ -18,18 +19,18 @@ export const initialState: State = { export function reducer(state = initialState, action: SidebarActions): State { switch (action.type) { case SidebarActionTypes.ToggleSidebarAction: - return { ...state, showSidebar: !state.showSidebar }; + return { ...state, showSidebar: !state.showSidebar, kind: action.payload }; case SidebarActionTypes.CloseSidebarAction: return { ...state, showSidebar: false }; case SidebarActionTypes.OpenSidebarAction: - return { ...state, showSidebar: true }; + return { ...state, showSidebar: true, kind: action.payload }; case SidebarActionTypes.SetSidebarVisibilityAction: return { ...state, showSidebar: action.payload }; case SidebarActionTypes.SetSidebarStateAction: return { ...state, mode: action.payload?.mode ?? state.mode, - showSidebar: action.payload?.open ?? state.showSidebar, + showSidebar: action.payload?.open ?? state.showSidebar, kind: action.payload.kind, }; case SidebarActionTypes.SetSidebarModeAction: return { ...state, mode: action.payload }; @@ -42,3 +43,4 @@ export function reducer(state = initialState, action: SidebarActions): State { export const getShowSidebar = (state: State) => state.showSidebar; export const getMode = (state: State) => state.mode; +export const getKind = (state: State) => state.kind; diff --git a/apps/daffio/src/app/core/sidebar/sidebar.module.ts b/apps/daffio/src/app/core/sidebar/sidebar.module.ts index 71b21c9bc7..d242c87f5c 100644 --- a/apps/daffio/src/app/core/sidebar/sidebar.module.ts +++ b/apps/daffio/src/app/core/sidebar/sidebar.module.ts @@ -9,7 +9,7 @@ import { DaffRouterNamedViewOutletModule } from '@daffodil/router'; import { DaffioSidebarViewportContainer } from './containers/sidebar-viewport/sidebar-viewport.component'; import { DaffioSidebarStateModule } from './sidebar.state.module'; -import { DaffioGuidesNavModule } from '../../guides/components/guides-nav/guides-nav.module'; +import { DaffioDocsPackagesListContainerModule } from '../../guides/containers/packages-list/packages-list.module'; @NgModule({ imports: [ @@ -21,7 +21,7 @@ import { DaffioGuidesNavModule } from '../../guides/components/guides-nav/guides DaffButtonModule, DaffioSidebarStateModule, - DaffioGuidesNavModule, + DaffioDocsPackagesListContainerModule, DaffRouterNamedViewOutletModule, ], declarations: [ diff --git a/apps/daffio/src/app/docs/components/doc-viewer/doc-viewer.component.html b/apps/daffio/src/app/docs/components/doc-viewer/doc-viewer.component.html index 558f1ff228..259670b657 100644 --- a/apps/daffio/src/app/docs/components/doc-viewer/doc-viewer.component.html +++ b/apps/daffio/src/app/docs/components/doc-viewer/doc-viewer.component.html @@ -1,7 +1,7 @@ - +
{ WrapperComponent, DaffioDocViewerComponent, ], + providers: [ + provideMockStore(), + ], }) .compileComponents(); })); diff --git a/apps/daffio/src/app/docs/components/doc-viewer/doc-viewer.component.ts b/apps/daffio/src/app/docs/components/doc-viewer/doc-viewer.component.ts index aaba903d37..022eb4ad34 100644 --- a/apps/daffio/src/app/docs/components/doc-viewer/doc-viewer.component.ts +++ b/apps/daffio/src/app/docs/components/doc-viewer/doc-viewer.component.ts @@ -9,7 +9,10 @@ import { SafeHtml, } from '@angular/platform-browser'; import { faBars } from '@fortawesome/free-solid-svg-icons'; +import { Store } from '@ngrx/store'; +import { ToggleSidebar } from '../../../core/sidebar/actions/sidebar.actions'; +import { DAFFIO_DOCS_CONTENT_SIDEBAR_KIND } from '../../../core/sidebar/containers/docs-sidebar/docs-sidebar.component'; import { DaffioDoc } from '../../models/doc'; @Component({ @@ -21,7 +24,7 @@ import { DaffioDoc } from '../../models/doc'; export class DaffioDocViewerComponent implements OnChanges { faBars = faBars; - constructor(private sanitizer: DomSanitizer) {} + constructor(private sanitizer: DomSanitizer, private store: Store) {} /** * The doc to render @@ -34,4 +37,8 @@ export class DaffioDocViewerComponent implements OnChanges { //It is necessary to bypass the default angular sanitization to keep id tags in the injected html. These id tags are used for fragment routing. this.sanitizedContent = this.sanitizer.bypassSecurityTrustHtml(this.doc.contents); } + + open() { + this.store.dispatch(new ToggleSidebar(DAFFIO_DOCS_CONTENT_SIDEBAR_KIND)); + } } diff --git a/apps/daffio/src/app/docs/containers/sidebar/sidebar.component.html b/apps/daffio/src/app/docs/containers/sidebar/sidebar.component.html deleted file mode 100644 index 8f7e3a7365..0000000000 --- a/apps/daffio/src/app/docs/containers/sidebar/sidebar.component.html +++ /dev/null @@ -1,3 +0,0 @@ - - -API Index \ No newline at end of file diff --git a/apps/daffio/src/app/docs/containers/sidebar/sidebar.component.scss b/apps/daffio/src/app/docs/containers/sidebar/sidebar.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/apps/daffio/src/app/docs/containers/sidebar/sidebar.component.spec.ts b/apps/daffio/src/app/docs/containers/sidebar/sidebar.component.spec.ts deleted file mode 100644 index 4be0f92264..0000000000 --- a/apps/daffio/src/app/docs/containers/sidebar/sidebar.component.spec.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { - ComponentFixture, - TestBed, - waitForAsync, -} from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; -import { DaffioGuidesNavModule } from 'apps/daffio/src/app/guides/components/guides-nav/guides-nav.module'; -import { of } from 'rxjs'; - -import { DaffioDocsSidebarContainer } from './sidebar.component'; -import { DaffioGuidesNavComponent } from '../../../guides/components/guides-nav/guides-nav.component'; -import { DaffioDocsService } from '../../services/docs.service'; -import { mockGuides } from '../../testing/factories/guide-list.factory'; - -describe('DaffioDocsSidebarContainer', () => { - let component: DaffioDocsSidebarContainer; - let fixture: ComponentFixture; - let docServiceSpy: jasmine.SpyObj; - - beforeEach(waitForAsync(() => { - docServiceSpy = jasmine.createSpyObj('DaffioDocsService', ['getGuideList']); - - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - NoopAnimationsModule, - DaffioGuidesNavModule, - HttpClientTestingModule, - ], - declarations: [ - DaffioDocsSidebarContainer, - ], - providers: [ - { - provide: DaffioDocsService, - useValue: docServiceSpy, - }, - ], - }) - .compileComponents(); - })); - - beforeEach(() => { - docServiceSpy.getGuideList.and.returnValue(of(mockGuides)); - - fixture = TestBed.createComponent(DaffioDocsSidebarContainer); - component = fixture.componentInstance; - - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('on ', () => { - let guidesNav: DaffioGuidesNavComponent; - - beforeEach(() => { - guidesNav = fixture.debugElement.query(By.directive(DaffioGuidesNavComponent)).componentInstance; - }); - - it('should set guideList', () => { - expect(guidesNav.guideList).toEqual(mockGuides); - }); - }); -}); diff --git a/apps/daffio/src/app/docs/containers/sidebar/sidebar.component.ts b/apps/daffio/src/app/docs/containers/sidebar/sidebar.component.ts deleted file mode 100644 index 6a2f34cb00..0000000000 --- a/apps/daffio/src/app/docs/containers/sidebar/sidebar.component.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { - ChangeDetectionStrategy, - Component, - OnInit, -} from '@angular/core'; -import { Observable } from 'rxjs'; - -import { DaffioDoc } from '../../models/doc'; -import { DaffioGuideList } from '../../models/guide-list'; -import { DaffioDocsService } from '../../services/docs.service'; - -@Component({ - selector: 'daffio-sidebar-container', - templateUrl: './sidebar.component.html', - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class DaffioDocsSidebarContainer implements OnInit{ - sidebarContents$: Observable; - - constructor( - private docService: DaffioDocsService, - ) {} - - ngOnInit() { - this.sidebarContents$ = this.docService.getGuideList(); - } -} diff --git a/apps/daffio/src/app/docs/containers/sidebar/sidebar.module.ts b/apps/daffio/src/app/docs/containers/sidebar/sidebar.module.ts deleted file mode 100644 index 893d0168fd..0000000000 --- a/apps/daffio/src/app/docs/containers/sidebar/sidebar.module.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { DaffButtonModule } from '@daffodil/design/button'; - -import { DaffioDocsSidebarContainer } from './sidebar.component'; -import { DaffioGuidesNavModule } from '../../../guides/components/guides-nav/guides-nav.module'; - -@NgModule({ - imports: [ - CommonModule, - RouterModule, - DaffButtonModule, - DaffioGuidesNavModule, - ], - declarations: [ - DaffioDocsSidebarContainer, - ], - exports: [ - DaffioDocsSidebarContainer, - ], -}) -export class DaffioDocsSidebarModule {} diff --git a/apps/daffio/src/app/guides/components/guides-nav/guides-nav.component.html b/apps/daffio/src/app/guides/components/packages-list/packages-list.component.html similarity index 100% rename from apps/daffio/src/app/guides/components/guides-nav/guides-nav.component.html rename to apps/daffio/src/app/guides/components/packages-list/packages-list.component.html diff --git a/apps/daffio/src/app/guides/components/guides-nav/guides-nav.component.spec.ts b/apps/daffio/src/app/guides/components/packages-list/packages-list.component.spec.ts similarity index 81% rename from apps/daffio/src/app/guides/components/guides-nav/guides-nav.component.spec.ts rename to apps/daffio/src/app/guides/components/packages-list/packages-list.component.spec.ts index 3c59166fb3..aa7fe504c8 100644 --- a/apps/daffio/src/app/guides/components/guides-nav/guides-nav.component.spec.ts +++ b/apps/daffio/src/app/guides/components/packages-list/packages-list.component.spec.ts @@ -9,16 +9,16 @@ import { RouterTestingModule } from '@angular/router/testing'; import { DaffTreeModule } from '@daffodil/design/tree'; -import { DaffioGuidesNavComponent } from './guides-nav.component'; +import { DaffioDocsPackagesListComponent } from './packages-list.component'; -describe('DaffioGuidesNavComponent', () => { - let component: DaffioGuidesNavComponent; - let fixture: ComponentFixture; +describe('DaffioDocsPackagesListComponent', () => { + let component: DaffioDocsPackagesListComponent; + let fixture: ComponentFixture; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ - DaffioGuidesNavComponent, + DaffioDocsPackagesListComponent, ], imports: [ RouterTestingModule, @@ -30,7 +30,7 @@ describe('DaffioGuidesNavComponent', () => { })); beforeEach(() => { - fixture = TestBed.createComponent(DaffioGuidesNavComponent); + fixture = TestBed.createComponent(DaffioDocsPackagesListComponent); component = fixture.componentInstance; const guideWithoutChildren = { id: 'id2', diff --git a/apps/daffio/src/app/guides/components/guides-nav/guides-nav.component.ts b/apps/daffio/src/app/guides/components/packages-list/packages-list.component.ts similarity index 87% rename from apps/daffio/src/app/guides/components/guides-nav/guides-nav.component.ts rename to apps/daffio/src/app/guides/components/packages-list/packages-list.component.ts index bd778f7e9b..0e23d70630 100644 --- a/apps/daffio/src/app/guides/components/guides-nav/guides-nav.component.ts +++ b/apps/daffio/src/app/guides/components/packages-list/packages-list.component.ts @@ -21,11 +21,11 @@ const visit = (guide: DaffioGuideList): DaffTreeData => ({ }); @Component({ - selector: 'daffio-guides-nav', - templateUrl: './guides-nav.component.html', + selector: 'daffio-docs-packages-list', + templateUrl: './packages-list.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) -export class DaffioGuidesNavComponent { +export class DaffioDocsPackagesListComponent { _guideList: DaffioGuideList; /** diff --git a/apps/daffio/src/app/guides/components/guides-nav/guides-nav.module.ts b/apps/daffio/src/app/guides/components/packages-list/packages-list.module.ts similarity index 61% rename from apps/daffio/src/app/guides/components/guides-nav/guides-nav.module.ts rename to apps/daffio/src/app/guides/components/packages-list/packages-list.module.ts index 8ed419e7ba..e04c5d2504 100644 --- a/apps/daffio/src/app/guides/components/guides-nav/guides-nav.module.ts +++ b/apps/daffio/src/app/guides/components/packages-list/packages-list.module.ts @@ -4,14 +4,14 @@ import { RouterModule } from '@angular/router'; import { DaffTreeModule } from '@daffodil/design/tree'; -import { DaffioGuidesNavComponent } from './guides-nav.component'; +import { DaffioDocsPackagesListComponent } from './packages-list.component'; @NgModule({ declarations: [ - DaffioGuidesNavComponent, + DaffioDocsPackagesListComponent, ], exports: [ - DaffioGuidesNavComponent, + DaffioDocsPackagesListComponent, ], imports: [ CommonModule, @@ -19,4 +19,4 @@ import { DaffioGuidesNavComponent } from './guides-nav.component'; DaffTreeModule, ], }) -export class DaffioGuidesNavModule { } +export class DaffioDocsPackagesListComponentModule { } diff --git a/apps/daffio/src/app/guides/containers/packages-list/packages-list.component.html b/apps/daffio/src/app/guides/containers/packages-list/packages-list.component.html new file mode 100644 index 0000000000..c3b058c7f7 --- /dev/null +++ b/apps/daffio/src/app/guides/containers/packages-list/packages-list.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/daffio/src/app/guides/containers/packages-list/packages-list.component.spec.ts b/apps/daffio/src/app/guides/containers/packages-list/packages-list.component.spec.ts new file mode 100644 index 0000000000..e7c64a81ab --- /dev/null +++ b/apps/daffio/src/app/guides/containers/packages-list/packages-list.component.spec.ts @@ -0,0 +1,39 @@ +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { + waitForAsync, + ComponentFixture, + TestBed, +} from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { RouterTestingModule } from '@angular/router/testing'; + +import { DaffioDocsPackagesListContainer } from './packages-list.component'; + +describe('DaffioDocsPackagesListContainer', () => { + let component: DaffioDocsPackagesListContainer; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ + DaffioDocsPackagesListContainer, + ], + imports: [ + RouterTestingModule, + NoopAnimationsModule, + HttpClientTestingModule, + ], + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DaffioDocsPackagesListContainer); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/daffio/src/app/guides/containers/packages-list/packages-list.component.ts b/apps/daffio/src/app/guides/containers/packages-list/packages-list.component.ts new file mode 100644 index 0000000000..6ab342da11 --- /dev/null +++ b/apps/daffio/src/app/guides/containers/packages-list/packages-list.component.ts @@ -0,0 +1,28 @@ +import { + ChangeDetectionStrategy, + Component, + OnInit, +} from '@angular/core'; +import { Observable } from 'rxjs'; + +import { DaffioDoc } from '../../../docs/models/doc'; +import { DaffioGuideList } from '../../../docs/models/guide-list'; +import { DaffioDocsService } from '../../../docs/services/docs.service'; + +@Component({ + selector: 'daffio-docs-packages-list-container', + templateUrl: './packages-list.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class DaffioDocsPackagesListContainer implements OnInit { + + packagesList$: Observable; + + constructor( + private docService: DaffioDocsService, + ) {} + + ngOnInit() { + this.packagesList$ = this.docService.getGuideList(); + } +} diff --git a/apps/daffio/src/app/guides/containers/packages-list/packages-list.module.ts b/apps/daffio/src/app/guides/containers/packages-list/packages-list.module.ts new file mode 100644 index 0000000000..4aaefa63ac --- /dev/null +++ b/apps/daffio/src/app/guides/containers/packages-list/packages-list.module.ts @@ -0,0 +1,21 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { DaffioDocsPackagesListContainer } from './packages-list.component'; +import { DaffioDocsPackagesListComponentModule } from '../../components/packages-list/packages-list.module'; + +@NgModule({ + declarations: [ + DaffioDocsPackagesListContainer, + ], + exports: [ + DaffioDocsPackagesListContainer, + ], + imports: [ + CommonModule, + RouterModule, + DaffioDocsPackagesListComponentModule, + ], +}) +export class DaffioDocsPackagesListContainerModule { } diff --git a/apps/design-land/src/app/core/sidebar-viewport/sidebar-viewport.component.spec.ts b/apps/design-land/src/app/core/sidebar-viewport/sidebar-viewport.component.spec.ts index 555845ba7c..55c4b76d38 100644 --- a/apps/design-land/src/app/core/sidebar-viewport/sidebar-viewport.component.spec.ts +++ b/apps/design-land/src/app/core/sidebar-viewport/sidebar-viewport.component.spec.ts @@ -7,7 +7,6 @@ import { import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { RouterTestingModule } from '@angular/router/testing'; -import { DaffioGuidesNavModule } from 'apps/daffio/src/app/guides/components/guides-nav/guides-nav.module'; import { DaffSidebarModule, @@ -31,7 +30,6 @@ describe('DesignLandSidebarViewportComponent', () => { RouterTestingModule, NoopAnimationsModule, DaffSidebarModule, - DaffioGuidesNavModule, HttpClientTestingModule, ], declarations: [ diff --git a/package-lock.json b/package-lock.json index fa596d6651..fee400a585 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "@fortawesome/free-brands-svg-icons": "^6.4.2", "@fortawesome/free-regular-svg-icons": "^6.4.2", "@fortawesome/free-solid-svg-icons": "^6.4.2", + "@ngrx/component": "^15.0.0", "@ngrx/effects": "^15.0.0", "@ngrx/entity": "^15.0.0", "@ngrx/router-store": "^15.0.0", @@ -6107,6 +6108,19 @@ "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==", "dev": true }, + "node_modules/@ngrx/component": { + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/@ngrx/component/-/component-15.4.0.tgz", + "integrity": "sha512-mkSFYAOBQ6i8BNioJj0PWcXQ6D9x6LYmhmDdMrs9cUeCRT4ePbvy05D3m+45UPSQQoNMtS+g209D63tYXYy3uQ==", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/common": "^15.0.0", + "@angular/core": "^15.0.0", + "rxjs": "^6.5.3 || ^7.5.0" + } + }, "node_modules/@ngrx/effects": { "version": "15.4.0", "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-15.4.0.tgz", @@ -39505,6 +39519,14 @@ "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==", "dev": true }, + "@ngrx/component": { + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/@ngrx/component/-/component-15.4.0.tgz", + "integrity": "sha512-mkSFYAOBQ6i8BNioJj0PWcXQ6D9x6LYmhmDdMrs9cUeCRT4ePbvy05D3m+45UPSQQoNMtS+g209D63tYXYy3uQ==", + "requires": { + "tslib": "^2.0.0" + } + }, "@ngrx/effects": { "version": "15.4.0", "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-15.4.0.tgz", diff --git a/package.json b/package.json index 2f24fbeb2b..0e6aadee43 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@fortawesome/free-brands-svg-icons": "^6.4.2", "@fortawesome/free-regular-svg-icons": "^6.4.2", "@fortawesome/free-solid-svg-icons": "^6.4.2", + "@ngrx/component": "^15.0.0", "@ngrx/effects": "^15.0.0", "@ngrx/entity": "^15.0.0", "@ngrx/router-store": "^15.0.0",