Skip to content

Commit 991b888

Browse files
committed
Move init logic to main component loaded with host directive
1 parent 292a83a commit 991b888

File tree

9 files changed

+309
-254
lines changed

9 files changed

+309
-254
lines changed

projects/amd-app/src/app/app.component.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,25 @@ export class AppComponent {
1515

1616
@HostListener('document:github:niklr/angular-material-datatransfer.create', ['$event'])
1717
public onCreate(event): void {
18-
this.amdComponent.create(event);
18+
if (!!event && !!event.detail) {
19+
const config = event.detail;
20+
this.amdComponent.create(config);
21+
}
1922
}
2023

2124
@HostListener('document:github:niklr/angular-material-datatransfer.update-config', ['$event'])
2225
public onUpdateConfig(event): void {
23-
this.amdComponent.setConfig(event);
26+
if (!!event && !!event.detail) {
27+
const config = event.detail;
28+
this.amdComponent.setConfig(config);
29+
}
2430
}
2531

2632
@HostListener('document:github:niklr/angular-material-datatransfer.download-item', ['$event'])
2733
public downloadItem(event): void {
2834
if (!!event && !!event.detail) {
2935
const item = event.detail;
30-
this.amdComponent.datatransferFacade.download(item.filename, item.url, item.size);
36+
this.amdComponent.download(item.filename, item.url, item.size);
3137
}
3238
}
3339

projects/amd-lib/README.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ angular-material-datatransfer-lib
33

44
Demo: https://niklr.github.io/angular-material-datatransfer/
55

6-
angular-material-datatransfer-lib is a web-based library combining the upload and download of multiple simultaneous files in a unified user interface.
6+
angular-material-datatransfer-lib is a library combining the upload and download of multiple simultaneous files in a unified user interface.
77
The library is explicitly designed for modern browsers supporting advanced [`HTML5 File API`](http://www.w3.org/TR/FileAPI/) features.
88

99
The unified user interface is built on top of Google's [Material Design](https://material.io) implemented by [Angular Material](https://material.angular.io/) using [Angular](https://angular.io/). Material Design by Google's definition is a visual language that synthesizes the classic principles of good design with the innovation and possibility of technology and science.
@@ -38,7 +38,7 @@ Follow the steps below to add this library to your project:
3838
],
3939
"stylePreprocessorOptions": {
4040
"includePaths": [
41-
"node_modules"
41+
"node_modules"
4242
]
4343
},
4444
"scripts": [
@@ -51,10 +51,18 @@ Follow the steps below to add this library to your project:
5151
* [`angular-material-theme.scss`](https://github.com/niklr/angular-material-datatransfer/tree/master/examples/example1/src/style/angular-material-theme.scss)
5252
* [`app.scss`](https://github.com/niklr/angular-material-datatransfer/tree/master/examples/example1/src/style/app.scss)
5353
6. Append the following lines in `src/styles.scss`
54-
* `@import 'angular-material.scss'`;
55-
* `@import 'style/app.scss'`;
54+
55+
```css
56+
@import 'angular-material.scss';
57+
@import 'style/app.scss';
58+
```
59+
5660
7. Include Material Icons in the header of `index.html`
57-
* `<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">`
61+
62+
```html
63+
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
64+
```
65+
5866
8. Extend `app.module.ts` by importing `AngularMaterialDatatransferModule` and `AngularMaterialDatatransferComponent`
5967

6068
```js
@@ -120,7 +128,7 @@ export class AppComponent implements AfterViewInit {
120128
}
121129
}
122130
};
123-
this.amdComponent.create({ detail: config });
131+
this.amdComponent.create(config);
124132
}, 10);
125133
}
126134

Lines changed: 1 addition & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -1,178 +1 @@
1-
<div class="amd-font" *ngIf="isCreated">
2-
<div *ngIf="config.core.showUploadDropzone">
3-
<amd-dropzone></amd-dropzone>
4-
</div>
5-
6-
<div fxLayout="row" fxLayout.lt-sm="column" style="margin-bottom: 10px">
7-
<div fxFlex>
8-
<button class="amd-mr-1" mat-raised-button *ngIf="datatransferFacade.showStartButton()" (click)="datatransferFacade.startAll()">
9-
<mat-icon>play_arrow</mat-icon> Start
10-
</button>
11-
<button class="amd-mr-1" mat-raised-button *ngIf="datatransferFacade.showPauseButton()" (click)="datatransferFacade.pauseAll()">
12-
<mat-icon>pause</mat-icon> Pause
13-
</button>
14-
<button class="amd-mr-1" mat-raised-button *ngIf="datatransferFacade.showRemoveButton()" (click)="datatransferFacade.removeAll()">
15-
<mat-icon>close</mat-icon> Remove all
16-
</button>
17-
<button class="amd-mr-1" mat-raised-button *ngIf="datatransferFacade.showRetryButton()" (click)="datatransferFacade.retryAll()">
18-
<mat-icon>refresh</mat-icon> Retry ({{datatransferStore.failedCount}})
19-
</button>
20-
<mat-menu #exportMenu="matMenu">
21-
<button mat-menu-item (click)="datatransferFacade.export('CSV')">
22-
<span>CSV</span>
23-
</button>
24-
<button mat-menu-item (click)="datatransferFacade.export('JSON')">
25-
<span>JSON</span>
26-
</button>
27-
</mat-menu>
28-
<button mat-raised-button *ngIf="datatransferFacade.showExportButton()" [matMenuTriggerFor]="exportMenu">
29-
Export
30-
<mat-icon>expand_more</mat-icon>
31-
</button>
32-
<mat-checkbox *ngIf="datatransferFacade.showPreprocessingCheckbox()"
33-
[(ngModel)]="config.core.preprocessHashChecked" style="margin-left: 10px;">
34-
Preprocessing <span *ngIf="datatransferFacade.showPreprocessingTooltip()" class="amd-vertical-align-middle"
35-
[matTooltip]="config.core.preprocessHashTooltipContent" matTooltipPosition="right">
36-
<mat-icon>info_outline</mat-icon>
37-
</span>
38-
</mat-checkbox>
39-
</div>
40-
<div fxFlex="70px" fxFlex.lt-sm="0px">
41-
</div>
42-
<div fxFlex>
43-
<div *ngIf="uploadProgress.percent > 0">
44-
<amd-progress [progressContainer]="uploadProgress"></amd-progress>
45-
</div>
46-
<div *ngIf="downloadProgress.percent > 0">
47-
<amd-progress [progressContainer]="downloadProgress"></amd-progress>
48-
</div>
49-
</div>
50-
</div>
51-
52-
<div class="amd-container">
53-
<div fxLayout="row" class="amd-container-header" style="align-items: center;">
54-
<div fxFlex="40px">
55-
<mat-checkbox (change)="datatransferFacade.toggleVisible($event.checked)"></mat-checkbox>
56-
</div>
57-
<div fxFlex="50%" fxFlex.lt-sm="100%">
58-
Filename
59-
</div>
60-
<div fxFlex="50%" style="padding-left: 40px;" fxHide.lt-sm>
61-
Progress
62-
</div>
63-
<div fxFlex="20px">
64-
<mat-menu #batchItemMenu="matMenu">
65-
<button mat-menu-item (click)="datatransferFacade.removeSelected()">
66-
<mat-icon>close</mat-icon>
67-
<span>Remove</span>
68-
</button>
69-
</mat-menu>
70-
<button mat-icon-button [matMenuTriggerFor]="batchItemMenu">
71-
<mat-icon>more_vert</mat-icon>
72-
</button>
73-
</div>
74-
</div>
75-
<ng-template ngFor let-item [ngForOf]="paginationService.paginatedItems" let-i="index">
76-
<div *ngIf="datatransferFacade.showPath(paginationService.paginatedItems, i)">
77-
<div fxLayout="row" class="amd-container-headline">
78-
<div fxFlex class="amd-container-headline-item">
79-
<div class="amd-container-headline-item-entry">
80-
<div fxFlex="40px">
81-
<mat-icon>folder_open</mat-icon>
82-
</div>
83-
<div fxFlex>
84-
<span>
85-
<b>{{item.displayPath}}</b>
86-
</span>
87-
<button mat-icon-button (click)="datatransferFacade.openEditPathDialog(item)"
88-
*ngIf="datatransferFacade.showEditDialog(item)">
89-
<mat-icon aria-label="Edit path">edit</mat-icon>
90-
</button>
91-
</div>
92-
</div>
93-
</div>
94-
</div>
95-
</div>
96-
<div fxLayout="row" fxLayout.lt-sm="column" class="amd-container-row" [ngClass]="{'selected': item.isSelected}">
97-
<div fxFlex class="amd-container-row-item">
98-
<div class="amd-container-row-item-entry">
99-
<div fxFlex="40px">
100-
<mat-checkbox [(ngModel)]="item.isSelected"></mat-checkbox>
101-
</div>
102-
<div fxFlex="100%">
103-
<div matTooltip="{{item.name}}" matTooltipPosition="above">
104-
<span>{{item.name}}</span>
105-
<button mat-icon-button (click)="datatransferFacade.openEditFilenameDialog(item)"
106-
*ngIf="datatransferFacade.showEditDialog(item)">
107-
<mat-icon aria-label="Edit filename">edit</mat-icon>
108-
</button>
109-
</div>
110-
</div>
111-
</div>
112-
</div>
113-
<div fxFlex class="amd-container-row-item">
114-
<div class="amd-container-row-item-entry">
115-
<div fxFlex="40px" matTooltip="{{item.preprocessContainer.percent}}%"
116-
*ngIf="datatransferFacade.showSpinner(item); else showStatusClass">
117-
<mat-progress-spinner *ngIf="item.preprocessContainer.percent > 0" [diameter]="20" mode="determinate"
118-
[value]="item.preprocessContainer.percent"></mat-progress-spinner>
119-
</div>
120-
<ng-template #showStatusClass>
121-
<div fxFlex="40px">
122-
<mat-icon>{{datatransferFacade.getStatusClass(item.status)}}</mat-icon>
123-
</div>
124-
</ng-template>
125-
<div fxFlex="100%">
126-
<div *ngIf="datatransferFacade.showProgressbar(item); else showStatusBlock">
127-
<div class="amd-container-row-item-entry-stats">
128-
<div fxFlex="25%" fxFlex.lt-md="50%">
129-
{{item.progressContainer.displayBitrate}}
130-
</div>
131-
<div fxFlex="25%" fxHide.lt-md style="text-align: center">
132-
{{item.progressContainer.displayTimeLeft}}
133-
</div>
134-
<div fxFlex="25%" fxHide.lt-md style="text-align: center">
135-
{{item.progressContainer.percent}}%
136-
</div>
137-
<div fxFlex="25%" fxFlex.lt-md="50%" style="text-align: right">
138-
{{item.progressContainer.loadedSizeContainer.displaySize}} / {{item.sizeContainer.displaySize}}
139-
{{item.sizeContainer.displayUnit}}
140-
</div>
141-
</div>
142-
<mat-progress-bar *ngIf="item.progressContainer.total > 0" color="primary" mode="determinate"
143-
[value]="item.progressContainer.percent">
144-
</mat-progress-bar>
145-
</div>
146-
<ng-template #showStatusBlock>
147-
{{item.getStatusName()}} ({{item.sizeContainer.displaySize}} {{item.sizeContainer.displayUnit}})
148-
<div *ngIf="!!item.message">
149-
<small>{{datatransferFacade.parseMessage(item)}}</small>
150-
</div>
151-
</ng-template>
152-
</div>
153-
<div fxFlex="20px">
154-
<mat-menu #itemMenu="matMenu">
155-
<button mat-menu-item (click)="datatransferFacade.retryItem(item)"
156-
*ngIf="datatransferFacade.showRetryButtonByItem(item)">
157-
<mat-icon>refresh</mat-icon>
158-
<span>Retry</span>
159-
</button>
160-
<button mat-menu-item (click)="datatransferFacade.removeItem(item)">
161-
<mat-icon>close</mat-icon>
162-
<span>Remove</span>
163-
</button>
164-
</mat-menu>
165-
<button mat-icon-button [matMenuTriggerFor]="itemMenu">
166-
<mat-icon>more_vert</mat-icon>
167-
</button>
168-
</div>
169-
</div>
170-
</div>
171-
</div>
172-
</ng-template>
173-
</div>
174-
175-
<div style="font-size: 12px; margin-top: 20px; text-align: right;">
176-
<amd-pagination [paginationService]="paginationService"></amd-pagination>
177-
</div>
178-
</div>
1+
<ng-template amd-host></ng-template>
Lines changed: 26 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
import { Component, OnInit, ApplicationRef } from '@angular/core';
1+
import { Component, OnInit, ViewChild, ComponentFactoryResolver } from '@angular/core';
2+
import { CustomEventType, CustomEventTypeExtensions } from './enums/custom-event-type.enum';
3+
import { HostDirective } from './directives/host.directive';
4+
import { MainComponent } from './components/main.component';
25
import { DatatransferFacade } from './facades/datatransfer.facade';
3-
import { IProgressContainer } from './models/progress-container.model';
4-
import { LoggerService } from './services/logger.service';
5-
import { ConfigService } from './services/config.service';
66
import { DatatransferFacadeFactory } from './factories/datatransfer-facade.factory';
7-
import { DatatransferStore } from './stores/datatransfer.store';
7+
import { ConfigService } from './services/config.service';
88
import { PaginationService } from './services/pagination.service';
9-
import { CustomEventType, CustomEventTypeExtensions } from './enums/custom-event-type.enum';
10-
import { IAppConfig } from './models/app-config.model';
119

1210
@Component({
1311
// tslint:disable-next-line:component-selector
@@ -16,74 +14,39 @@ import { IAppConfig } from './models/app-config.model';
1614
})
1715
export class AngularMaterialDatatransferComponent implements OnInit {
1816

19-
componentId: number;
17+
@ViewChild(HostDirective, { static: true }) amdHost: HostDirective;
2018

21-
isCreated = false;
22-
config: IAppConfig;
23-
datatransferFacade: DatatransferFacade;
24-
uploadProgress: IProgressContainer;
25-
downloadProgress: IProgressContainer;
19+
private datatransferFacade: DatatransferFacade;
2620

27-
constructor(private logger: LoggerService, private ref: ApplicationRef, private datatransferFacadeFactory: DatatransferFacadeFactory,
28-
private configService: ConfigService, public datatransferStore: DatatransferStore,
29-
public paginationService: PaginationService) {
30-
this.componentId = Math.random();
21+
constructor(private componentFactoryResolver: ComponentFactoryResolver,
22+
private datatransferFacadeFactory: DatatransferFacadeFactory,
23+
private configService: ConfigService,
24+
private paginationService: PaginationService) {
3125
}
3226

3327
ngOnInit() {
3428
document.dispatchEvent(new Event(CustomEventTypeExtensions.toString(CustomEventType.INIT)));
35-
// _.each(this.demoService.testItems, function (item: IDatatransferItem) {
36-
// this.datatransferFacade.addItem(item);
37-
// }.bind(this));
3829
}
3930

40-
private init(): void {
41-
if (this.config.core.showUploadDropzone) {
42-
const dropzoneElement = document.getElementById('amd-dropzone-component');
43-
if (dropzoneElement) {
44-
// this.removeAllEventListeners(dropzoneElement);
45-
dropzoneElement.addEventListener('click', this.datatransferFacade.openBrowseDialog.bind(this.datatransferFacade), false);
46-
this.datatransferFacade.assignUploadDrop(dropzoneElement);
47-
}
48-
} else {
49-
if (typeof this.config.core.uploadBrowseElementId !== 'undefined') {
50-
const uploadBrowseElement = document.getElementById(this.config.core.uploadBrowseElementId);
51-
if (uploadBrowseElement) {
52-
// this.removeAllEventListeners(uploadBrowseElement);
53-
uploadBrowseElement.addEventListener('click', this.datatransferFacade.openBrowseDialog.bind(this.datatransferFacade), false);
54-
}
55-
}
56-
if (typeof this.config.core.uploadDropElementId !== 'undefined') {
57-
const uploadDropElement = document.getElementById(this.config.core.uploadDropElementId);
58-
if (uploadDropElement) {
59-
// this.removeAllEventListeners(uploadDropElement);
60-
this.datatransferFacade.assignUploadDrop(uploadDropElement);
61-
}
62-
}
63-
}
31+
public create(config: any): void {
32+
this.setConfig(config);
6433
}
6534

66-
private removeAllEventListeners(element: HTMLElement): void {
67-
const elementClone = element.cloneNode(true);
68-
element.parentNode.replaceChild(elementClone, element);
69-
}
35+
public setConfig(config: any): void {
36+
this.configService.load(config);
37+
this.paginationService.setRppOptions(ConfigService.settings.core.paginationRppOptions);
38+
this.datatransferFacade = this.datatransferFacadeFactory.createDatatransferFacade();
39+
40+
const viewContainerRef = this.amdHost.viewContainerRef;
41+
viewContainerRef.clear();
7042

71-
public create(event: any): void {
72-
if (!this.isCreated) {
73-
this.setConfig(event);
74-
this.isCreated = true;
75-
this.ref.tick();
76-
this.init();
77-
}
43+
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(MainComponent);
44+
const componentRef = viewContainerRef.createComponent(componentFactory);
45+
const componentRefInstance = componentRef.instance as MainComponent;
46+
componentRefInstance.datatransferFacade = this.datatransferFacade;
7847
}
7948

80-
public setConfig(event: any): void {
81-
this.configService.load(event);
82-
this.config = ConfigService.settings;
83-
this.datatransferFacade = this.datatransferFacadeFactory.createDatatransferFacade();
84-
this.uploadProgress = this.datatransferStore.uploadProgress;
85-
this.downloadProgress = this.datatransferStore.downloadProgress;
86-
this.paginationService.setRppOptions(ConfigService.settings.core.paginationRppOptions);
87-
this.logger.log('AngularMaterialDatatransferComponent.componentId: ' + this.componentId);
49+
public download(filename: string, url: string, size: number): void {
50+
this.datatransferFacade.download(filename, url, size);
8851
}
8952
}

0 commit comments

Comments
 (0)