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 { DocumentCardSmallComponent } from './components/document-list/document-card-small/document-card-small.component'; | ||||
| 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({ | ||||
|   declarations: [ | ||||
| @@ -60,7 +63,10 @@ import { NgxFileDropModule } from 'ngx-file-drop'; | ||||
|     ToastsComponent, | ||||
|     FilterEditorComponent, | ||||
|     DocumentCardLargeComponent, | ||||
|     DocumentCardSmallComponent | ||||
|     DocumentCardSmallComponent, | ||||
|     TextComponent, | ||||
|     SelectComponent, | ||||
|     CheckComponent | ||||
|   ], | ||||
|   imports: [ | ||||
|     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