mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-07-12 15:05:08 +00:00
Chorehancement: update to Angular v22, 'zoneless' / 'reactive' (#13114)
This commit is contained in:
+3
-3
@@ -41,20 +41,20 @@ describe('CorrespondentEditDialogComponent', () => {
|
||||
|
||||
fixture = TestBed.createComponent(CorrespondentEditDialogComponent)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
settingsService.currentUser = { id: 99, username: 'user99' }
|
||||
settingsService.currentUser.set({ id: 99, username: 'user99' })
|
||||
component = fixture.componentInstance
|
||||
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should support create and edit modes', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
|
||||
const editTitleSpy = jest.spyOn(component, 'getEditTitle')
|
||||
fixture.detectChanges()
|
||||
expect(createTitleSpy).toHaveBeenCalled()
|
||||
expect(editTitleSpy).not.toHaveBeenCalled()
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
fixture.detectChanges()
|
||||
expect(editTitleSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
+8
-8
@@ -44,33 +44,33 @@ describe('CustomFieldEditDialogComponent', () => {
|
||||
|
||||
fixture = TestBed.createComponent(CustomFieldEditDialogComponent)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
settingsService.currentUser = { id: 99, username: 'user99' }
|
||||
settingsService.currentUser.set({ id: 99, username: 'user99' })
|
||||
component = fixture.componentInstance
|
||||
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should support create and edit modes', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
|
||||
const editTitleSpy = jest.spyOn(component, 'getEditTitle')
|
||||
fixture.detectChanges()
|
||||
expect(createTitleSpy).toHaveBeenCalled()
|
||||
expect(editTitleSpy).not.toHaveBeenCalled()
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
fixture.detectChanges()
|
||||
expect(editTitleSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should disable data type select on edit', () => {
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
fixture.detectChanges()
|
||||
component.ngOnInit()
|
||||
expect(component.objectForm.get('data_type').disabled).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should initialize select options on edit', () => {
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
component.object = {
|
||||
id: 1,
|
||||
name: 'Field 1',
|
||||
@@ -91,7 +91,7 @@ describe('CustomFieldEditDialogComponent', () => {
|
||||
})
|
||||
|
||||
it('should support add / remove select options', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
fixture.detectChanges()
|
||||
component.ngOnInit()
|
||||
expect(
|
||||
@@ -115,7 +115,7 @@ describe('CustomFieldEditDialogComponent', () => {
|
||||
const selectOptionInputs = component[
|
||||
'selectOptionInputs'
|
||||
] as QueryList<ElementRef>
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
component.objectForm.get('data_type').setValue(CustomFieldDataType.Select)
|
||||
component.ngOnInit()
|
||||
component.ngAfterViewInit()
|
||||
@@ -125,7 +125,7 @@ describe('CustomFieldEditDialogComponent', () => {
|
||||
})
|
||||
|
||||
it('should send all select options including those changed in form on save', () => {
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
component.object = {
|
||||
id: 1,
|
||||
name: 'Field 1',
|
||||
|
||||
+1
-1
@@ -149,7 +149,7 @@ export class CustomFieldEditDialogComponent
|
||||
}
|
||||
|
||||
get typeFieldDisabled(): boolean {
|
||||
return this.dialogMode === EditDialogMode.EDIT
|
||||
return this.dialogMode() === EditDialogMode.EDIT
|
||||
}
|
||||
|
||||
private updateSelectOptions() {
|
||||
|
||||
+3
-3
@@ -41,20 +41,20 @@ describe('DocumentTypeEditDialogComponent', () => {
|
||||
|
||||
fixture = TestBed.createComponent(DocumentTypeEditDialogComponent)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
settingsService.currentUser = { id: 99, username: 'user99' }
|
||||
settingsService.currentUser.set({ id: 99, username: 'user99' })
|
||||
component = fixture.componentInstance
|
||||
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should support create and edit modes', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
|
||||
const editTitleSpy = jest.spyOn(component, 'getEditTitle')
|
||||
fixture.detectChanges()
|
||||
expect(createTitleSpy).toHaveBeenCalled()
|
||||
expect(editTitleSpy).not.toHaveBeenCalled()
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
fixture.detectChanges()
|
||||
expect(editTitleSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
@@ -4,12 +4,7 @@ import {
|
||||
provideHttpClientTesting,
|
||||
} from '@angular/common/http/testing'
|
||||
import { Component } from '@angular/core'
|
||||
import {
|
||||
ComponentFixture,
|
||||
TestBed,
|
||||
fakeAsync,
|
||||
tick,
|
||||
} from '@angular/core/testing'
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||
import {
|
||||
FormControl,
|
||||
FormGroup,
|
||||
@@ -122,7 +117,7 @@ describe('EditDialogComponent', () => {
|
||||
tagService = TestBed.inject(TagService)
|
||||
permissionsService = TestBed.inject(PermissionsService)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
settingsService.currentUser = currentUser
|
||||
settingsService.currentUser.set(currentUser as any)
|
||||
permissionsService.initialize([], currentUser as any)
|
||||
activeModal = TestBed.inject(NgbActiveModal)
|
||||
httpTestingController = TestBed.inject(HttpTestingController)
|
||||
@@ -136,7 +131,7 @@ describe('EditDialogComponent', () => {
|
||||
it('should interpolate object permissions', () => {
|
||||
component.getMatchingAlgorithms() // coverage
|
||||
component.object = tag
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
component.ngOnInit()
|
||||
|
||||
expect(component.objectForm.get('permissions_form').value).toEqual({
|
||||
@@ -145,15 +140,17 @@ describe('EditDialogComponent', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('should delay close enabled', fakeAsync(() => {
|
||||
it('should delay close enabled', () => {
|
||||
jest.useFakeTimers()
|
||||
expect(component.closeEnabled).toBeFalsy()
|
||||
component.ngOnInit()
|
||||
tick(100)
|
||||
jest.advanceTimersByTime(100)
|
||||
expect(component.closeEnabled).toBeTruthy()
|
||||
}))
|
||||
jest.useRealTimers()
|
||||
})
|
||||
|
||||
it('should set default owner when in create mode if unset', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
component.ngOnInit()
|
||||
expect(component.objectForm.get('permissions_form').value.owner).toEqual(
|
||||
currentUser.id
|
||||
@@ -164,7 +161,7 @@ describe('EditDialogComponent', () => {
|
||||
})
|
||||
|
||||
it('should set default perms when in create mode if set', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
settingsService.set(SETTINGS_KEYS.DEFAULT_PERMS_OWNER, 11)
|
||||
settingsService.set(SETTINGS_KEYS.DEFAULT_PERMS_VIEW_USERS, [1, 2])
|
||||
settingsService.set(SETTINGS_KEYS.DEFAULT_PERMS_VIEW_GROUPS, [3])
|
||||
@@ -203,18 +200,18 @@ describe('EditDialogComponent', () => {
|
||||
})
|
||||
|
||||
it('should support create and edit modes', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
|
||||
const editTitleSpy = jest.spyOn(component, 'getEditTitle')
|
||||
fixture.detectChanges()
|
||||
component.getTitle()
|
||||
expect(createTitleSpy).toHaveBeenCalled()
|
||||
expect(editTitleSpy).not.toHaveBeenCalled()
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
fixture.detectChanges()
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
component.getTitle()
|
||||
expect(editTitleSpy).toHaveBeenCalled()
|
||||
// coverage
|
||||
component.dialogMode = null
|
||||
fixture.detectChanges()
|
||||
component.dialogMode.set(null)
|
||||
component.getTitle()
|
||||
})
|
||||
|
||||
it('should close on cancel', () => {
|
||||
@@ -225,14 +222,14 @@ describe('EditDialogComponent', () => {
|
||||
|
||||
it('should update an object on save in edit mode', () => {
|
||||
const updateSpy = jest.spyOn(tagService, 'update')
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
component.save()
|
||||
expect(updateSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not submit owner or permissions for non-owner edits', () => {
|
||||
component.object = tag
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
component.ngOnInit()
|
||||
|
||||
component.objectForm.get('name').setValue('Updated tag')
|
||||
@@ -251,7 +248,7 @@ describe('EditDialogComponent', () => {
|
||||
|
||||
it('should create an object on save in edit mode', () => {
|
||||
const createSpy = jest.spyOn(tagService, 'create')
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
component.save()
|
||||
expect(createSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
OnInit,
|
||||
Output,
|
||||
inject,
|
||||
model,
|
||||
} from '@angular/core'
|
||||
import { FormGroup } from '@angular/forms'
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
@@ -45,10 +46,7 @@ export abstract class EditDialogComponent<
|
||||
protected settingsService = inject(SettingsService)
|
||||
protected permissionsService = inject(PermissionsService)
|
||||
|
||||
users: User[]
|
||||
|
||||
@Input()
|
||||
dialogMode: EditDialogMode = EditDialogMode.CREATE
|
||||
dialogMode = model(EditDialogMode.CREATE)
|
||||
|
||||
@Input()
|
||||
object: T
|
||||
@@ -59,18 +57,20 @@ export abstract class EditDialogComponent<
|
||||
@Output()
|
||||
failed = new EventEmitter()
|
||||
|
||||
users: User[]
|
||||
|
||||
networkActive = false
|
||||
|
||||
closeEnabled = false
|
||||
|
||||
error = null
|
||||
error: any = null
|
||||
|
||||
abstract getForm(): FormGroup
|
||||
|
||||
objectForm: FormGroup = this.getForm()
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.object != null && this.dialogMode !== EditDialogMode.CREATE) {
|
||||
if (this.object != null && this.dialogMode() !== EditDialogMode.CREATE) {
|
||||
this.object['permissions_form'] = {
|
||||
owner: (this.object as ObjectWithPermissions).owner,
|
||||
set_permissions: (this.object as ObjectWithPermissions).permissions,
|
||||
@@ -124,7 +124,7 @@ export abstract class EditDialogComponent<
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
switch (this.dialogMode) {
|
||||
switch (this.dialogMode()) {
|
||||
case EditDialogMode.CREATE:
|
||||
return this.getCreateTitle()
|
||||
case EditDialogMode.EDIT:
|
||||
@@ -151,7 +151,7 @@ export abstract class EditDialogComponent<
|
||||
|
||||
protected shouldSubmitPermissions(): boolean {
|
||||
return (
|
||||
this.dialogMode === EditDialogMode.CREATE ||
|
||||
this.dialogMode() === EditDialogMode.CREATE ||
|
||||
this.permissionsService.currentUserOwnsObject(this.object)
|
||||
)
|
||||
}
|
||||
@@ -172,7 +172,7 @@ export abstract class EditDialogComponent<
|
||||
delete newObject['set_permissions']
|
||||
}
|
||||
var serverResponse: Observable<T>
|
||||
switch (this.dialogMode) {
|
||||
switch (this.dialogMode()) {
|
||||
case EditDialogMode.CREATE:
|
||||
serverResponse = this.service.create(newObject)
|
||||
break
|
||||
|
||||
+3
-3
@@ -45,20 +45,20 @@ describe('GroupEditDialogComponent', () => {
|
||||
|
||||
fixture = TestBed.createComponent(GroupEditDialogComponent)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
settingsService.currentUser = { id: 99, username: 'user99' }
|
||||
settingsService.currentUser.set({ id: 99, username: 'user99' })
|
||||
component = fixture.componentInstance
|
||||
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should support create and edit modes', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
|
||||
const editTitleSpy = jest.spyOn(component, 'getEditTitle')
|
||||
fixture.detectChanges()
|
||||
expect(createTitleSpy).toHaveBeenCalled()
|
||||
expect(editTitleSpy).not.toHaveBeenCalled()
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
fixture.detectChanges()
|
||||
expect(editTitleSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
+2
-2
@@ -25,8 +25,8 @@
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="m-0 me-2">
|
||||
@if (testResult) {
|
||||
<ngb-alert #testResultAlert [type]="testResult" class="mb-0 py-2" (closed)="testResult = null">{{testResultMessage}}</ngb-alert>
|
||||
@if (testResult()) {
|
||||
<ngb-alert #testResultAlert [type]="testResult()" class="mb-0 py-2" (closed)="testResult.set(null)">{{testResultMessage}}</ngb-alert>
|
||||
}
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-primary" (click)="test()" [disabled]="networkActive || testActive">
|
||||
|
||||
+10
-13
@@ -3,12 +3,7 @@ import {
|
||||
HttpTestingController,
|
||||
provideHttpClientTesting,
|
||||
} from '@angular/common/http/testing'
|
||||
import {
|
||||
ComponentFixture,
|
||||
TestBed,
|
||||
fakeAsync,
|
||||
tick,
|
||||
} from '@angular/core/testing'
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { NgSelectModule } from '@ng-select/ng-select'
|
||||
@@ -58,25 +53,26 @@ describe('MailAccountEditDialogComponent', () => {
|
||||
|
||||
fixture = TestBed.createComponent(MailAccountEditDialogComponent)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
settingsService.currentUser = { id: 99, username: 'user99' }
|
||||
settingsService.currentUser.set({ id: 99, username: 'user99' })
|
||||
component = fixture.componentInstance
|
||||
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should support create and edit modes', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
|
||||
const editTitleSpy = jest.spyOn(component, 'getEditTitle')
|
||||
fixture.detectChanges()
|
||||
expect(createTitleSpy).toHaveBeenCalled()
|
||||
expect(editTitleSpy).not.toHaveBeenCalled()
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
fixture.detectChanges()
|
||||
expect(editTitleSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should support test mail account and show appropriate expiring alert', fakeAsync(() => {
|
||||
it('should support test mail account and show appropriate expiring alert', () => {
|
||||
jest.useFakeTimers()
|
||||
component.object = {
|
||||
name: 'example',
|
||||
imap_server: 'imap.example.com',
|
||||
@@ -97,7 +93,7 @@ describe('MailAccountEditDialogComponent', () => {
|
||||
expect(fixture.nativeElement.textContent).toContain(
|
||||
'Successfully connected'
|
||||
)
|
||||
tick(6000)
|
||||
jest.advanceTimersByTime(6000)
|
||||
fixture.detectChanges()
|
||||
expect(fixture.nativeElement.textContent).not.toContain(
|
||||
'Successfully connected'
|
||||
@@ -118,6 +114,7 @@ describe('MailAccountEditDialogComponent', () => {
|
||||
.flush({}, { status: 500, statusText: 'error' })
|
||||
fixture.detectChanges()
|
||||
expect(fixture.nativeElement.textContent).toContain('Unable to connect')
|
||||
tick(6000)
|
||||
}))
|
||||
jest.advanceTimersByTime(6000)
|
||||
jest.useRealTimers()
|
||||
})
|
||||
})
|
||||
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
import { Component, ViewChild, inject } from '@angular/core'
|
||||
import { Component, ViewChild, inject, signal } from '@angular/core'
|
||||
import {
|
||||
FormControl,
|
||||
FormGroup,
|
||||
@@ -38,7 +38,7 @@ const IMAP_SECURITY_OPTIONS = [
|
||||
})
|
||||
export class MailAccountEditDialogComponent extends EditDialogComponent<MailAccount> {
|
||||
testActive: boolean = false
|
||||
testResult: string
|
||||
readonly testResult = signal<string>(undefined)
|
||||
alertTimeout
|
||||
|
||||
@ViewChild('testResultAlert', { static: false }) testResultAlert: NgbAlert
|
||||
@@ -77,7 +77,7 @@ export class MailAccountEditDialogComponent extends EditDialogComponent<MailAcco
|
||||
|
||||
test() {
|
||||
this.testActive = true
|
||||
this.testResult = null
|
||||
this.testResult.set(null)
|
||||
clearTimeout(this.alertTimeout)
|
||||
const mailService = this.service as MailAccountService
|
||||
const newObject = Object.assign(
|
||||
@@ -87,19 +87,19 @@ export class MailAccountEditDialogComponent extends EditDialogComponent<MailAcco
|
||||
mailService.test(newObject).subscribe({
|
||||
next: (result: { success: boolean }) => {
|
||||
this.testActive = false
|
||||
this.testResult = result.success ? 'success' : 'danger'
|
||||
this.testResult.set(result.success ? 'success' : 'danger')
|
||||
this.alertTimeout = setTimeout(() => this.testResultAlert.close(), 5000)
|
||||
},
|
||||
error: (e) => {
|
||||
this.testActive = false
|
||||
this.testResult = 'danger'
|
||||
this.testResult.set('danger')
|
||||
this.alertTimeout = setTimeout(() => this.testResultAlert.close(), 5000)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
get testResultMessage() {
|
||||
return this.testResult === 'success'
|
||||
return this.testResult() === 'success'
|
||||
? $localize`Successfully connected to the mail server`
|
||||
: $localize`Unable to connect to the mail server`
|
||||
}
|
||||
|
||||
+3
-3
@@ -13,7 +13,7 @@
|
||||
<pngx-input-text [horizontal]="true" i18n-title title="Name" formControlName="name" [error]="error?.name" autocomplete="off"></pngx-input-text>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<pngx-input-select [horizontal]="true" i18n-title title="Account" [items]="accounts" formControlName="account"></pngx-input-select>
|
||||
<pngx-input-select [horizontal]="true" i18n-title title="Account" [items]="accounts()" formControlName="account"></pngx-input-select>
|
||||
</div>
|
||||
<div class="col-md-2 pt-2">
|
||||
<pngx-input-switch [horizontal]="true" i18n-title title="Enabled" formControlName="enabled"></pngx-input-switch>
|
||||
@@ -65,10 +65,10 @@
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<pngx-input-tags [horizontal]="true" [allowCreate]="false" formControlName="assign_tags"></pngx-input-tags>
|
||||
<pngx-input-select [horizontal]="true" i18n-title title="Assign document type" [items]="documentTypes" [allowNull]="true" formControlName="assign_document_type"></pngx-input-select>
|
||||
<pngx-input-select [horizontal]="true" i18n-title title="Assign document type" [items]="documentTypes()" [allowNull]="true" formControlName="assign_document_type"></pngx-input-select>
|
||||
<pngx-input-select [horizontal]="true" i18n-title title="Assign correspondent from" [items]="metadataCorrespondentOptions" formControlName="assign_correspondent_from"></pngx-input-select>
|
||||
@if (showCorrespondentField) {
|
||||
<pngx-input-select [horizontal]="true" i18n-title title="Assign correspondent" [items]="correspondents" [allowNull]="true" formControlName="assign_correspondent"></pngx-input-select>
|
||||
<pngx-input-select [horizontal]="true" i18n-title title="Assign correspondent" [items]="correspondents()" [allowNull]="true" formControlName="assign_correspondent"></pngx-input-select>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+3
-3
@@ -75,20 +75,20 @@ describe('MailRuleEditDialogComponent', () => {
|
||||
|
||||
fixture = TestBed.createComponent(MailRuleEditDialogComponent)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
settingsService.currentUser = { id: 99, username: 'user99' }
|
||||
settingsService.currentUser.set({ id: 99, username: 'user99' })
|
||||
component = fixture.componentInstance
|
||||
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should support create and edit modes', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
|
||||
const editTitleSpy = jest.spyOn(component, 'getEditTitle')
|
||||
fixture.detectChanges()
|
||||
expect(createTitleSpy).toHaveBeenCalled()
|
||||
expect(editTitleSpy).not.toHaveBeenCalled()
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
fixture.detectChanges()
|
||||
expect(editTitleSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
+17
-25
@@ -1,11 +1,12 @@
|
||||
import { Component, inject } from '@angular/core'
|
||||
import { toSignal } from '@angular/core/rxjs-interop'
|
||||
import {
|
||||
FormControl,
|
||||
FormGroup,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
} from '@angular/forms'
|
||||
import { first } from 'rxjs'
|
||||
import { map } from 'rxjs'
|
||||
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
||||
import { Correspondent } from 'src/app/data/correspondent'
|
||||
import { DocumentType } from 'src/app/data/document-type'
|
||||
@@ -154,37 +155,28 @@ const METADATA_CORRESPONDENT_OPTIONS = [
|
||||
],
|
||||
})
|
||||
export class MailRuleEditDialogComponent extends EditDialogComponent<MailRule> {
|
||||
private accountService: MailAccountService
|
||||
private correspondentService: CorrespondentService
|
||||
private documentTypeService: DocumentTypeService
|
||||
private readonly accountService = inject(MailAccountService)
|
||||
private readonly correspondentService = inject(CorrespondentService)
|
||||
private readonly documentTypeService = inject(DocumentTypeService)
|
||||
|
||||
accounts: MailAccount[]
|
||||
correspondents: Correspondent[]
|
||||
documentTypes: DocumentType[]
|
||||
readonly accounts = toSignal(
|
||||
this.accountService.listAll().pipe(map((result) => result.results)),
|
||||
{ initialValue: undefined as MailAccount[] }
|
||||
)
|
||||
readonly correspondents = toSignal(
|
||||
this.correspondentService.listAll().pipe(map((result) => result.results)),
|
||||
{ initialValue: undefined as Correspondent[] }
|
||||
)
|
||||
readonly documentTypes = toSignal(
|
||||
this.documentTypeService.listAll().pipe(map((result) => result.results)),
|
||||
{ initialValue: undefined as DocumentType[] }
|
||||
)
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.service = inject(MailRuleService)
|
||||
this.accountService = inject(MailAccountService)
|
||||
this.correspondentService = inject(CorrespondentService)
|
||||
this.documentTypeService = inject(DocumentTypeService)
|
||||
this.userService = inject(UserService)
|
||||
this.settingsService = inject(SettingsService)
|
||||
|
||||
this.accountService
|
||||
.listAll()
|
||||
.pipe(first())
|
||||
.subscribe((result) => (this.accounts = result.results))
|
||||
|
||||
this.correspondentService
|
||||
.listAll()
|
||||
.pipe(first())
|
||||
.subscribe((result) => (this.correspondents = result.results))
|
||||
|
||||
this.documentTypeService
|
||||
.listAll()
|
||||
.pipe(first())
|
||||
.subscribe((result) => (this.documentTypes = result.results))
|
||||
}
|
||||
|
||||
getCreateTitle() {
|
||||
|
||||
+3
-3
@@ -30,20 +30,20 @@ describe('StoragePathEditDialogComponent', () => {
|
||||
documentService = TestBed.inject(DocumentService)
|
||||
fixture = TestBed.createComponent(StoragePathEditDialogComponent)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
settingsService.currentUser = { id: 99, username: 'user99' }
|
||||
settingsService.currentUser.set({ id: 99, username: 'user99' })
|
||||
component = fixture.componentInstance
|
||||
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should support create and edit modes', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
|
||||
const editTitleSpy = jest.spyOn(component, 'getEditTitle')
|
||||
fixture.detectChanges()
|
||||
expect(createTitleSpy).toHaveBeenCalled()
|
||||
expect(editTitleSpy).not.toHaveBeenCalled()
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
fixture.detectChanges()
|
||||
expect(editTitleSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
+3
-3
@@ -67,11 +67,11 @@ export class StoragePathEditDialogComponent
|
||||
private testDocument: Document
|
||||
public testResult: string
|
||||
public testFailed: boolean = false
|
||||
public loading = false
|
||||
public testLoading = false
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.loading.set(false)
|
||||
this.service = inject(StoragePathService)
|
||||
this.userService = inject(UserService)
|
||||
this.settingsService = inject(SettingsService)
|
||||
@@ -138,7 +138,7 @@ export class StoragePathEditDialogComponent
|
||||
this.documentsInput$.pipe(
|
||||
distinctUntilChanged(),
|
||||
takeUntil(this.unsubscribeNotifier),
|
||||
tap(() => (this.loading = true)),
|
||||
tap(() => this.loading.set(true)),
|
||||
switchMap((title) =>
|
||||
this.documentsService
|
||||
.listFiltered(
|
||||
@@ -152,7 +152,7 @@ export class StoragePathEditDialogComponent
|
||||
.pipe(
|
||||
map((result) => result.results),
|
||||
catchError(() => of([])), // empty on error
|
||||
tap(() => (this.loading = false))
|
||||
tap(() => this.loading.set(false))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
+3
-3
@@ -48,20 +48,20 @@ describe('TagEditDialogComponent', () => {
|
||||
|
||||
fixture = TestBed.createComponent(TagEditDialogComponent)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
settingsService.currentUser = { id: 99, username: 'user99' }
|
||||
settingsService.currentUser.set({ id: 99, username: 'user99' })
|
||||
component = fixture.componentInstance
|
||||
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should support create and edit modes', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
|
||||
const editTitleSpy = jest.spyOn(component, 'getEditTitle')
|
||||
fixture.detectChanges()
|
||||
expect(createTitleSpy).toHaveBeenCalled()
|
||||
expect(editTitleSpy).not.toHaveBeenCalled()
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
fixture.detectChanges()
|
||||
expect(editTitleSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
+2
-2
@@ -31,7 +31,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<pngx-input-select i18n-title title="Groups" [items]="groups" multiple="true" formControlName="groups"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="Groups" [items]="groups()" multiple="true" formControlName="groups"></pngx-input-select>
|
||||
|
||||
@if (object?.is_mfa_enabled && currentUserIsSuperUser) {
|
||||
<label class="form-label" i18n>Two-factor Authentication</label>
|
||||
@@ -42,7 +42,7 @@
|
||||
i18n-title
|
||||
buttonClasses="btn-outline-danger btn-sm"
|
||||
iconName="trash"
|
||||
[disabled]="totpLoading"
|
||||
[disabled]="totpLoading()"
|
||||
(confirm)="deactivateTotp()">
|
||||
</pngx-confirm-button>
|
||||
}
|
||||
|
||||
+6
-6
@@ -73,7 +73,7 @@ describe('UserEditDialogComponent', () => {
|
||||
|
||||
fixture = TestBed.createComponent(UserEditDialogComponent)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
settingsService.currentUser = { id: 99, username: 'user99' }
|
||||
settingsService.currentUser.set({ id: 99, username: 'user99' })
|
||||
permissionsService = TestBed.inject(PermissionsService)
|
||||
toastService = TestBed.inject(ToastService)
|
||||
component = fixture.componentInstance
|
||||
@@ -82,13 +82,13 @@ describe('UserEditDialogComponent', () => {
|
||||
})
|
||||
|
||||
it('should support create and edit modes', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
|
||||
const editTitleSpy = jest.spyOn(component, 'getEditTitle')
|
||||
fixture.detectChanges()
|
||||
expect(createTitleSpy).toHaveBeenCalled()
|
||||
expect(editTitleSpy).not.toHaveBeenCalled()
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
fixture.detectChanges()
|
||||
expect(editTitleSpy).toHaveBeenCalled()
|
||||
})
|
||||
@@ -114,17 +114,17 @@ describe('UserEditDialogComponent', () => {
|
||||
it('should detect whether password was changed in form on save', () => {
|
||||
component.objectForm.get('password').setValue(null)
|
||||
component.save()
|
||||
expect(component.passwordIsSet).toBeFalsy()
|
||||
expect(component.passwordIsSet()).toBeFalsy()
|
||||
|
||||
// unchanged pw
|
||||
component.objectForm.get('password').setValue('*******')
|
||||
component.save()
|
||||
expect(component.passwordIsSet).toBeFalsy()
|
||||
expect(component.passwordIsSet()).toBeFalsy()
|
||||
|
||||
// unchanged pw
|
||||
component.objectForm.get('password').setValue('helloworld')
|
||||
component.save()
|
||||
expect(component.passwordIsSet).toBeTruthy()
|
||||
expect(component.passwordIsSet()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should support deactivation of TOTP', () => {
|
||||
|
||||
+16
-17
@@ -1,11 +1,12 @@
|
||||
import { Component, OnInit, inject } from '@angular/core'
|
||||
import { Component, OnInit, inject, signal } from '@angular/core'
|
||||
import { toSignal } from '@angular/core/rxjs-interop'
|
||||
import {
|
||||
FormControl,
|
||||
FormGroup,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
} from '@angular/forms'
|
||||
import { first } from 'rxjs'
|
||||
import { first, map } from 'rxjs'
|
||||
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
||||
import { Group } from 'src/app/data/group'
|
||||
import { User } from 'src/app/data/user'
|
||||
@@ -38,22 +39,19 @@ export class UserEditDialogComponent
|
||||
implements OnInit
|
||||
{
|
||||
private toastService = inject(ToastService)
|
||||
private groupsService: GroupService
|
||||
private readonly groupsService = inject(GroupService)
|
||||
|
||||
groups: Group[]
|
||||
passwordIsSet: boolean = false
|
||||
public totpLoading: boolean = false
|
||||
readonly groups = toSignal(
|
||||
this.groupsService.listAll().pipe(map((result) => result.results)),
|
||||
{ initialValue: undefined as Group[] }
|
||||
)
|
||||
readonly passwordIsSet = signal(false)
|
||||
readonly totpLoading = signal(false)
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.service = inject(UserService)
|
||||
this.groupsService = inject(GroupService)
|
||||
this.settingsService = inject(SettingsService)
|
||||
|
||||
this.groupsService
|
||||
.listAll()
|
||||
.pipe(first())
|
||||
.subscribe((result) => (this.groups = result.results))
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -103,14 +101,15 @@ export class UserEditDialogComponent
|
||||
if (!groupsVal) return []
|
||||
else
|
||||
return groupsVal.flatMap(
|
||||
(id) => this.groups.find((g) => g.id == id)?.permissions
|
||||
(id) => this.groups()?.find((g) => g.id == id)?.permissions
|
||||
)
|
||||
}
|
||||
|
||||
save(): void {
|
||||
this.passwordIsSet =
|
||||
this.passwordIsSet.set(
|
||||
this.objectForm.get('password').value?.toString().replaceAll('*', '')
|
||||
.length > 0
|
||||
)
|
||||
super.save()
|
||||
}
|
||||
|
||||
@@ -119,13 +118,13 @@ export class UserEditDialogComponent
|
||||
}
|
||||
|
||||
deactivateTotp() {
|
||||
this.totpLoading = true
|
||||
this.totpLoading.set(true)
|
||||
;(this.service as UserService)
|
||||
.deactivateTotp(this.object)
|
||||
.pipe(first())
|
||||
.subscribe({
|
||||
next: (result) => {
|
||||
this.totpLoading = false
|
||||
this.totpLoading.set(false)
|
||||
if (result) {
|
||||
this.toastService.showInfo($localize`Totp deactivated`)
|
||||
this.object.is_mfa_enabled = false
|
||||
@@ -134,7 +133,7 @@ export class UserEditDialogComponent
|
||||
}
|
||||
},
|
||||
error: (e) => {
|
||||
this.totpLoading = false
|
||||
this.totpLoading.set(false)
|
||||
this.toastService.showError($localize`Totp deactivation failed`, e)
|
||||
},
|
||||
})
|
||||
|
||||
+10
-10
@@ -140,7 +140,7 @@
|
||||
</div>
|
||||
@if (formGroup.get('schedule_date_field').value === 'custom_field') {
|
||||
<div class="col-4">
|
||||
<pngx-input-select i18n-title title="Custom field" formControlName="schedule_date_custom_field" [items]="dateCustomFields" i18n-hint hint="Custom field to use for date." [error]="error?.schedule_date_custom_field"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="Custom field" formControlName="schedule_date_custom_field" [items]="dateCustomFields()" i18n-hint hint="Custom field to use for date." [error]="error?.schedule_date_custom_field"></pngx-input-select>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -162,7 +162,7 @@
|
||||
@if (formGroup.get('type').value === WorkflowTriggerType.Consumption) {
|
||||
<pngx-input-select i18n-title title="Filter sources" [items]="sourceOptions" horizontal="true" [multiple]="true" formControlName="sources" [error]="error?.sources"></pngx-input-select>
|
||||
<pngx-input-text i18n-title title="Filter path" formControlName="filter_path" horizontal="true" i18n-hint hint="Apply to documents that match this path. Wildcards specified as * are allowed. Case-normalized." [error]="error?.filter_path"></pngx-input-text>
|
||||
<pngx-input-select i18n-title title="Filter mail rule" [items]="mailRules" horizontal="true" [allowNull]="true" formControlName="filter_mailrule" i18n-hint hint="Apply to documents consumed via this mail rule." [error]="error?.filter_mailrule"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="Filter mail rule" [items]="mailRules()" horizontal="true" [allowNull]="true" formControlName="filter_mailrule" i18n-hint hint="Apply to documents consumed via this mail rule." [error]="error?.filter_mailrule"></pngx-input-select>
|
||||
}
|
||||
@if (formGroup.get('type').value === WorkflowTriggerType.DocumentAdded || formGroup.get('type').value === WorkflowTriggerType.DocumentUpdated || formGroup.get('type').value === WorkflowTriggerType.Scheduled) {
|
||||
<pngx-input-select i18n-title title="Content matching algorithm" horizontal="true" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></pngx-input-select>
|
||||
@@ -262,10 +262,10 @@
|
||||
<div class="col">
|
||||
<pngx-input-text i18n-title title="Assign title" formControlName="assign_title" i18n-hint hint="Can include some placeholders, see <a target='_blank' href='https://docs.paperless-ngx.com/usage/#workflows'>documentation</a>." [error]="error?.actions?.[i]?.assign_title"></pngx-input-text>
|
||||
<pngx-input-tags [allowCreate]="false" i18n-title title="Assign tags" formControlName="assign_tags"></pngx-input-tags>
|
||||
<pngx-input-select i18n-title title="Assign document type" [items]="documentTypes" [allowNull]="true" formControlName="assign_document_type"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="Assign correspondent" [items]="correspondents" [allowNull]="true" formControlName="assign_correspondent"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="Assign storage path" [items]="storagePaths" [allowNull]="true" formControlName="assign_storage_path"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="Assign custom fields" multiple="true" [items]="customFields" [allowNull]="true" formControlName="assign_custom_fields"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="Assign document type" [items]="documentTypes()" [allowNull]="true" formControlName="assign_document_type"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="Assign correspondent" [items]="correspondents()" [allowNull]="true" formControlName="assign_correspondent"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="Assign storage path" [items]="storagePaths()" [allowNull]="true" formControlName="assign_storage_path"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="Assign custom fields" multiple="true" [items]="customFields()" [allowNull]="true" formControlName="assign_custom_fields"></pngx-input-select>
|
||||
<pngx-input-custom-fields-values formControlName="assign_custom_fields_values" [selectedFields]="formGroup.get('assign_custom_fields').value" (removeSelectedField)="removeSelectedCustomField($event, formGroup)"></pngx-input-custom-fields-values>
|
||||
</div>
|
||||
<div class="col">
|
||||
@@ -326,25 +326,25 @@
|
||||
<h6 class="form-label" i18n>Remove correspondents</h6>
|
||||
<pngx-input-switch i18n-title title="Remove all" [horizontal]="true" formControlName="remove_all_correspondents"></pngx-input-switch>
|
||||
<div class="mt-n3">
|
||||
<pngx-input-select i18n-title title="" multiple="true" [items]="correspondents" formControlName="remove_correspondents"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="" multiple="true" [items]="correspondents()" formControlName="remove_correspondents"></pngx-input-select>
|
||||
</div>
|
||||
|
||||
<h6 class="form-label" i18n>Remove document types</h6>
|
||||
<pngx-input-switch i18n-title title="Remove all" [horizontal]="true" formControlName="remove_all_document_types"></pngx-input-switch>
|
||||
<div class="mt-n3">
|
||||
<pngx-input-select i18n-title title="" multiple="true" [items]="documentTypes" formControlName="remove_document_types"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="" multiple="true" [items]="documentTypes()" formControlName="remove_document_types"></pngx-input-select>
|
||||
</div>
|
||||
|
||||
<h6 class="form-label" i18n>Remove storage paths</h6>
|
||||
<pngx-input-switch i18n-title title="Remove all" [horizontal]="true" formControlName="remove_all_storage_paths"></pngx-input-switch>
|
||||
<div class="mt-n3">
|
||||
<pngx-input-select i18n-title title="" multiple="true" [items]="storagePaths" formControlName="remove_storage_paths"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="" multiple="true" [items]="storagePaths()" formControlName="remove_storage_paths"></pngx-input-select>
|
||||
</div>
|
||||
|
||||
<h6 class="form-label" i18n>Remove custom fields</h6>
|
||||
<pngx-input-switch i18n-title title="Remove all" [horizontal]="true" formControlName="remove_all_custom_fields"></pngx-input-switch>
|
||||
<div class="mt-n3">
|
||||
<pngx-input-select i18n-title title="" multiple="true" [items]="customFields" formControlName="remove_custom_fields"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="" multiple="true" [items]="customFields()" formControlName="remove_custom_fields"></pngx-input-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
|
||||
+8
-12
@@ -187,14 +187,14 @@ describe('WorkflowEditDialogComponent', () => {
|
||||
|
||||
fixture = TestBed.createComponent(WorkflowEditDialogComponent)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
settingsService.currentUser = { id: 99, username: 'user99' }
|
||||
settingsService.currentUser.set({ id: 99, username: 'user99' })
|
||||
component = fixture.componentInstance
|
||||
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should support create and edit modes, support adding triggers and actions on new workflow', () => {
|
||||
component.dialogMode = EditDialogMode.CREATE
|
||||
component.dialogMode.set(EditDialogMode.CREATE)
|
||||
const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
|
||||
const editTitleSpy = jest.spyOn(component, 'getEditTitle')
|
||||
fixture.detectChanges()
|
||||
@@ -209,7 +209,7 @@ describe('WorkflowEditDialogComponent', () => {
|
||||
expect(component.object).not.toBeUndefined()
|
||||
expect(component.object.triggers).toHaveLength(1)
|
||||
|
||||
component.dialogMode = EditDialogMode.EDIT
|
||||
component.dialogMode.set(EditDialogMode.EDIT)
|
||||
fixture.detectChanges()
|
||||
expect(editTitleSpy).toHaveBeenCalled()
|
||||
})
|
||||
@@ -771,25 +771,21 @@ describe('WorkflowEditDialogComponent', () => {
|
||||
false
|
||||
)
|
||||
|
||||
component.correspondents = [{ id: 1, name: 'C1' } as any]
|
||||
component.documentTypes = [{ id: 2, name: 'DT' } as any]
|
||||
component.storagePaths = [{ id: 3, name: 'SP' } as any]
|
||||
|
||||
expect(
|
||||
component.getFilterSelectItems(TriggerFilterType.CorrespondentIs)
|
||||
).toEqual(component.correspondents)
|
||||
).toEqual(component.correspondents())
|
||||
expect(
|
||||
component.getFilterSelectItems(TriggerFilterType.DocumentTypeIs)
|
||||
).toEqual(component.documentTypes)
|
||||
).toEqual(component.documentTypes())
|
||||
expect(
|
||||
component.getFilterSelectItems(TriggerFilterType.DocumentTypeAny)
|
||||
).toEqual(component.documentTypes)
|
||||
).toEqual(component.documentTypes())
|
||||
expect(
|
||||
component.getFilterSelectItems(TriggerFilterType.StoragePathIs)
|
||||
).toEqual(component.storagePaths)
|
||||
).toEqual(component.storagePaths())
|
||||
expect(
|
||||
component.getFilterSelectItems(TriggerFilterType.StoragePathAny)
|
||||
).toEqual(component.storagePaths)
|
||||
).toEqual(component.storagePaths())
|
||||
expect(component.getFilterSelectItems(TriggerFilterType.TagsAll)).toEqual(
|
||||
[]
|
||||
)
|
||||
|
||||
+44
-58
@@ -4,7 +4,8 @@ import {
|
||||
moveItemInArray,
|
||||
} from '@angular/cdk/drag-drop'
|
||||
import { NgTemplateOutlet } from '@angular/common'
|
||||
import { Component, OnInit, inject } from '@angular/core'
|
||||
import { Component, OnInit, computed, inject, signal } from '@angular/core'
|
||||
import { toSignal } from '@angular/core/rxjs-interop'
|
||||
import {
|
||||
AbstractControl,
|
||||
FormArray,
|
||||
@@ -15,7 +16,7 @@ import {
|
||||
} from '@angular/forms'
|
||||
import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||
import { Subscription, first, takeUntil } from 'rxjs'
|
||||
import { Subscription, map, takeUntil } from 'rxjs'
|
||||
import { Correspondent } from 'src/app/data/correspondent'
|
||||
import { CustomField, CustomFieldDataType } from 'src/app/data/custom-field'
|
||||
import { DocumentType } from 'src/app/data/document-type'
|
||||
@@ -470,23 +471,40 @@ export class WorkflowEditDialogComponent
|
||||
public TriggerFilterType = TriggerFilterType
|
||||
public filterDefinitions = TRIGGER_FILTER_DEFINITIONS
|
||||
|
||||
private correspondentService: CorrespondentService
|
||||
private documentTypeService: DocumentTypeService
|
||||
private storagePathService: StoragePathService
|
||||
private mailRuleService: MailRuleService
|
||||
private customFieldsService: CustomFieldsService
|
||||
private readonly correspondentService = inject(CorrespondentService)
|
||||
private readonly documentTypeService = inject(DocumentTypeService)
|
||||
private readonly storagePathService = inject(StoragePathService)
|
||||
private readonly mailRuleService = inject(MailRuleService)
|
||||
private readonly customFieldsService = inject(CustomFieldsService)
|
||||
|
||||
templates: Workflow[]
|
||||
correspondents: Correspondent[]
|
||||
documentTypes: DocumentType[]
|
||||
storagePaths: StoragePath[]
|
||||
mailRules: MailRule[]
|
||||
customFields: CustomField[]
|
||||
dateCustomFields: CustomField[]
|
||||
readonly templates = signal<Workflow[]>(undefined)
|
||||
readonly correspondents = toSignal(
|
||||
this.correspondentService.listAll().pipe(map((result) => result.results)),
|
||||
{ initialValue: undefined as Correspondent[] }
|
||||
)
|
||||
readonly documentTypes = toSignal(
|
||||
this.documentTypeService.listAll().pipe(map((result) => result.results)),
|
||||
{ initialValue: undefined as DocumentType[] }
|
||||
)
|
||||
readonly storagePaths = toSignal(
|
||||
this.storagePathService.listAll().pipe(map((result) => result.results)),
|
||||
{ initialValue: undefined as StoragePath[] }
|
||||
)
|
||||
readonly mailRules = toSignal(
|
||||
this.mailRuleService.listAll().pipe(map((result) => result.results)),
|
||||
{ initialValue: undefined as MailRule[] }
|
||||
)
|
||||
readonly customFields = toSignal(
|
||||
this.customFieldsService.listAll().pipe(map((result) => result.results)),
|
||||
{ initialValue: undefined as CustomField[] }
|
||||
)
|
||||
readonly dateCustomFields = computed(() =>
|
||||
this.customFields()?.filter((f) => f.data_type === CustomFieldDataType.Date)
|
||||
)
|
||||
|
||||
expandedItem: number = null
|
||||
|
||||
private allowedActionTypes = []
|
||||
readonly allowedActionTypes = signal([])
|
||||
|
||||
private readonly triggerFilterOptionsMap = new WeakMap<
|
||||
FormArray,
|
||||
@@ -496,43 +514,8 @@ export class WorkflowEditDialogComponent
|
||||
constructor() {
|
||||
super()
|
||||
this.service = inject(WorkflowService)
|
||||
this.correspondentService = inject(CorrespondentService)
|
||||
this.documentTypeService = inject(DocumentTypeService)
|
||||
this.storagePathService = inject(StoragePathService)
|
||||
this.mailRuleService = inject(MailRuleService)
|
||||
this.userService = inject(UserService)
|
||||
this.settingsService = inject(SettingsService)
|
||||
this.customFieldsService = inject(CustomFieldsService)
|
||||
|
||||
this.correspondentService
|
||||
.listAll()
|
||||
.pipe(first())
|
||||
.subscribe((result) => (this.correspondents = result.results))
|
||||
|
||||
this.documentTypeService
|
||||
.listAll()
|
||||
.pipe(first())
|
||||
.subscribe((result) => (this.documentTypes = result.results))
|
||||
|
||||
this.storagePathService
|
||||
.listAll()
|
||||
.pipe(first())
|
||||
.subscribe((result) => (this.storagePaths = result.results))
|
||||
|
||||
this.mailRuleService
|
||||
.listAll()
|
||||
.pipe(first())
|
||||
.subscribe((result) => (this.mailRules = result.results))
|
||||
|
||||
this.customFieldsService
|
||||
.listAll()
|
||||
.pipe(first())
|
||||
.subscribe((result) => {
|
||||
this.customFields = result.results
|
||||
this.dateCustomFields = this.customFields?.filter(
|
||||
(f) => f.data_type === CustomFieldDataType.Date
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
getCreateTitle() {
|
||||
@@ -565,11 +548,13 @@ export class WorkflowEditDialogComponent
|
||||
this.checkRemovalActionFields.bind(this)
|
||||
)
|
||||
this.checkRemovalActionFields(this.objectForm.value)
|
||||
this.allowedActionTypes = this.settingsService.get(
|
||||
SETTINGS_KEYS.EMAIL_ENABLED
|
||||
this.allowedActionTypes.set(
|
||||
this.settingsService.get(SETTINGS_KEYS.EMAIL_ENABLED)
|
||||
? WORKFLOW_ACTION_OPTIONS
|
||||
: WORKFLOW_ACTION_OPTIONS.filter(
|
||||
(a) => a.id !== WorkflowActionType.Email
|
||||
)
|
||||
)
|
||||
? WORKFLOW_ACTION_OPTIONS
|
||||
: WORKFLOW_ACTION_OPTIONS.filter((a) => a.id !== WorkflowActionType.Email)
|
||||
}
|
||||
|
||||
private checkRemovalActionFields(formWorkflow: Workflow) {
|
||||
@@ -954,11 +939,11 @@ export class WorkflowEditDialogComponent
|
||||
|
||||
switch (definition.selectItems) {
|
||||
case 'correspondents':
|
||||
return this.correspondents
|
||||
return this.correspondents()
|
||||
case 'documentTypes':
|
||||
return this.documentTypes
|
||||
return this.documentTypes()
|
||||
case 'storagePaths':
|
||||
return this.storagePaths
|
||||
return this.storagePaths()
|
||||
default:
|
||||
return []
|
||||
}
|
||||
@@ -1294,7 +1279,8 @@ export class WorkflowEditDialogComponent
|
||||
}
|
||||
|
||||
get actionTypeOptions() {
|
||||
return this.allowedActionTypes
|
||||
this.settingsService.trackChanges()
|
||||
return this.allowedActionTypes()
|
||||
}
|
||||
|
||||
getActionTypeOptionName(type: WorkflowActionType): string {
|
||||
|
||||
Reference in New Issue
Block a user