Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5,280 changes: 2,640 additions & 2,640 deletions package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import {
ChangeDetectionStrategy,
Component,
ElementRef,
HostBinding,
Input,
OnChanges,
OnInit,
SimpleChanges,
ViewEncapsulation
} from '@angular/core';

import {
AbstractDynamicCellComponent,
getClassNames,
getStyleHintClasses
} from '../../helpers';
import { DynamicTableDecoratorService } from '../../services/dynamic-table-decorator.service';

@Component({
selector: '[ngrDynamicTableCell]', // tslint:disable-line:component-selector
templateUrl: './dynamic-table-cell.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
})
export class DynamicTableCellComponent extends AbstractDynamicCellComponent
implements OnInit, OnChanges {
@Input()
decorator: string;

@Input()
decoratorOptions: any;

@Input()
classPrefix = 'ngr-dynamic-table-cell';

@HostBinding('class')
get classNames() {
const externalClasses = Array.from(this.el.nativeElement.classList);
const decoratorClass = this.decorator
? `${this.classPrefix}--${this.decorator}`
: '';
const styleHints =
(this.decoratorOptions && this.decoratorOptions.styleHints) || [];

return getClassNames([
...externalClasses,
this.classPrefix,
decoratorClass,
...getStyleHintClasses(this.classPrefix, styleHints)
]);
}

@HostBinding('innerHtml')
content: string;

constructor(
private decoratorService: DynamicTableDecoratorService,
private el: ElementRef
) {
super();
}

ngOnInit() {}

ngOnChanges(changes: SimpleChanges) {
if (
changes['decorator'] ||
changes['decoratorOptions'] ||
changes['data'] ||
changes['path']
) {
this._updateComponent();
}
}

protected _updateComponent() {
this.content = this.decoratorService.applyDecorator(
this.decorator,
this.data,
this.path,
this.decoratorOptions
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div #componentContainer></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import {
AfterViewInit,
ChangeDetectionStrategy,
Component,
ComponentFactoryResolver,
ComponentRef,
EventEmitter,
HostBinding,
Injector,
Input,
OnChanges,
OnInit,
Output,
SimpleChange,
SimpleChanges,
ViewChild,
ViewContainerRef,
ViewEncapsulation
} from '@angular/core';
import { Subscription } from 'rxjs';

import {
AbstractDynamicCellComponent,
ComponentRegistries,
getInjectionTokenForComponentType,
getStyleHintClasses,
getClassNames
} from '../../helpers';
import { DynamicTableRowData } from '../../models/dynamic-table.model';

/**
* Component that is used with the `component` decorator options to inject a custom component into the table cell
*/
@Component({
selector: '[ngrDynamicTableComponentCell]', // tslint:disable-line:component-selector
templateUrl: './dynamic-table-component-cell.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
})
export class DynamicTableComponentCellComponent
extends AbstractDynamicCellComponent
implements OnInit, OnChanges, AfterViewInit {
@Input()
component: string;

@Input()
componentOptions: any;

@Input()
decoratorOptions: any = { styleHints: [] };

@Input()
classPrefix = 'ngr-dynamic-table-cell';

@Output()
event: EventEmitter<any> = new EventEmitter();

@ViewChild('componentContainer', { read: ViewContainerRef })
componentContainer: ViewContainerRef;

private isViewInitialized = false;

private componentRef: ComponentRef<DynamicTableComponentCell>;
private componentRefChanges;

private componentEventSubscription: Subscription;

constructor(
private injector: Injector,
private componentFactoryResolver: ComponentFactoryResolver
) {
super();
}

@HostBinding('class')
get classNames() {
const styleHints =
(this.decoratorOptions && this.decoratorOptions.styleHints) || [];

return getClassNames([
'dynamic-table-cell',
'dynamic-table-cell--component',
...getStyleHintClasses(this.classPrefix, styleHints)
]);
}

ngOnInit() {}

ngAfterViewInit() {
this.isViewInitialized = true;
this._updateComponent({});
}

ngOnChanges(changes: SimpleChanges) {
if (changes['component']) {
this._updateComponent(changes, true);
} else {
this._updateComponent(changes);
}
}

private createComponentRef() {
const injectionToken = getInjectionTokenForComponentType<
DynamicTableComponentCell
>(ComponentRegistries.TABLE_CELL, this.component);

if (injectionToken) {
const type = this.injector.get(injectionToken);
const factory = this.componentFactoryResolver.resolveComponentFactory(
type
);
this.componentRef = this.componentContainer.createComponent(
factory
);

Object.assign(this.componentRef.instance, {
...this.componentRef.instance,
data: this.data,
path: this.path,
options: this.componentOptions
});

this.componentRefChanges = {
data: new SimpleChange(null, this.data, true),
path: new SimpleChange(null, this.path, true),
options: new SimpleChange(null, this.componentOptions, true)
};

this.componentRef.instance.ngOnChanges(this.componentRefChanges);
}
}

private updateComponentSubscriptions() {
if (this.componentRef) {
if (this.componentEventSubscription) {
this.componentEventSubscription.unsubscribe();
}

if (this.componentRef.instance.event) {
this.componentEventSubscription = this.componentRef.instance.event.subscribe(
this.event
);
}
}
}

/**
* Update the injected component
* @param changes
* @param recreate
*/
protected _updateComponent(changes: SimpleChanges, recreate = false) {
this.componentRefChanges = {
...changes,
options: changes.componentOptions
};
const shouldDestroy = this.componentRef && recreate;

if (!this.componentRef || recreate) {
if (shouldDestroy) {
this.componentRef.destroy();
}

this.createComponentRef();
this.updateComponentSubscriptions();
}
}
}

export interface DynamicTableComponentCell extends OnChanges {
data: DynamicTableRowData;

options: any;

path: string;

event?: EventEmitter<any>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<a [href]="link">
{{ label }}<i *ngIf="options.icon" class="external-link-icon far fa-{{options.icon}}"></i>
</a>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Component, Input, ViewEncapsulation } from '@angular/core';
import { get } from 'lodash';

import { DynamicTableRowData } from '../../models/dynamic-table.model';
import { DynamicTableComponentCell } from '../dynamic-table-component-cell/dynamic-table-component-cell.component';
import { AbstractDynamicCellComponent } from '../../helpers';

@Component({
selector: 'ngr-dynamic-table-link-cell',
templateUrl: './dynamic-table-link-cell.component.html',
encapsulation: ViewEncapsulation.None
})
export class DynamicTableLinkCellComponent extends AbstractDynamicCellComponent
implements DynamicTableComponentCell {
@Input()
data: DynamicTableRowData;
@Input()
options: any;
@Input()
path: string;

label = '';
link = '';

constructor() {
super();
}

protected _updateComponent() {
this.label = get(this.data, this.path) || this.options.label;
this.link = get(this.data, this.options.linkPath as string);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<ng-container *ngFor="let column of config.columns">
<td *ngIf="column.decorator === 'component'; else regularCell" ngrDynamicTableComponentCell [component]="column.decoratorOptions?.component"
[decoratorOptions]="column.decoratorOptions" [componentOptions]="column.decoratorOptions?.componentOptions"
[data]="data" [path]="column.path" (event)="onComponentEvent($event)"></td>
<ng-template #regularCell>
<td ngrDynamicTableCell [decorator]="column.decorator" [decoratorOptions]="column.decoratorOptions" [data]="data"
[path]="column.path"></td>
</ng-template>
</ng-container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {
Component,
EventEmitter,
Input,
OnInit,
Output,
ViewEncapsulation
} from '@angular/core';

import {
DynamicTableConfig,
DynamicTableRowData
} from '../../models/dynamic-table.model';

@Component({
selector: '[ngrDynamicTableRow]', // tslint:disable-line:component-selector
templateUrl: './dynamic-table-row.component.html',
encapsulation: ViewEncapsulation.None
})
export class DynamicTableRowComponent implements OnInit {
@Input()
config: DynamicTableConfig;

@Input()
data: DynamicTableRowData;

@Input()
selected: boolean;

@Output()
toggleSelection: EventEmitter<boolean> = new EventEmitter<boolean>();

@Output()
componentEvent: EventEmitter<any> = new EventEmitter();

constructor() {}

ngOnInit() {}

onComponentEvent(event: any) {
this.componentEvent.next(event);
}
}
Loading