added templates component

This commit is contained in:
VLE2FE
2020-07-27 17:52:03 +02:00
parent 15aeeb27ee
commit 55248e25ef
42 changed files with 862 additions and 57 deletions

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { ArrayInputHelperService } from './array-input-helper.service';
describe('ArrayInputHelperService', () => {
let service: ArrayInputHelperService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ArrayInputHelperService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,26 @@
import { Injectable } from '@angular/core';
import {Observable, Subject} from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ArrayInputHelperService {
com: Subject<{ id: string, index: number, value: any }> = new Subject();
constructor() { }
values(id: string) {
return new Observable<{index: number, value: any}>(observer => {
this.com.subscribe(data => {
if (data.id === id) {
observer.next({index: data.index, value: data.value});
}
});
});
}
newValue(id: string, index: number, value: any) {
this.com.next({id, index, value});
}
}

View File

@ -0,0 +1,3 @@
<ng-container *ngFor="let ignore of [].constructor(values.length); index as i">
<ng-container *ngTemplateOutlet="item.templateRef; context: {$implicit: {i: i, value: values[i]}}"></ng-container>
</ng-container>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RbArrayInputComponent } from './rb-array-input.component';
describe('RbArrayInputComponent', () => {
let component: RbArrayInputComponent;
let fixture: ComponentFixture<RbArrayInputComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ RbArrayInputComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(RbArrayInputComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,107 @@
import {
AfterViewInit,
Component,
ContentChild,
Directive,
forwardRef,
HostListener,
Input,
OnInit,
TemplateRef
} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import _ from 'lodash';
import {ArrayInputHelperService} from './array-input-helper.service';
// TODO: implement everywhere
@Directive({ // directive for template and input values
// tslint:disable-next-line:directive-selector
selector: '[rbArrayInputItem]'
})
export class RbArrayInputItemDirective {
constructor(public templateRef: TemplateRef<any>) {
}
}
@Directive({ // directive for change detection
// tslint:disable-next-line:directive-selector
selector: '[rbArrayInputListener]'
})
export class RbArrayInputListenerDirective {
@Input() rbArrayInputListener: string;
@Input() index: number;
constructor(
private helperService: ArrayInputHelperService
) { }
@HostListener('ngModelChange', ['$event'])
onChange(event) {
console.log(event);
this.helperService.newValue(this.rbArrayInputListener, this.index, event);
}
}
@Component({
// tslint:disable-next-line:component-selector
selector: 'rb-array-input',
templateUrl: './rb-array-input.component.html',
styleUrls: ['./rb-array-input.component.scss'],
providers: [{provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RbArrayInputComponent), multi: true}]
})
export class RbArrayInputComponent implements ControlValueAccessor, OnInit, AfterViewInit {
@Input() pushTemplate: any;
@Input() pushPath: string;
@ContentChild(RbArrayInputItemDirective) item: RbArrayInputItemDirective;
@ContentChild(RbArrayInputListenerDirective) item2: RbArrayInputListenerDirective;
values = []; // main array to display
onChange = (ignore?: any): void => {};
onTouched = (ignore?: any): void => {};
constructor(
private helperService: ArrayInputHelperService
) { }
ngOnInit(): void {
}
ngAfterViewInit() {
setTimeout(() => { // needed to find reference
this.helperService.values(this.item2.rbArrayInputListener).subscribe(data => { // action on value change
this.values[data.index][this.pushPath] = data.value;
console.log(this.values);
if (this.values[this.values.length - 1][this.pushPath] === '' && this.values[this.values.length - 2][this.pushPath] === '') { // remove last element if last two are empty
this.values.pop();
}
else if (this.values[this.values.length - 1][this.pushPath] !== '') { // add element if last one is filled
this.values.push(_.cloneDeep(this.pushTemplate));
}
this.onChange(this.values.filter(e => e !== '')); // trigger ngModel with filled elements
});
}, 0);
}
writeValue(obj: any) { // add empty value on init
this.values = obj ? obj : [];
if (this.values.length === 0 || this.values[0] !== '') {
console.log(this.values);
this.values.push(_.cloneDeep(this.pushTemplate));
}
}
registerOnChange(fn: any) {
this.onChange = fn;
}
registerOnTouched(fn: any) {
this.onTouched = fn;
}
}

View File

@ -0,0 +1,32 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RbTableComponent } from './rb-table/rb-table.component';
import {RbArrayInputComponent, RbArrayInputListenerDirective, RbArrayInputItemDirective} from './rb-array-input/rb-array-input.component';
import {RbUiComponentsModule} from '@inst-iot/bosch-angular-ui-components';
import {FormsModule} from '@angular/forms';
import { RbIconButtonComponent } from './rb-icon-button/rb-icon-button.component';
@NgModule({
declarations: [
RbTableComponent,
RbArrayInputComponent,
RbArrayInputListenerDirective,
RbArrayInputItemDirective,
RbIconButtonComponent
],
imports: [
CommonModule,
FormsModule,
RbUiComponentsModule
],
exports: [
RbTableComponent,
RbArrayInputComponent,
RbArrayInputListenerDirective,
RbArrayInputItemDirective,
RbIconButtonComponent
]
})
export class RbCustomInputsModule { }

View File

@ -0,0 +1,4 @@
<button class="rb-btn rb" [ngClass]="'rb-' + mode" type="button" [disabled]="disabled">
<span class="rb-ic" [ngClass]="'rb-ic-' + icon"></span>&nbsp;&nbsp;
<ng-content></ng-content>
</button>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RbIconButtonComponent } from './rb-icon-button.component';
describe('RbIconButtonComponent', () => {
let component: RbIconButtonComponent;
let fixture: ComponentFixture<RbIconButtonComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ RbIconButtonComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(RbIconButtonComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,22 @@
import {Component, Input, OnInit} from '@angular/core';
// TODO: apply everywhere
@Component({
// tslint:disable-next-line:component-selector
selector: 'rb-icon-button',
templateUrl: './rb-icon-button.component.html',
styleUrls: ['./rb-icon-button.component.scss']
})
export class RbIconButtonComponent implements OnInit {
@Input() icon: string;
@Input() mode: string;
@Input() disabled;
constructor() { }
ngOnInit(): void {
}
}

View File

@ -0,0 +1,6 @@
<script src="rb-table.component.ts"></script>
<div class="table-wrapper">
<table>
<ng-content></ng-content>
</table>
</div>

View File

@ -0,0 +1,35 @@
@import "~@inst-iot/bosch-angular-ui-components/styles/variables/colors";
.table-wrapper {
overflow-x: auto;
width: 100%;
&, & > table { // scrollbar at the top
transform:rotateX(180deg);
-ms-transform:rotateX(180deg); /* IE 9 */
-webkit-transform:rotateX(180deg); /* Safari and Chrome */
}
}
table {
width: 100%;
border-collapse: collapse;
::ng-deep tr {
border-bottom: 1px solid $color-gray-mercury;
::ng-deep td, ::ng-deep th {
padding: 8px 5px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
max-width: 200px;
}
::ng-deep th {
text-align: left;
}
}
}

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RbTableComponent } from './rb-table.component';
describe('RbTableComponent', () => {
let component: RbTableComponent;
let fixture: ComponentFixture<RbTableComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ RbTableComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(RbTableComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,16 @@
import { Component, OnInit } from '@angular/core';
@Component({
// tslint:disable-next-line:component-selector
selector: 'rb-table',
templateUrl: './rb-table.component.html',
styleUrls: ['./rb-table.component.scss']
})
export class RbTableComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}