@verisoft/ui-govcz 20.1.0 → 20.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/package.json +4 -4
  2. package/src/lib/components/shared-components/action-button-group/action-button-group.component.html +25 -0
  3. package/src/lib/components/shared-components/action-button-group/action-button-group.component.scss +0 -0
  4. package/src/lib/components/shared-components/action-button-group/action-button-group.component.spec.ts +21 -0
  5. package/src/lib/components/shared-components/action-button-group/action-button-group.component.ts +111 -0
  6. package/src/lib/components/shared-components/action-button-group/components/action-button/action-button.component.html +10 -0
  7. package/src/lib/components/shared-components/action-button-group/components/action-button/action-button.component.scss +0 -0
  8. package/src/lib/components/shared-components/action-button-group/components/action-button/action-button.component.spec.ts +21 -0
  9. package/src/lib/components/shared-components/action-button-group/components/action-button/action-button.component.ts +69 -0
  10. package/src/lib/components/shared-components/action-button-group/index.ts +2 -0
  11. package/src/lib/components/shared-components/dynamic-component/dynamic-component-factory.service.ts +142 -0
  12. package/src/lib/components/shared-components/dynamic-component/dynamic-component.component.ts +56 -0
  13. package/src/lib/components/shared-components/dynamic-component/index.ts +2 -0
  14. package/src/lib/components/shared-components/generic-field/generic-field.component.html +98 -0
  15. package/src/lib/components/shared-components/generic-field/generic-field.component.spec.ts +21 -0
  16. package/src/lib/components/shared-components/generic-field/generic-field.component.ts +90 -0
  17. package/src/lib/components/shared-components/generic-field/index.ts +1 -0
  18. package/src/lib/components/shared-components/generic-form/generic-form.component.html +46 -0
  19. package/src/lib/components/shared-components/generic-form/generic-form.component.spec.ts +21 -0
  20. package/src/lib/components/shared-components/generic-form/generic-form.component.ts +56 -0
  21. package/src/lib/components/shared-components/generic-form/generic-form.model.spec.ts +82 -0
  22. package/src/lib/components/shared-components/generic-form/generic-form.model.ts +68 -0
  23. package/src/lib/components/shared-components/generic-form/index.ts +2 -0
  24. package/src/lib/components/shared-components/index.ts +4 -0
  25. package/styles/dist/main.css +13 -0
  26. package/styles/dist/main.css.map +1 -0
@@ -0,0 +1,90 @@
1
+
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ EventEmitter,
6
+ Input,
7
+ Output,
8
+ } from '@angular/core';
9
+ import { ReactiveFormsModule } from '@angular/forms';
10
+ import {
11
+ DatasourceType,
12
+ FilterEvent,
13
+ LazyLoadEvent,
14
+ } from '@verisoft/core';
15
+ import {
16
+ BaseFormInputComponent,
17
+ DatasourceDirective,
18
+ FieldSize,
19
+ FieldSizeType,
20
+ GENERIC_FIELD_COMPONENT_TOKEN,
21
+ GenericFieldCore,
22
+ GenericFieldType,
23
+ GenericFieldTypeType,
24
+ } from '@verisoft/ui-core';
25
+ import { Icons } from '../../../icons';
26
+ import { CalendarComponent } from '../../calendar';
27
+ import { CheckboxComponent } from '../../checkbox';
28
+ import { DropdownComponent } from '../../dropdown';
29
+ import { MultiselectComponent } from '../../multiselect';
30
+ import { TextfieldComponent } from '../../textfield';
31
+
32
+ @Component({
33
+ selector: 'v-generic-field',
34
+ imports: [
35
+ DropdownComponent,
36
+ CalendarComponent,
37
+ MultiselectComponent,
38
+ TextfieldComponent,
39
+ ReactiveFormsModule,
40
+ CheckboxComponent,
41
+ DatasourceDirective
42
+ ],
43
+ providers: [
44
+ {
45
+ provide: GENERIC_FIELD_COMPONENT_TOKEN,
46
+ useExisting: GenericFieldComponent,
47
+ },
48
+ ],
49
+ templateUrl: './generic-field.component.html',
50
+ changeDetection: ChangeDetectionStrategy.OnPush
51
+ })
52
+ export class GenericFieldComponent<T>
53
+ extends BaseFormInputComponent
54
+ implements GenericFieldCore<T>
55
+ {
56
+ @Input() type?: GenericFieldTypeType = GenericFieldType.text;
57
+
58
+ @Input() floatLabel?: boolean;
59
+
60
+ @Input() optionLabel: string | undefined;
61
+
62
+ @Input() optionValue: string | undefined;
63
+
64
+ @Input() options: T[] | undefined;
65
+
66
+ @Input() size?: FieldSizeType = FieldSize.medium;
67
+
68
+ @Input() loading = false;
69
+
70
+ @Input() lazy = false;
71
+
72
+ @Input() filter = true;
73
+
74
+ @Input() datasource?: DatasourceType<T>
75
+
76
+ @Input() filterField?: string;
77
+
78
+ @Input() showFilter?: boolean;
79
+
80
+ @Input() localSearch?: boolean;
81
+
82
+ @Output() changed = new EventEmitter<any>();
83
+ @Output() showed = new EventEmitter<any>();
84
+ @Output() cleared = new EventEmitter<any>();
85
+ @Output() lazyLoad = new EventEmitter<LazyLoadEvent>();
86
+ @Output() filtered = new EventEmitter<FilterEvent>();
87
+
88
+ fieldTypes = GenericFieldType;
89
+ icons = Icons;
90
+ }
@@ -0,0 +1 @@
1
+ export * from './generic-field.component';
@@ -0,0 +1,46 @@
1
+ @if (formGroupComputed) {
2
+ <div
3
+ class="v-generic-form"
4
+ [ngClass]="showAsRow ? 'd-flex flex-row' : 'row'"
5
+ [formGroup]="formGroupComputed"
6
+ >
7
+ @for(field of fields; track field) { @if (columnClass) {
8
+ <div class="v-generic-form__column {{ columnClass }}">
9
+ <v-generic-field
10
+ [type]="field.type"
11
+ [label]="field.label ?? 'NOT SET' | translate"
12
+ [floatLabel]="field.floatLabel"
13
+ [testId]="field.testId"
14
+ [options]="field.options"
15
+ [optionLabel]="field.optionLabel"
16
+ [optionValue]="field.optionValue ?? field.optionLabel"
17
+ [options]="field.options"
18
+ [size]="field.size"
19
+ [formControlName]="field.name"
20
+ [datasource]="field.datasource"
21
+ [showFilter]="field.showFilter"
22
+ [filterField]="field.filterField"
23
+ [localSearch]="field.localSearch"
24
+ ></v-generic-field>
25
+ </div>
26
+ } @else {
27
+ <v-generic-field
28
+ class="me-4"
29
+ [type]="field.type"
30
+ [label]="field.label ?? 'NOT SET' | translate"
31
+ [floatLabel]="field.floatLabel"
32
+ [testId]="field.testId"
33
+ [options]="field.options"
34
+ [optionLabel]="field.optionLabel"
35
+ [optionValue]="field.optionValue ?? field.optionLabel"
36
+ [options]="field.options"
37
+ [size]="field.size"
38
+ [formControlName]="field.name"
39
+ [datasource]="field.datasource"
40
+ [showFilter]="field.showFilter"
41
+ [filterField]="field.filterField"
42
+ [localSearch]="field.localSearch"
43
+ ></v-generic-field>
44
+ } }
45
+ </div>
46
+ }
@@ -0,0 +1,21 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { GenericFormComponent } from './generic-form.component';
3
+
4
+ describe('GenericFormComponent', () => {
5
+ let component: GenericFormComponent;
6
+ let fixture: ComponentFixture<GenericFormComponent>;
7
+
8
+ beforeEach(async () => {
9
+ await TestBed.configureTestingModule({
10
+ imports: [GenericFormComponent],
11
+ }).compileComponents();
12
+
13
+ fixture = TestBed.createComponent(GenericFormComponent);
14
+ component = fixture.componentInstance;
15
+ fixture.detectChanges();
16
+ });
17
+
18
+ it('should create', () => {
19
+ expect(component).toBeTruthy();
20
+ });
21
+ });
@@ -0,0 +1,56 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ Input,
6
+ OnChanges,
7
+ SimpleChanges,
8
+ } from '@angular/core';
9
+ import { ReactiveFormsModule, UntypedFormGroup } from '@angular/forms';
10
+ import { TranslateModule } from '@ngx-translate/core';
11
+ import { GenericFieldDefinition } from '@verisoft/ui-core';
12
+ import { GenericFieldComponent } from '../generic-field';
13
+ import {
14
+ generateFormGroup,
15
+ getColumnClass,
16
+ } from './generic-form.model';
17
+
18
+ @Component({
19
+ selector: 'v-generic-form',
20
+ imports: [
21
+ CommonModule,
22
+ GenericFieldComponent,
23
+ ReactiveFormsModule,
24
+ TranslateModule,
25
+ ],
26
+ templateUrl: './generic-form.component.html',
27
+ changeDetection: ChangeDetectionStrategy.OnPush
28
+ })
29
+ export class GenericFormComponent implements OnChanges {
30
+ @Input() formGroup?: UntypedFormGroup;
31
+
32
+ @Input() fields?: GenericFieldDefinition[];
33
+
34
+ @Input() columns?: number;
35
+
36
+ @Input() showAsRow!: boolean;
37
+
38
+ formGroupComputed!: UntypedFormGroup;
39
+
40
+ columnClass?: string;
41
+
42
+ ngOnChanges(changes: SimpleChanges): void {
43
+ if (changes['fields'] || changes['formGroup']) {
44
+ this.formGroupComputed = generateFormGroup(
45
+ this.fields,
46
+ this.formGroupComputed,
47
+ this.formGroup,
48
+ !!changes['formGroup']
49
+ );
50
+ }
51
+
52
+ if (changes['columns']) {
53
+ this.columnClass = getColumnClass(this.columns);
54
+ }
55
+ }
56
+ }
@@ -0,0 +1,82 @@
1
+ import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';
2
+ import { generateFormGroup, GenericFieldDefinition } from './generic-form.model';
3
+
4
+ describe('GenericFormModel', () => {
5
+ describe('generateFormGroup', () => {
6
+ const fields = [{ name: 'name' }, { name: 'age' }];
7
+
8
+ const containsField = (formGroup: UntypedFormGroup, field: GenericFieldDefinition) => expect(formGroup.get(field.name)).toBeDefined();
9
+
10
+ test('Should create a new group when no group was provided', () => {
11
+ const formGroup = generateFormGroup([], undefined, undefined, false);
12
+
13
+ expect(formGroup).toBeDefined();
14
+ });
15
+
16
+ test('Should create a new group when no fields are provided', () => {
17
+ const formGroup = generateFormGroup(
18
+ undefined,
19
+ undefined,
20
+ undefined,
21
+ false
22
+ );
23
+
24
+ expect(formGroup).toBeDefined();
25
+ });
26
+
27
+ test('Should create a new group with defined control when fields are provided', () => {
28
+ const formGroup = generateFormGroup(fields, undefined, undefined, false);
29
+
30
+ expect(formGroup).toBeDefined();
31
+ containsField(formGroup, fields[0]);
32
+ containsField(formGroup, fields[1]);
33
+ });
34
+
35
+ test('Should used input group and creates control when fields are provided and formgroup does not have a controls', () => {
36
+ const inputGroup = new UntypedFormGroup({});
37
+
38
+ const formGroup = generateFormGroup(fields, undefined, inputGroup, false);
39
+
40
+ expect(formGroup).toBe(inputGroup);
41
+ containsField(formGroup, fields[0]);
42
+ });
43
+
44
+ test('Should not remove control from input group when input group is provided and fields does not contain control definition.', () => {
45
+ const inputGroup = new UntypedFormGroup({
46
+ student: new UntypedFormControl(),
47
+ });
48
+
49
+ const formGroup = generateFormGroup(fields, undefined, inputGroup, false);
50
+
51
+ expect(formGroup.get('student')).toBeDefined();
52
+ });
53
+
54
+ test('Should use existing group when input group is provided but have already defined group.', () => {
55
+ const inputGroup = new UntypedFormGroup({
56
+ student: new UntypedFormControl(),
57
+ });
58
+
59
+ const lastGroup = new UntypedFormGroup({
60
+ });
61
+
62
+ const formGroup = generateFormGroup(fields, lastGroup, inputGroup, false);
63
+
64
+ expect(formGroup).toBe(lastGroup);
65
+ containsField(formGroup, fields[0]);
66
+ });
67
+
68
+ test('Should use existing a new input group when last form group exists, but input group was changed.', () => {
69
+ const inputGroup = new UntypedFormGroup({
70
+ student: new UntypedFormControl(),
71
+ });
72
+
73
+ const lastGroup = new UntypedFormGroup({
74
+ });
75
+
76
+ const formGroup = generateFormGroup(fields, lastGroup, inputGroup, true);
77
+
78
+ expect(formGroup).toBe(inputGroup);
79
+ containsField(formGroup, fields[0]);
80
+ });
81
+ });
82
+ });
@@ -0,0 +1,68 @@
1
+ import {
2
+ UntypedFormControl,
3
+ UntypedFormGroup,
4
+ } from '@angular/forms';
5
+ import { GenericFieldDefinition } from '@verisoft/ui-core';
6
+
7
+ export function generateFormGroup(
8
+ fields: GenericFieldDefinition[] | undefined,
9
+ lastGroupValue: UntypedFormGroup | undefined,
10
+ inputGroup: UntypedFormGroup | undefined,
11
+ inputGroupChanged = false
12
+ ): UntypedFormGroup {
13
+ const formGroup =
14
+ (inputGroupChanged
15
+ ? inputGroup ?? lastGroupValue
16
+ : lastGroupValue ?? inputGroup) ?? new UntypedFormGroup({});
17
+
18
+ fields?.forEach((field) => {
19
+ const control = formGroup.get(field.name);
20
+ if (!control) {
21
+ formGroup.addControl(
22
+ field.name,
23
+ new UntypedFormControl(field.value, field.validator)
24
+ );
25
+ } else if (control && control.value !== field.value) {
26
+ control.setValue(field.value);
27
+ control.setValidators(field.validator ?? null);
28
+ }
29
+ else {
30
+ control.setValidators(field.validator ?? null);
31
+ }
32
+
33
+ if (field.readonly && (control || formGroup.get(field.name))) {
34
+ formGroup.get(field.name)?.disable();
35
+ }
36
+ });
37
+ if (!inputGroupChanged) {
38
+ for (const field in formGroup.controls) {
39
+ const control = fields?.find((x) => x.name == field);
40
+ if (!control) {
41
+ formGroup.removeControl(field);
42
+ }
43
+ }
44
+ }
45
+
46
+ return formGroup;
47
+ }
48
+
49
+ export function getColumnClass(value?: number): string | undefined {
50
+ if (!value) {
51
+ return undefined;
52
+ }
53
+
54
+ switch (value) {
55
+ case 1:
56
+ return 'col-12';
57
+ case 2:
58
+ return 'col-12 col-md-6';
59
+ case 3:
60
+ return 'col-12 col-md-4';
61
+ case 4:
62
+ return 'col-12 col-md-3';
63
+ case 6:
64
+ return 'col-12 col-md-2';
65
+ }
66
+
67
+ return 'col-12 col-md-1';
68
+ }
@@ -0,0 +1,2 @@
1
+ export * from './generic-form.component';
2
+ export * from './generic-form.model';
@@ -0,0 +1,4 @@
1
+ export * from './action-button-group';
2
+ export * from './generic-field';
3
+ export * from './generic-form';
4
+ export * from './dynamic-component';