mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	added some reusable form controls
This commit is contained in:
		| @@ -33,6 +33,9 @@ import { AuthInterceptor } from './services/auth.interceptor'; | |||||||
| import { DocumentCardLargeComponent } from './components/document-list/document-card-large/document-card-large.component'; | import { DocumentCardLargeComponent } from './components/document-list/document-card-large/document-card-large.component'; | ||||||
| import { DocumentCardSmallComponent } from './components/document-list/document-card-small/document-card-small.component'; | import { DocumentCardSmallComponent } from './components/document-list/document-card-small/document-card-small.component'; | ||||||
| import { NgxFileDropModule } from 'ngx-file-drop'; | import { NgxFileDropModule } from 'ngx-file-drop'; | ||||||
|  | import { TextComponent } from './components/common/input/text/text.component'; | ||||||
|  | import { SelectComponent } from './components/common/input/select/select.component'; | ||||||
|  | import { CheckComponent } from './components/common/input/check/check.component'; | ||||||
|  |  | ||||||
| @NgModule({ | @NgModule({ | ||||||
|   declarations: [ |   declarations: [ | ||||||
| @@ -60,7 +63,10 @@ import { NgxFileDropModule } from 'ngx-file-drop'; | |||||||
|     ToastsComponent, |     ToastsComponent, | ||||||
|     FilterEditorComponent, |     FilterEditorComponent, | ||||||
|     DocumentCardLargeComponent, |     DocumentCardLargeComponent, | ||||||
|     DocumentCardSmallComponent |     DocumentCardSmallComponent, | ||||||
|  |     TextComponent, | ||||||
|  |     SelectComponent, | ||||||
|  |     CheckComponent | ||||||
|   ], |   ], | ||||||
|   imports: [ |   imports: [ | ||||||
|     BrowserModule, |     BrowserModule, | ||||||
|   | |||||||
							
								
								
									
										43
									
								
								src-ui/src/app/components/common/input/abstract-input.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src-ui/src/app/components/common/input/abstract-input.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | import { Component, Directive, forwardRef, Input, OnInit } from '@angular/core'; | ||||||
|  | import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; | ||||||
|  | import { v4 as uuidv4 } from 'uuid'; | ||||||
|  |  | ||||||
|  | @Directive() | ||||||
|  | export class AbstractInputComponent<T> implements OnInit, ControlValueAccessor { | ||||||
|  |  | ||||||
|  |   constructor() { } | ||||||
|  |  | ||||||
|  |   onChange = (newValue: T) => {}; | ||||||
|  |    | ||||||
|  |   onTouched = () => {}; | ||||||
|  |  | ||||||
|  |   writeValue(newValue: any): void { | ||||||
|  |     this.value = newValue | ||||||
|  |   } | ||||||
|  |   registerOnChange(fn: any): void { | ||||||
|  |     this.onChange = fn; | ||||||
|  |   } | ||||||
|  |   registerOnTouched(fn: any): void { | ||||||
|  |     this.onTouched = fn; | ||||||
|  |   } | ||||||
|  |   setDisabledState?(isDisabled: boolean): void { | ||||||
|  |     this.disabled = isDisabled; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Input() | ||||||
|  |   title: string | ||||||
|  |  | ||||||
|  |   @Input() | ||||||
|  |   disabled = false; | ||||||
|  |  | ||||||
|  |   value: T | ||||||
|  |  | ||||||
|  |   ngOnInit(): void { | ||||||
|  |     this.inputId = uuidv4() | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   inputId: string | ||||||
|  |  | ||||||
|  |   @Input() | ||||||
|  |   hint: string | ||||||
|  | } | ||||||
| @@ -0,0 +1,5 @@ | |||||||
|  | <div class="form-group form-check"> | ||||||
|  |   <input type="checkbox" class="form-check-input" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" (blur)="onTouched()" [disabled]="disabled"> | ||||||
|  |   <label class="form-check-label" [for]="inputId">{{title}}</label> | ||||||
|  |   <small *ngIf="hint" class="form-text text-muted">{{hint}}</small> | ||||||
|  | </div> | ||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||||||
|  |  | ||||||
|  | import { CheckComponent } from './check.component'; | ||||||
|  |  | ||||||
|  | describe('CheckComponent', () => { | ||||||
|  |   let component: CheckComponent; | ||||||
|  |   let fixture: ComponentFixture<CheckComponent>; | ||||||
|  |  | ||||||
|  |   beforeEach(async () => { | ||||||
|  |     await TestBed.configureTestingModule({ | ||||||
|  |       declarations: [ CheckComponent ] | ||||||
|  |     }) | ||||||
|  |     .compileComponents(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   beforeEach(() => { | ||||||
|  |     fixture = TestBed.createComponent(CheckComponent); | ||||||
|  |     component = fixture.componentInstance; | ||||||
|  |     fixture.detectChanges(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('should create', () => { | ||||||
|  |     expect(component).toBeTruthy(); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | import { Component, forwardRef, Input, OnInit } from '@angular/core'; | ||||||
|  | import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; | ||||||
|  | import { v4 as uuidv4 } from 'uuid'; | ||||||
|  | import { AbstractInputComponent } from '../abstract-input'; | ||||||
|  |  | ||||||
|  | @Component({ | ||||||
|  |   providers: [{ | ||||||
|  |     provide: NG_VALUE_ACCESSOR, | ||||||
|  |     useExisting: forwardRef(() => CheckComponent), | ||||||
|  |     multi: true | ||||||
|  |   }], | ||||||
|  |   selector: 'app-input-check', | ||||||
|  |   templateUrl: './check.component.html', | ||||||
|  |   styleUrls: ['./check.component.css'] | ||||||
|  | }) | ||||||
|  | export class CheckComponent extends AbstractInputComponent<boolean> { | ||||||
|  |  | ||||||
|  |   constructor() {  | ||||||
|  |     super() | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | <div class="form-group"> | ||||||
|  |   <label [for]="inputId">{{title}}</label> | ||||||
|  |   <select class="form-control" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" (blur)="onTouched()" [disabled]="disabled" [style.color]="textColor" [style.background]="backgroundColor"> | ||||||
|  |     <option *ngFor="let i of items" [ngValue]="i.id" class="form-control">{{i.name}}</option> | ||||||
|  |   </select> | ||||||
|  |   <small *ngIf="hint" class="form-text text-muted">{{hint}}</small> | ||||||
|  | </div> | ||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||||||
|  |  | ||||||
|  | import { SelectComponent } from './select.component'; | ||||||
|  |  | ||||||
|  | describe('SelectComponent', () => { | ||||||
|  |   let component: SelectComponent; | ||||||
|  |   let fixture: ComponentFixture<SelectComponent>; | ||||||
|  |  | ||||||
|  |   beforeEach(async () => { | ||||||
|  |     await TestBed.configureTestingModule({ | ||||||
|  |       declarations: [ SelectComponent ] | ||||||
|  |     }) | ||||||
|  |     .compileComponents(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   beforeEach(() => { | ||||||
|  |     fixture = TestBed.createComponent(SelectComponent); | ||||||
|  |     component = fixture.componentInstance; | ||||||
|  |     fixture.detectChanges(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('should create', () => { | ||||||
|  |     expect(component).toBeTruthy(); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @@ -0,0 +1,31 @@ | |||||||
|  | import { Component, forwardRef, Input, OnInit } from '@angular/core'; | ||||||
|  | import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; | ||||||
|  | import { v4 as uuidv4 } from 'uuid'; | ||||||
|  | import { AbstractInputComponent } from '../abstract-input'; | ||||||
|  |  | ||||||
|  | @Component({ | ||||||
|  |   providers: [{ | ||||||
|  |     provide: NG_VALUE_ACCESSOR, | ||||||
|  |     useExisting: forwardRef(() => SelectComponent), | ||||||
|  |     multi: true | ||||||
|  |   }], | ||||||
|  |   selector: 'app-input-select', | ||||||
|  |   templateUrl: './select.component.html', | ||||||
|  |   styleUrls: ['./select.component.css'] | ||||||
|  | }) | ||||||
|  | export class SelectComponent extends AbstractInputComponent<number> { | ||||||
|  |  | ||||||
|  |   constructor() { | ||||||
|  |     super() | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |   @Input() | ||||||
|  |   items: any[] | ||||||
|  |  | ||||||
|  |   @Input() | ||||||
|  |   textColor: any | ||||||
|  |  | ||||||
|  |   @Input() | ||||||
|  |   backgroundColor: any | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,5 @@ | |||||||
|  | <div class="form-group"> | ||||||
|  |   <label [for]="inputId">{{title}}</label> | ||||||
|  |   <input type="text" class="form-control" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)"> | ||||||
|  |   <small *ngIf="hint" class="form-text text-muted">{{hint}}</small> | ||||||
|  | </div> | ||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||||||
|  |  | ||||||
|  | import { TextComponent } from './text.component'; | ||||||
|  |  | ||||||
|  | describe('TextComponent', () => { | ||||||
|  |   let component: TextComponent; | ||||||
|  |   let fixture: ComponentFixture<TextComponent>; | ||||||
|  |  | ||||||
|  |   beforeEach(async () => { | ||||||
|  |     await TestBed.configureTestingModule({ | ||||||
|  |       declarations: [ TextComponent ] | ||||||
|  |     }) | ||||||
|  |     .compileComponents(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   beforeEach(() => { | ||||||
|  |     fixture = TestBed.createComponent(TextComponent); | ||||||
|  |     component = fixture.componentInstance; | ||||||
|  |     fixture.detectChanges(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('should create', () => { | ||||||
|  |     expect(component).toBeTruthy(); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | import { Component, forwardRef, Input, OnInit } from '@angular/core'; | ||||||
|  | import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; | ||||||
|  | import { v4 as uuidv4 } from 'uuid'; | ||||||
|  | import { AbstractInputComponent } from '../abstract-input'; | ||||||
|  |  | ||||||
|  | @Component({ | ||||||
|  |   providers: [{ | ||||||
|  |     provide: NG_VALUE_ACCESSOR, | ||||||
|  |     useExisting: forwardRef(() => TextComponent), | ||||||
|  |     multi: true | ||||||
|  |   }], | ||||||
|  |   selector: 'app-input-text', | ||||||
|  |   templateUrl: './text.component.html', | ||||||
|  |   styleUrls: ['./text.component.css'] | ||||||
|  | }) | ||||||
|  | export class TextComponent extends AbstractInputComponent<string> { | ||||||
|  |  | ||||||
|  |   constructor() { | ||||||
|  |     super() | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 Jonas Winkler
					Jonas Winkler