diff --git a/docs/apps-list.component.md b/docs/apps-list.component.md index 8744ebdbda..b78ccd4018 100644 --- a/docs/apps-list.component.md +++ b/docs/apps-list.component.md @@ -12,6 +12,19 @@ Shows all available apps. ``` +## Passing custom no-apps template + +If we intend to show a custom template if there are no apps present + +```html + + +
No apps present
+
+
+``` + ### Properties | Name | Type | Default value | Description | diff --git a/lib/process-services/app-list/apps-list.component.html b/lib/process-services/app-list/apps-list.component.html index dab36c7336..89c2d5e65a 100644 --- a/lib/process-services/app-list/apps-list.component.html +++ b/lib/process-services/app-list/apps-list.component.html @@ -34,6 +34,22 @@ - + + +
+ +
+
+ + + + + + + +
+ {{ 'ADF_TASK_LIST.APPS.NONE' | translate }} +
+
+
+
diff --git a/lib/process-services/app-list/apps-list.component.scss b/lib/process-services/app-list/apps-list.component.scss index 2af14a42ee..2702466dd8 100644 --- a/lib/process-services/app-list/apps-list.component.scss +++ b/lib/process-services/app-list/apps-list.component.scss @@ -24,6 +24,17 @@ $themes: ( theme-10: (bg: #cabb33, color: #baab23) ); +.adf-app-list-spinner { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + height: 85vh; + .mat-spinner { + margin: 0 auto; + } +} + .adf-app-listgrid { padding: 8px; diff --git a/lib/process-services/app-list/apps-list.component.spec.ts b/lib/process-services/app-list/apps-list.component.spec.ts index 63f7296dd4..3d481fc217 100644 --- a/lib/process-services/app-list/apps-list.component.spec.ts +++ b/lib/process-services/app-list/apps-list.component.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { DebugElement } from '@angular/core'; +import { DebugElement, Component } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { AppsProcessService, CoreModule } from '@alfresco/adf-core'; @@ -70,6 +70,19 @@ describe('AppsListComponent', () => { expect(getAppsSpy).toHaveBeenCalled(); }); + it('loading should be false by default', () => { + expect(component.loading).toBeFalsy(); + }); + + it('should show the loading spinner when the apps are loading', async(() => { + component.loading = true; + fixture.detectChanges(); + fixture.whenStable().then(() => { + let loadingSpinner = fixture.nativeElement.querySelector('mat-spinner'); + expect(loadingSpinner).toBeDefined(); + }); + })); + it('should show the apps filtered by defaultAppId', () => { component.filtersAppId = [{defaultAppId: 'fake-app-1'}]; fixture.detectChanges(); @@ -239,3 +252,45 @@ describe('AppsListComponent', () => { }); }); + +@Component({ + template: ` + + +
No Apps
+
+
+ ` +}) +class CustomEmptyAppListTemplateComponent { +} + +describe('Custom CustomEmptyAppListTemplateComponent', () => { + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + AppsListComponent, + CustomEmptyAppListTemplateComponent + ], + imports: [ + MaterialModule + ] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CustomEmptyAppListTemplateComponent); + fixture.detectChanges(); + }); + + it('should render the custom no-apps template', async(() => { + fixture.whenStable().then(() => { + fixture.detectChanges(); + let title: any = fixture.debugElement.queryAll(By.css('[adf-empty-list-header]')); + expect(title.length).toBe(1); + expect(title[0].nativeElement.innerText).toBe('No Apps'); + }); + })); +}); diff --git a/lib/process-services/app-list/apps-list.component.ts b/lib/process-services/app-list/apps-list.component.ts index c80a1b0dde..a4b028aca1 100644 --- a/lib/process-services/app-list/apps-list.component.ts +++ b/lib/process-services/app-list/apps-list.component.ts @@ -15,8 +15,8 @@ * limitations under the License. */ -import { AppsProcessService, TranslationService } from '@alfresco/adf-core'; -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { AppsProcessService, TranslationService, EmptyListComponent } from '@alfresco/adf-core'; +import { AfterContentInit, Component, EventEmitter, Input, OnInit, Output, ContentChild } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { Observer } from 'rxjs/Observer'; import { AppDefinitionRepresentationModel } from '../task-list'; @@ -27,7 +27,7 @@ import { IconModel } from './icon.model'; templateUrl: 'apps-list.component.html', styleUrls: ['./apps-list.component.scss'] }) -export class AppsListComponent implements OnInit { +export class AppsListComponent implements OnInit, AfterContentInit { public static LAYOUT_LIST: string = 'LIST'; public static LAYOUT_GRID: string = 'GRID'; @@ -37,6 +37,9 @@ export class AppsListComponent implements OnInit { public static DEFAULT_TASKS_APP_ICON: string = 'glyphicon-asterisk'; public static DEFAULT_TASKS_APP_MATERIAL_ICON: string = 'favorite_border'; + @ContentChild(EmptyListComponent) + emptyTemplate: EmptyListComponent; + /** (**required**) Defines the layout of the apps. There are two possible * values, "GRID" and "LIST". */ @@ -64,6 +67,10 @@ export class AppsListComponent implements OnInit { private iconsMDL: IconModel; + loading: boolean = false; + + hasCustomEmptyListTemplate: boolean = false; + constructor( private appsProcessService: AppsProcessService, private translationService: TranslationService) { @@ -82,7 +89,14 @@ export class AppsListComponent implements OnInit { this.load(); } + ngAfterContentInit() { + if (this.emptyTemplate) { + this.hasCustomEmptyListTemplate = true; + } + } + private load() { + this.loading = true; this.appsProcessService.getDeployedApplications() .subscribe( (res: AppDefinitionRepresentationModel[]) => { @@ -94,10 +108,12 @@ export class AppsListComponent implements OnInit { } else if (app.deploymentId) { this.appsObserver.next(app); } + this.loading = false; }); }, (err) => { this.error.emit(err); + this.loading = false; } ); } @@ -185,6 +201,10 @@ export class AppsListComponent implements OnInit { return this.appList.length === 0; } + isLoading(): boolean { + return this.loading; + } + getTheme(app: AppDefinitionRepresentationModel): string { return app.theme ? app.theme : ''; } diff --git a/lib/process-services/app-list/apps-list.module.ts b/lib/process-services/app-list/apps-list.module.ts index d6423d50d6..e24801ec43 100644 --- a/lib/process-services/app-list/apps-list.module.ts +++ b/lib/process-services/app-list/apps-list.module.ts @@ -20,6 +20,7 @@ import { FlexLayoutModule } from '@angular/flex-layout'; import { NgModule } from '@angular/core'; import { MaterialModule } from '../material.module'; import { TranslateModule } from '@ngx-translate/core'; +import { DataTableModule } from '@alfresco/adf-core'; import { AppsListComponent } from './apps-list.component'; import { SelectAppsDialogComponent } from './select-apps-dialog-component'; @@ -29,7 +30,8 @@ import { SelectAppsDialogComponent } from './select-apps-dialog-component'; CommonModule, MaterialModule, FlexLayoutModule, - TranslateModule + TranslateModule, + DataTableModule ], declarations: [ AppsListComponent,