Saving work, basic frontend getting & display
This commit is contained in:
parent
d9526ea32f
commit
6f62da077a
@ -41,6 +41,9 @@ export class AbstractInputComponent<T> implements OnInit, ControlValueAccessor {
|
||||
@Input()
|
||||
error: string
|
||||
|
||||
@Input()
|
||||
horizontal: boolean = false
|
||||
|
||||
value: T
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -1,5 +1,9 @@
|
||||
<div class="mb-3">
|
||||
<label class="form-label" [for]="inputId">{{title}}</label>
|
||||
<div class="row">
|
||||
<div class="d-flex align-items-center" [class.col-md-3]="horizontal">
|
||||
<label class="form-label mb-md-0" [for]="inputId">{{title}}</label>
|
||||
</div>
|
||||
<div [class.col-md-9]="horizontal">
|
||||
<div class="input-group" [class.is-invalid]="error">
|
||||
<input #inputField class="form-control" [class.is-invalid]="error" [placeholder]="placeholder" [id]="inputId" maxlength="10"
|
||||
(dateSelect)="onChange(value)" (change)="onChange(value)" (keypress)="onKeyPress($event)" (paste)="onPaste($event)"
|
||||
@ -24,3 +28,5 @@
|
||||
</ng-container>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,9 @@
|
||||
<div class="mb-3">
|
||||
<div class="row">
|
||||
<div [class.col-md-3]="horizontal">
|
||||
<label class="form-label" [for]="inputId">{{title}}</label>
|
||||
</div>
|
||||
<div [class.col-md-9]="horizontal">
|
||||
<div class="input-group" [class.is-invalid]="error">
|
||||
<input #inputField type="number" class="form-control" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [class.is-invalid]="error" [disabled]="disabled">
|
||||
<button *ngIf="showAdd" class="btn btn-outline-secondary" type="button" id="button-addon1" (click)="nextAsn()" [disabled]="disabled">+1</button>
|
||||
@ -8,5 +12,6 @@
|
||||
{{error}}
|
||||
</div>
|
||||
<small *ngIf="hint" class="form-text text-muted">{{hint}}</small>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,9 @@
|
||||
<div class="mb-3 paperless-input-select" [class.disabled]="disabled">
|
||||
<label *ngIf="title" class="form-label" [for]="inputId">{{title}}</label>
|
||||
<div class="row">
|
||||
<div class="d-flex align-items-center" [class.col-md-3]="horizontal">
|
||||
<label *ngIf="title" class="form-label mb-md-0" [for]="inputId">{{title}}</label>
|
||||
</div>
|
||||
<div [class.col-md-9]="horizontal">
|
||||
<div [class.input-group]="allowCreateNew || showFilter">
|
||||
<ng-select name="inputId" [(ngModel)]="value"
|
||||
[disabled]="disabled"
|
||||
@ -38,7 +42,7 @@
|
||||
<ng-container *ngFor="let s of getSuggestions()">
|
||||
<a (click)="value = s.id; onChange(value)" [routerLink]="[]">{{s.name}}</a>
|
||||
</ng-container>
|
||||
|
||||
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,9 @@
|
||||
<div class="mb-3 paperless-input-select paperless-input-tags" [class.disabled]="disabled">
|
||||
<label class="form-label" for="tags" i18n>{{title}}</label>
|
||||
|
||||
<div class="row">
|
||||
<div class="d-flex align-items-center" [class.col-md-3]="horizontal">
|
||||
<label class="form-label mb-md-0" for="tags" i18n>{{title}}</label>
|
||||
</div>
|
||||
<div [class.col-md-9]="horizontal">
|
||||
<div class="input-group flex-nowrap">
|
||||
<ng-select #tagSelect name="tags" [items]="tags" bindLabel="name" bindValue="id" [(ngModel)]="value"
|
||||
[disabled]="disabled"
|
||||
@ -44,8 +47,7 @@
|
||||
<ng-container *ngFor="let tag of getSuggestions()">
|
||||
<a (click)="addTag(tag.id)" [routerLink]="[]">{{tag.name}}</a>
|
||||
</ng-container>
|
||||
|
||||
|
||||
</small>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -77,6 +77,9 @@ export class TagsComponent implements OnInit, ControlValueAccessor {
|
||||
@Input()
|
||||
showFilter: boolean = false
|
||||
|
||||
@Input()
|
||||
horizontal: boolean = false
|
||||
|
||||
@Output()
|
||||
filterDocuments = new EventEmitter<PaperlessTag[]>()
|
||||
|
||||
|
@ -1,8 +1,14 @@
|
||||
<div class="mb-3">
|
||||
<label class="form-label" [for]="inputId">{{title}}</label>
|
||||
<div class="row">
|
||||
<div class="d-flex align-items-center" [class.col-md-3]="horizontal">
|
||||
<label class="form-label mb-md-0" [for]="inputId">{{title}}</label>
|
||||
</div>
|
||||
<div [class.col-md-9]="horizontal">
|
||||
<input #inputField type="text" class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [disabled]="disabled">
|
||||
<small *ngIf="hint" class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
|
||||
<div class="invalid-feedback">
|
||||
{{error}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -81,19 +81,23 @@
|
||||
<li [ngbNavItem]="DocumentDetailNavIDs.Details">
|
||||
<a ngbNavLink i18n>Details</a>
|
||||
<ng-template ngbNavContent>
|
||||
|
||||
<pngx-input-text #inputTitle i18n-title title="Title" formControlName="title" (keyup)="titleKeyUp($event)" [error]="error?.title"></pngx-input-text>
|
||||
<pngx-input-number i18n-title title="Archive serial number" [error]="error?.archive_serial_number" formControlName='archive_serial_number'></pngx-input-number>
|
||||
<pngx-input-date i18n-title title="Date created" formControlName="created_date" [suggestions]="suggestions?.dates" [showFilter]="true" (filterDocuments)="filterDocuments($event)"
|
||||
<div class="my-3">
|
||||
<pngx-input-text #inputTitle i18n-title title="Title" formControlName="title" [horizontal]="true" (keyup)="titleKeyUp($event)" [error]="error?.title"></pngx-input-text>
|
||||
<pngx-input-number i18n-title title="Archive serial number" [error]="error?.archive_serial_number" [horizontal]="true" formControlName='archive_serial_number'></pngx-input-number>
|
||||
<pngx-input-date i18n-title title="Date created" formControlName="created_date" [suggestions]="suggestions?.dates" [showFilter]="true" [horizontal]="true" (filterDocuments)="filterDocuments($event)"
|
||||
[error]="error?.created_date"></pngx-input-date>
|
||||
<pngx-input-select [items]="correspondents" i18n-title title="Correspondent" formControlName="correspondent" [allowNull]="true" [showFilter]="true" (filterDocuments)="filterDocuments($event)"
|
||||
<pngx-input-select [items]="correspondents" i18n-title title="Correspondent" formControlName="correspondent" [allowNull]="true" [showFilter]="true" [horizontal]="true" (filterDocuments)="filterDocuments($event)"
|
||||
(createNew)="createCorrespondent($event)" [suggestions]="suggestions?.correspondents" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Correspondent }"></pngx-input-select>
|
||||
<pngx-input-select [items]="documentTypes" i18n-title title="Document type" formControlName="document_type" [allowNull]="true" [showFilter]="true" (filterDocuments)="filterDocuments($event)"
|
||||
<pngx-input-select [items]="documentTypes" i18n-title title="Document type" formControlName="document_type" [allowNull]="true" [showFilter]="true" [horizontal]="true" (filterDocuments)="filterDocuments($event)"
|
||||
(createNew)="createDocumentType($event)" [suggestions]="suggestions?.document_types" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.DocumentType }"></pngx-input-select>
|
||||
<pngx-input-select [items]="storagePaths" i18n-title title="Storage path" formControlName="storage_path" [allowNull]="true" [showFilter]="true" (filterDocuments)="filterDocuments($event)"
|
||||
<pngx-input-select [items]="storagePaths" i18n-title title="Storage path" formControlName="storage_path" [allowNull]="true" [showFilter]="true" [horizontal]="true" (filterDocuments)="filterDocuments($event)"
|
||||
(createNew)="createStoragePath($event)" [suggestions]="suggestions?.storage_paths" i18n-placeholder placeholder="Default" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.StoragePath }"></pngx-input-select>
|
||||
<pngx-input-tags formControlName="tags" [suggestions]="suggestions?.tags" [showFilter]="true" (filterDocuments)="filterDocuments($event)" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Tag }"></pngx-input-tags>
|
||||
|
||||
<pngx-input-tags formControlName="tags" [suggestions]="suggestions?.tags" [showFilter]="true" [horizontal]="true" (filterDocuments)="filterDocuments($event)" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Tag }"></pngx-input-tags>
|
||||
<ng-container *ngFor="let field of customFields">
|
||||
<pngx-input-text [formControlName]="'custom-field-' + field.id" *ngIf="field.type === PaperlessCustomFieldDataType.String" [title]="field.name" [horizontal]="true"></pngx-input-text>
|
||||
<pngx-input-date [formControlName]="'custom-field-' + field.id" *ngIf="field.type === PaperlessCustomFieldDataType.Date" [title]="field.name" [horizontal]="true"></pngx-input-date>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-template>
|
||||
</li>
|
||||
|
||||
|
@ -63,7 +63,11 @@ import { EditDialogMode } from '../common/edit-dialog/edit-dialog.component'
|
||||
import { ObjectWithId } from 'src/app/data/object-with-id'
|
||||
import { FilterRule } from 'src/app/data/filter-rule'
|
||||
import { ISODateAdapter } from 'src/app/utils/ngb-iso-date-adapter'
|
||||
import { ShareLinksDropdownComponent } from '../common/share-links-dropdown/share-links-dropdown.component'
|
||||
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
|
||||
import {
|
||||
PaperlessCustomField,
|
||||
PaperlessCustomFieldDataType,
|
||||
} from 'src/app/data/paperless-custom-field'
|
||||
|
||||
enum DocumentDetailNavIDs {
|
||||
Details = 1,
|
||||
@ -135,6 +139,9 @@ export class DocumentDetailComponent
|
||||
|
||||
ogDate: Date
|
||||
|
||||
public readonly PaperlessCustomFieldDataType = PaperlessCustomFieldDataType
|
||||
customFields: PaperlessCustomField[]
|
||||
|
||||
@ViewChild('nav') nav: NgbNav
|
||||
@ViewChild('pdfPreview') set pdfPreview(element) {
|
||||
// this gets called when compontent added or removed from DOM
|
||||
@ -166,7 +173,8 @@ export class DocumentDetailComponent
|
||||
private storagePathService: StoragePathService,
|
||||
private permissionsService: PermissionsService,
|
||||
private userService: UserService,
|
||||
private http: HttpClient
|
||||
private http: HttpClient,
|
||||
private customFieldsService: CustomFieldsService
|
||||
) {
|
||||
super()
|
||||
}
|
||||
@ -385,6 +393,28 @@ export class DocumentDetailComponent
|
||||
updateComponent(doc: PaperlessDocument) {
|
||||
this.document = doc
|
||||
this.requiresPassword = false
|
||||
this.customFieldsService
|
||||
.getFields(doc.id)
|
||||
.pipe(first())
|
||||
.subscribe({
|
||||
next: (fields) => {
|
||||
this.customFields = fields
|
||||
this.customFields.forEach((field) => {
|
||||
this.documentForm.addControl(
|
||||
`custom-field-${field.id}`,
|
||||
new FormControl(field.data)
|
||||
)
|
||||
})
|
||||
this.store.next(this.documentForm.value)
|
||||
console.log(fields)
|
||||
},
|
||||
error: (error) => {
|
||||
this.toastService.showError(
|
||||
$localize`Error retrieving custom fields`,
|
||||
error
|
||||
)
|
||||
},
|
||||
})
|
||||
this.documentsService
|
||||
.getMetadata(doc.id)
|
||||
.pipe(first())
|
||||
@ -511,6 +541,11 @@ export class DocumentDetailComponent
|
||||
}
|
||||
this.title = doc.title
|
||||
this.documentForm.patchValue(doc)
|
||||
this.customFields.forEach((field) => {
|
||||
this.documentForm
|
||||
.get(`custom-field-${field.id}`)
|
||||
.patchValue(field.data)
|
||||
})
|
||||
this.openDocumentService.setDirty(doc, false)
|
||||
},
|
||||
error: () => {
|
||||
|
16
src-ui/src/app/data/paperless-custom-field.ts
Normal file
16
src-ui/src/app/data/paperless-custom-field.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { ObjectWithId } from './object-with-id'
|
||||
|
||||
export enum PaperlessCustomFieldDataType {
|
||||
String = 'string',
|
||||
Url = 'url',
|
||||
Date = 'date',
|
||||
}
|
||||
|
||||
export interface PaperlessCustomField extends ObjectWithId {
|
||||
type: PaperlessCustomFieldDataType
|
||||
name: string
|
||||
data: any
|
||||
document: number // PaperlessDocument
|
||||
created?: Date
|
||||
user: number // PaperlessUser
|
||||
}
|
40
src-ui/src/app/services/rest/custom-fields.service.ts
Normal file
40
src-ui/src/app/services/rest/custom-fields.service.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { HttpClient, HttpParams } from '@angular/common/http'
|
||||
import { AbstractPaperlessService } from './abstract-paperless-service'
|
||||
import { Observable } from 'rxjs'
|
||||
import { PaperlessCustomField } from 'src/app/data/paperless-custom-field'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class CustomFieldsService extends AbstractPaperlessService<PaperlessCustomField> {
|
||||
constructor(http: HttpClient) {
|
||||
super(http, 'documents')
|
||||
}
|
||||
|
||||
getFields(documentId: number): Observable<PaperlessCustomField[]> {
|
||||
return this.http.get<PaperlessCustomField[]>(
|
||||
this.getResourceUrl(documentId, 'custom_metadata')
|
||||
)
|
||||
}
|
||||
|
||||
addField(
|
||||
documentId: number,
|
||||
field: PaperlessCustomField
|
||||
): Observable<PaperlessCustomField[]> {
|
||||
return this.http.post<PaperlessCustomField[]>(
|
||||
this.getResourceUrl(documentId, 'custom_metadata'),
|
||||
field
|
||||
)
|
||||
}
|
||||
|
||||
// deleteField(
|
||||
// documentId: number,
|
||||
// fieldId: number
|
||||
// ): Observable<PaperlessCustomField[]> {
|
||||
// return this.http.delete<PaperlessCustomField[]>(
|
||||
// this.getResourceUrl(documentId, 'custom_metadata'),
|
||||
// { params: new HttpParams({ fromString: `id=${fieldId}` }) }
|
||||
// )
|
||||
// }
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user