diff --git a/lib/core/form/components/form-renderer.component.scss b/lib/core/form/components/form-renderer.component.scss index ee6d2a6bda..e9bff3df13 100644 --- a/lib/core/form/components/form-renderer.component.scss +++ b/lib/core/form/components/form-renderer.component.scss @@ -106,6 +106,19 @@ font-weight: bold; } } + + &-left-label-input-container { + display: flex; + + div:nth-child(2) { + flex: 1; + } + } + + &-left-label { + line-height: 64px; + margin-right: 15px; + } } form-field { diff --git a/lib/core/form/components/widgets/core/form-field.model.ts b/lib/core/form/components/widgets/core/form-field.model.ts index d6d4c24be5..befdaad0f4 100644 --- a/lib/core/form/components/widgets/core/form-field.model.ts +++ b/lib/core/form/components/widgets/core/form-field.model.ts @@ -76,6 +76,7 @@ export class FormFieldModel extends FormWidgetModel { rule?: FormFieldRule; selectLoggedUser: boolean; groupsRestriction: string[]; + leftLabels: boolean = false; // container model members numberOfColumns: number = 1; @@ -219,6 +220,10 @@ export class FormFieldModel extends FormWidgetModel { } } + if (form?.json) { + this.leftLabels = form.json.leftLabels || false; + } + const emptyOption = Array.isArray(this.options) ? this.options.find(({ id }) => id === 'empty') : undefined; if (this.hasEmptyValue === undefined) { this.hasEmptyValue = json?.hasEmptyValue ?? !!emptyOption; diff --git a/lib/core/form/components/widgets/form.theme.scss b/lib/core/form/components/widgets/form.theme.scss index de0ec42114..286affc701 100644 --- a/lib/core/form/components/widgets/form.theme.scss +++ b/lib/core/form/components/widgets/form.theme.scss @@ -64,6 +64,10 @@ ul > li > form-field > .adf-focus { border-color: var(--theme-warn-color); } } + + &-left-label { + color: var(--theme-secondary-text-color); + } } /* query for Microsoft IE 11 */ diff --git a/lib/core/form/components/widgets/number/number.widget.html b/lib/core/form/components/widgets/number/number.widget.html index 1981d8d5a8..5a23df0c4c 100644 --- a/lib/core/form/components/widgets/number/number.widget.html +++ b/lib/core/form/components/widgets/number/number.widget.html @@ -1,23 +1,28 @@
- - - - - - + [class.adf-invalid]="!field.isValid && isTouched()" [class.adf-readonly]="field.readOnly" [class.adf-left-label-input-container]="field.leftLabels"> +
+ +
+
+ + + + + + +
diff --git a/lib/core/form/components/widgets/number/number.widget.spec.ts b/lib/core/form/components/widgets/number/number.widget.spec.ts index b3a0698d3f..d401742aa0 100644 --- a/lib/core/form/components/widgets/number/number.widget.spec.ts +++ b/lib/core/form/components/widgets/number/number.widget.spec.ts @@ -15,17 +15,101 @@ * limitations under the License. */ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule } from '@angular/forms'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { TranslateModule } from '@ngx-translate/core'; +import { CoreTestingModule, setupTestBed } from 'core/testing'; +import { FormFieldModel, FormFieldTypes, FormModel } from '../core'; import { NumberWidgetComponent } from './number.widget'; describe('NumberWidgetComponent', () => { let widget: NumberWidgetComponent; + let fixture: ComponentFixture; + let element: HTMLElement; + + setupTestBed({ + imports: [ + TranslateModule.forRoot(), + CoreTestingModule, + MatInputModule, + FormsModule, + MatIconModule + ] + }); beforeEach(() => { - widget = new NumberWidgetComponent(null, null); + fixture = TestBed.createComponent(NumberWidgetComponent); + widget = fixture.componentInstance; + element = fixture.nativeElement; }); it('should exist', () => { expect(widget).toBeDefined(); }); + + describe('when form model has left labels', () => { + + it('should have left labels classes on leftLabels true', async () => { + widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: true }), { + id: 'number-id', + name: 'number-name', + value: '', + type: FormFieldTypes.NUMBER, + readOnly: false, + required: true + }); + + fixture.detectChanges(); + await fixture.whenStable(); + + const widgetContainer = element.querySelector('.adf-left-label-input-container'); + expect(widgetContainer).not.toBeNull(); + + const adfLeftLabel = element.querySelector('.adf-left-label'); + expect(adfLeftLabel).not.toBeNull(); + }); + + it('should not have left labels classes on leftLabels false', async () => { + widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: false }), { + id: 'number-id', + name: 'number-name', + value: '', + type: FormFieldTypes.NUMBER, + readOnly: false, + required: true + }); + + fixture.detectChanges(); + await fixture.whenStable(); + + const widgetContainer = element.querySelector('.adf-left-label-input-container'); + expect(widgetContainer).toBeNull(); + + const adfLeftLabel = element.querySelector('.adf-left-label'); + expect(adfLeftLabel).toBeNull(); + }); + + it('should not have left labels classes on leftLabels not present', async () => { + widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { + id: 'number-id', + name: 'number-name', + value: '', + type: FormFieldTypes.NUMBER, + readOnly: false, + required: true + }); + + fixture.detectChanges(); + await fixture.whenStable(); + + const widgetContainer = element.querySelector('.adf-left-label-input-container'); + expect(widgetContainer).toBeNull(); + + const adfLeftLabel = element.querySelector('.adf-left-label'); + expect(adfLeftLabel).toBeNull(); + }); + }); }); diff --git a/lib/core/form/components/widgets/text/text.widget.html b/lib/core/form/components/widgets/text/text.widget.html index 616c2fd54f..56938549f0 100644 --- a/lib/core/form/components/widgets/text/text.widget.html +++ b/lib/core/form/components/widgets/text/text.widget.html @@ -1,23 +1,28 @@
- - - - - - -
+ [class.adf-invalid]="!field.isValid && isTouched()" [class.adf-readonly]="field.readOnly" [class.adf-left-label-input-container]="field.leftLabels"> +
+ +
+
+ + + + + + +
+ diff --git a/lib/core/form/components/widgets/text/text.widget.spec.ts b/lib/core/form/components/widgets/text/text.widget.spec.ts index bc34c4c05b..852891f12b 100644 --- a/lib/core/form/components/widgets/text/text.widget.spec.ts +++ b/lib/core/form/components/widgets/text/text.widget.spec.ts @@ -442,5 +442,68 @@ describe('TextWidgetComponent', () => { expect(label.innerText).toBe('Phone : (__) ___-___'); }); }); + + describe('when form model has left labels', () => { + + it('should have left labels classes on leftLabels true', async () => { + widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: true }), { + id: 'text-id', + name: 'text-name', + value: '', + type: FormFieldTypes.TEXT, + readOnly: false, + required: true + }); + + fixture.detectChanges(); + await fixture.whenStable(); + + const widgetContainer = element.querySelector('.adf-left-label-input-container'); + expect(widgetContainer).not.toBeNull(); + + const adfLeftLabel = element.querySelector('.adf-left-label'); + expect(adfLeftLabel).not.toBeNull(); + }); + + it('should not have left labels classes on leftLabels false', async () => { + widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: false }), { + id: 'text-id', + name: 'text-name', + value: '', + type: FormFieldTypes.TEXT, + readOnly: false, + required: true + }); + + fixture.detectChanges(); + await fixture.whenStable(); + + const widgetContainer = element.querySelector('.adf-left-label-input-container'); + expect(widgetContainer).toBeNull(); + + const adfLeftLabel = element.querySelector('.adf-left-label'); + expect(adfLeftLabel).toBeNull(); + }); + + it('should not have left labels classes on leftLabels not present', async () => { + widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { + id: 'text-id', + name: 'text-name', + value: '', + type: FormFieldTypes.TEXT, + readOnly: false, + required: true + }); + + fixture.detectChanges(); + await fixture.whenStable(); + + const widgetContainer = element.querySelector('.adf-left-label-input-container'); + expect(widgetContainer).toBeNull(); + + const adfLeftLabel = element.querySelector('.adf-left-label'); + expect(adfLeftLabel).toBeNull(); + }); + }); }); }); diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.html b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.html index e739d6e333..ee7096d763 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.html +++ b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.html @@ -1,36 +1,38 @@
+ [class.adf-invalid]="(!field.isValid && isTouched()) || isRestApiFailed" [class.adf-readonly]="field.readOnly" [class.adf-left-label-input-container]="field.leftLabels">
-
- - - - - {{opt.name}} - - {{field.value}} - - - - - +
+ + + + + {{opt.name}} + + {{field.value}} + + + + + +
diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts index 70ebc0169c..1386813d6c 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts @@ -628,5 +628,65 @@ describe('DropdownCloudWidgetComponent', () => { expect(widget.field.options).toEqual(mockRestDropdownOptions); }); }); + + describe('when form model has left labels', () => { + + it('should have left labels classes on leftLabels true', async () => { + widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: true }), { + id: 'dropdown-id', + name: 'option list', + type: FormFieldTypes.DROPDOWN, + readOnly: false, + options: filterOptionList + }); + + fixture.detectChanges(); + await fixture.whenStable(); + + const widgetContainer = element.querySelector('.adf-left-label-input-container'); + expect(widgetContainer).not.toBeNull(); + + const adfLeftLabel = element.querySelector('.adf-left-label'); + expect(adfLeftLabel).not.toBeNull(); + }); + + it('should not have left labels classes on leftLabels false', async () => { + widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: false }), { + id: 'dropdown-id', + name: 'option list', + type: FormFieldTypes.DROPDOWN, + readOnly: false, + options: filterOptionList + }); + + fixture.detectChanges(); + await fixture.whenStable(); + + const widgetContainer = element.querySelector('.adf-left-label-input-container'); + expect(widgetContainer).toBeNull(); + + const adfLeftLabel = element.querySelector('.adf-left-label'); + expect(adfLeftLabel).toBeNull(); + }); + + it('should not have left labels classes on leftLabels not present', async () => { + widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { + id: 'dropdown-id', + name: 'option list', + type: FormFieldTypes.DROPDOWN, + readOnly: false, + options: filterOptionList + }); + + fixture.detectChanges(); + await fixture.whenStable(); + + const widgetContainer = element.querySelector('.adf-left-label-input-container'); + expect(widgetContainer).toBeNull(); + + const adfLeftLabel = element.querySelector('.adf-left-label'); + expect(adfLeftLabel).toBeNull(); + }); + }); }); });