mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
Make separate properties, assign_custom_fields_values
This commit is contained in:
@@ -188,7 +188,8 @@
|
||||
<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-custom-fields-select i18n-title title="Assign custom fields" formControlName="assign_custom_fields_w_values"></pngx-input-custom-fields-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 i18n-title title="Assign custom field values" [selectedFields]="formGroup.get('assign_custom_fields').value" formControlName="assign_custom_fields_values"></pngx-input-custom-fields-values>
|
||||
</div>
|
||||
<div class="col">
|
||||
<pngx-input-select i18n-title title="Assign owner" [items]="users" bindLabel="username" formControlName="assign_owner" [allowNull]="true"></pngx-input-select>
|
||||
|
@@ -16,7 +16,7 @@ import { NgbAccordionModule, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||
import { first } from 'rxjs'
|
||||
import { Correspondent } from 'src/app/data/correspondent'
|
||||
import { CustomField } from 'src/app/data/custom-field'
|
||||
import { CustomField, CustomFieldDataType } from 'src/app/data/custom-field'
|
||||
import { DocumentType } from 'src/app/data/document-type'
|
||||
import { MailRule } from 'src/app/data/mail-rule'
|
||||
import {
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
WorkflowTriggerType,
|
||||
} from 'src/app/data/workflow-trigger'
|
||||
import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
|
||||
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
|
||||
import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
|
||||
import { MailRuleService } from 'src/app/services/rest/mail-rule.service'
|
||||
import { StoragePathService } from 'src/app/services/rest/storage-path.service'
|
||||
@@ -46,7 +47,7 @@ import { WorkflowService } from 'src/app/services/rest/workflow.service'
|
||||
import { SettingsService } from 'src/app/services/settings.service'
|
||||
import { ConfirmButtonComponent } from '../../confirm-button/confirm-button.component'
|
||||
import { CheckComponent } from '../../input/check/check.component'
|
||||
import { CustomFieldsSelectComponent } from '../../input/custom-fields-select/custom-fields-select.component'
|
||||
import { CustomFieldsValuesComponent } from '../../input/custom-fields-values/custom-fields-values.component'
|
||||
import { EntriesComponent } from '../../input/entries/entries.component'
|
||||
import { NumberComponent } from '../../input/number/number.component'
|
||||
import { PermissionsGroupComponent } from '../../input/permissions/permissions-group/permissions-group.component'
|
||||
@@ -148,10 +149,10 @@ const TRIGGER_MATCHING_ALGORITHMS = MATCHING_ALGORITHMS.filter(
|
||||
SwitchComponent,
|
||||
NumberComponent,
|
||||
TextComponent,
|
||||
CustomFieldsSelectComponent,
|
||||
SelectComponent,
|
||||
TextAreaComponent,
|
||||
TagsComponent,
|
||||
CustomFieldsValuesComponent,
|
||||
PermissionsGroupComponent,
|
||||
PermissionsUserComponent,
|
||||
ConfirmButtonComponent,
|
||||
@@ -169,12 +170,14 @@ export class WorkflowEditDialogComponent
|
||||
{
|
||||
public WorkflowTriggerType = WorkflowTriggerType
|
||||
public WorkflowActionType = WorkflowActionType
|
||||
public CustomFieldDataType = CustomFieldDataType
|
||||
|
||||
templates: Workflow[]
|
||||
correspondents: Correspondent[]
|
||||
documentTypes: DocumentType[]
|
||||
storagePaths: StoragePath[]
|
||||
mailRules: MailRule[]
|
||||
customFields: CustomField[]
|
||||
dateCustomFields: CustomField[]
|
||||
|
||||
expandedItem: number = null
|
||||
@@ -189,7 +192,8 @@ export class WorkflowEditDialogComponent
|
||||
storagePathService: StoragePathService,
|
||||
mailRuleService: MailRuleService,
|
||||
userService: UserService,
|
||||
settingsService: SettingsService
|
||||
settingsService: SettingsService,
|
||||
customFieldsService: CustomFieldsService
|
||||
) {
|
||||
super(service, activeModal, userService, settingsService)
|
||||
|
||||
@@ -212,6 +216,16 @@ export class WorkflowEditDialogComponent
|
||||
.listAll()
|
||||
.pipe(first())
|
||||
.subscribe((result) => (this.mailRules = result.results))
|
||||
|
||||
customFieldsService
|
||||
.listAll()
|
||||
.pipe(first())
|
||||
.subscribe((result) => {
|
||||
this.customFields = result.results
|
||||
this.dateCustomFields = this.customFields?.filter(
|
||||
(f) => f.data_type === CustomFieldDataType.Date
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
getCreateTitle() {
|
||||
@@ -252,8 +266,6 @@ export class WorkflowEditDialogComponent
|
||||
}
|
||||
|
||||
private checkRemovalActionFields(formWorkflow: Workflow) {
|
||||
console.log('checkRemovalActionFields', formWorkflow)
|
||||
|
||||
formWorkflow.actions
|
||||
.filter((action) => action.type === WorkflowActionType.Removal)
|
||||
.forEach((action, i) => {
|
||||
@@ -429,8 +441,9 @@ export class WorkflowEditDialogComponent
|
||||
assign_view_groups: new FormControl(action.assign_view_groups),
|
||||
assign_change_users: new FormControl(action.assign_change_users),
|
||||
assign_change_groups: new FormControl(action.assign_change_groups),
|
||||
assign_custom_fields_w_values: new FormControl(
|
||||
action.assign_custom_fields_w_values
|
||||
assign_custom_fields: new FormControl(action.assign_custom_fields),
|
||||
assign_custom_fields_values: new FormControl(
|
||||
action.assign_custom_fields_values
|
||||
),
|
||||
remove_tags: new FormControl(action.remove_tags),
|
||||
remove_all_tags: new FormControl(action.remove_all_tags),
|
||||
@@ -557,7 +570,8 @@ export class WorkflowEditDialogComponent
|
||||
assign_view_groups: [],
|
||||
assign_change_users: [],
|
||||
assign_change_groups: [],
|
||||
assign_custom_fields_w_values: [],
|
||||
assign_custom_fields: [],
|
||||
assign_custom_fields_values: {},
|
||||
remove_tags: [],
|
||||
remove_all_tags: false,
|
||||
remove_document_types: [],
|
||||
@@ -636,4 +650,8 @@ export class WorkflowEditDialogComponent
|
||||
})
|
||||
super.save()
|
||||
}
|
||||
|
||||
public getCustomField(id: number): CustomField {
|
||||
return this.customFields.find((field) => field.id === id)
|
||||
}
|
||||
}
|
||||
|
@@ -1,113 +0,0 @@
|
||||
<div class="mb-3 paperless-input-select" [class.disabled]="disabled">
|
||||
<div class="row">
|
||||
<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>
|
||||
}
|
||||
</div>
|
||||
<div [class.col-md-9]="horizontal">
|
||||
<div [class.is-invalid]="error">
|
||||
<ng-select name="inputId" [(ngModel)]="selectedFields"
|
||||
[disabled]="disabled"
|
||||
[clearable]="true"
|
||||
[items]="fields"
|
||||
[addTag]="false"
|
||||
notFoundText="No fields found"
|
||||
i18n-notFoundText
|
||||
[multiple]="true"
|
||||
bindLabel="name"
|
||||
bindValue="id"
|
||||
(change)="onChange(value)">
|
||||
<ng-template ng-option-tmp let-item="item">
|
||||
<span [title]="item.name">{{item.name}}</span>
|
||||
</ng-template>
|
||||
</ng-select>
|
||||
@if (selectedFields.length) {
|
||||
<div class="list-group mt-3 selected-fields">
|
||||
@for (fieldId of selectedFields; track fieldId) {
|
||||
<div class="list-group-item
|
||||
d-flex
|
||||
justify-content-between
|
||||
align-items-center">
|
||||
@switch (getCustomField(fieldId)?.data_type) {
|
||||
@case (CustomFieldDataType.String) {
|
||||
<pngx-input-text [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"></pngx-input-text>
|
||||
}
|
||||
@case (CustomFieldDataType.Date) {
|
||||
<pngx-input-date [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"></pngx-input-date>
|
||||
}
|
||||
@case (CustomFieldDataType.Integer) {
|
||||
<pngx-input-number [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"
|
||||
[showAdd]="false"></pngx-input-number>
|
||||
}
|
||||
@case (CustomFieldDataType.Float) {
|
||||
<pngx-input-number [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"
|
||||
[showAdd]="false"
|
||||
[step]=".1"></pngx-input-number>
|
||||
}
|
||||
@case (CustomFieldDataType.Monetary) {
|
||||
<pngx-input-monetary [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[defaultCurrency]="getCustomField(fieldId)?.extra_data?.default_currency"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"></pngx-input-monetary>
|
||||
}
|
||||
@case (CustomFieldDataType.Boolean) {
|
||||
<pngx-input-check [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"></pngx-input-check>
|
||||
}
|
||||
@case (CustomFieldDataType.Url) {
|
||||
<pngx-input-url [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"></pngx-input-url>
|
||||
}
|
||||
@case (CustomFieldDataType.DocumentLink) {
|
||||
<pngx-input-document-link [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"></pngx-input-document-link>
|
||||
}
|
||||
@case (CustomFieldDataType.Select) {
|
||||
<pngx-input-select [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[items]="getCustomField(fieldId)?.extra_data.select_options"
|
||||
class="flex-grow-1"
|
||||
bindLabel="label"
|
||||
[allowNull]="true"
|
||||
[horizontal]="true"></pngx-input-select>
|
||||
}
|
||||
}
|
||||
<button type="button" class="btn btn-link text-danger" (click)="removeField(fieldId)">
|
||||
<i-bs name="trash"></i-bs>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="invalid-feedback">
|
||||
{{error}}
|
||||
</div>
|
||||
@if (hint) {
|
||||
<small class="form-text text-muted">{{hint}}</small>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@@ -1,41 +0,0 @@
|
||||
// styles for ng-select child are in styles.scss
|
||||
.paperless-input-select.disabled {
|
||||
.input-group,
|
||||
div > div {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
::ng-deep ng-select {
|
||||
pointer-events: none;
|
||||
|
||||
.ng-select-container {
|
||||
background-color: var(--pngx-bg-disabled) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep .private .ng-value-container {
|
||||
font-style: italic;
|
||||
opacity: .75;
|
||||
}
|
||||
|
||||
::ng-deep .is-invalid ng-select .ng-select-container input {
|
||||
// replicate bootstrap
|
||||
padding-right: calc(1.5em + 0.75rem) !important;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-position: right calc(0.375em + 0.1875rem) center !important;
|
||||
background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) !important;
|
||||
}
|
||||
|
||||
.input-group .ng-select-taggable:first-child:nth-last-child(2) {
|
||||
max-width: calc(100% - 45px); // fudge factor for (1x) ng-select button width
|
||||
}
|
||||
|
||||
.input-group .ng-select-taggable:first-child:nth-last-child(3) {
|
||||
max-width: calc(100% - 90px); // fudge factor for (2x) ng-select button width
|
||||
}
|
||||
|
||||
:host ::ng-deep .list-group-item .mb-3 {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
@@ -1,135 +0,0 @@
|
||||
import {
|
||||
ComponentFixture,
|
||||
TestBed,
|
||||
fakeAsync,
|
||||
tick,
|
||||
} from '@angular/core/testing'
|
||||
import {
|
||||
FormsModule,
|
||||
NG_VALUE_ACCESSOR,
|
||||
ReactiveFormsModule,
|
||||
} from '@angular/forms'
|
||||
import { RouterTestingModule } from '@angular/router/testing'
|
||||
import { NgSelectModule } from '@ng-select/ng-select'
|
||||
import {
|
||||
DEFAULT_MATCHING_ALGORITHM,
|
||||
MATCH_ALL,
|
||||
} from 'src/app/data/matching-model'
|
||||
import { Tag } from 'src/app/data/tag'
|
||||
import { SelectComponent } from './select.component'
|
||||
|
||||
const items: Tag[] = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Tag1',
|
||||
is_inbox_tag: false,
|
||||
matching_algorithm: DEFAULT_MATCHING_ALGORITHM,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Tag2',
|
||||
is_inbox_tag: true,
|
||||
matching_algorithm: MATCH_ALL,
|
||||
match: 'str',
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: 'Tag10',
|
||||
is_inbox_tag: false,
|
||||
matching_algorithm: DEFAULT_MATCHING_ALGORITHM,
|
||||
},
|
||||
]
|
||||
|
||||
describe('SelectComponent', () => {
|
||||
let component: SelectComponent
|
||||
let fixture: ComponentFixture<SelectComponent>
|
||||
let input: HTMLInputElement
|
||||
|
||||
beforeEach(async () => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [],
|
||||
imports: [
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
NgSelectModule,
|
||||
RouterTestingModule,
|
||||
SelectComponent,
|
||||
],
|
||||
}).compileComponents()
|
||||
|
||||
fixture = TestBed.createComponent(SelectComponent)
|
||||
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
|
||||
component = fixture.componentInstance
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should support private items', () => {
|
||||
component.value = 3
|
||||
component.items = items
|
||||
expect(component.items).toContainEqual({
|
||||
id: 3,
|
||||
name: 'Private',
|
||||
private: true,
|
||||
})
|
||||
|
||||
component.checkForPrivateItems([4, 5])
|
||||
expect(component.items).toContainEqual({
|
||||
id: 4,
|
||||
name: 'Private',
|
||||
private: true,
|
||||
})
|
||||
expect(component.items).toContainEqual({
|
||||
id: 5,
|
||||
name: 'Private',
|
||||
private: true,
|
||||
})
|
||||
})
|
||||
|
||||
it('should support suggestions', () => {
|
||||
expect(component.value).toBeUndefined()
|
||||
component.items = items
|
||||
component.suggestions = [1, 2]
|
||||
fixture.detectChanges()
|
||||
const suggestionAnchor: HTMLAnchorElement =
|
||||
fixture.nativeElement.querySelector('a')
|
||||
suggestionAnchor.click()
|
||||
expect(component.value).toEqual(1)
|
||||
})
|
||||
|
||||
it('should support create new and emit the value', () => {
|
||||
expect(component.allowCreateNew).toBeFalsy()
|
||||
component.items = items
|
||||
let createNewVal
|
||||
component.createNew.subscribe((v) => (createNewVal = v))
|
||||
expect(component.allowCreateNew).toBeTruthy()
|
||||
component.onSearch({ term: 'foo' })
|
||||
component.addItem(undefined)
|
||||
expect(createNewVal).toEqual('foo')
|
||||
component.addItem('bar')
|
||||
expect(createNewVal).toEqual('bar')
|
||||
component.onSearch({ term: 'baz' })
|
||||
component.clickNew()
|
||||
expect(createNewVal).toEqual('baz')
|
||||
})
|
||||
|
||||
it('should clear search term on blur after delay', fakeAsync(() => {
|
||||
const clearSpy = jest.spyOn(component, 'clearLastSearchTerm')
|
||||
component.onBlur()
|
||||
tick(3000)
|
||||
expect(clearSpy).toHaveBeenCalled()
|
||||
}))
|
||||
|
||||
it('should emit filtered documents', () => {
|
||||
component.value = 10
|
||||
component.items = items
|
||||
const emitSpy = jest.spyOn(component.filterDocuments, 'emit')
|
||||
component.onFilterDocuments()
|
||||
expect(emitSpy).toHaveBeenCalledWith([items[2]])
|
||||
})
|
||||
|
||||
it('should return the correct filter button title', () => {
|
||||
component.title = 'Tag'
|
||||
const expectedTitle = `Filter documents with this ${component.title}`
|
||||
expect(component.filterButtonTitle).toEqual(expectedTitle)
|
||||
})
|
||||
})
|
@@ -0,0 +1,77 @@
|
||||
<div class="list-group mt-3 selected-fields">
|
||||
@for (fieldId of selectedFields; track fieldId) {
|
||||
<div class="list-group-item
|
||||
d-flex
|
||||
justify-content-between
|
||||
align-items-center">
|
||||
@switch (getCustomField(fieldId)?.data_type) {
|
||||
@case (CustomFieldDataType.String) {
|
||||
<pngx-input-text [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"></pngx-input-text>
|
||||
}
|
||||
@case (CustomFieldDataType.Date) {
|
||||
<pngx-input-date [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"></pngx-input-date>
|
||||
}
|
||||
@case (CustomFieldDataType.Integer) {
|
||||
<pngx-input-number [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"
|
||||
[showAdd]="false"></pngx-input-number>
|
||||
}
|
||||
@case (CustomFieldDataType.Float) {
|
||||
<pngx-input-number [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"
|
||||
[showAdd]="false"
|
||||
[step]=".1"></pngx-input-number>
|
||||
}
|
||||
@case (CustomFieldDataType.Monetary) {
|
||||
<pngx-input-monetary [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[defaultCurrency]="getCustomField(fieldId)?.extra_data?.default_currency"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"></pngx-input-monetary>
|
||||
}
|
||||
@case (CustomFieldDataType.Boolean) {
|
||||
<pngx-input-check [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"></pngx-input-check>
|
||||
}
|
||||
@case (CustomFieldDataType.Url) {
|
||||
<pngx-input-url [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"></pngx-input-url>
|
||||
}
|
||||
@case (CustomFieldDataType.DocumentLink) {
|
||||
<pngx-input-document-link [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[horizontal]="true"></pngx-input-document-link>
|
||||
}
|
||||
@case (CustomFieldDataType.Select) {
|
||||
<pngx-input-select [(ngModel)]="value[fieldId]" (ngModelChange)="onChange(value)"
|
||||
[title]="getCustomField(fieldId)?.name"
|
||||
class="flex-grow-1"
|
||||
[items]="getCustomField(fieldId)?.extra_data.select_options"
|
||||
class="flex-grow-1"
|
||||
bindLabel="label"
|
||||
[allowNull]="true"
|
||||
[horizontal]="true"></pngx-input-select>
|
||||
}
|
||||
}
|
||||
<button type="button" class="btn btn-link text-danger" (click)="removeField(fieldId)">
|
||||
<i-bs name="trash"></i-bs>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
@@ -0,0 +1,3 @@
|
||||
:host ::ng-deep .list-group-item .mb-3 {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
import { Component, forwardRef } from '@angular/core'
|
||||
import { Component, forwardRef, Input } from '@angular/core'
|
||||
import {
|
||||
FormsModule,
|
||||
NG_VALUE_ACCESSOR,
|
||||
@@ -23,13 +23,13 @@ import { UrlComponent } from '../url/url.component'
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => CustomFieldsSelectComponent),
|
||||
useExisting: forwardRef(() => CustomFieldsValuesComponent),
|
||||
multi: true,
|
||||
},
|
||||
],
|
||||
selector: 'pngx-input-custom-fields-select',
|
||||
templateUrl: './custom-fields-select.component.html',
|
||||
styleUrls: ['./custom-fields-select.component.scss'],
|
||||
selector: 'pngx-input-custom-fields-values',
|
||||
templateUrl: './custom-fields-values.component.html',
|
||||
styleUrl: './custom-fields-values.component.scss',
|
||||
imports: [
|
||||
TextComponent,
|
||||
DateComponent,
|
||||
@@ -46,7 +46,7 @@ import { UrlComponent } from '../url/url.component'
|
||||
NgxBootstrapIconsModule,
|
||||
],
|
||||
})
|
||||
export class CustomFieldsSelectComponent extends AbstractInputComponent<Object> {
|
||||
export class CustomFieldsValuesComponent extends AbstractInputComponent<Object> {
|
||||
public CustomFieldDataType = CustomFieldDataType
|
||||
|
||||
constructor(customFieldsService: CustomFieldsService) {
|
||||
@@ -56,9 +56,11 @@ export class CustomFieldsSelectComponent extends AbstractInputComponent<Object>
|
||||
})
|
||||
}
|
||||
|
||||
fields: CustomField[]
|
||||
private fields: CustomField[]
|
||||
|
||||
_selectedFields: number[]
|
||||
private _selectedFields: number[]
|
||||
|
||||
@Input()
|
||||
set selectedFields(newFields: number[]) {
|
||||
this._selectedFields = newFields
|
||||
// map the selected fields to an object with field_id as key and value as value
|
||||
@@ -68,20 +70,11 @@ export class CustomFieldsSelectComponent extends AbstractInputComponent<Object>
|
||||
}, {})
|
||||
this.onChange(this.value)
|
||||
}
|
||||
|
||||
get selectedFields(): number[] {
|
||||
return this._selectedFields
|
||||
}
|
||||
|
||||
writeValue(newValue: Object): void {
|
||||
// value will be a json object with field_id as key and value as value
|
||||
this._selectedFields = newValue
|
||||
? this.fields
|
||||
.filter((field) => field.id in newValue)
|
||||
.map((field) => field.id)
|
||||
: []
|
||||
super.writeValue(newValue)
|
||||
}
|
||||
|
||||
public getCustomField(id: number): CustomField {
|
||||
return this.fields.find((field) => field.id === id)
|
||||
}
|
@@ -56,7 +56,9 @@ export interface WorkflowAction extends ObjectWithId {
|
||||
|
||||
assign_change_groups?: number[] // [Group.id]
|
||||
|
||||
assign_custom_fields_w_values?: number[] // { [CustomField.id]: value }
|
||||
assign_custom_fields?: number[] // [CustomField.id]
|
||||
|
||||
assign_custom_fields_values?: object
|
||||
|
||||
remove_tags?: number[] // Tag.id
|
||||
|
||||
|
Reference in New Issue
Block a user