Lots of cleanup, looking good. Simplify

This commit is contained in:
shamoon
2025-10-07 10:29:42 -07:00
parent 0fe5ca9b60
commit b323c180be
5 changed files with 132 additions and 129 deletions

View File

@@ -188,50 +188,45 @@
<i-bs name="plus-circle"></i-bs>&nbsp;<span i18n>Add condition</span>
</button>
</div>
<div class="mt-2" formArrayName="conditions">
<div class="mt-2 conditions" formArrayName="conditions">
@if (getConditionsFormArray(formGroup).length === 0) {
<p class="text-muted small" i18n>No conditions added. Add one to define document filters.</p>
}
@for (condition of getConditionsFormArray(formGroup).controls; track condition; let conditionIndex = $index) {
<div [formGroupName]="conditionIndex" class="border rounded p-3 mb-2">
<div class="d-flex align-items-start gap-2 mb-2">
<div class="flex-grow-1">
<div class="d-flex align-items-center gap-2">
<div class="w-25">
<pngx-input-select
i18n-title
title="Condition type"
[items]="getConditionTypeOptions(formGroup, conditionIndex)"
formControlName="type"
[allowNull]="false"
horizontal="true"
></pngx-input-select>
</div>
<div class="flex-grow-1">
@if (isTagsCondition(condition.get('type').value)) {
<pngx-input-tags
[allowCreate]="false"
[title]="null"
formControlName="values"
></pngx-input-tags>
} @else {
<pngx-input-select
[items]="getConditionSelectItems(condition.get('type').value)"
[allowNull]="true"
[multiple]="isSelectMultiple(condition.get('type').value)"
formControlName="values"
></pngx-input-select>
}
</div>
<button
type="button"
class="btn btn-link text-danger p-0 ms-1"
class="btn btn-link text-danger p-0"
(click)="removeCondition(formGroup, conditionIndex)"
>
<i-bs name="trash"></i-bs><span class="ms-1" i18n>Delete</span>
</button>
</div>
@if (isTagsCondition(condition.get('type').value)) {
<pngx-input-tags
[allowCreate]="false"
[title]="getConditionValueLabel(condition.get('type').value)"
[hint]="getConditionHint(formGroup, conditionIndex)"
formControlName="values"
horizontal="true"
></pngx-input-tags>
} @else {
<pngx-input-select
[title]="getConditionValueLabel(condition.get('type').value)"
[items]="getConditionSelectItems(condition.get('type').value)"
[hint]="getConditionHint(formGroup, conditionIndex)"
[allowNull]="true"
[multiple]="isSelectMultiple(condition.get('type').value)"
formControlName="values"
horizontal="true"
></pngx-input-select>
}
</div>
}
</div>

View File

@@ -7,3 +7,7 @@
.accordion-button {
font-size: 1rem;
}
:host ::ng-deep .conditions .paperless-input-select.mb-3 {
margin-bottom: 0 !important;
}

View File

@@ -150,20 +150,17 @@ export enum TriggerConditionType {
interface TriggerConditionDefinition {
id: TriggerConditionType
name: string
hint?: string
valueLabel: string
inputType: 'tags' | 'select'
allowMultipleEntries: boolean
allowMultipleValues: boolean
selectItems?: 'correspondents' | 'documentTypes' | 'storagePaths'
disabled?: boolean
}
const TRIGGER_CONDITION_DEFINITIONS: TriggerConditionDefinition[] = [
{
id: TriggerConditionType.TagsAny,
name: $localize`Has any of these tags`,
hint: $localize`Trigger matches when the document has at least one of the selected tags.`,
valueLabel: $localize`Tags`,
inputType: 'tags',
allowMultipleEntries: false,
allowMultipleValues: true,
@@ -171,8 +168,6 @@ const TRIGGER_CONDITION_DEFINITIONS: TriggerConditionDefinition[] = [
{
id: TriggerConditionType.TagsAll,
name: $localize`Has all of these tags`,
hint: $localize`Trigger matches only when every selected tag is present.`,
valueLabel: $localize`Tags`,
inputType: 'tags',
allowMultipleEntries: false,
allowMultipleValues: true,
@@ -180,8 +175,6 @@ const TRIGGER_CONDITION_DEFINITIONS: TriggerConditionDefinition[] = [
{
id: TriggerConditionType.TagsNone,
name: $localize`Does not have these tags`,
hint: $localize`Trigger matches only when none of the selected tags are present.`,
valueLabel: $localize`Tags`,
inputType: 'tags',
allowMultipleEntries: false,
allowMultipleValues: true,
@@ -189,8 +182,6 @@ const TRIGGER_CONDITION_DEFINITIONS: TriggerConditionDefinition[] = [
{
id: TriggerConditionType.CorrespondentIs,
name: $localize`Has correspondent`,
hint: $localize`Trigger matches when the document has the selected correspondent.`,
valueLabel: $localize`Correspondent`,
inputType: 'select',
allowMultipleEntries: false,
allowMultipleValues: false,
@@ -199,8 +190,6 @@ const TRIGGER_CONDITION_DEFINITIONS: TriggerConditionDefinition[] = [
{
id: TriggerConditionType.CorrespondentNot,
name: $localize`Does not have correspondents`,
hint: $localize`Trigger matches when the document does not have any of the selected correspondents.`,
valueLabel: $localize`Correspondents`,
inputType: 'select',
allowMultipleEntries: false,
allowMultipleValues: true,
@@ -209,8 +198,6 @@ const TRIGGER_CONDITION_DEFINITIONS: TriggerConditionDefinition[] = [
{
id: TriggerConditionType.DocumentTypeIs,
name: $localize`Has document type`,
hint: $localize`Trigger matches when the document has the selected document type.`,
valueLabel: $localize`Document type`,
inputType: 'select',
allowMultipleEntries: false,
allowMultipleValues: false,
@@ -219,8 +206,6 @@ const TRIGGER_CONDITION_DEFINITIONS: TriggerConditionDefinition[] = [
{
id: TriggerConditionType.DocumentTypeNot,
name: $localize`Does not have document types`,
hint: $localize`Trigger matches when the document does not have any of the selected document types.`,
valueLabel: $localize`Document types`,
inputType: 'select',
allowMultipleEntries: false,
allowMultipleValues: true,
@@ -229,8 +214,6 @@ const TRIGGER_CONDITION_DEFINITIONS: TriggerConditionDefinition[] = [
{
id: TriggerConditionType.StoragePathIs,
name: $localize`Has storage path`,
hint: $localize`Trigger matches when the document has the selected storage path.`,
valueLabel: $localize`Storage path`,
inputType: 'select',
allowMultipleEntries: false,
allowMultipleValues: false,
@@ -239,8 +222,6 @@ const TRIGGER_CONDITION_DEFINITIONS: TriggerConditionDefinition[] = [
{
id: TriggerConditionType.StoragePathNot,
name: $localize`Does not have storage paths`,
hint: $localize`Trigger matches when the document does not have any of the selected storage paths.`,
valueLabel: $localize`Storage paths`,
inputType: 'select',
allowMultipleEntries: false,
allowMultipleValues: true,
@@ -304,6 +285,11 @@ export class WorkflowEditDialogComponent
private allowedActionTypes = []
private conditionTypeOptionCache = new WeakMap<
FormArray,
TriggerConditionDefinition[]
>()
constructor() {
super()
this.service = inject(WorkflowService)
@@ -723,19 +709,30 @@ export class WorkflowEditDialogComponent
getConditionTypeOptions(formGroup: FormGroup, conditionIndex: number) {
const conditions = this.getConditionsFormArray(formGroup)
const options = this.getConditionTypeOptionsForArray(conditions)
const currentType = conditions.at(conditionIndex).get('type')
.value as TriggerConditionType
const usedTypes = conditions.controls.map(
(control) => control.get('type').value as TriggerConditionType
)
return this.conditionDefinitions.map((definition) => ({
id: definition.id,
name: definition.name,
disabled:
!definition.allowMultipleEntries &&
conditions.controls.some((control, idx) => {
options.forEach((option) => {
if (option.allowMultipleEntries) {
option.disabled = false
return
}
const usedElsewhere = usedTypes.some((type, idx) => {
if (idx === conditionIndex) {
return false
}
return control.get('type').value === definition.id
}),
}))
return type === option.id
})
option.disabled = usedElsewhere && option.id !== currentType
})
return options
}
canAddCondition(formGroup: FormGroup): boolean {
@@ -802,17 +799,6 @@ export class WorkflowEditDialogComponent
return this.getConditionDefinition(type)?.name ?? ''
}
getConditionHint(formGroup: FormGroup, conditionIndex: number): string {
const conditions = this.getConditionsFormArray(formGroup)
const type = conditions.at(conditionIndex).get('type')
.value as TriggerConditionType
return this.getConditionDefinition(type)?.hint ?? ''
}
getConditionValueLabel(type: TriggerConditionType): string {
return this.getConditionDefinition(type)?.valueLabel ?? ''
}
isTagsCondition(type: TriggerConditionType): boolean {
return this.getConditionDefinition(type)?.inputType === 'tags'
}
@@ -876,6 +862,20 @@ export class WorkflowEditDialogComponent
return value
}
private getConditionTypeOptionsForArray(
conditions: FormArray
): TriggerConditionDefinition[] {
let cached = this.conditionTypeOptionCache.get(conditions)
if (!cached) {
cached = this.conditionDefinitions.map((definition) => ({
...definition,
disabled: false,
}))
this.conditionTypeOptionCache.set(conditions, cached)
}
return cached
}
private createTriggerField(
trigger: WorkflowTrigger,
emitEvent: boolean = false

View File

@@ -1,5 +1,6 @@
<div class="mb-3 paperless-input-select" [class.disabled]="disabled">
<div class="row">
@if (title || removable) {
<div class="d-flex align-items-center position-relative hidden-button-container" [class.col-md-3]="horizontal">
@if (title) {
<label class="form-label" [class.mb-md-0]="horizontal" [for]="inputId">{{title}}</label>
@@ -10,6 +11,7 @@
</button>
}
</div>
}
<div [class.col-md-9]="horizontal">
<div [class.input-group]="allowCreateNew || showFilter" [class.is-invalid]="error">
<ng-select name="inputId" [(ngModel)]="value"
@@ -63,4 +65,4 @@
}
</div>
</div>
</div>
</div>

View File

@@ -1,8 +1,10 @@
<div class="mb-3 paperless-input-select paperless-input-tags" [class.disabled]="disabled" [class.pb-3]="getSuggestions().length > 0">
<div class="row">
@if (title) {
<div class="d-flex align-items-center" [class.col-md-3]="horizontal">
<label class="form-label" [class.mb-md-0]="horizontal" for="tags">{{title}}</label>
</div>
}
<div class="position-relative" [class.col-md-9]="horizontal">
<div class="input-group flex-nowrap">
<ng-select #tagSelect name="tags" [items]="tags" bindLabel="name" bindValue="id" [(ngModel)]="value"