diff --git a/projects/go-lib/package.json b/projects/go-lib/package.json index c8aebcebd..c6e8fba01 100644 --- a/projects/go-lib/package.json +++ b/projects/go-lib/package.json @@ -1,6 +1,6 @@ { "name": "@tangoe/goponents", - "version": "1.16.0", + "version": "1.16.1", "repository": { "type": "git", "url": "git+https://github.com/mobi/goponents.git" diff --git a/projects/go-lib/src/lib/components/go-checkbox/go-checkbox-group.component.html b/projects/go-lib/src/lib/components/go-checkbox/go-checkbox-group.component.html index 70001180e..cca4448f5 100644 --- a/projects/go-lib/src/lib/components/go-checkbox/go-checkbox-group.component.html +++ b/projects/go-lib/src/lib/components/go-checkbox/go-checkbox-group.component.html @@ -6,11 +6,18 @@ {{ legend }} + > + {{ legend }} + - - - + +
+ +
diff --git a/projects/go-lib/src/lib/components/go-checkbox/go-checkbox-group.component.spec.ts b/projects/go-lib/src/lib/components/go-checkbox/go-checkbox-group.component.spec.ts index 90ca99509..80ceedbb6 100644 --- a/projects/go-lib/src/lib/components/go-checkbox/go-checkbox-group.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-checkbox/go-checkbox-group.component.spec.ts @@ -1,34 +1,48 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; +import { + FormControl, + FormGroup, + FormsModule, + ReactiveFormsModule, +} from "@angular/forms"; -import { GoCheckboxGroupComponent } from './go-checkbox-group.component'; -import { GoHintModule } from '../go-hint/go-hint.module'; -import { GoCheckboxComponent } from './go-checkbox.component'; -import { Component } from '@angular/core'; -import { GoRequiredTextModule } from '../go-required-text/go-required-text.module'; -import { GoFormErrorsModule } from '../go-form-errors/go-form-errors.module'; +import { GoCheckboxGroupComponent } from "./go-checkbox-group.component"; +import { GoHintModule } from "../go-hint/go-hint.module"; +import { GoCheckboxComponent } from "./go-checkbox.component"; +import { Component } from "@angular/core"; +import { GoRequiredTextModule } from "../go-required-text/go-required-text.module"; +import { GoFormErrorsModule } from "../go-form-errors/go-form-errors.module"; +import { By } from "@angular/platform-browser"; @Component({ - selector: 'go-test', + selector: "go-test", template: `
- +
- +
- ` + `, }) class GoTestCheckboxGroupComponent { checkboxForm: FormGroup = new FormGroup({ - option1: new FormControl(''), - option2: new FormControl('') + option1: new FormControl(""), + option2: new FormControl(""), }); } -describe('GoCheckboxGroupComponent', () => { +describe("GoCheckboxGroupComponent", () => { let checkboxOne: GoCheckboxComponent; let checkboxTwo: GoCheckboxComponent; let component: GoCheckboxGroupComponent; @@ -36,16 +50,19 @@ describe('GoCheckboxGroupComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [GoCheckboxGroupComponent, GoCheckboxComponent, GoTestCheckboxGroupComponent], + declarations: [ + GoCheckboxGroupComponent, + GoCheckboxComponent, + GoTestCheckboxGroupComponent, + ], imports: [ GoFormErrorsModule, GoHintModule, GoRequiredTextModule, FormsModule, - ReactiveFormsModule - ] - }) - .compileComponents(); + ReactiveFormsModule, + ], + }).compileComponents(); })); beforeEach(() => { @@ -59,22 +76,42 @@ describe('GoCheckboxGroupComponent', () => { checkboxTwo = checkboxArray[1]; }); - it('should create', () => { + it("should create", () => { expect(component).toBeTruthy(); }); - describe('ngAfterContentInit', () => { + describe("ngAfterContentInit", () => { beforeEach(() => { checkboxOne.theme = null; checkboxTwo.theme = null; }); - it('should set a theme on each child component', () => { - component.theme = 'dark'; + it("should set a theme on each child component", () => { + component.theme = "dark"; component.ngAfterContentInit(); - expect(checkboxOne.theme).toBe('dark'); - expect(checkboxTwo.theme).toBe('dark'); + expect(checkboxOne.theme).toBe("dark"); + expect(checkboxTwo.theme).toBe("dark"); }); }); + it("component should not render go-form-errors if hideFieldError property is true ", () => { + component.hideFieldError = true; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(0); + }); + it("component should render go-form-errors if hideFieldError property is false ", () => { + component.hideFieldError = false; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); + it("component should render go-form-errors if hideFieldError is not set ", () => { + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); }); diff --git a/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.html b/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.html index cb599e477..8dd2672c1 100644 --- a/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.html +++ b/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.html @@ -1,19 +1,28 @@
-
diff --git a/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.spec.ts b/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.spec.ts index 20f06b4bb..e937bc8ac 100644 --- a/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.spec.ts @@ -1,11 +1,12 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { GoFormErrorsModule } from '../go-form-errors/go-form-errors.module'; -import { GoHintModule } from '../go-hint/go-hint.module'; -import { GoRequiredTextModule } from '../go-required-text/go-required-text.module'; -import { GoCheckboxComponent } from './go-checkbox.component'; - -describe('GoCheckboxComponent', () => { +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; +import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { GoFormErrorsModule } from "../go-form-errors/go-form-errors.module"; +import { GoHintModule } from "../go-hint/go-hint.module"; +import { GoRequiredTextModule } from "../go-required-text/go-required-text.module"; +import { GoCheckboxComponent } from "./go-checkbox.component"; +import { By } from "@angular/platform-browser"; + +describe("GoCheckboxComponent", () => { let component: GoCheckboxComponent; let fixture: ComponentFixture; @@ -17,10 +18,9 @@ describe('GoCheckboxComponent', () => { ReactiveFormsModule, GoFormErrorsModule, GoHintModule, - GoRequiredTextModule - ] - }) - .compileComponents(); + GoRequiredTextModule, + ], + }).compileComponents(); })); beforeEach(() => { @@ -30,12 +30,12 @@ describe('GoCheckboxComponent', () => { fixture.detectChanges(); }); - it('should create', () => { + it("should create", () => { expect(component).toBeTruthy(); }); - describe('ngAfterViewInit', () => { - it('sets the hidden input to indeterminate if indeterminate input is true', () => { + describe("ngAfterViewInit", () => { + it("sets the hidden input to indeterminate if indeterminate input is true", () => { expect(component.hiddenInputRef.nativeElement.indeterminate).toBe(false); component.indeterminate = true; @@ -45,4 +45,24 @@ describe('GoCheckboxComponent', () => { expect(component.hiddenInputRef.nativeElement.indeterminate).toBe(true); }); }); + it("component should not render go-form-errors if hideFieldError property is true ", () => { + component.hideFieldError = true; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(0); + }); + it("component should render go-form-errors if hideFieldError property is false ", () => { + component.hideFieldError = false; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); + it("component should render go-form-errors if hideFieldError is not set ", () => { + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); }); diff --git a/projects/go-lib/src/lib/components/go-datepicker/go-datepicker.component.html b/projects/go-lib/src/lib/components/go-datepicker/go-datepicker.component.html index aba770d2e..502cb2915 100644 --- a/projects/go-lib/src/lib/components/go-datepicker/go-datepicker.component.html +++ b/projects/go-lib/src/lib/components/go-datepicker/go-datepicker.component.html @@ -1,7 +1,8 @@ - @@ -17,6 +18,8 @@ [(ngModel)]="selectedDate" (blur)="validateDate()" [disabled]="control.disabled" + (input)="onInputCloseCalendar()" + (click)="toggleDatepicker($event)" /> - - +
+ +
diff --git a/projects/go-lib/src/lib/components/go-datepicker/go-datepicker.component.spec.ts b/projects/go-lib/src/lib/components/go-datepicker/go-datepicker.component.spec.ts index bbc42342e..571910c6c 100644 --- a/projects/go-lib/src/lib/components/go-datepicker/go-datepicker.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-datepicker/go-datepicker.component.spec.ts @@ -1,19 +1,21 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { GoDatepickerComponent } from './go-datepicker.component'; -import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { GoHintModule } from '../go-hint/go-hint.module'; -import { GoIconButtonModule } from '../go-icon-button/go-icon-button.module'; -import { GoCalendarComponent } from './go-calendar.component'; -import { GoCalendarDayViewComponent } from './day-view/go-calendar-day-view.component'; -import { GoCalendarMonthViewComponent } from './month-view/go-calendar-month-view.component'; -import { GoCalendarYearViewComponent } from './year-view/go-calendar-year-view.component'; -import { GoRequiredTextModule } from '../go-required-text/go-required-text.module'; -import { GoFormErrorsModule } from '../go-form-errors/go-form-errors.module'; - -describe('GoDatepickerComponent', () => { +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; + +import { GoDatepickerComponent } from "./go-datepicker.component"; +import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { GoHintModule } from "../go-hint/go-hint.module"; +import { GoIconButtonModule } from "../go-icon-button/go-icon-button.module"; +import { GoCalendarComponent } from "./go-calendar.component"; +import { GoCalendarDayViewComponent } from "./day-view/go-calendar-day-view.component"; +import { GoCalendarMonthViewComponent } from "./month-view/go-calendar-month-view.component"; +import { GoCalendarYearViewComponent } from "./year-view/go-calendar-year-view.component"; +import { GoRequiredTextModule } from "../go-required-text/go-required-text.module"; +import { GoFormErrorsModule } from "../go-form-errors/go-form-errors.module"; +import { By } from "@angular/platform-browser"; + +describe("GoDatepickerComponent", () => { let component: GoDatepickerComponent; let fixture: ComponentFixture; + let inputElement: HTMLInputElement; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -22,7 +24,7 @@ describe('GoDatepickerComponent', () => { GoCalendarDayViewComponent, GoCalendarMonthViewComponent, GoCalendarYearViewComponent, - GoDatepickerComponent + GoDatepickerComponent, ], imports: [ GoFormErrorsModule, @@ -31,25 +33,25 @@ describe('GoDatepickerComponent', () => { FormsModule, GoHintModule, GoRequiredTextModule, - ReactiveFormsModule - ] - }) - .compileComponents(); + ReactiveFormsModule, + ], + }).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(GoDatepickerComponent); component = fixture.componentInstance; component.control = new FormControl(''); + inputElement = fixture.nativeElement.querySelector("input"); }); - it('should create', () => { + it("should create", () => { fixture.detectChanges(); expect(component).toBeTruthy(); }); - describe('onInit', () => { + describe("onInit", () => { afterEach(() => { component.selectedDate = null; component.min = null; @@ -58,90 +60,90 @@ describe('GoDatepickerComponent', () => { component.maxDate = null; }); - it('should allow the control to be initialized with a date object', () => { + it("should allow the control to be initialized with a date object", () => { component.control.setValue(new Date(2015, 4, 15)); fixture.detectChanges(); - expect(component.selectedDate).toEqual('5/15/2015'); + expect(component.selectedDate).toEqual("5/15/2015"); }); - it('should allow the control value to be changed after initialization', () => { + it("should allow the control value to be changed after initialization", () => { // Confirm initialized date is set component.control.setValue(new Date(2015, 4, 15)); fixture.detectChanges(); - expect(component.selectedDate).toEqual('5/15/2015'); + expect(component.selectedDate).toEqual("5/15/2015"); // Change date after initialization component.control.setValue(new Date(2015, 5, 16)); fixture.detectChanges(); - expect(component.selectedDate).toEqual('6/16/2015'); + expect(component.selectedDate).toEqual("6/16/2015"); }); - it('should allow the control to be initialized with a date string', () => { - component.control.setValue('05/15/2015'); + it("should allow the control to be initialized with a date string", () => { + component.control.setValue("05/15/2015"); fixture.detectChanges(); - expect(component.selectedDate).toEqual('5/15/2015'); - expect(component.control.value).toEqual(new Date (2015, 4, 15)); + expect(component.selectedDate).toEqual("5/15/2015"); + expect(component.control.value).toEqual(new Date(2015, 4, 15)); }); - it('sets a min if minDate is passed in', () => { - component.minDate = '05/15/2015'; + it("sets a min if minDate is passed in", () => { + component.minDate = "05/15/2015"; fixture.detectChanges(); - expect(component.min).toEqual(new Date (2015, 4, 15)); + expect(component.min).toEqual(new Date(2015, 4, 15)); }); - it('sets min to null if no minDate is passed in', () => { + it("sets min to null if no minDate is passed in", () => { fixture.detectChanges(); expect(component.min).toEqual(null); }); - it('sets a max date if maxDate is passed in', () => { - component.maxDate = '05/15/2015'; + it("sets a max date if maxDate is passed in", () => { + component.maxDate = "05/15/2015"; fixture.detectChanges(); - expect(component.max).toEqual(new Date (2015, 4, 15)); + expect(component.max).toEqual(new Date(2015, 4, 15)); }); - it('sets max date to null if no maxDate is passed in', () => { + it("sets max date to null if no maxDate is passed in", () => { fixture.detectChanges(); expect(component.max).toEqual(null); }); - it('should set control to null if date is above maxDate', () => { - component.maxDate = '05/15/2015'; - component.control.setValue('05/16/2015'); + it("should set control to null if date is above maxDate", () => { + component.maxDate = "05/15/2015"; + component.control.setValue("05/16/2015"); fixture.detectChanges(); expect(component.control.value).toBe(null); }); - it('should set control to null if date is below minDate', () => { - component.minDate = '05/15/2015'; - component.control.setValue('05/14/2015'); + it("should set control to null if date is below minDate", () => { + component.minDate = "05/15/2015"; + component.control.setValue("05/14/2015"); fixture.detectChanges(); expect(component.control.value).toBe(null); }); - it('should set control to date if between min and max dates', () => { - component.minDate = '05/15/2015'; - component.maxDate = '05/17/2015'; - component.control.setValue('05/16/2015'); + it("should set control to date if between min and max dates", () => { + component.minDate = "05/15/2015"; + component.maxDate = "05/17/2015"; + component.control.setValue("05/16/2015"); fixture.detectChanges(); expect(component.control.value).toEqual(new Date(2015, 4, 16)); }); - it('should reset control', () => { - component.control.setValue('09/16/2016'); + it("should reset control", () => { + component.control.setValue("09/16/2016"); component.control.reset(); fixture.detectChanges(); @@ -149,49 +151,49 @@ describe('GoDatepickerComponent', () => { }); }); - describe('restrictInput', () => { + describe("restrictInput", () => { afterEach(() => { component.selectedDate = null; }); - it('should strip out letters from selectedDate input', () => { + it("should strip out letters from selectedDate input", () => { fixture.detectChanges(); - component.selectedDate = '15/d25/1as'; + component.selectedDate = "15/d25/1as"; component.restrictInput(); - expect(component.selectedDate).toBe('15/25/1'); + expect(component.selectedDate).toBe("15/25/1"); }); }); - describe('template', () => { + describe("template", () => { afterEach(() => { component.selectedDate = null; component.locale = null; component.control.setValue(null); }); - it('should allow input based on locale', () => { - component.locale = 'de'; - component.selectedDate = '05.12.15'; + it("should allow input based on locale", () => { + component.locale = "de"; + component.selectedDate = "05.12.15"; component.validateDate(); expect(component.control.value).toEqual(new Date(2015, 11, 5)); }); - it('should always allow for international date format regardless of locale', () => { - component.locale = 'de'; - component.selectedDate = '2015.12.5'; + it("should always allow for international date format regardless of locale", () => { + component.locale = "de"; + component.selectedDate = "2015.12.5"; component.validateDate(); expect(component.control.value).toEqual(new Date(2015, 11, 5)); }); - it('should set date to null if invalid based on locale', () => { - component.locale = 'de'; - component.selectedDate = '05.27.15'; + it("should set date to null if invalid based on locale", () => { + component.locale = "de"; + component.selectedDate = "05.27.15"; component.control.setValue(new Date()); component.validateDate(); @@ -199,9 +201,9 @@ describe('GoDatepickerComponent', () => { expect(component.control.value).toEqual(null); }); - it('should set date to null if year is more than 4 digits', () => { - component.locale = 'en-US'; - component.selectedDate = '05/15/20121'; + it("should set date to null if year is more than 4 digits", () => { + component.locale = "en-US"; + component.selectedDate = "05/15/20121"; component.control.setValue(new Date()); component.validateDate(); @@ -210,29 +212,78 @@ describe('GoDatepickerComponent', () => { }); }); - describe('toggleDatepicker', () => { - it('should not open datepicker if control is disabled', () => { - spyOn(component.goCalendar, 'openCalendar'); + describe("toggleDatepicker", () => { + it("should not open datepicker if control is disabled", () => { + spyOn(component.goCalendar, "openCalendar"); component.control.disable(); - component.toggleDatepicker(new Event('click')); + component.toggleDatepicker(new Event("click")); expect(component.goCalendar.openCalendar).not.toHaveBeenCalled(); }); - it('should open if calendar is previously closed', () => { + it("should open if calendar is previously closed", () => { component.goCalendar.closeCalendar(); - component.toggleDatepicker(new Event('click')); + component.toggleDatepicker(new Event("click")); expect(component.goCalendar.isOpen).toBe(true); }); - it('should close calendar if previously opened', () => { + it("should close calendar if previously opened", () => { + component.goCalendar.openCalendar(new Date()); + + component.toggleDatepicker(new Event("click")); + + expect(component.goCalendar.isOpen).toBe(false); + }); + }); + it("component should not render go-form-errors if hideFieldError property is true ", () => { + component.hideFieldError = true; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(0); + }); + it("component should render go-form-errors if hideFieldError property is false ", () => { + component.hideFieldError = false; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); + it("component should render go-form-errors if hideFieldError is not set ", () => { + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); + + describe("onInputCloseCalendar", () => { + it('close the calendar when the user interacts with the date field by typing inside it. ', () => { + component.goCalendar.openCalendar(new Date()); + + component.onInputCloseCalendar(); + + expect(component.goCalendar.isOpen).toBe(false); + }); + }); + + describe("onInputCloseCalendar", () => { + it("close the calendar when the user interacts with the date field by typing inside it. ", () => { component.goCalendar.openCalendar(new Date()); - component.toggleDatepicker(new Event('click')); + component.onInputCloseCalendar(); expect(component.goCalendar.isOpen).toBe(false); }); + + it("should call onInputCloseCalendar() when input event is emitted.", () => { + const onInputCloseCalendarSpy = spyOn(component, "onInputCloseCalendar"); + + inputElement.dispatchEvent(new Event("input")); + + expect(onInputCloseCalendarSpy).toHaveBeenCalled(); + }); }); + }); diff --git a/projects/go-lib/src/lib/components/go-datepicker/go-datepicker.component.ts b/projects/go-lib/src/lib/components/go-datepicker/go-datepicker.component.ts index 1c0bf6ff4..cd74b1fbe 100644 --- a/projects/go-lib/src/lib/components/go-datepicker/go-datepicker.component.ts +++ b/projects/go-lib/src/lib/components/go-datepicker/go-datepicker.component.ts @@ -118,4 +118,10 @@ export class GoDatepickerComponent extends GoFormBaseComponent implements OnDest private initializePlaceholder(): void { this.placeholder = this.placeholder || LocaleFormat.format(this.locale); } + + public onInputCloseCalendar(): void { + if (this.goCalendar.isOpen) { + this.goCalendar.closeCalendar(); + } + } } diff --git a/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.html b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.html index e0877a7f5..e7f263203 100644 --- a/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.html +++ b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.html @@ -1,13 +1,18 @@ - -
- +
- -
- - + (dragonDropleave)="onDragLeave()" + > +
+ Drag and Drop File or Click to Browse
+ class="go-file-upload__container go-file-upload__container--selected" + > + iconClass="go-icon--large" + > File Selected
@@ -45,35 +47,53 @@ #filePicker class="go-file-upload__input" (change)="onFilePicked($event)" - [attr.multiple]="multiple ? true : null"> - + [attr.multiple]="multiple ? true : null" + />
-
- - +
+ Uploading File...
-
- - -

- {{ file }} - + + +

+ {{ file }} +

- - - - + +
+ +
diff --git a/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.spec.ts b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.spec.ts index 5d491fd0a..dbfb809a5 100644 --- a/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.spec.ts @@ -1,17 +1,24 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { GoFileUploadComponent } from './go-file-upload.component'; -import { CommonModule } from '@angular/common'; -import { FormArray, FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { GoButtonModule } from '../go-button/go-button.module'; -import { GoHintModule } from '../go-hint/go-hint.module'; -import { GoIconButtonModule } from '../go-icon-button/go-icon-button.module'; -import { GoIconModule } from '../go-icon/go-icon.module'; -import { GoLoaderModule } from '../go-loader/go-loader.module'; -import { GoRequiredTextModule } from '../go-required-text/go-required-text.module'; -import { GoFormErrorsModule } from '../go-form-errors/go-form-errors.module'; - -describe('GoFileUploadComponent', () => { +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; + +import { GoFileUploadComponent } from "./go-file-upload.component"; +import { CommonModule } from "@angular/common"; +import { + FormArray, + FormControl, + FormGroup, + FormsModule, + ReactiveFormsModule, +} from "@angular/forms"; +import { GoButtonModule } from "../go-button/go-button.module"; +import { GoHintModule } from "../go-hint/go-hint.module"; +import { GoIconButtonModule } from "../go-icon-button/go-icon-button.module"; +import { GoIconModule } from "../go-icon/go-icon.module"; +import { GoLoaderModule } from "../go-loader/go-loader.module"; +import { GoRequiredTextModule } from "../go-required-text/go-required-text.module"; +import { GoFormErrorsModule } from "../go-form-errors/go-form-errors.module"; +import { By } from "@angular/platform-browser"; + +describe("GoFileUploadComponent", () => { let component: GoFileUploadComponent; let fixture: ComponentFixture; @@ -28,67 +35,66 @@ describe('GoFileUploadComponent', () => { GoIconButtonModule, GoLoaderModule, GoRequiredTextModule, - ReactiveFormsModule - ] - }) - .compileComponents(); + ReactiveFormsModule, + ], + }).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(GoFileUploadComponent); component = fixture.componentInstance; - component.control = new FormControl(''); + component.control = new FormControl(""); fixture.detectChanges(); }); - it('should create', () => { + it("should create", () => { expect(component).toBeTruthy(); }); - describe('onDragOver', () => { + describe("onDragOver", () => { it('should set state to "selecting" if it\'s not loading', () => { - component.state = 'selected'; + component.state = "selected"; component.isLoading = false; component.onDragOver(); - expect(component.state).toEqual('selecting'); + expect(component.state).toEqual("selecting"); }); }); - describe('onDragLeave', () => { + describe("onDragLeave", () => { it('should set state to "selected" if any files are uploaded', () => { const file: FormGroup = new FormGroup({ - file: new FormControl('whatever') + file: new FormControl("whatever"), }); component.files = new FormArray([file]); - component.state = 'selecting'; + component.state = "selecting"; component.onDragLeave(); - expect(component.state).toEqual('selected'); + expect(component.state).toEqual("selected"); }); }); - describe('reset', () => { - it('calls clear on files', () => { - spyOn(component.files, 'clear').and.callThrough(); + describe("reset", () => { + it("calls clear on files", () => { + spyOn(component.files, "clear").and.callThrough(); component.reset(); expect(component.files.clear).toHaveBeenCalled(); }); - it('sets filePreview to empty array', () => { - component.filePreview = ['whatever']; + it("sets filePreview to empty array", () => { + component.filePreview = ["whatever"]; component.reset(); expect(component.filePreview).toEqual([]); }); - it('sets isLoading to false', () => { + it("sets isLoading to false", () => { component.isLoading = true; component.reset(); @@ -97,79 +103,101 @@ describe('GoFileUploadComponent', () => { }); it('sets state to "selecting"', () => { - component.state = 'selected'; + component.state = "selected"; component.reset(); - expect(component.state).toEqual('selecting'); + expect(component.state).toEqual("selecting"); }); }); - describe('removeFile', () => { + describe("removeFile", () => { beforeEach(() => { const file: FormGroup = new FormGroup({ - file: new FormControl('whatever') + file: new FormControl("whatever"), }); component.files = new FormArray([file]); - component.filePreview = ['whatever']; + component.filePreview = ["whatever"]; }); - it('should set state to selecting if it was previously selected', () => { - component.state = 'selected'; + it("should set state to selecting if it was previously selected", () => { + component.state = "selected"; component.removeFile(0); - expect(component.state).toBe('selecting'); + expect(component.state).toBe("selecting"); }); - it('should not change the state if the state was selecting', () => { - component.state = 'selecting'; + it("should not change the state if the state was selecting", () => { + component.state = "selecting"; component.removeFile(0); - expect(component.state).toBe('selecting'); + expect(component.state).toBe("selecting"); }); - it('should remove the file at the given index from the form control', () => { + it("should remove the file at the given index from the form control", () => { component.removeFile(0); expect(component.control.value.length).toBe(0); }); - it('should remove the file at the given index from our file Preview Array', () => { + it("should remove the file at the given index from our file Preview Array", () => { component.removeFile(0); expect(component.filePreview.length).toBe(0); }); }); - describe('onFilePicked', () => { - const files: Object[] = [{ - id: 1, - name: 'file' - }]; + describe("onFilePicked", () => { + const files: Object[] = [ + { + id: 1, + name: "file", + }, + ]; afterEach(() => { component.files = component.fb.array([]); component.filePreview = []; }); - it('doesn\'t error when dropping a file', () => { + it("doesn't error when dropping a file", () => { component.onFilePicked({ dataTransfer: { - files: files - } + files: files, + }, }); expect(component.files.length).toBe(1); expect(component.filePreview.length).toBe(1); - expect(component.filePreview[0]).toBe('file'); + expect(component.filePreview[0]).toBe("file"); }); - it('doesn\t error when clicking on the file upload', () => { + it("doesn\t error when clicking on the file upload", () => { component.onFilePicked({ target: { - files: files - } + files: files, + }, }); expect(component.files.length).toBe(1); expect(component.filePreview.length).toBe(1); - expect(component.filePreview[0]).toBe('file'); + expect(component.filePreview[0]).toBe("file"); }); }); + it("component should not render go-form-errors if hideFieldError property is true ", () => { + component.hideFieldError = true; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(0); + }); + it("component should render go-form-errors if hideFieldError property is false ", () => { + component.hideFieldError = false; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); + it("component should render go-form-errors if hideFieldError is not set ", () => { + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); }); diff --git a/projects/go-lib/src/lib/components/go-form-base/go-form-base.component.ts b/projects/go-lib/src/lib/components/go-form-base/go-form-base.component.ts index b25329b5c..3767d51b1 100644 --- a/projects/go-lib/src/lib/components/go-form-base/go-form-base.component.ts +++ b/projects/go-lib/src/lib/components/go-form-base/go-form-base.component.ts @@ -3,7 +3,7 @@ import { AbstractControl, FormControl } from '@angular/forms'; import { GoFormService } from '../../services/form.service'; @Component({ - template: '' + template: '', }) export class GoFormBaseComponent { /** @@ -41,6 +41,11 @@ export class GoFormBaseComponent { */ @Input() theme: 'light' | 'dark' = 'light'; + /** + * Property to control the visibility of go-form-errors under form field. + */ + @Input() hideFieldError: boolean; + /** * Returns an object for ngClass generated by the GoFormService for inputs */ diff --git a/projects/go-lib/src/lib/components/go-input/go-input.component.html b/projects/go-lib/src/lib/components/go-input/go-input.component.html index fe4c492c9..1682b028e 100644 --- a/projects/go-lib/src/lib/components/go-input/go-input.component.html +++ b/projects/go-lib/src/lib/components/go-input/go-input.component.html @@ -6,16 +6,23 @@ {{ label }} - + - - - + +
+ +
diff --git a/projects/go-lib/src/lib/components/go-input/go-input.component.spec.ts b/projects/go-lib/src/lib/components/go-input/go-input.component.spec.ts index ccbc388da..245883c6d 100644 --- a/projects/go-lib/src/lib/components/go-input/go-input.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-input/go-input.component.spec.ts @@ -1,12 +1,13 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; -import { GoInputComponent } from './go-input.component'; -import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { GoHintModule } from '../go-hint/go-hint.module'; -import { GoRequiredTextModule } from '../go-required-text/go-required-text.module'; -import { GoFormErrorsModule } from '../go-form-errors/go-form-errors.module'; +import { GoInputComponent } from "./go-input.component"; +import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { GoHintModule } from "../go-hint/go-hint.module"; +import { GoRequiredTextModule } from "../go-required-text/go-required-text.module"; +import { GoFormErrorsModule } from "../go-form-errors/go-form-errors.module"; +import { By } from "@angular/platform-browser"; -describe('GoInputComponent', () => { +describe("GoInputComponent", () => { let component: GoInputComponent; let fixture: ComponentFixture; @@ -18,40 +19,59 @@ describe('GoInputComponent', () => { GoFormErrorsModule, GoHintModule, GoRequiredTextModule, - ReactiveFormsModule - ] - }) - .compileComponents(); + ReactiveFormsModule, + ], + }).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(GoInputComponent); component = fixture.componentInstance; - component.control = new FormControl('Some Value'); + component.control = new FormControl("Some Value"); fixture.detectChanges(); }); - it('should create', () => { + it("should create", () => { expect(component).toBeTruthy(); }); - describe('ngOnInit()', () => { - it('sets minlength to 0 if minlength is greater than maxlength', () => { + describe("ngOnInit()", () => { + it("sets minlength to 0 if minlength is greater than maxlength", () => { component.minlength = 10; component.maxlength = 8; component.ngOnInit(); expect(component.minlength).toBe(0); - }) - - it('sets maxlength to 524288 if maxlength is greater than 524288', () => { + }); + + it("sets maxlength to 524288 if maxlength is greater than 524288", () => { component.maxlength = 524290; component.ngOnInit(); expect(component.maxlength).toBe(524288); - }) + }); + it("component should not render go-form-errors if hideFieldError property is true ", () => { + component.hideFieldError = true; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(0); + }); + it("component should render go-form-errors if hideFieldError property is false ", () => { + component.hideFieldError = false; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); + it("component should render go-form-errors if hideFieldError is not set ", () => { + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); }); }); diff --git a/projects/go-lib/src/lib/components/go-radio/go-radio-group.component.html b/projects/go-lib/src/lib/components/go-radio/go-radio-group.component.html index a29a09f3d..9f00f2be3 100644 --- a/projects/go-lib/src/lib/components/go-radio/go-radio-group.component.html +++ b/projects/go-lib/src/lib/components/go-radio/go-radio-group.component.html @@ -1,17 +1,21 @@ -
+
+ *ngIf="enableLegend" + > {{ legend }} - - - + +
+ +
diff --git a/projects/go-lib/src/lib/components/go-radio/go-radio-group.component.spec.ts b/projects/go-lib/src/lib/components/go-radio/go-radio-group.component.spec.ts index 5f87d3e87..45bb5bcda 100644 --- a/projects/go-lib/src/lib/components/go-radio/go-radio-group.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-radio/go-radio-group.component.spec.ts @@ -1,31 +1,40 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { Component } from '@angular/core'; +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; +import { Component } from "@angular/core"; -import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { GoHintModule } from '../go-hint/go-hint.module'; -import { GoRadioGroupComponent } from './go-radio-group.component'; -import { GoRadioButtonComponent } from './go-radio-button.component'; -import { GoRequiredTextModule } from '../go-required-text/go-required-text.module'; -import { GoFormErrorsModule } from '../go-form-errors/go-form-errors.module'; +import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { GoHintModule } from "../go-hint/go-hint.module"; +import { GoRadioGroupComponent } from "./go-radio-group.component"; +import { GoRadioButtonComponent } from "./go-radio-button.component"; +import { GoRequiredTextModule } from "../go-required-text/go-required-text.module"; +import { GoFormErrorsModule } from "../go-form-errors/go-form-errors.module"; +import { By } from "@angular/platform-browser"; @Component({ - selector: 'go-test', + selector: "go-test", template: `
- +
- +
- ` + `, }) class GoTestRadioGroupComponent { - radioControl: FormControl = new FormControl(''); + radioControl: FormControl = new FormControl(""); } -describe('GoRadioGroupComponent', () => { +describe("GoRadioGroupComponent", () => { let component: GoRadioGroupComponent; let fixture: ComponentFixture; let buttonOne: GoRadioButtonComponent; @@ -33,16 +42,19 @@ describe('GoRadioGroupComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [GoRadioButtonComponent, GoRadioGroupComponent, GoTestRadioGroupComponent], + declarations: [ + GoRadioButtonComponent, + GoRadioGroupComponent, + GoTestRadioGroupComponent, + ], imports: [ FormsModule, GoFormErrorsModule, GoHintModule, GoRequiredTextModule, - ReactiveFormsModule - ] - }) - .compileComponents(); + ReactiveFormsModule, + ], + }).compileComponents(); })); beforeEach(() => { @@ -51,16 +63,17 @@ describe('GoRadioGroupComponent', () => { fixture.detectChanges(); - const buttonArray: GoRadioButtonComponent[] = component.radioButtons.toArray(); + const buttonArray: GoRadioButtonComponent[] = + component.radioButtons.toArray(); buttonOne = buttonArray[0]; buttonTwo = buttonArray[1]; }); - it('should create', () => { + it("should create", () => { expect(component).toBeTruthy(); }); - describe('ngAfterContentChecked', () => { + describe("ngAfterContentChecked", () => { beforeEach(() => { buttonOne.theme = null; buttonTwo.theme = null; @@ -71,44 +84,44 @@ describe('GoRadioGroupComponent', () => { component.radioButtonCount = 0; }); - it('should set a theme on each child component', () => { - component.theme = 'dark'; + it("should set a theme on each child component", () => { + component.theme = "dark"; component.ngAfterContentChecked(); - expect(buttonOne.theme).toBe('dark'); - expect(buttonTwo.theme).toBe('dark'); + expect(buttonOne.theme).toBe("dark"); + expect(buttonTwo.theme).toBe("dark"); }); - it('should set a name on each child component when legend is provided', () => { - component.legend = 'Random Name'; + it("should set a name on each child component when legend is provided", () => { + component.legend = "Random Name"; component.ngAfterContentChecked(); - expect(buttonOne.name).toContain('Random-Name-'); - expect(buttonTwo.name).toContain('Random-Name-'); + expect(buttonOne.name).toContain("Random-Name-"); + expect(buttonTwo.name).toContain("Random-Name-"); }); - it('should have enableLegend set to true by default on page load', () => { + it("should have enableLegend set to true by default on page load", () => { component.ngAfterContentChecked(); expect(component.enableLegend).toBeTruthy(); }); - it('should have enableFieldset set to true by default on page load', () => { + it("should have enableFieldset set to true by default on page load", () => { component.ngAfterContentChecked(); expect(component.enableFieldset).toBeTruthy(); }); - - it('should set a name on each child component when legend is NOT provided', () => { + + it("should set a name on each child component when legend is NOT provided", () => { component.legend = undefined; component.ngAfterContentChecked(); - expect(buttonOne.name).toContain('radio-group-'); - expect(buttonTwo.name).toContain('radio-group-'); + expect(buttonOne.name).toContain("radio-group-"); + expect(buttonTwo.name).toContain("radio-group-"); }); - it('should set a control on each child component', () => { - const newControl: FormControl = new FormControl('option1'); + it("should set a control on each child component", () => { + const newControl: FormControl = new FormControl("option1"); component.control = newControl; component.ngAfterContentChecked(); @@ -117,4 +130,24 @@ describe('GoRadioGroupComponent', () => { expect(buttonTwo.control).toBe(newControl); }); }); + it("component should not render go-form-errors if hideFieldError property is true ", () => { + component.hideFieldError = true; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(0); + }); + it("component should render go-form-errors if hideFieldError property is false ", () => { + component.hideFieldError = false; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); + it("component should render go-form-errors if hideFieldError is not set ", () => { + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); }); diff --git a/projects/go-lib/src/lib/components/go-select/go-select.component.html b/projects/go-lib/src/lib/components/go-select/go-select.component.html index c3ac2862b..3ee97e67a 100644 --- a/projects/go-lib/src/lib/components/go-select/go-select.component.html +++ b/projects/go-lib/src/lib/components/go-select/go-select.component.html @@ -2,7 +2,8 @@ *ngIf="label" class="go-form__label" [attr.for]="_id" - [ngClass]="{'go-form__label--dark': theme === 'dark'}"> + [ngClass]="{ 'go-form__label--dark': theme === 'dark' }" +> {{ label }} @@ -24,7 +25,8 @@ [multiple]="multiple" [ngClass]="{ 'go-select--dark': theme === 'dark', - 'go-select--hide-arrow': hideDropDownArrow || (typeahead && items?.length === 0), + 'go-select--hide-arrow': + hideDropDownArrow || (typeahead && items?.length === 0), 'go-select--hide-dropdown': searchable && items?.length === 0 }" [placeholder]="placeholder" @@ -37,53 +39,60 @@ (scroll)="onScroll($event)" #select > - + - + - + - + - + - - - - + +
+ +
diff --git a/projects/go-lib/src/lib/components/go-select/go-select.component.scss b/projects/go-lib/src/lib/components/go-select/go-select.component.scss index 0648faec8..2861d208c 100644 --- a/projects/go-lib/src/lib/components/go-select/go-select.component.scss +++ b/projects/go-lib/src/lib/components/go-select/go-select.component.scss @@ -28,6 +28,10 @@ min-height: auto; } +.ng-select.ng-select-disabled>.ng-select-container { + background-color: $theme-light-app-bg; +} + .ng-select.ng-select.ng-select-multiple .ng-select-container .ng-value-container, .ng-select.ng-select-single .ng-select-container .ng-value-container { align-items: flex-start; diff --git a/projects/go-lib/src/lib/components/go-select/go-select.component.spec.ts b/projects/go-lib/src/lib/components/go-select/go-select.component.spec.ts index ab68c1bb9..671beea94 100644 --- a/projects/go-lib/src/lib/components/go-select/go-select.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-select/go-select.component.spec.ts @@ -1,15 +1,16 @@ -import { CommonModule } from '@angular/common'; -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { NgSelectModule } from '@ng-select/ng-select'; -import { GoButtonModule } from '../go-button/go-button.module'; -import { GoFormErrorsModule } from '../go-form-errors/go-form-errors.module'; -import { GoHintModule } from '../go-hint/go-hint.module'; -import { GoRequiredTextModule } from '../go-required-text/go-required-text.module'; -import { GoSelectComponent } from './go-select.component'; -import { Subject } from 'rxjs'; - -describe('GoSelectComponent', () => { +import { CommonModule } from "@angular/common"; +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; +import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { NgSelectModule } from "@ng-select/ng-select"; +import { GoButtonModule } from "../go-button/go-button.module"; +import { GoFormErrorsModule } from "../go-form-errors/go-form-errors.module"; +import { GoHintModule } from "../go-hint/go-hint.module"; +import { GoRequiredTextModule } from "../go-required-text/go-required-text.module"; +import { GoSelectComponent } from "./go-select.component"; +import { Subject } from "rxjs"; +import { By } from "@angular/platform-browser"; + +describe("GoSelectComponent", () => { let component: GoSelectComponent; let fixture: ComponentFixture; @@ -24,7 +25,7 @@ describe('GoSelectComponent', () => { GoRequiredTextModule, NgSelectModule, FormsModule, - ReactiveFormsModule + ReactiveFormsModule, ] }).compileComponents(); })); @@ -32,26 +33,25 @@ describe('GoSelectComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(GoSelectComponent); component = fixture.componentInstance; - component.control = new FormControl('Some Value'); + component.control = new FormControl("Some Value"); fixture.detectChanges(); }); - it('should create', () => { + it("should create", () => { expect(component).toBeTruthy(); }); - describe('onSelectAll()', () => { - + describe("onSelectAll()", () => { beforeEach(() => { component.multiple = true; }); - it('adds all of the available items to the form control value', () => { + it("adds all of the available items to the form control value", () => { component.bindValue = undefined; component.items = [ - { value: 1, label: 'Label 1' }, - { value: 2, label: 'Label 2' }, - { value: 3, label: 'Label 3' } + { value: 1, label: "Label 1" }, + { value: 2, label: "Label 2" }, + { value: 3, label: "Label 3" }, ]; component.onSelectAll(); @@ -59,12 +59,12 @@ describe('GoSelectComponent', () => { expect(component.control.value).toEqual(component.items); }); - it('uses bindValue to get value if bindValue exists', () => { - component.bindValue = 'id'; + it("uses bindValue to get value if bindValue exists", () => { + component.bindValue = "id"; component.items = [ - { id: 1, label: 'Label 1' }, - { id: 2, label: 'Label 2' }, - { id: 3, label: 'Label 3' } + { id: 1, label: "Label 1" }, + { id: 2, label: "Label 2" }, + { id: 3, label: "Label 3" }, ]; component.onSelectAll(); @@ -72,110 +72,148 @@ describe('GoSelectComponent', () => { expect(component.control.value).toEqual([1, 2, 3]); }); - it('should select only filtered list, when filtered and selectAll', () => { - component.bindValue = 'id'; + it("should select only filtered list, when filtered and selectAll", () => { + component.bindValue = "id"; component.items = [ - { id: 1, label: 'banana' }, - { id: 2, label: 'apple' }, - { id: 3, label: 'green apple' } + { id: 1, label: "banana" }, + { id: 2, label: "apple" }, + { id: 3, label: "green apple" }, ]; const filteredItems: any[] = [ - { id: 2, label: 'apple' }, - { id: 3, label: 'green apple' } + { id: 2, label: "apple" }, + { id: 3, label: "green apple" }, ]; - component.ngSelect.searchTerm = 'apple'; - component.handleInput({ items: filteredItems, term: 'apple' }); + component.ngSelect.searchTerm = "apple"; + component.handleInput({ items: filteredItems, term: "apple" }); component.onSelectAll(); expect(component.control.value).toEqual([2, 3]); }); - it('should select filtered list with existing items in control value, when filtered and selectAll', () => { - component.bindValue = 'id'; + it("should select filtered list with existing items in control value, when filtered and selectAll", () => { + component.bindValue = "id"; component.control.patchValue([4]); component.items = [ - { id: 1, label: 'banana' }, - { id: 2, label: 'apple' }, - { id: 3, label: 'green apple' }, - { id: 4, label: 'grapes' } + { id: 1, label: "banana" }, + { id: 2, label: "apple" }, + { id: 3, label: "green apple" }, + { id: 4, label: "grapes" }, ]; const filteredItems: any[] = [ - { id: 2, label: 'apple' }, - { id: 3, label: 'green apple' } + { id: 2, label: "apple" }, + { id: 3, label: "green apple" }, ]; - component.ngSelect.searchTerm = 'apple'; - component.handleInput({ items: filteredItems, term: 'apple' }); + component.ngSelect.searchTerm = "apple"; + component.handleInput({ items: filteredItems, term: "apple" }); component.onSelectAll(); expect(component.control.value.length).toEqual(3); }); }); - describe('onSelectAll() with typeahead', () => { + describe("onSelectAll() with typeahead", () => { beforeEach(() => { component.typeahead = new Subject(); component.multiple = true; }); - it('should store items in previousSelectedItems', () => { + it("should store items in previousSelectedItems", () => { const initialItems: any[] = [ - { id: 1, label: 'banana' }, - { id: 2, label: 'apple' }, + { id: 1, label: "banana" }, + { id: 2, label: "apple" }, ]; component.items = initialItems; - component['handleTypeAheadSelectAll'](); - expect(component['previousSelectedItems']).toEqual(initialItems); + component["handleTypeAheadSelectAll"](); + expect(component["previousSelectedItems"]).toEqual(initialItems); }); - it('should add items in previousSelectedItems', () => { - component.handleItemAdd({ id: 1, label: 'banana' }); - expect(component['previousSelectedItems']).toEqual([ - { id: 1, label: 'banana' }, + it("should add items in previousSelectedItems", () => { + component.handleItemAdd({ id: 1, label: "banana" }); + expect(component["previousSelectedItems"]).toEqual([ + { id: 1, label: "banana" }, ]); }); - it('should remove items from previousSelectedItems', () => { - component['previousSelectedItems'] = [{ id: 1, label: 'banana' }]; - component.handleItemRemove({ value: { id: 1, label: 'banana' } }); - expect(component['previousSelectedItems']).toEqual([]); + it("should set background color when disabled", () => { + component.control.disable(); + fixture.detectChanges(); + + const ngSelectContainer = fixture.nativeElement.querySelector( + ".ng-select-container" + ); + + // Get the computed background color + const computedBgColor = + getComputedStyle(ngSelectContainer).backgroundColor; + + // Assuming $theme-light-app-bg is a valid CSS color value + const expectedBgColor = "rgb(240, 240, 240)"; + + // Assert that the computed background color matches the expected value + expect(computedBgColor).toBe(expectedBgColor); + }); + + it("set background color when not disabled", () => { + component.control.enable(); + fixture.detectChanges(); + + const ngSelectContainer = fixture.nativeElement.querySelector( + ".ng-select-container" + ); + + // Get the computed background color + const computedBgColor = + getComputedStyle(ngSelectContainer).backgroundColor; + + // Assuming an empty string because no background color is set when not disabled + const expectedBgColor = "rgb(255, 255, 255)"; + + // Assert that the computed background color matches the expected value + expect(computedBgColor).toBe(expectedBgColor); }); - it('handleControlInitialValue(), should assign previousSelectedItems', () => { + it("should remove items from previousSelectedItems", () => { + component["previousSelectedItems"] = [{ id: 1, label: "banana" }]; + component.handleItemRemove({ value: { id: 1, label: "banana" } }); + expect(component["previousSelectedItems"]).toEqual([]); + }); + + it("handleControlInitialValue(), should assign previousSelectedItems", () => { component.control.patchValue([1]); - component.bindValue = 'id'; + component.bindValue = "id"; component.items = [ - { id: 1, label: 'banana' }, - { id: 2, label: 'apple' }, + { id: 1, label: "banana" }, + { id: 2, label: "apple" }, ]; - component['handleControlInitialValue'](); - expect(component['previousSelectedItems']).toEqual([ - { id: 1, label: 'banana' }, + component["handleControlInitialValue"](); + expect(component["previousSelectedItems"]).toEqual([ + { id: 1, label: "banana" }, ]); }); }); - describe('processSelectAll', () => { - it('process select all and patch value in form', () => { - component.bindValue = 'id'; + describe("processSelectAll", () => { + it("process select all and patch value in form", () => { + component.bindValue = "id"; const items: any[] = [ - { id: 1, label: 'banana' }, - { id: 2, label: 'apple' }, - { id: 3, label: 'green apple' }, - { id: 4, label: 'grapes' }, + { id: 1, label: "banana" }, + { id: 2, label: "apple" }, + { id: 3, label: "green apple" }, + { id: 4, label: "grapes" }, ]; - component['processSelectAll'](items); + component["processSelectAll"](items); expect(component.control.value).toEqual([1, 2, 3, 4]); }); }); - describe('onRemoveAll', () => { - it('uses removed the selected values', () => { - component.bindValue = 'id'; - spyOn(component, 'resetTypeAheadItems'); + describe("onRemoveAll", () => { + it("uses removed the selected values", () => { + component.bindValue = "id"; + spyOn(component, "resetTypeAheadItems"); component.items = [ - { id: 1, label: 'Label 1' }, - { id: 2, label: 'Label 2' }, - { id: 3, label: 'Label 3' }, + { id: 1, label: "Label 1" }, + { id: 2, label: "Label 2" }, + { id: 3, label: "Label 3" }, ]; component.onSelectAll(); @@ -183,7 +221,29 @@ describe('GoSelectComponent', () => { component.onRemoveAll(); expect(component.control.value).toBeNull(); - expect(component['resetTypeAheadItems']).toHaveBeenCalled(); + expect(component["resetTypeAheadItems"]).toHaveBeenCalled(); }); }); + + it("component should not render go-form-errors if hideFieldError property is true ", () => { + component.hideFieldError = true; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(0); + }); + + it("component should render go-form-errors if hideFieldError property is false ", () => { + component.hideFieldError = false; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); + it("component should render go-form-errors if hideFieldError is not set ", () => { + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); }); diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.scss b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.scss index 0e7ec9df0..1f0fccc62 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.scss +++ b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.scss @@ -93,9 +93,11 @@ } &--launch { - color: $base-light-secondary; + color: $app-launch-color-secondary; cursor: default; - font-size: .6875rem; + font-family: 'Nunito'; + font-size: 0.875rem; + font-weight: lighter; padding: .75rem; width: 100%; diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.spec.ts b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.spec.ts index 566ef34e4..cd88c5653 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.spec.ts @@ -75,6 +75,34 @@ describe('GoSideNavComponent', () => { ] } ]; + + component.navAppDrawer = { + currentAppIcon: 'power_settings_new', + currentAppDisplayName: 'go-design', + appDrawerConfig: [ + { + displayName: 'GitHub', + icon: 'code', + url: 'https://github.com/', + target: 'github' + }, + { + displayName: 'Go Design', + icon: 'power_settings_new', + url: 'https://tangoe.design/getting-started' + }, + { + displayName: 'Google', + icon: 'search', + url: 'https://www.google.com/' + }, + { + displayName: 'Stack Overflow', + icon: 'contact_support', + url: 'https://stackoverflow.com/' + } + ] + }; fixture.detectChanges(); }); diff --git a/projects/go-lib/src/lib/components/go-text-area/go-text-area.component.html b/projects/go-lib/src/lib/components/go-text-area/go-text-area.component.html index 741651ca6..7541de85f 100644 --- a/projects/go-lib/src/lib/components/go-text-area/go-text-area.component.html +++ b/projects/go-lib/src/lib/components/go-text-area/go-text-area.component.html @@ -3,7 +3,7 @@ *ngIf="label" class="go-form__label" [attr.for]="_id" - [ngClass]="{'go-form__label--dark': theme === 'dark'}" + [ngClass]="{ 'go-form__label--dark': theme === 'dark' }" > {{ label }} @@ -19,7 +19,12 @@ [minlength]="minlength" > - - - + +
+ +
diff --git a/projects/go-lib/src/lib/components/go-text-area/go-text-area.component.spec.ts b/projects/go-lib/src/lib/components/go-text-area/go-text-area.component.spec.ts index a03b90a5d..6fb53bb21 100644 --- a/projects/go-lib/src/lib/components/go-text-area/go-text-area.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-text-area/go-text-area.component.spec.ts @@ -1,12 +1,13 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; -import { GoTextAreaComponent } from './go-text-area.component'; -import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { GoHintModule } from '../go-hint/go-hint.module'; -import { GoRequiredTextModule } from '../go-required-text/go-required-text.module'; -import { GoFormErrorsModule } from '../go-form-errors/go-form-errors.module'; +import { GoTextAreaComponent } from "./go-text-area.component"; +import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { GoHintModule } from "../go-hint/go-hint.module"; +import { GoRequiredTextModule } from "../go-required-text/go-required-text.module"; +import { GoFormErrorsModule } from "../go-form-errors/go-form-errors.module"; +import { By } from "@angular/platform-browser"; -describe('GoTextAreaComponent', () => { +describe("GoTextAreaComponent", () => { let component: GoTextAreaComponent; let fixture: ComponentFixture; @@ -18,27 +19,25 @@ describe('GoTextAreaComponent', () => { GoFormErrorsModule, GoHintModule, GoRequiredTextModule, - ReactiveFormsModule - ] - }) - .compileComponents(); + ReactiveFormsModule, + ], + }).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(GoTextAreaComponent); component = fixture.componentInstance; - component.control = new FormControl(''); + component.control = new FormControl(""); fixture.detectChanges(); }); - it('should create', () => { + it("should create", () => { expect(component).toBeTruthy(); }); - describe('ngOnInit()', () => { - - it('doesn\'n error if no minlength passed in', () => { + describe("ngOnInit()", () => { + it("doesn'n error if no minlength passed in", () => { component.minlength = undefined; component.maxlength = 20; @@ -48,7 +47,7 @@ describe('GoTextAreaComponent', () => { expect(component.maxlength).toBe(20); }); - it('doesn\'n error if no maxlength passed in', () => { + it("doesn'n error if no maxlength passed in", () => { component.minlength = 20; component.maxlength = undefined; @@ -58,7 +57,7 @@ describe('GoTextAreaComponent', () => { expect(component.maxlength).toBe(undefined); }); - it('sets minlength to 0 if minlength is greater than maxlength', () => { + it("sets minlength to 0 if minlength is greater than maxlength", () => { component.minlength = 150; component.maxlength = 100; @@ -68,4 +67,24 @@ describe('GoTextAreaComponent', () => { expect(component.maxlength).toBe(100); }); }); + it("component should not render go-form-errors if hideFieldError property is true ", () => { + component.hideFieldError = true; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(0); + }); + it("component should render go-form-errors if hideFieldError property is false ", () => { + component.hideFieldError = false; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); + it("component should render go-form-errors if hideFieldError is not set ", () => { + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); }); diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.html b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.html index 3aab190a2..3d1269146 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.html +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.html @@ -25,18 +25,18 @@ (click)="toggleTimepicker($event)" >
- - - +
+ +
diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts.spec.ts b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts.spec.ts index c834bb50d..55f34ab57 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts.spec.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts.spec.ts @@ -1,25 +1,23 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { GoTimepickerComponent } from './go-timepicker.component'; -import { GoTimeComponent } from './go-time.component'; -import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { GoHintModule } from '../go-hint/go-hint.module'; -import { GoIconButtonModule } from '../go-icon-button/go-icon-button.module'; -import { GoRequiredTextModule } from '../go-required-text/go-required-text.module'; -import { GoButtonModule } from '../go-button/go-button.module'; -import { GoTimeFormat } from './go-time-format.model'; -import { GoFormErrorsModule } from '../go-form-errors/go-form-errors.module'; - -describe('GoTimepickerComponent', () => { +import { async, ComponentFixture, TestBed } from "@angular/core/testing"; + +import { GoTimepickerComponent } from "./go-timepicker.component"; +import { GoTimeComponent } from "./go-time.component"; +import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { GoHintModule } from "../go-hint/go-hint.module"; +import { GoIconButtonModule } from "../go-icon-button/go-icon-button.module"; +import { GoRequiredTextModule } from "../go-required-text/go-required-text.module"; +import { GoButtonModule } from "../go-button/go-button.module"; +import { GoTimeFormat } from "./go-time-format.model"; +import { GoFormErrorsModule } from "../go-form-errors/go-form-errors.module"; +import { By } from "@angular/platform-browser"; + +describe("GoTimepickerComponent", () => { let component: GoTimepickerComponent; let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ - GoTimeComponent, - GoTimepickerComponent - ], + declarations: [GoTimeComponent, GoTimepickerComponent], imports: [ GoFormErrorsModule, GoIconButtonModule, @@ -35,107 +33,121 @@ describe('GoTimepickerComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(GoTimepickerComponent); component = fixture.componentInstance; - component.control = new FormControl(''); + component.control = new FormControl(""); }); - it('should create', () => { + it("should create", () => { component.ngOnInit(); expect(component).toBeTruthy(); }); - describe('ngOnInit', () => { + describe("ngOnInit", () => { afterEach(() => { component.selectedTime = null; }); - it('check with date object', () => { - const time: string = '05:15 AM'; - component.control.setValue(new Date('2017-04-30 05:15:00')); + it("check with date object", () => { + const time: string = "05:15 AM"; + component.control.setValue(new Date("2017-04-30 05:15:00")); component.ngOnInit(); expect(component.changeTimeFormat(component.selectedTime)).toBe(time); }); - it('change the time format 24hr to 12hr', () => { - component.control.setValue('18:15:00'); - const time: string = '06:15 PM'; + it("change the time format 24hr to 12hr", () => { + component.control.setValue("18:15:00"); + const time: string = "06:15 PM"; component.ngOnInit(); expect(component.selectedTime).toEqual(time); }); }); - describe('ngAfterViewInit', () => { + describe("ngAfterViewInit", () => { afterEach(() => { component.selectedTime = null; }); - it('after change the value of time', () => { - const time: string = '06:15 PM'; + it("after change the value of time", () => { + const time: string = "06:15 PM"; component.ngAfterViewInit(); - component.control.setValue('18:15:00'); + component.control.setValue("18:15:00"); expect(component.selectedTime).toEqual(time); }); }); - describe('timePicked', () => { + describe("timePicked", () => { afterEach(() => { component.selectedTime = null; }); - it('set the time with AM', () => { - const time: string = '10:20 AM'; + it("set the time with AM", () => { + const time: string = "10:20 AM"; const goTimeFormat: GoTimeFormat = { - hours: '10', - minutes: '20', - ampm: 'AM', + hours: "10", + minutes: "20", + ampm: "AM", }; component.timePicked(goTimeFormat); expect(component.selectedTime).toEqual(time); }); - it('set the time with PM', () => { - const time: string = '10:20 PM'; + it("set the time with PM", () => { + const time: string = "10:20 PM"; const goTimeFormat: GoTimeFormat = { - hours: '10', - minutes: '20', - ampm: 'PM', + hours: "10", + minutes: "20", + ampm: "PM", }; component.timePicked(goTimeFormat); expect(component.selectedTime).toEqual(time); }); - it('clear selected time', () => { - const time: string = ''; + it("clear selected time", () => { + const time: string = ""; component.timePicked(null); expect(component.selectedTime).toEqual(time); }); }); - describe('toggleTimepicker', () => { + describe("toggleTimepicker", () => { afterEach(() => { component.selectedTime = null; }); - it('should not open timepicker if control is disabled', () => { + it("should not open timepicker if control is disabled", () => { component.control.disable(); - component.toggleTimepicker(new Event('click')); + component.toggleTimepicker(new Event("click")); expect(component.timeOpen).toBe(false); }); - it('change selected time format to 24H', () => { - component.selectedTime = '05:42 PM'; - const convertTime: string = '17:42'; + it("change selected time format to 24H", () => { + component.selectedTime = "05:42 PM"; + const convertTime: string = "17:42"; - component.toggleTimepicker(new Event('click')); + component.toggleTimepicker(new Event("click")); expect(component.openTimeValue).toBe(convertTime); }); }); + it("component should not render go-form-errors if hideFieldError property is true ", () => { + component.hideFieldError = true; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(0); + }); + it("component should render go-form-errors if hideFieldError property is false ", () => { + component.hideFieldError = false; + fixture.detectChanges(); + expect( + fixture.debugElement.queryAll(By.css("go-form-errors"))?.length + ).toBe(1); + }); }); diff --git a/projects/go-lib/styles/_variables.scss b/projects/go-lib/styles/_variables.scss index 63f79b9d1..8bbe9f284 100644 --- a/projects/go-lib/styles/_variables.scss +++ b/projects/go-lib/styles/_variables.scss @@ -149,3 +149,6 @@ $form-border-neutral: transparentize($ui-color-neutral, .25); $form-shadow-neutral: 0 0 0 3px transparentize($ui-color-neutral, .75); $form-shadow-hover: 0 0 0 3px transparentize($base-light-tertiary, .5); + +//App launch +$app-launch-color-secondary: #6c757d; diff --git a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/forms-overview/forms-overview.component.html b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/forms-overview/forms-overview.component.html index 4f5c46ddd..456fe9ba3 100644 --- a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/forms-overview/forms-overview.component.html +++ b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/forms-overview/forms-overview.component.html @@ -5,25 +5,28 @@

Reactive Forms

-

As per the Angular Documentation:

+

+ As per the + Angular Documentation: +

- Reactive forms use an explicit and immutable approach to - managing the state of a form at a given point in time. - Each change to the form state returns a new state, which - maintains the integrity of the model between changes. - Reactive forms are built around observable streams, where - form inputs and values are provided as streams of input - values, which can be accessed synchronously. + Reactive forms use an explicit and immutable approach to managing the + state of a form at a given point in time. Each change to the form state + returns a new state, which maintains the integrity of the model between + changes. Reactive forms are built around observable streams, where form + inputs and values are provided as streams of input values, which can be + accessed synchronously.

- Reactive forms differ from template-driven forms in distinct - ways. Reactive forms provide more predictability with - synchronous access to the data model, immutability with - observable operators, and change tracking through observable - streams. If you prefer direct access to modify data in your - template, template-driven forms are less explicit because they - rely on directives embedded in the template, along with mutable - data to track changes asynchronously. + Reactive forms differ from template-driven forms in distinct ways. + Reactive forms provide more predictability with synchronous access to + the data model, immutability with observable operators, and change + tracking through observable streams. If you prefer direct access to + modify data in your template, template-driven forms are less explicit + because they rely on directives embedded in the template, along with + mutable data to track changes asynchronously.

@@ -34,15 +37,22 @@

Required Inputs

-

As per the Angular Documentation:

+

+ As per the + Angular Documentation: +

- Form controls have the ability to pass in Validators. In the case of every form input in Goponents we pass a control - thus you may specify on the control passed in to any form input a Validators.required validator on the control. Adding this validator - to any control in Goponents will render a red asterisk next to the label automatically. + Form controls have the ability to pass in Validators. In the case of + every form input in Goponents we pass a control thus you may specify on + the control passed in to any form input a Validators.required validator + on the control. Adding this validator to any control in Goponents will + render a red asterisk next to the label automatically.

- +
@@ -53,40 +63,62 @@

Validation Errors

-

As per the Angular Documentation:

+

+ As per the + Angular Documentation: +

- Form controls have the ability to hold a set of ValidationErrors. In the case of every form input in Goponents we automatically look for these - ValidationErrors and render error text beneath the form element dynamically. This is how form error handling should be done within Goponents. + Form controls have the ability to hold a set of + ValidationErrors. In the case of + every form input in Goponents we automatically look for these + ValidationErrors and render + error text beneath the form element dynamically. These errors are + displayed by default, but they can be hidden by setting + hideFieldError input property to + true. This is how form error handling should be done within Goponents.

+ + placeholder="Try typing something..." + >

- Angular provides some ValidationErrors out of the box, Goponents provides default error messages for: - email, max, maxlength, - min, minlength, required, and requiredtrue. - These will automatically render error messages if the matching Angular Validators are set for the control. If desired, these can be overridden by - passing a key/value validator with the same name of the Angular one and a custom string as the value. + Angular provides some + ValidationErrors out of the box, + Goponents provides default error messages for: + email, + max, + maxlength, + min, + minlength, + required, and + requiredtrue. These will + automatically render error messages if the matching Angular Validators + are set for the control. If desired, these can be overridden by passing + a key/value validator with the same name of the Angular one and a custom + string as the value.

-

- Form Elements Example -

+

Form Elements Example

@@ -98,84 +130,95 @@

label="Form Theme" [clearable]="false" [control]="themeSelect" - [items]="['light', 'dark']"> + [items]="['light', 'dark']" + > -
+
+ [ngClass]="{ + 'go-form--dark card-form-dark': themeSelect.value === 'dark' + }" + [formGroup]="form" + >

Create Profile

+ [control]="form.get('name')" + > + [control]="form.get('bio')" + > + [control]="form.get('birthday')" + > + [control]="form.get('birthtime')" + > + [theme]="themeSelect.value" + > + [items]="hpCharacters" + > + [control]="form.get('enableNotifications')" + > + [control]="form.get('notificationMethod')" + >
- - +
- - +
+ [control]="form.get('notificationsReceived')" + > + [control]="form.get('notificationsReceived').get('comments')" + > + [control]="form.get('notificationsReceived').get('mentions')" + >