Display list view module title

- Change List and ListHeader components to grab data and pass it down
- Update ModuleTitle component to title as input and display it
- Update and add jasmine test for these components
This commit is contained in:
Clemente Raposo 2020-05-22 14:55:39 +01:00 committed by Dillon-Brown
parent 16de3551f2
commit 4da2aa3bba
13 changed files with 303 additions and 157 deletions

View file

@ -18,8 +18,8 @@ import {FilterUiModule} from '@components/filter/filter.module';
import {ColumnchooserUiModule} from '@components/columnchooser/columnchooser.module';
import {WidgetUiModule} from '@components/widget/widget.module';
import {TableUiModule} from '@components/table/table.module';
import {ModuletitleUiModule} from '@components/module-title/module-title.module';
import {ListheaderUiModule} from '@components/list-header/list-header.module';
import {ModuleTitleModule} from '@components/module-title/module-title.module';
import {ListHeaderModule} from '@components/list-header/list-header.module';
import {ListcontainerUiModule} from '@components/list-container/list-container.module';
import {ListModule} from '@views/list/list.module';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
@ -60,8 +60,8 @@ import {BnNgIdleService} from 'bn-ng-idle';
ListModule,
WidgetUiModule,
TableUiModule,
ModuletitleUiModule,
ListheaderUiModule,
ModuleTitleModule,
ListHeaderModule,
ListcontainerUiModule,
ColumnchooserUiModule,
ImageModule,

View file

@ -1,44 +1,45 @@
<!-- Start List View Header Section -->
<div class="list-view-header">
<ng-template [ngIf]="displayResponsiveTable">
<div class="d-flex flex-nowrap">
<div class="row">
<div class="col">
<div class="order-3">
<scrm-action-menu-ui></scrm-action-menu-ui>
</div>
</div>
<div class="w-100"></div>
<div class="col">
<div class="order-2">
<scrm-module-title-ui></scrm-module-title-ui>
</div>
</div>
<div class="w-100"></div>
<div class="col">
<div class="order-1">
<scrm-settings-menu-ui></scrm-settings-menu-ui>
</div>
</div>
</div>
<ng-container *ngIf="(vm$ | async) as vm">
<div class="list-view-header">
<ng-container *ngIf="displayResponsiveTable">
<div class="d-flex flex-nowrap">
<div class="row">
<div class="col">
<div class="order-3">
<scrm-action-menu-ui></scrm-action-menu-ui>
</div>
</div>
<div class="w-100"></div>
<div class="col">
<div class="order-2">
<scrm-module-title [title]="getModuleTitle(vm.appListStrings, vm.moduleInfo)">
</scrm-module-title>
</div>
</div>
<div class="w-100"></div>
<div class="col">
<div class="order-1">
<scrm-settings-menu-ui></scrm-settings-menu-ui>
</div>
</div>
</div>
</div>
</ng-container>
<ng-template [ngIf]="!displayResponsiveTable">
<div class="row mr-0">
<div class="col-md-4">
<scrm-module-title [title]="getModuleTitle(vm.appListStrings, vm.moduleInfo)"></scrm-module-title>
</div>
<div class="col-md-8">
<div class="row mr-1 ml-1">
<div class="w-100">
<scrm-action-menu-ui></scrm-action-menu-ui>
</div>
<div class="w-100">
<scrm-settings-menu-ui></scrm-settings-menu-ui>
</div>
</div>
</div>
</div>
</ng-template>
</div>
</ng-template>
<ng-template [ngIf]="!displayResponsiveTable">
<div class="row mr-0">
<div class="col-md-4">
<scrm-module-title-ui></scrm-module-title-ui>
</div>
<div class="col-md-8">
<div class="row mr-1 ml-1">
<div class="w-100">
<scrm-action-menu-ui></scrm-action-menu-ui>
</div>
<div class="w-100">
<scrm-settings-menu-ui></scrm-settings-menu-ui>
</div>
</div>
</div>
</div>
</ng-template>
</div>
<!-- End List View Header Section -->
</ng-container>

View file

@ -1,50 +1,104 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ListheaderUiComponent} from './list-header.component';
import {ModuletitleUiModule} from '@components/module-title/module-title.module';
import {ActionmenuUiModule} from '@components/action-menu/action-menu.module';
import {SettingsmenuUiModule} from '@components/settings-menu/settings-menu.module';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {Component} from '@angular/core';
import {take} from 'rxjs/operators';
import {of} from 'rxjs';
import {HttpClientTestingModule} from '@angular/common/http/testing';
import {ApolloTestingModule} from 'apollo-angular/testing';
import {ListHeaderComponent} from './list-header.component';
import {ModuleTitleModule} from '@components/module-title/module-title.module';
import {ActionmenuUiModule} from '@components/action-menu/action-menu.module';
import {SettingsmenuUiModule} from '@components/settings-menu/settings-menu.module';
import {ImageModule} from '@components/image/image.module';
import {ThemeImagesFacade} from '@base/facades/theme-images/theme-images.facade';
import {of} from 'rxjs';
import {themeImagesMockData} from '@base/facades/theme-images/theme-images.facade.spec.mock';
import {take} from 'rxjs/operators';
import {LanguageFacade} from '@store/language/language.facade';
import {languageMockData} from '@store/language/language.facade.spec.mock';
import {NavigationFacade} from '@store/navigation/navigation.facade';
import {navigationMockData} from '@store/navigation/navigation.facade.spec.mock';
describe('ListheaderUiComponent', () => {
let component: ListheaderUiComponent;
let fixture: ComponentFixture<ListheaderUiComponent>;
@Component({
selector: 'list-header-test-host-component',
template: '<scrm-list-header [module]="module"></scrm-list-header>'
})
class ListHeaderTestHostComponent {
module = 'accounts';
}
beforeEach(async(() => {
describe('ListHeaderComponent', () => {
let testHostComponent: ListHeaderTestHostComponent;
let testHostFixture: ComponentFixture<ListHeaderTestHostComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
ModuletitleUiModule,
ModuleTitleModule,
ActionmenuUiModule,
SettingsmenuUiModule,
ApolloTestingModule,
HttpClientTestingModule,
ImageModule
],
declarations: [ListheaderUiComponent],
declarations: [ListHeaderComponent, ListHeaderTestHostComponent],
providers: [
{
provide: ThemeImagesFacade, useValue: {
images$: of(themeImagesMockData).pipe(take(1))
}
},
{
provide: LanguageFacade, useValue: {
appListStrings$: of(languageMockData.appListStrings).pipe(take(1))
}
},
{
provide: NavigationFacade, useValue: {
vm$: of(navigationMockData.navbar).pipe(take(1))
}
},
],
})
.compileComponents();
}));
});
beforeEach(() => {
fixture = TestBed.createComponent(ListheaderUiComponent);
component = fixture.componentInstance;
fixture.detectChanges();
testHostFixture = TestBed.createComponent(ListHeaderTestHostComponent);
testHostComponent = testHostFixture.componentInstance;
testHostFixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
expect(testHostComponent).toBeTruthy();
});
it('should have action menu', () => {
const actionMenuElement = testHostFixture.nativeElement.querySelector('scrm-action-menu-ui');
const actionButtons = actionMenuElement.getElementsByClassName('action-button');
expect(testHostComponent).toBeTruthy();
expect(actionMenuElement).toBeTruthy();
expect(actionButtons).toBeTruthy();
expect(actionButtons.length).toBeGreaterThan(0);
});
it('should have title', () => {
const titleElement = testHostFixture.nativeElement.querySelector('scrm-module-title');
expect(testHostComponent).toBeTruthy();
expect(titleElement).toBeTruthy();
expect(titleElement.innerHTML).toContain('ACCOUNTS');
});
it('should have settings', () => {
const settingsMenuElement = testHostFixture.nativeElement.querySelector('scrm-settings-menu-ui');
const settingsButtons = settingsMenuElement.getElementsByClassName('settings-button');
expect(testHostComponent).toBeTruthy();
expect(settingsMenuElement).toBeTruthy();
expect(settingsButtons).toBeTruthy();
expect(settingsButtons.length).toBeGreaterThan(0);
});
});

View file

@ -1,14 +1,54 @@
import {Component, OnInit} from '@angular/core';
import {Component, Input} from '@angular/core';
import {combineLatest, Observable} from 'rxjs';
import {map} from 'rxjs/operators';
import {LanguageFacade, LanguageListStringMap} from '@store/language/language.facade';
import {NavbarModule, Navigation, NavigationFacade} from '@store/navigation/navigation.facade';
@Component({
selector: 'scrm-list-header-ui',
templateUrl: 'list-header.component.html',
selector: 'scrm-list-header',
templateUrl: 'list-header.component.html'
})
export class ListHeaderComponent {
export class ListheaderUiComponent implements OnInit {
displayResponsiveTable: any;
@Input() module;
appListStrings$: Observable<LanguageListStringMap> = this.language.appListStrings$;
navigation$: Observable<Navigation> = this.navigation.vm$;
displayResponsiveTable = false;
ngOnInit() {
vm$ = combineLatest([
this.appListStrings$,
this.navigation$
]).pipe(
map((
[
appListStrings,
navigation
]
) => {
const moduleInfo = this.getModuleInfo(navigation, this.module);
return {
appListStrings,
navigation,
moduleInfo
};
})
);
constructor(protected language: LanguageFacade, protected navigation: NavigationFacade) {
}
getModuleInfo(navigation: Navigation, module: string): NavbarModule {
if (!navigation || !navigation.modules) {
return null;
}
return navigation.modules[module];
}
getModuleTitle(appListStrings: LanguageListStringMap, module: NavbarModule): string {
if (!appListStrings || !appListStrings.moduleList || !module || !module.labelKey) {
return '';
}
return appListStrings.moduleList[module.labelKey] || '';
}
}

View file

@ -1,25 +1,25 @@
import {NgModule, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {AppManagerModule} from '../../app-manager/app-manager.module';
import {ListheaderUiComponent} from './list-header.component';
import {ListHeaderComponent} from './list-header.component';
import {ModuletitleUiModule} from '../module-title/module-title.module';
import {ModuleTitleModule} from '../module-title/module-title.module';
import {ActionmenuUiModule} from '../action-menu/action-menu.module';
import {SettingsmenuUiModule} from '../settings-menu/settings-menu.module';
import {AngularSvgIconModule} from 'angular-svg-icon';
@NgModule({
declarations: [ListheaderUiComponent],
exports: [ListheaderUiComponent],
imports: [
CommonModule,
AppManagerModule.forChild(ListheaderUiComponent),
ModuletitleUiModule,
ActionmenuUiModule,
SettingsmenuUiModule,
AngularSvgIconModule
]
declarations: [ListHeaderComponent],
exports: [ListHeaderComponent],
imports: [
CommonModule,
AppManagerModule.forChild(ListHeaderComponent),
ModuleTitleModule,
ActionmenuUiModule,
SettingsmenuUiModule,
AngularSvgIconModule
]
})
export class ListheaderUiModule {
}
export class ListHeaderModule {
}

View file

@ -1 +1 @@
<h2 class="list-view-title">MODULE TITLE</h2>
<h2 class="list-view-title">{{title | uppercase}}</h2>

View file

@ -1,25 +1,48 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {ModuletitleUiComponent} from './module-title.component';
import {ModuleTitleComponent} from './module-title.component';
import {Component} from '@angular/core';
describe('ModuletitleUiComponent', () => {
let component: ModuletitleUiComponent;
let fixture: ComponentFixture<ModuletitleUiComponent>;
@Component({
selector: 'module-title-test-host-component',
template: '<scrm-module-title [title]="title"></scrm-module-title>'
})
class ModuleTitleTestHostComponent {
title = 'Accounts';
}
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ModuletitleUiComponent]
})
.compileComponents();
}));
describe('ModuleTitleComponent', () => {
let testHostComponent: ModuleTitleTestHostComponent;
let testHostFixture: ComponentFixture<ModuleTitleTestHostComponent>;
beforeEach(() => {
fixture = TestBed.createComponent(ModuletitleUiComponent);
component = fixture.componentInstance;
fixture.detectChanges();
TestBed.configureTestingModule({
declarations: [
ModuleTitleComponent,
ModuleTitleTestHostComponent,
],
imports: [],
providers: [],
}).compileComponents();
});
beforeEach(() => {
testHostFixture = TestBed.createComponent(ModuleTitleTestHostComponent);
testHostComponent = testHostFixture.componentInstance;
testHostFixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
expect(testHostComponent).toBeTruthy();
});
it('should have title', () => {
const h4Element = testHostFixture.nativeElement.querySelector('h2');
expect(testHostComponent).toBeTruthy();
expect(h4Element).toBeTruthy();
expect(h4Element.className).toContain('list-view-title');
expect(h4Element.textContent).toContain('ACCOUNTS');
});
});

View file

@ -1,15 +1,9 @@
import {Component, OnInit} from '@angular/core';
import {Component, Input} from '@angular/core';
@Component({
selector: 'scrm-module-title-ui',
templateUrl: 'module-title.component.html',
selector: 'scrm-module-title',
templateUrl: 'module-title.component.html'
})
export class ModuletitleUiComponent implements OnInit {
ngOnInit() {
}
export class ModuleTitleComponent {
@Input() title = '';
}

View file

@ -1,18 +1,13 @@
import {NgModule, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {AppManagerModule} from '../../app-manager/app-manager.module';
import {ModuletitleUiComponent} from './module-title.component';
import {AngularSvgIconModule} from 'angular-svg-icon';
import {ModuleTitleComponent} from './module-title.component';
@NgModule({
declarations: [ModuletitleUiComponent],
exports: [ModuletitleUiComponent],
declarations: [ModuleTitleComponent],
exports: [ModuleTitleComponent],
imports: [
CommonModule,
AppManagerModule.forChild(ModuletitleUiComponent),
AngularSvgIconModule
]
})
export class ModuletitleUiModule {
}
export class ModuleTitleModule {
}

View file

@ -1,9 +1,7 @@
<!-- Start List View Section -->
<div class="list-view">
<div class="list-view" *ngIf="(vm$ | async) as vm">
<scrm-field [view]="'list'" [type]="'varchar'" [value]="'MY FIELD VALUE'"></scrm-field>
<scrm-list-header-ui></scrm-list-header-ui>
<scrm-list-header [module]="vm.appState.module"></scrm-list-header>
<scrm-list-container-ui></scrm-list-container-ui>
</div>
<!-- End List View Section -->

View file

@ -1,29 +1,37 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ListComponent} from './list.component';
import {ListheaderUiModule} from '@components/list-header/list-header.module';
import {ListcontainerUiModule} from '@components/list-container/list-container.module';
import {Component} from '@angular/core';
import {HttpClientTestingModule} from '@angular/common/http/testing';
import {RouterTestingModule} from '@angular/router/testing';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {ImageModule} from '@components/image/image.module';
import {ApolloTestingModule} from 'apollo-angular/testing';
import {ThemeImagesFacade} from '@base/facades/theme-images/theme-images.facade';
import {themeImagesMockData} from '@base/facades/theme-images/theme-images.facade.spec.mock';
import {take} from 'rxjs/operators';
import {of} from 'rxjs';
import {ApolloTestingModule} from 'apollo-angular/testing';
import {ListComponent} from './list.component';
import {ListHeaderModule} from '@components/list-header/list-header.module';
import {ListcontainerUiModule} from '@components/list-container/list-container.module';
import {ImageModule} from '@components/image/image.module';
import {ThemeImagesFacade} from '@base/facades/theme-images/theme-images.facade';
import {themeImagesMockData} from '@base/facades/theme-images/theme-images.facade.spec.mock';
import {AppStateFacade} from '@store/app-state/app-state.facade';
import {DynamicModule} from "ng-dynamic-component";
import {FieldModule} from "../../fields/field.module";
import { By } from '@angular/platform-browser';
@Component({
selector: 'list-test-host-component',
template: '<scrm-list></scrm-list>'
})
class ListTestHostComponent {
}
describe('ListComponent', () => {
let component: ListComponent;
let fixture: ComponentFixture<ListComponent>;
let testHostComponent: ListTestHostComponent;
let testHostFixture: ComponentFixture<ListTestHostComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
ListheaderUiModule,
ListHeaderModule,
ListcontainerUiModule,
HttpClientTestingModule,
RouterTestingModule,
@ -33,11 +41,21 @@ describe('ListComponent', () => {
DynamicModule,
FieldModule
],
declarations: [ListComponent],
declarations: [ListComponent, ListTestHostComponent],
providers: [
{
provide: ThemeImagesFacade, useValue: {
images$: of(themeImagesMockData).pipe(take(1))
},
},
{
provide: AppStateFacade, useValue: {
vm$: of({
loading: false,
module: 'accounts',
view: 'list',
loaded: true
}).pipe(take(1))
}
},
],
@ -46,19 +64,36 @@ describe('ListComponent', () => {
}));
beforeEach(() => {
fixture = TestBed.createComponent(ListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
testHostFixture = TestBed.createComponent(ListTestHostComponent);
testHostComponent = testHostFixture.componentInstance;
testHostFixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
expect(testHostComponent).toBeTruthy();
});
it('should have list header', () => {
const headerElement = testHostFixture.nativeElement.querySelector('scrm-list-header');
expect(testHostComponent).toBeTruthy();
expect(headerElement).toBeTruthy();
});
it('should have list container', () => {
const listContainerElement = testHostFixture.nativeElement.querySelector('scrm-list-container-ui');
expect(testHostComponent).toBeTruthy();
expect(listContainerElement).toBeTruthy();
});
it('should have title', () => {
const element = fixture.debugElement.query(By.css('.ng-star-inserted')).nativeElement;
expect(fixture).toBeTruthy();
const element = testHostFixture.debugElement.query(By.css('.ng-star-inserted')).nativeElement;
expect(testHostFixture).toBeTruthy();
expect(element).toBeTruthy();
expect(element.textContent).toContain('MY FIELD VALUE');
});
});

View file

@ -1,16 +1,22 @@
import {Component, OnInit} from '@angular/core';
import {Component} from '@angular/core';
import {AppState, AppStateFacade} from '@store/app-state/app-state.facade';
import {combineLatest, Observable} from 'rxjs';
import {map} from 'rxjs/operators';
@Component({
selector: 'scrm-list',
templateUrl: './list.component.html',
styleUrls: []
})
export class ListComponent implements OnInit {
export class ListComponent {
appState$: Observable<AppState> = this.appState.vm$;
constructor() {
vm$ = combineLatest([this.appState$]).pipe(
map(([appState]) => ({
appState,
}))
);
constructor(protected appState: AppStateFacade) {
}
ngOnInit() {
}
}

View file

@ -1,7 +1,7 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ListComponent} from './list.component';
import {ListheaderUiModule} from '@components/list-header/list-header.module';
import {ListHeaderModule} from '@components/list-header/list-header.module';
import {ListcontainerUiModule} from '@components/list-container/list-container.module';
import {FieldModule} from '../../fields/field.module';
@ -10,7 +10,7 @@ import {FieldModule} from '../../fields/field.module';
exports: [ListComponent],
imports: [
CommonModule,
ListheaderUiModule,
ListHeaderModule,
ListcontainerUiModule,
FieldModule
]