Skip to content

Commit

Permalink
Merge pull request #227 from netgrif/NAE-1929
Browse files Browse the repository at this point in the history
[NAE-1929] Data field type list of strings
  • Loading branch information
renczesstefan authored Dec 13, 2023
2 parents 9a2a3d4 + aaa9793 commit dd1244d
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export enum ComponentPrefixes {
TEXT = 'text-',
USER = 'user-',
USER_LIST = 'user-list-',
STRING_COLLECTION = 'string-collection-',
}

export interface Component {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export * from './task-ref-field/task-ref-dashboard-field/abstract-task-ref-dashb
export * from './task-ref-field/task-ref-list-field/abstract-task-ref-list-field.component';
export * from './case-ref-field/case-ref-default/case-ref-default.component';
export * from './case-ref-field/model/case-ref-injection-tokens';
export * from './string-collection-field/string-collection-default-field/abstract-string-collection-default-field.component';

/* Class */
export * from './models/abstract-data-field';
Expand All @@ -89,6 +90,7 @@ export * from './i18n-field/models/i18n-field';
export * from './user-list-field/models/user-list-field';
export * from './user-list-field/models/user-list-value';
export * from './case-ref-field/model/case-ref-field';
export * from './string-collection-field/models/string-collection-field';

/* Interfaces */
export * from './models/changed-fields';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {DataField} from '../../models/abstract-data-field';
import {Behavior} from '../../models/behavior';
import {Layout} from '../../models/layout';
import {Validation} from '../../models/validation';
import {Component, ComponentPrefixes} from '../../models/component';

export class StringCollectionField extends DataField<Array<string>> {

constructor(stringId: string, title: string, initialValue: Array<string>, behavior: Behavior,
placeholder?: string, description?: string, layout?: Layout, validations?: Array<Validation>, component?: Component,
parentTaskId?: string) {
super(stringId, title, initialValue, behavior, placeholder, description, layout, validations, component, parentTaskId);
}

public getTypedComponentType(): string {
return ComponentPrefixes.STRING_COLLECTION + this.getComponentType();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {Component, ElementRef, Inject, OnInit, Optional, ViewChild} from '@angular/core';
import {AbstractBaseDataFieldComponent} from '../../base-component/abstract-base-data-field.component';
import {TranslateService} from '@ngx-translate/core';
import {DATA_FIELD_PORTAL_DATA, DataFieldPortalData} from '../../models/data-field-portal-data-injection-token';
import {StringCollectionField} from '../models/string-collection-field';
import {ENTER, COMMA, SEMICOLON} from '@angular/cdk/keycodes';
import {MatChipInputEvent} from '@angular/material/chips';

@Component({
selector: 'ncc-abstract-string-collection-default-field',
template: '',
})
export abstract class AbstractStringCollectionDefaultFieldComponent extends AbstractBaseDataFieldComponent<StringCollectionField> implements OnInit {

@ViewChild('input') input: ElementRef;
public separatorKeysCodes: number[] = [ENTER];

protected constructor(protected _translate: TranslateService,
@Optional() @Inject(DATA_FIELD_PORTAL_DATA) dataFieldPortalData: DataFieldPortalData<StringCollectionField>) {
super(dataFieldPortalData);
}

ngOnInit() {
if (this.dataField?.component?.properties?.semicolon === 'true') {
this.separatorKeysCodes.push(SEMICOLON);
}
if (this.dataField?.component?.properties?.comma === 'true') {
this.separatorKeysCodes.push(COMMA);
}
}

remove(value: string): void {
const index = this.dataField.value.indexOf(value);

if (index >= 0) {
const choiceArray = [...this.dataField.value];
choiceArray.splice(index, 1);
this.dataField.value = choiceArray;
}
}

add(event: MatChipInputEvent | FocusEvent): void {
const value = event['value'] ?? (event['target']?.['value'] ?? '');

if (value && value.trim()) {
this.dataField.value = (this.dataField.value === null || this.dataField.value === undefined) ? [] : this.dataField.value
const choiceArray = [...this.dataField.value];
choiceArray.push(value);
this.dataField.value = choiceArray;
this.input.nativeElement.value = '';
} else {
this.input.nativeElement.value = '';
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ export enum FieldTypeResource {
TASK_REF = 'taskRef',
CASE_REF = 'caseRef',
FILTER = 'filter',
I18N = 'i18n'
I18N = 'i18n',
STRING_COLLECTION = 'stringCollection'
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {UserListField} from '../../data-fields/user-list-field/models/user-list-
import {UserListValue} from '../../data-fields/user-list-field/models/user-list-value';
import {decodeBase64, encodeBase64} from "../../utility/base64";
import {CaseRefField} from '../../data-fields/case-ref-field/model/case-ref-field';
import {StringCollectionField} from '../../data-fields/string-collection-field/models/string-collection-field';


@Injectable({
Expand Down Expand Up @@ -113,6 +114,9 @@ export class FieldConverterService {
case FieldTypeResource.I18N:
return new I18nField(item.stringId, item.name, item.value ?? {defaultValue: ''}, item.behavior, item.placeholder,
item.description, item.layout, item.validations, item.component);
case FieldTypeResource.STRING_COLLECTION:
return new StringCollectionField(item.stringId, item.name, item.value ? item.value : [], item.behavior,
item.placeholder, item.description, item.layout, item.validations, item.component, item.parentTaskId);
}
}

Expand Down Expand Up @@ -145,6 +149,10 @@ export class FieldConverterService {
return FieldTypeResource.FILTER;
} else if (item instanceof I18nField) {
return FieldTypeResource.I18N;
} else if (item instanceof CaseRefField) {
return FieldTypeResource.CASE_REF;
} else if (item instanceof StringCollectionField) {
return FieldTypeResource.STRING_COLLECTION;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@

.netgrif-input {

.mat-standard-chip {
height: unset;
min-height: 1px;
}

.mat-paginator-page-size-select .mat-form-field-infix {
min-width: unset !important;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ import { MultichoiceCaserefFieldComponent } from './multichoice-field/multichoic
import {
EnumerationCaserefFieldComponent
} from './enumeration-field/enumeration-caseref-field/enumeration-caseref-field.component';
import { StringCollectionDefaultFieldComponent } from './string-collection-field/string-collection-default-field/string-collection-default-field.component';

@NgModule({
declarations: [
Expand Down Expand Up @@ -186,7 +187,8 @@ import {
TaskRefListFieldComponent,
CaseRefDefaultComponent,
MultichoiceCaserefFieldComponent,
EnumerationCaserefFieldComponent
EnumerationCaserefFieldComponent,
StringCollectionDefaultFieldComponent
],
exports: [
DataFieldTemplateComponent
Expand Down Expand Up @@ -262,5 +264,6 @@ export class DataFieldsComponentModule {
registry.register("case-ref-default", (injector: Injector) => new ComponentPortal<any>(CaseRefDefaultComponent, null, injector));
registry.register("user-default", (injector: Injector) => new ComponentPortal<any>(UserDefaultFieldComponent, null, injector));
registry.register("user-list-default", (injector: Injector) => new ComponentPortal<any>(UserListDefaultFieldComponent, null, injector));
registry.register("string-collection-default", (injector: Injector) => new ComponentPortal<any>(StringCollectionDefaultFieldComponent, null, injector));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<mat-form-field [appearance]="dataField.materialAppearance" class="full-width" color="primary">
<mat-label *ngIf="!showLargeLayout.value">{{dataField.title}}</mat-label>
<mat-chip-list #chipList aria-label="Autocomplete" [formControl]="formControlRef">
<mat-chip
*ngFor="let option of dataField.value" (removed)="remove(option)">
{{option}}
<button *ngIf="!formControlRef.disabled" matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
</mat-chip>
<input
matInput
#input
[placeholder]="dataField.placeholder"
[required]="dataField.behavior.required"
[matChipInputFor]="chipList"
(matChipInputTokenEnd)="add($event)"
(blur)="add($event)"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes">
</mat-chip-list>
<mat-hint [ngClass]="{'mat-hint-disabled': formControlRef.disabled}">{{dataField.description}}</mat-hint>
<mat-error
*ngIf="dataField.isInvalid(formControlRef)">{{'dataField.validations.required' | translate}}</mat-error>
</mat-form-field>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.full-width {
display: block;
margin: 0 auto;
width: 100%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {StringCollectionDefaultFieldComponent} from './string-collection-default-field.component';
import {Component} from '@angular/core';
import {StringCollectionField, TranslateLibModule} from 'netgrif-components-core';
import {HttpClientTestingModule} from '@angular/common/http/testing';

describe('StringCollectionDefaultFieldComponent', () => {
let component: StringCollectionDefaultFieldComponent;
let fixture: ComponentFixture<TestWrapperComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
TranslateLibModule,
HttpClientTestingModule
],
declarations: [StringCollectionDefaultFieldComponent]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(TestWrapperComponent);
component = fixture.debugElement.children[0].componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});


@Component({
selector: 'nc-test-wrapper',
template: '<nc-string-collection-default-field [dataField]="field"></nc-string-collection-default-field>'
})
class TestWrapperComponent {
field = new StringCollectionField('', '', ['633c6187bb12a90925e0a17e'], {
required: true,
optional: true,
visible: true,
editable: true,
hidden: true
}, undefined, undefined, undefined, []);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {Component, Inject, Optional} from '@angular/core';
import {
AbstractStringCollectionDefaultFieldComponent,
DATA_FIELD_PORTAL_DATA,
DataFieldPortalData,
TaskRefField
} from 'netgrif-components-core';
import {TranslateService} from '@ngx-translate/core';

@Component({
selector: 'nc-string-collection-default-field',
templateUrl: './string-collection-default-field.component.html',
styleUrls: ['./string-collection-default-field.component.scss']
})
export class StringCollectionDefaultFieldComponent extends AbstractStringCollectionDefaultFieldComponent {

constructor(protected _translate: TranslateService,
@Optional() @Inject(DATA_FIELD_PORTAL_DATA) dataFieldPortalData: DataFieldPortalData<TaskRefField>) {
super(_translate, dataFieldPortalData)
}

}

0 comments on commit dd1244d

Please sign in to comment.