-
}
- @if (templates.length === 0) {
-
No templates defined.
+ @if (workflows.length === 0) {
+
No workflows defined.
}
diff --git a/src-ui/src/app/components/manage/workflows/workflows.component.scss b/src-ui/src/app/components/manage/workflows/workflows.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src-ui/src/app/components/manage/consumption-templates/consumption-templates.component.spec.ts b/src-ui/src/app/components/manage/workflows/workflows.component.spec.ts
similarity index 70%
rename from src-ui/src/app/components/manage/consumption-templates/consumption-templates.component.spec.ts
rename to src-ui/src/app/components/manage/workflows/workflows.component.spec.ts
index 2cb365576..e24e7f8b8 100644
--- a/src-ui/src/app/components/manage/consumption-templates/consumption-templates.component.spec.ts
+++ b/src-ui/src/app/components/manage/workflows/workflows.component.spec.ts
@@ -9,55 +9,71 @@ import {
NgbModalModule,
} from '@ng-bootstrap/ng-bootstrap'
import { of, throwError } from 'rxjs'
-import {
- DocumentSource,
- ConsumptionTemplate,
-} from 'src/app/data/consumption-template'
+import { Workflow } from 'src/app/data/workflow'
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
-import { ConsumptionTemplateService } from 'src/app/services/rest/consumption-template.service'
+import { WorkflowService } from 'src/app/services/rest/workflow.service'
import { ToastService } from 'src/app/services/toast.service'
import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
import { PageHeaderComponent } from '../../common/page-header/page-header.component'
-import { ConsumptionTemplatesComponent } from './consumption-templates.component'
-import { ConsumptionTemplateEditDialogComponent } from '../../common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component'
+import { WorkflowsComponent } from './workflows.component'
+import { WorkflowEditDialogComponent } from '../../common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component'
import { PermissionsService } from 'src/app/services/permissions.service'
+import {
+ DocumentSource,
+ WorkflowTriggerType,
+} from 'src/app/data/workflow-trigger'
-const templates: ConsumptionTemplate[] = [
+const workflows: Workflow[] = [
{
- id: 0,
- name: 'Template 1',
- order: 0,
- sources: [
- DocumentSource.ConsumeFolder,
- DocumentSource.ApiUpload,
- DocumentSource.MailFetch,
+ name: 'Workflow 1',
+ id: 1,
+ order: 1,
+ triggers: [
+ {
+ id: 1,
+ type: WorkflowTriggerType.Consumption,
+ sources: [DocumentSource.ConsumeFolder],
+ filter_filename: '*',
+ },
+ ],
+ actions: [
+ {
+ id: 1,
+ assign_title: 'foo',
+ },
],
- filter_filename: 'foo',
- filter_path: 'bar',
- assign_tags: [1, 2, 3],
},
{
- id: 1,
- name: 'Template 2',
- order: 1,
- sources: [DocumentSource.MailFetch],
- filter_filename: null,
- filter_path: 'foo/bar',
- assign_owner: 1,
+ name: 'Workflow 2',
+ id: 2,
+ order: 2,
+ triggers: [
+ {
+ id: 2,
+ type: WorkflowTriggerType.DocumentAdded,
+ filter_filename: 'foo',
+ },
+ ],
+ actions: [
+ {
+ id: 2,
+ assign_title: 'bar',
+ },
+ ],
},
]
-describe('ConsumptionTemplatesComponent', () => {
- let component: ConsumptionTemplatesComponent
- let fixture: ComponentFixture
- let consumptionTemplateService: ConsumptionTemplateService
+describe('WorkflowsComponent', () => {
+ let component: WorkflowsComponent
+ let fixture: ComponentFixture
+ let workflowService: WorkflowService
let modalService: NgbModal
let toastService: ToastService
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
- ConsumptionTemplatesComponent,
+ WorkflowsComponent,
IfPermissionsDirective,
PageHeaderComponent,
ConfirmDialogComponent,
@@ -81,18 +97,18 @@ describe('ConsumptionTemplatesComponent', () => {
],
})
- consumptionTemplateService = TestBed.inject(ConsumptionTemplateService)
- jest.spyOn(consumptionTemplateService, 'listAll').mockReturnValue(
+ workflowService = TestBed.inject(WorkflowService)
+ jest.spyOn(workflowService, 'listAll').mockReturnValue(
of({
- count: templates.length,
- all: templates.map((o) => o.id),
- results: templates,
+ count: workflows.length,
+ all: workflows.map((o) => o.id),
+ results: workflows,
})
)
modalService = TestBed.inject(NgbModal)
toastService = TestBed.inject(ToastService)
- fixture = TestBed.createComponent(ConsumptionTemplatesComponent)
+ fixture = TestBed.createComponent(WorkflowsComponent)
component = fixture.componentInstance
fixture.detectChanges()
})
@@ -108,8 +124,7 @@ describe('ConsumptionTemplatesComponent', () => {
createButton.triggerEventHandler('click')
expect(modal).not.toBeUndefined()
- const editDialog =
- modal.componentInstance as ConsumptionTemplateEditDialogComponent
+ const editDialog = modal.componentInstance as WorkflowEditDialogComponent
// fail first
editDialog.failed.emit({ error: 'error creating item' })
@@ -117,7 +132,7 @@ describe('ConsumptionTemplatesComponent', () => {
expect(reloadSpy).not.toHaveBeenCalled()
// succeed
- editDialog.succeeded.emit(templates[0])
+ editDialog.succeeded.emit(workflows[0])
expect(toastInfoSpy).toHaveBeenCalled()
expect(reloadSpy).toHaveBeenCalled()
})
@@ -133,9 +148,8 @@ describe('ConsumptionTemplatesComponent', () => {
editButton.triggerEventHandler('click')
expect(modal).not.toBeUndefined()
- const editDialog =
- modal.componentInstance as ConsumptionTemplateEditDialogComponent
- expect(editDialog.object).toEqual(templates[0])
+ const editDialog = modal.componentInstance as WorkflowEditDialogComponent
+ expect(editDialog.object).toEqual(workflows[0])
// fail first
editDialog.failed.emit({ error: 'error editing item' })
@@ -143,7 +157,7 @@ describe('ConsumptionTemplatesComponent', () => {
expect(reloadSpy).not.toHaveBeenCalled()
// succeed
- editDialog.succeeded.emit(templates[0])
+ editDialog.succeeded.emit(workflows[0])
expect(toastInfoSpy).toHaveBeenCalled()
expect(reloadSpy).toHaveBeenCalled()
})
@@ -152,7 +166,7 @@ describe('ConsumptionTemplatesComponent', () => {
let modal: NgbModalRef
modalService.activeInstances.subscribe((m) => (modal = m[m.length - 1]))
const toastErrorSpy = jest.spyOn(toastService, 'showError')
- const deleteSpy = jest.spyOn(consumptionTemplateService, 'delete')
+ const deleteSpy = jest.spyOn(workflowService, 'delete')
const reloadSpy = jest.spyOn(component, 'reload')
const deleteButton = fixture.debugElement.queryAll(By.css('button'))[3]
diff --git a/src-ui/src/app/components/manage/consumption-templates/consumption-templates.component.ts b/src-ui/src/app/components/manage/workflows/workflows.component.ts
similarity index 52%
rename from src-ui/src/app/components/manage/consumption-templates/consumption-templates.component.ts
rename to src-ui/src/app/components/manage/workflows/workflows.component.ts
index 301699abd..0be2db3f3 100644
--- a/src-ui/src/app/components/manage/consumption-templates/consumption-templates.component.ts
+++ b/src-ui/src/app/components/manage/workflows/workflows.component.ts
@@ -1,33 +1,34 @@
import { Component, OnInit } from '@angular/core'
-import { ConsumptionTemplateService } from 'src/app/services/rest/consumption-template.service'
+import { WorkflowService } from 'src/app/services/rest/workflow.service'
import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
import { Subject, takeUntil } from 'rxjs'
-import { ConsumptionTemplate } from 'src/app/data/consumption-template'
+import { Workflow } from 'src/app/data/workflow'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { ToastService } from 'src/app/services/toast.service'
import { PermissionsService } from 'src/app/services/permissions.service'
import {
- ConsumptionTemplateEditDialogComponent,
+ WorkflowEditDialogComponent,
DOCUMENT_SOURCE_OPTIONS,
-} from '../../common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component'
+ WORKFLOW_TYPE_OPTIONS,
+} from '../../common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component'
import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
import { EditDialogMode } from '../../common/edit-dialog/edit-dialog.component'
@Component({
- selector: 'pngx-consumption-templates',
- templateUrl: './consumption-templates.component.html',
- styleUrls: ['./consumption-templates.component.scss'],
+ selector: 'pngx-workflows',
+ templateUrl: './workflows.component.html',
+ styleUrls: ['./workflows.component.scss'],
})
-export class ConsumptionTemplatesComponent
+export class WorkflowsComponent
extends ComponentWithPermissions
implements OnInit
{
- public templates: ConsumptionTemplate[] = []
+ public workflows: Workflow[] = []
private unsubscribeNotifier: Subject = new Subject()
constructor(
- private consumptionTemplateService: ConsumptionTemplateService,
+ private workflowService: WorkflowService,
public permissionsService: PermissionsService,
private modalService: NgbModal,
private toastService: ToastService
@@ -40,68 +41,68 @@ export class ConsumptionTemplatesComponent
}
reload() {
- this.consumptionTemplateService
+ this.workflowService
.listAll()
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((r) => {
- this.templates = r.results
+ this.workflows = r.results
})
}
- getSourceList(template: ConsumptionTemplate): string {
- return template.sources
- .map((id) => DOCUMENT_SOURCE_OPTIONS.find((s) => s.id === id).name)
+ getTypesList(template: Workflow): string {
+ return template.triggers
+ .map(
+ (trigger) =>
+ WORKFLOW_TYPE_OPTIONS.find((t) => t.id === trigger.type).name
+ )
.join(', ')
}
- editTemplate(rule: ConsumptionTemplate) {
- const modal = this.modalService.open(
- ConsumptionTemplateEditDialogComponent,
- {
- backdrop: 'static',
- size: 'xl',
- }
- )
- modal.componentInstance.dialogMode = rule
+ editWorkflow(workflow: Workflow) {
+ const modal = this.modalService.open(WorkflowEditDialogComponent, {
+ backdrop: 'static',
+ size: 'xl',
+ })
+ modal.componentInstance.dialogMode = workflow
? EditDialogMode.EDIT
: EditDialogMode.CREATE
- modal.componentInstance.object = rule
+ modal.componentInstance.object = workflow
modal.componentInstance.succeeded
.pipe(takeUntil(this.unsubscribeNotifier))
- .subscribe((newTemplate) => {
+ .subscribe((newWorkflow) => {
this.toastService.showInfo(
- $localize`Saved template "${newTemplate.name}".`
+ $localize`Saved workflow "${newWorkflow.name}".`
)
- this.consumptionTemplateService.clearCache()
+ this.workflowService.clearCache()
this.reload()
})
modal.componentInstance.failed
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((e) => {
- this.toastService.showError($localize`Error saving template.`, e)
+ this.toastService.showError($localize`Error saving workflow.`, e)
})
}
- deleteTemplate(rule: ConsumptionTemplate) {
+ deleteWorkflow(workflow: Workflow) {
const modal = this.modalService.open(ConfirmDialogComponent, {
backdrop: 'static',
})
- modal.componentInstance.title = $localize`Confirm delete template`
- modal.componentInstance.messageBold = $localize`This operation will permanently delete this template.`
+ modal.componentInstance.title = $localize`Confirm delete workflow`
+ modal.componentInstance.messageBold = $localize`This operation will permanently delete this workflow.`
modal.componentInstance.message = $localize`This operation cannot be undone.`
modal.componentInstance.btnClass = 'btn-danger'
modal.componentInstance.btnCaption = $localize`Proceed`
modal.componentInstance.confirmClicked.subscribe(() => {
modal.componentInstance.buttonsEnabled = false
- this.consumptionTemplateService.delete(rule).subscribe({
+ this.workflowService.delete(workflow).subscribe({
next: () => {
modal.close()
- this.toastService.showInfo($localize`Deleted template`)
- this.consumptionTemplateService.clearCache()
+ this.toastService.showInfo($localize`Deleted workflow`)
+ this.workflowService.clearCache()
this.reload()
},
error: (e) => {
- this.toastService.showError($localize`Error deleting template.`, e)
+ this.toastService.showError($localize`Error deleting workflow.`, e)
},
})
})
diff --git a/src-ui/src/app/data/consumption-template.ts b/src-ui/src/app/data/workflow-action.ts
similarity index 64%
rename from src-ui/src/app/data/consumption-template.ts
rename to src-ui/src/app/data/workflow-action.ts
index cc85712c8..a313e0e63 100644
--- a/src-ui/src/app/data/consumption-template.ts
+++ b/src-ui/src/app/data/workflow-action.ts
@@ -1,24 +1,6 @@
import { ObjectWithId } from './object-with-id'
-export enum DocumentSource {
- ConsumeFolder = 1,
- ApiUpload = 2,
- MailFetch = 3,
-}
-
-export interface ConsumptionTemplate extends ObjectWithId {
- name: string
-
- order: number
-
- sources: DocumentSource[]
-
- filter_filename: string
-
- filter_path?: string
-
- filter_mailrule?: number // MailRule.id
-
+export interface WorkflowAction extends ObjectWithId {
assign_title?: string
assign_tags?: number[] // Tag.id
diff --git a/src-ui/src/app/data/workflow-trigger.ts b/src-ui/src/app/data/workflow-trigger.ts
new file mode 100644
index 000000000..c8745c4ac
--- /dev/null
+++ b/src-ui/src/app/data/workflow-trigger.ts
@@ -0,0 +1,25 @@
+import { ObjectWithId } from './object-with-id'
+
+export enum DocumentSource {
+ ConsumeFolder = 1,
+ ApiUpload = 2,
+ MailFetch = 3,
+}
+
+export enum WorkflowTriggerType {
+ Consumption = 1,
+ DocumentAdded = 2,
+ DocumentUpdated = 3,
+}
+
+export interface WorkflowTrigger extends ObjectWithId {
+ type: WorkflowTriggerType
+
+ sources?: DocumentSource[]
+
+ filter_filename?: string
+
+ filter_path?: string
+
+ filter_mailrule?: number // MailRule.id
+}
diff --git a/src-ui/src/app/data/workflow.ts b/src-ui/src/app/data/workflow.ts
new file mode 100644
index 000000000..9351c2fec
--- /dev/null
+++ b/src-ui/src/app/data/workflow.ts
@@ -0,0 +1,13 @@
+import { ObjectWithId } from './object-with-id'
+import { WorkflowAction } from './workflow-action'
+import { WorkflowTrigger } from './workflow-trigger'
+
+export interface Workflow extends ObjectWithId {
+ name: string
+
+ order: number
+
+ triggers: WorkflowTrigger[]
+
+ actions: WorkflowAction[]
+}
diff --git a/src-ui/src/app/services/permissions.service.spec.ts b/src-ui/src/app/services/permissions.service.spec.ts
index 968082ae9..66276fbbb 100644
--- a/src-ui/src/app/services/permissions.service.spec.ts
+++ b/src-ui/src/app/services/permissions.service.spec.ts
@@ -252,10 +252,18 @@ describe('PermissionsService', () => {
'view_sharelink',
'change_sharelink',
'delete_sharelink',
- 'add_consumptiontemplate',
- 'view_consumptiontemplate',
- 'change_consumptiontemplate',
- 'delete_consumptiontemplate',
+ 'add_workflow',
+ 'view_workflow',
+ 'change_workflow',
+ 'delete_workflow',
+ 'add_workflowtrigger',
+ 'view_workflowtrigger',
+ 'change_workflowtrigger',
+ 'delete_workflowtrigger',
+ 'add_workflowaction',
+ 'view_workflowaction',
+ 'change_workflowaction',
+ 'delete_workflowaction',
'add_customfield',
'view_customfield',
'change_customfield',
diff --git a/src-ui/src/app/services/permissions.service.ts b/src-ui/src/app/services/permissions.service.ts
index a4e30d57e..3a1b99377 100644
--- a/src-ui/src/app/services/permissions.service.ts
+++ b/src-ui/src/app/services/permissions.service.ts
@@ -25,8 +25,10 @@ export enum PermissionType {
Group = '%s_group',
Admin = '%s_logentry',
ShareLink = '%s_sharelink',
- ConsumptionTemplate = '%s_consumptiontemplate',
CustomField = '%s_customfield',
+ Workflow = '%s_workflow',
+ WorkflowTrigger = '%s_workflowtrigger',
+ WorkflowAction = '%s_workflowaction',
}
@Injectable({
diff --git a/src-ui/src/app/services/rest/workflow-action.service.spec.ts b/src-ui/src/app/services/rest/workflow-action.service.spec.ts
new file mode 100644
index 000000000..817ec1584
--- /dev/null
+++ b/src-ui/src/app/services/rest/workflow-action.service.spec.ts
@@ -0,0 +1,48 @@
+import { HttpTestingController } from '@angular/common/http/testing'
+import { TestBed } from '@angular/core/testing'
+import { Subscription } from 'rxjs'
+import { environment } from 'src/environments/environment'
+import { commonAbstractPaperlessServiceTests } from './abstract-paperless-service.spec'
+import { WorkflowActionService } from './workflow-action.service'
+import { WorkflowAction } from 'src/app/data/workflow-action'
+
+let httpTestingController: HttpTestingController
+let service: WorkflowActionService
+const endpoint = 'workflow_actions'
+const actions: WorkflowAction[] = [
+ {
+ id: 1,
+ assign_correspondent: 2,
+ },
+ {
+ id: 2,
+ assign_document_type: 1,
+ },
+]
+
+// run common tests
+commonAbstractPaperlessServiceTests(endpoint, WorkflowActionService)
+
+describe(`Additional service tests for WorkflowActionService`, () => {
+ it('should reload', () => {
+ service.reload()
+ const req = httpTestingController.expectOne(
+ `${environment.apiBaseUrl}${endpoint}/?page=1&page_size=100000`
+ )
+ req.flush({
+ results: actions,
+ })
+ expect(service.allActions).toEqual(actions)
+ })
+
+ beforeEach(() => {
+ // Dont need to setup again
+
+ httpTestingController = TestBed.inject(HttpTestingController)
+ service = TestBed.inject(WorkflowActionService)
+ })
+
+ afterEach(() => {
+ httpTestingController.verify()
+ })
+})
diff --git a/src-ui/src/app/services/rest/consumption-template.service.ts b/src-ui/src/app/services/rest/workflow-action.service.ts
similarity index 56%
rename from src-ui/src/app/services/rest/consumption-template.service.ts
rename to src-ui/src/app/services/rest/workflow-action.service.ts
index eb932ebf7..c462f60a8 100644
--- a/src-ui/src/app/services/rest/consumption-template.service.ts
+++ b/src-ui/src/app/services/rest/workflow-action.service.ts
@@ -1,42 +1,43 @@
import { HttpClient } from '@angular/common/http'
import { Injectable } from '@angular/core'
import { tap } from 'rxjs'
-import { ConsumptionTemplate } from 'src/app/data/consumption-template'
+import { Workflow } from 'src/app/data/workflow'
import { AbstractPaperlessService } from './abstract-paperless-service'
+import { WorkflowAction } from 'src/app/data/workflow-action'
@Injectable({
providedIn: 'root',
})
-export class ConsumptionTemplateService extends AbstractPaperlessService {
+export class WorkflowActionService extends AbstractPaperlessService {
loading: boolean
constructor(http: HttpClient) {
- super(http, 'consumption_templates')
+ super(http, 'workflow_actions')
}
public reload() {
this.loading = true
this.listAll().subscribe((r) => {
- this.templates = r.results
+ this.actions = r.results
this.loading = false
})
}
- private templates: ConsumptionTemplate[] = []
+ private actions: WorkflowAction[] = []
- public get allTemplates(): ConsumptionTemplate[] {
- return this.templates
+ public get allActions(): WorkflowAction[] {
+ return this.actions
}
- create(o: ConsumptionTemplate) {
+ create(o: WorkflowAction) {
return super.create(o).pipe(tap(() => this.reload()))
}
- update(o: ConsumptionTemplate) {
+ update(o: WorkflowAction) {
return super.update(o).pipe(tap(() => this.reload()))
}
- delete(o: ConsumptionTemplate) {
+ delete(o: WorkflowAction) {
return super.delete(o).pipe(tap(() => this.reload()))
}
}
diff --git a/src-ui/src/app/services/rest/consumption-template.service.spec.ts b/src-ui/src/app/services/rest/workflow-trigger.service.spec.ts
similarity index 57%
rename from src-ui/src/app/services/rest/consumption-template.service.spec.ts
rename to src-ui/src/app/services/rest/workflow-trigger.service.spec.ts
index 920d0575c..01d72e1cc 100644
--- a/src-ui/src/app/services/rest/consumption-template.service.spec.ts
+++ b/src-ui/src/app/services/rest/workflow-trigger.service.spec.ts
@@ -1,61 +1,54 @@
import { HttpTestingController } from '@angular/common/http/testing'
import { TestBed } from '@angular/core/testing'
-import { Subscription } from 'rxjs'
import { environment } from 'src/environments/environment'
import { commonAbstractPaperlessServiceTests } from './abstract-paperless-service.spec'
-import { ConsumptionTemplateService } from './consumption-template.service'
+import { WorkflowTriggerService } from './workflow-trigger.service'
import {
DocumentSource,
- ConsumptionTemplate,
-} from 'src/app/data/consumption-template'
+ WorkflowTrigger,
+ WorkflowTriggerType,
+} from 'src/app/data/workflow-trigger'
let httpTestingController: HttpTestingController
-let service: ConsumptionTemplateService
-const endpoint = 'consumption_templates'
-const templates: ConsumptionTemplate[] = [
+let service: WorkflowTriggerService
+const endpoint = 'workflow_triggers'
+const triggers: WorkflowTrigger[] = [
{
- name: 'Template 1',
id: 1,
- order: 1,
+ type: WorkflowTriggerType.Consumption,
filter_filename: '*test*',
filter_path: null,
sources: [DocumentSource.ApiUpload],
- assign_correspondent: 2,
},
{
- name: 'Template 2',
id: 2,
- order: 2,
+ type: WorkflowTriggerType.DocumentAdded,
filter_filename: null,
filter_path: '/test/',
sources: [DocumentSource.ConsumeFolder, DocumentSource.ApiUpload],
- assign_document_type: 1,
},
]
// run common tests
-commonAbstractPaperlessServiceTests(
- 'consumption_templates',
- ConsumptionTemplateService
-)
+commonAbstractPaperlessServiceTests(endpoint, WorkflowTriggerService)
-describe(`Additional service tests for ConsumptionTemplateService`, () => {
+describe(`Additional service tests for WorkflowTriggerService`, () => {
it('should reload', () => {
service.reload()
const req = httpTestingController.expectOne(
`${environment.apiBaseUrl}${endpoint}/?page=1&page_size=100000`
)
req.flush({
- results: templates,
+ results: triggers,
})
- expect(service.allTemplates).toEqual(templates)
+ expect(service.allWorkflows).toEqual(triggers)
})
beforeEach(() => {
// Dont need to setup again
httpTestingController = TestBed.inject(HttpTestingController)
- service = TestBed.inject(ConsumptionTemplateService)
+ service = TestBed.inject(WorkflowTriggerService)
})
afterEach(() => {
diff --git a/src-ui/src/app/services/rest/workflow-trigger.service.ts b/src-ui/src/app/services/rest/workflow-trigger.service.ts
new file mode 100644
index 000000000..963ed071e
--- /dev/null
+++ b/src-ui/src/app/services/rest/workflow-trigger.service.ts
@@ -0,0 +1,42 @@
+import { HttpClient } from '@angular/common/http'
+import { Injectable } from '@angular/core'
+import { tap } from 'rxjs'
+import { AbstractPaperlessService } from './abstract-paperless-service'
+import { WorkflowTrigger } from 'src/app/data/workflow-trigger'
+
+@Injectable({
+ providedIn: 'root',
+})
+export class WorkflowTriggerService extends AbstractPaperlessService {
+ loading: boolean
+
+ constructor(http: HttpClient) {
+ super(http, 'workflow_triggers')
+ }
+
+ public reload() {
+ this.loading = true
+ this.listAll().subscribe((r) => {
+ this.triggers = r.results
+ this.loading = false
+ })
+ }
+
+ private triggers: WorkflowTrigger[] = []
+
+ public get allWorkflows(): WorkflowTrigger[] {
+ return this.triggers
+ }
+
+ create(o: WorkflowTrigger) {
+ return super.create(o).pipe(tap(() => this.reload()))
+ }
+
+ update(o: WorkflowTrigger) {
+ return super.update(o).pipe(tap(() => this.reload()))
+ }
+
+ delete(o: WorkflowTrigger) {
+ return super.delete(o).pipe(tap(() => this.reload()))
+ }
+}
diff --git a/src-ui/src/app/services/rest/workflow.service.spec.ts b/src-ui/src/app/services/rest/workflow.service.spec.ts
new file mode 100644
index 000000000..121fb9e21
--- /dev/null
+++ b/src-ui/src/app/services/rest/workflow.service.spec.ts
@@ -0,0 +1,80 @@
+import { HttpTestingController } from '@angular/common/http/testing'
+import { TestBed } from '@angular/core/testing'
+import { environment } from 'src/environments/environment'
+import { commonAbstractPaperlessServiceTests } from './abstract-paperless-service.spec'
+import { WorkflowService } from './workflow.service'
+import { Workflow } from 'src/app/data/workflow'
+import {
+ DocumentSource,
+ WorkflowTriggerType,
+} from 'src/app/data/workflow-trigger'
+
+let httpTestingController: HttpTestingController
+let service: WorkflowService
+const endpoint = 'workflows'
+const workflows: Workflow[] = [
+ {
+ name: 'Workflow 1',
+ id: 1,
+ order: 1,
+ triggers: [
+ {
+ id: 1,
+ type: WorkflowTriggerType.Consumption,
+ sources: [DocumentSource.ConsumeFolder],
+ filter_filename: '*',
+ },
+ ],
+ actions: [
+ {
+ id: 1,
+ assign_title: 'foo',
+ },
+ ],
+ },
+ {
+ name: 'Workflow 2',
+ id: 2,
+ order: 2,
+ triggers: [
+ {
+ id: 2,
+ type: WorkflowTriggerType.DocumentAdded,
+ filter_filename: 'foo',
+ },
+ ],
+ actions: [
+ {
+ id: 2,
+ assign_title: 'bar',
+ },
+ ],
+ },
+]
+
+// run common tests
+commonAbstractPaperlessServiceTests(endpoint, WorkflowService)
+
+describe(`Additional service tests for WorkflowService`, () => {
+ it('should reload', () => {
+ service.reload()
+ const req = httpTestingController.expectOne(
+ `${environment.apiBaseUrl}${endpoint}/?page=1&page_size=100000`
+ )
+ req.flush({
+ results: workflows,
+ })
+ expect(service.allWorkflows).toEqual(workflows)
+ })
+
+ beforeEach(() => {
+ // Dont need to setup again
+
+ httpTestingController = TestBed.inject(HttpTestingController)
+ service = TestBed.inject(WorkflowService)
+ })
+
+ afterEach(() => {
+ httpTestingController.verify()
+ })
+})
diff --git a/src-ui/src/app/services/rest/workflow.service.ts b/src-ui/src/app/services/rest/workflow.service.ts
new file mode 100644
index 000000000..0b489bc67
--- /dev/null
+++ b/src-ui/src/app/services/rest/workflow.service.ts
@@ -0,0 +1,42 @@
+import { HttpClient } from '@angular/common/http'
+import { Injectable } from '@angular/core'
+import { tap } from 'rxjs'
+import { Workflow } from 'src/app/data/workflow'
+import { AbstractPaperlessService } from './abstract-paperless-service'
+
+@Injectable({
+ providedIn: 'root',
+})
+export class WorkflowService extends AbstractPaperlessService {
+ loading: boolean
+
+ constructor(http: HttpClient) {
+ super(http, 'workflows')
+ }
+
+ public reload() {
+ this.loading = true
+ this.listAll().subscribe((r) => {
+ this.workflows = r.results
+ this.loading = false
+ })
+ }
+
+ private workflows: Workflow[] = []
+
+ public get allWorkflows(): Workflow[] {
+ return this.workflows
+ }
+
+ create(o: Workflow) {
+ return super.create(o).pipe(tap(() => this.reload()))
+ }
+
+ update(o: Workflow) {
+ return super.update(o).pipe(tap(() => this.reload()))
+ }
+
+ delete(o: Workflow) {
+ return super.delete(o).pipe(tap(() => this.reload()))
+ }
+}
diff --git a/src-ui/src/styles.scss b/src-ui/src/styles.scss
index e128b27fa..c8e8e8d5c 100644
--- a/src-ui/src/styles.scss
+++ b/src-ui/src/styles.scss
@@ -647,8 +647,6 @@ code {
}
.accordion {
- --bs-accordion-btn-padding-x: 0.75rem;
- --bs-accordion-btn-padding-y: 0.375rem;
--bs-accordion-btn-bg: var(--bs-light);
--bs-accordion-btn-color: var(--bs-primary);
--bs-accordion-color: var(--bs-body-color);