From 6e5e3243edd9fbd22fc530ef062c641ba1647269 Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Wed, 30 Sep 2020 14:31:08 +0530 Subject: [PATCH 01/21] Add Virtual scrollbar logic for go-select module. --- .../go-select/go-select.component.html | 5 +- .../go-select/go-select.component.ts | 13 +- .../select-docs/select-docs.component.html | 44 +++++++ .../select-docs/select-docs.component.ts | 123 ++++++++++++++++++ 4 files changed, 182 insertions(+), 3 deletions(-) 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 e7fef8b02..893e4cd2e 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 @@ -21,7 +21,10 @@ [placeholder]="placeholder" [typeahead]="typeahead" [searchable]="searchable" - [typeToSearchText]="typeToSearchText"> + [typeToSearchText]="typeToSearchText" + [virtualScroll]="virtualScroll" + (scrollToEnd)="onScrollToEnd()" + (scroll)="onScroll($event)"> + +
  • + +
  • + + + diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss new file mode 100644 index 000000000..6e8ecf1b2 --- /dev/null +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss @@ -0,0 +1,154 @@ +@import '../../../styles/variables'; +@import '../../../styles/mixins'; + +.go-time { + background: $theme-light-bg; + border: 1px solid $theme-light-border; + border-radius: $global-radius; + position: absolute; + z-index: z-index(toaster); + padding: 0px 5px 0px 5px; + width: 179px; +} + +.go-time--above { + bottom: 2.5rem; +} + +.go-time--right { + right: 0; +} + +.go-time--append-to-content { + position: static; +} + +.go-time--wrapper { + display: flex; +} +.hour-minute-input { + width: 36px; + height: 35px; + border: 1px solid lightgray; + border-radius: 4px; + outline: none; + background: transparent; + padding: 0.5rem; + font-family: 'Roboto', 'Lato', 'Helvetica', 'Arial', sans-serif; + font-size: 0.875rem; + text-align: center; +} +// .go-calendar__close-calendar-content { +// flex-grow: 1; +// } + +.go-up-arrow { + float: left; + width: 50%; +} +.go-time-column { + float: left; +} +.hour-content { + max-width: 16%; + padding: 0px 32px 0px 20px; +} +.colon-content { + max-width: 9%; + padding: 9px 13px; +} +.minute-content { + padding: 0px 0px; + max-width: 15%; +} +.padding-left-23 { + padding-left: 23px; +} +.padding-left-31 { + padding-left: 31px; +} +input::placeholder { + // color: red; + font-size: 10.8px; +} +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + /* display: none; <- Crashes Chrome on hover */ + -webkit-appearance: none; + margin: 0; /* <-- Apparently some margin are still there even though it's hidden */ +} + +input[type='number'] { + -moz-appearance: textfield; /* Firefox */ +} +.action-button { + padding: 3px 3px; + font-size: 12px; + border-radius: 4px; + transition-duration: 0.25s; + transition-property: all; + transition-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1); + align-items: center; + border: 0; + cursor: pointer; + display: inline-flex; + font-family: Roboto, Lato, Helvetica, Arial, sans-serif; + font-weight: 500; + letter-spacing: 0.015rem; + line-height: 1.2; + outline: 0; + position: relative; + text-decoration: none; + text-transform: uppercase; +} +.clear-btn { + background: #fff; + color: #313536; + border: 1px solid #cbcbcb; + &:hover, + &:focus { + background: $theme-light-bg-hover; + border: 1px solid $theme-light-bg-hover; + } + &:hover, + &:focus, + &:active { + border: 1px solid lighten($base-light-secondary, 10%); + box-shadow: 0 0 0 3px transparentize($base-light-tertiary, 0.75); + } + + &:active { + background: $theme-light-bg-active; + border: 1px solid $theme-light-bg-active; + } +} +.apply-btn { + color: #fff; + background: #00838f; + border: 1px solid #00838f; + &:hover, + &:focus { + background: $ui-color-primary-hover; + border: 1px solid $ui-color-primary-hover; + box-shadow: $form-shadow-active; + } + + &:active { + background: $ui-color-primary-active; + border: 1px solid $ui-color-primary-active; + box-shadow: $form-shadow-active; + } +} +.go-time-action { + float: right; + padding-bottom: 4px; +} +.go-form__input--error { + border-color: $ui-color-negative; +} +.apply-button-margin { + margin-right: 3px; +} +.time-format { + font-weight: 500; +} diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts new file mode 100644 index 000000000..8a910d1a9 --- /dev/null +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts @@ -0,0 +1,230 @@ +import { + Component, + EventEmitter, + HostListener, + Input, + OnInit, + Output, +} from '@angular/core'; +import { fadeAnimation } from '../../animations/fade.animation'; + +import { GoTime } from './go-time'; +@Component({ + selector: 'go-time', + styleUrls: ['./go-time.component.scss'], + templateUrl: './go-time.component.html', + animations: [fadeAnimation], +}) +export class GoTimeComponent implements OnInit { + @Input() appendToContent: boolean; + @Input() goTime: GoTime; + @Input() displayAbove: boolean; + @Input() displayFromRight: boolean; + + @Output() timePicked: any = new EventEmitter(); + inputHourError: boolean = false; + inputMinuteError: boolean = false; + format: boolean = true; + opened: boolean = false; + clickInside: boolean = false; + clickActionButton: boolean = false; + timeFormat: any = { hours: '', minutes: '', ampm: '' }; + subscription: any; + hour: any; + minute: any; + + constructor() {} + + @HostListener('click') + ClickInside(): void { + this.clickInside = this.clickActionButton ? false : true; + this.opened = true; + } + + @HostListener('document: click') + onDocumentClick(): void { + if (this.opened && !this.clickInside) { + this.closeTimePicker(); + this.resetTimeInput(); + } + this.clickInside = false; + this.clickActionButton = false; + } + @HostListener('window:keydown', ['$event']) + keyEvent(event: KeyboardEvent): void { + switch (event.key) { + case 'Esc': // IE/Edge specific value + case 'Escape': + event.preventDefault(); + this.closeTimePicker(); + this.resetTimeInput(); + break; + default: + return; + } + } + public closeTimePicker(): void { + this.goTime.closeTime(); + } + ngOnInit(): void { + this.subscription = this.goTime.timeWindowOpen.subscribe( + (value: boolean) => { + if (value) { + if (this.goTime.selectedTime) { + this.changeTimeFormat(this.goTime.selectedTime); + } else { + this.timeFormat = this.formatAMPM(new Date()); + this.hour = this.timeFormat.hours; + this.minute = this.timeFormat.minutes; + this.format = this.timeFormat.ampm === 'am' ? true : false; + } + } + this.opened = value; + } + ); + } + formatAMPM(date: any): void { + let hours: any = date.getHours(); + let minutes: any = date.getMinutes(); + const ampm: any = hours >= 12 ? 'pm' : 'am'; + hours = hours % 12; + hours = hours ? hours : 12; // the hour '0' should be '12' + hours = hours > 9 ? hours : '0' + hours; + minutes = minutes > 9 ? minutes : '0' + minutes; + const formatTime: any = { hours, minutes, ampm }; + return formatTime; + } + changeTimeFormat(timeString: any): void { + const H: any = +timeString.substr(0, 2); + const h: any = H % 12 || 12; + const ampm: any = H < 12 || H === 24 ? 'AM' : 'PM'; + const minute: any = timeString.substr(3, 2); + this.hour = h > 9 ? h : '0' + h; + this.minute = (minute > 9 || minute === '00' || minute.length === 2) ? minute : '0' + minute; + this.format = ampm === 'AM' ? true : false; + } + changeFormat(): void { + this.format = !this.format; + } + increaseHour(): void { + if (this.hour >= 12) { + this.hour = '00'; + return; + } + if (Number(this.hour) < 9) { + this.hour = '0' + (Number(this.hour) + 1); + } else { + this.hour = Number(this.hour) + 1; + } + } + increaseMinute(): void { + if (this.minute >= 59) { + this.minute = '00'; + return; + } + if (Number(this.minute) < 9) { + this.minute = '0' + (Number(this.minute) + 1); + } else { + this.minute = Number(this.minute) + 1; + } + } + decreaseHour(): void { + if (this.hour === '00') { + this.hour = '00'; + return; + } + if (Number(this.hour) <= 10) { + this.hour = '0' + (Number(this.hour) - 1); + } else { + this.hour = Number(this.hour) - 1; + } + } + decreaseMinute(): void { + if (this.minute === '00') { + this.minute = '00'; + return; + } + if (Number(this.minute) <= 10) { + this.minute = '0' + (Number(this.minute) - 1); + } else { + this.minute = Number(this.minute) - 1; + } + } + twoDigitOnly(event): void { + const value: any = event.target.value; + if (value.length <= 2) { + const hour: any = value.replace(/[^0-9]+/g, ''); + (document.getElementById('hour') as HTMLInputElement).value = ''; + (document.getElementById('hour') as HTMLInputElement).value = hour; + } else if (value.length === 3) { + this.hour = value.substring(0, value.length - 1); + } + } + twoDigitNumber(e) { + e = e || window.event; + const charCode = typeof e.which === 'number' ? e.which : e.keyCode; + if (e.target.value.length >= 2) { + return false; + } + // Allow non-printable keys + if (!charCode || charCode === 8 /* Backspace */) { + return; + } + + const typedChar = String.fromCharCode(charCode); + + // Allow numeric characters + if (/\d/.test(typedChar)) { + return; + } + + // Allow the minus sign (-) if the user enters it first + if (typedChar === '-' && this.hour === '') { + return; + } + + // In all other cases, suppress the event + return false; + } + clear(): void { + this.clickActionButton = true; + this.resetTimeInput(); + this.closeTimePicker(); + this.timePicked.emit(); + } + apply(): void { + if (this.hour > 12 || this.minute > 59) { + this.inputTimeError(); + return; + } else { + this.resetTimeInput(); + } + this.clickActionButton = true; + if (!this.hour) { + this.hour = '12'; + } + if (!this.minute) { + this.minute = '00'; + } + this.hour = (this.minute.toString()).length > 1 ? this.hour : '0' + this.hour; + this.minute = (this.minute.toString()).length > 1 ? this.minute : '0' + this.minute; + this.timeFormat = { + hours: this.hour, + minutes: this.minute, + ampm: this.format ? 'AM' : 'PM', + }; + this.timePicked.emit(this.timeFormat); + this.closeTimePicker(); + } + inputTimeError(): void { + if (this.hour > 12) { + this.inputHourError = true; + } else if (this.minute > 59) { + this.inputMinuteError = true; + } + } + resetTimeInput(): void { + this.inputHourError = false; + this.inputMinuteError = false; + } +} diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time.ts new file mode 100644 index 000000000..1a587df50 --- /dev/null +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.ts @@ -0,0 +1,30 @@ +import { Subject } from 'rxjs'; + +export class GoTime { + private timeOpen: boolean = false; + timeWindowOpen: Subject = new Subject(); + + selectedTime: string; + + constructor() { + this.setTimeStatus(false); + } + + public openTime(time): void { + this.selectedTime = time; + this.setTimeStatus(true); + } + + public closeTime(): void { + this.setTimeStatus(false); + } + + get isOpen(): boolean { + return this.timeOpen; + } + + private setTimeStatus(isOpen: boolean = true): void { + this.timeOpen = isOpen; + this.timeWindowOpen.next(isOpen); + } +} 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 new file mode 100644 index 000000000..6f037c3d9 --- /dev/null +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.html @@ -0,0 +1,50 @@ + +
    + + + + +
    + + +
    + +
    + diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.scss b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.scss new file mode 100644 index 000000000..413e48a30 --- /dev/null +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.scss @@ -0,0 +1,9 @@ +.go-timepicker { + position: relative; +} + +.go-timepicker__toggle { + position: absolute; + right: 0.25rem; + top: 0.25rem; +} diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts new file mode 100644 index 000000000..c427b7f5e --- /dev/null +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts @@ -0,0 +1,91 @@ +import { Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; +import { FormControl } from '@angular/forms'; +import { generateId } from '../../utilities/form.utils'; +import { GoTime } from './go-time'; +@Component({ + selector: 'go-timepicker', + styleUrls: ['./go-timepicker.component.scss'], + templateUrl: './go-timepicker.component.html', +}) +export class GoTimepickerComponent implements OnInit { + displayAbove: boolean = false; + displayFromRight: boolean = true; + id: string; + + @Input() key: string; + @Input() label: string; + @Input() control: FormControl; + @Input() hints: string[]; + @Input() placeholder: string = ''; + @Input() theme: string = 'light'; + @Input() appendToContent: boolean = false; + + goTime: GoTime; + + selectedTime: string; + + @ViewChild('datepickerInput', { static: true }) datepickerInput: ElementRef; + constructor() { + this.goTime = new GoTime(); + } + ngOnInit(): void { + this.id = this.key || generateId(this.label, 'timepicker'); + this.selectedTime = this.changeTimeFormat(this.control.value); + } + public changeTimeFormat(timeString) { + if (!timeString) { + return; + } + const H = +timeString.substr(0, 2); + const h = H % 12 || 12; + const hour = h > 9 ? h : '0' + h; + const ampm = H < 12 || H === 24 ? 'AM' : 'PM'; + timeString = hour + timeString.substr(2, 3) + ' ' + ampm; + return timeString; + // this.selectedTime = timeString; + } + + public validateTime(): void {} + public toggleTimepicker(event: Event): void { + event.stopPropagation(); + // Have to disable this here because of the event that we need to stop propagation on. + if (this.control.disabled) { + return; + } + + if (this.goTime.isOpen) { + this.goTime.closeTime(); + } else { + const position: string = 'top'; + const distance: object = this.datepickerInput.nativeElement.getBoundingClientRect(); + this.displayAbove = + window.innerHeight - distance[position] < 350 && !this.appendToContent; + const convert24Hr: string = (/^\s*$/).test(this.selectedTime) ? undefined : this.convertTo24Hour(this.selectedTime); + const openTimeValue: string = convert24Hr ? convert24Hr : undefined; + this.goTime.openTime(openTimeValue); + } + } + public timePicked(event) { + if (event) { + const selctedTime: string = event.hours + ':' + event.minutes + ' ' + event.ampm; + this.control.setValue(selctedTime); + this.selectedTime = selctedTime; + } else { + this.selectedTime = ''; + } + } + convertTo24Hour(time12h) { + if (time12h){ + const [time, modifier] = time12h.split(' '); + + let [hours, minutes] = time.split(':'); + if (hours === '12') { + hours = '00'; + } + if (modifier === 'PM') { + hours = parseInt(hours, 10) + 12; + } + return `${hours}:${minutes}`; + } + } +} diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.module.ts b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.module.ts new file mode 100644 index 000000000..c764f0588 --- /dev/null +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { GoTimepickerComponent } from './go-timepicker.component'; +import { GoTimeComponent } from './go-time.component'; +import { GoRequiredTextModule } from '../go-required-text/go-required-text.module'; +import { GoIconButtonModule } from '../go-icon-button/go-icon-button.module'; +import { GoInputModule } from '../go-input/go-input.module'; +import { GoButtonModule } from '../go-button/go-button.module'; +import { GoIconModule } from '../go-icon/go-icon.module'; +import { GoHintModule } from '../go-hint/go-hint.module'; + +@NgModule({ + declarations: [GoTimepickerComponent, GoTimeComponent], + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + GoIconButtonModule, + GoInputModule, + GoButtonModule, + GoIconModule, + GoRequiredTextModule, + GoHintModule + ], + exports: [GoTimepickerComponent], +}) +export class GoTimepickerModule {} diff --git a/projects/go-lib/src/lib/go-shared.module.ts b/projects/go-lib/src/lib/go-shared.module.ts index 1e997021b..6ff1cd0a6 100644 --- a/projects/go-lib/src/lib/go-shared.module.ts +++ b/projects/go-lib/src/lib/go-shared.module.ts @@ -25,6 +25,7 @@ import { GoSideNavModule } from './components/go-side-nav/go-side-nav.module'; import { GoSwitchToggleModule } from './components/go-switch-toggle/go-switch-toggle.module'; import { GoTableModule } from './components/go-table/go-table.module'; import { GoTextAreaModule } from './components/go-text-area/go-text-area.module'; +import { GoTimepickerModule } from './components/go-timepicker/go-timepicker.module'; import { GoToastModule } from './components/go-toast/go-toast.module'; import { GoToasterModule } from './components/go-toaster/go-toaster.module'; import { GoCopyCardLinkModule } from './directives/go-copy-card-link/go-copy-card-link.module'; @@ -59,7 +60,8 @@ import { GoCopyCardLinkModule } from './directives/go-copy-card-link/go-copy-car GoTableModule, GoTextAreaModule, GoToastModule, - GoToasterModule + GoToasterModule, + GoTimepickerModule ], exports: [ GoAccordionModule, diff --git a/projects/go-lib/src/public_api.ts b/projects/go-lib/src/public_api.ts index 8087ed4a5..5210b68f2 100644 --- a/projects/go-lib/src/public_api.ts +++ b/projects/go-lib/src/public_api.ts @@ -164,6 +164,12 @@ export * from './lib/components/go-tree/go-tree.component'; export * from './lib/components/go-tree/go-tree.module'; export * from './lib/components/go-tree/go-tree-node-config.model'; +// Timepicker +// export * from './lib/components/go-datepicker/calendar-cell.model'; +// export * from './lib/components/go-datepicker/go-datepicker.component'; +// export * from './lib/components/go-datepicker/go-datepicker.module'; +export * from './lib/components/go-timepicker/go-time.component'; +export * from './lib/components/go-timepicker/go-timepicker.module'; /***** Utils *****/ export * from './lib/utilities/form.utils'; export * from './lib/utilities/colors.util'; diff --git a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.html b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.html new file mode 100644 index 000000000..cd5a57e06 --- /dev/null +++ b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.html @@ -0,0 +1,309 @@ +
    + + + + +

    Component Control

    + +
    +
    + +
    +

    + As with most of the form components, the only @Input + required of the timepicker component is a FormControl. + The FormControl can be passed in via the [control] + attribute on the <go-timepicker> component. A date can be initialized into the timepicker + by setting a time on the control. It can be initialized by either a string or a time object. + If using a string it can be entered as format (hh:mm:ss) +

    +
    + +
    +
    +
    +

    View

    + +
    +
    +

    Code

    + + + + +
    +
    +
    +
    +
    + + + +

    Component Label

    + +
    +
    + +
    +

    + All form components include an @Input() label: string; + that can be used to add a label to the input components. + In addition to displaying an HTML label, the text passed + in via the [label] + attribute is used to generate a unique ID to associate the + label with the timepicker. If no label is passed in, a generic, + but still unique ID will be generated. +

    +
    + +
    +
    +
    +

    View

    + + +
    +
    +

    Code

    + + +
    +
    +
    +
    +
    + + + +

    Component Key

    + +
    +
    + +
    +

    + As stated above the label attribute is used to generate a + unique ID to associate the label with the timepicker. As this might + not be desired, the @Input() key: string; + can be used to configure the ID attribute of the timepicker directly. + Anything passed into the component via the [key] + attribute will be used to both assign the ID to the timepicker and + associate the label with the timepicker. +

    +
    + +
    +
    +
    +

    View

    + + +
    +
    +

    Code

    + + +
    +
    +

    Example Output

    +

    + Notice in the below example output that the key has been assigned + to both the id attribute on + the input and the for attribute + on the label. +

    + + +
    +
    +
    +
    +
    + + + +

    Component Hints

    + +
    +
    + +
    +

    + Form hints exist to help give more information about the + inputs they are attached to. The @Input() key: Array<string> + can be used to pass in an array of hints to the timepicker component. +

    +
    + +
    +
    +
    +

    View

    + + +
    +
    +

    Code

    + + + + +
    +
    +
    +
    +
    + + + +

    Component Errors

    + +
    +
    + +
    +

    + FormControls all have a consistent way of setting errors + via the setErrors() function. + All goponents use this API to display errors on our components, but the + data needs to be displayed in a specific structure. +

    +

    + By default the input type is set to "Error", however this can be + overrides as shown below. +

    +
    + +
    +
    +
    +

    View

    + + +
    +
    +

    Code

    + + + + +
    +
    +
    +
    +
    + + + +

    Disable Component

    + +
    +
    + +
    +

    + FormControls can be either created as disable or later disabled + and re-enabled directly after they are created. +

    +
    + +
    +
    +
    +

    View

    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +

    Code

    + + + + +
    +
    +
    +
    +
    + + + +

    Component Placeholder

    + +
    +
    + +
    +

    + The timepicker components placeholder attribute can be set via + @Input() placeholder: string; + and the [placeholder] attribute. +

    +
    + +
    +
    +
    +

    View

    + + +
    +
    +

    Code

    + + +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.ts b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.ts new file mode 100644 index 000000000..1e30fbba9 --- /dev/null +++ b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.ts @@ -0,0 +1,114 @@ +import { Component, OnInit } from '@angular/core'; +import { FormControl } from '@angular/forms'; +import { SubNavService } from 'projects/go-style-guide/src/app/shared/components/sub-nav/sub-nav.service'; + +@Component({ + templateUrl: './timepicker-docs.component.html' +}) +export class TimepickerDocsComponent implements OnInit { + + time: FormControl = new FormControl('18:15:00'); + time2: FormControl = new FormControl(); + time3: FormControl = new FormControl(); + time4: FormControl = new FormControl(); + time5: FormControl = new FormControl(); + time6: FormControl = new FormControl(); + time7: FormControl = new FormControl(); + + hints: Array = [ + 'Please enter your time', + 'This is a second hint for no reason' + ]; + + basicInputExample: string = ` + + `; + + basicInputExampleComponent: string = ` + time: FormControl = new FormControl('18:15:00'); + `; + + basicInputLabelExample: string = ` + + `; + + basicInputKeyExample: string = ` + + `; + + basicInputKeyExampleOutput: string = ` + + + `; + + basicHintsTemplate: string = ` + hints: Array = [ + 'Please enter your time', + 'This is a second hint for no reason' + ]; + `; + + basicInputHintsExample: string = ` + + + `; + + basicErrorsTemplate: string = ` + this.time.setErrors([ + { + message: 'This date is invalid' + }, + { + type: 'Required', + message: 'This is a required input.' + } + ]); + `; + + basicDisabledExample: string = ` + startTime: new FormControl({ + value: '', + disabled: true + }); + `; + + basicDisabledExample2: string = ` + endTime: new FormControl(''); + + ngOnInit(): void { + this.endTime.disable(); + // Use this.endTime.enable(); to re-enable the input. + } + `; + + basicPlaceholderExample: string = ` + + + `; + + constructor(private subNavService: SubNavService) { + this.subNavService.pageTitle = 'Timepicker'; + this.subNavService.linkToSource = 'https://github.com/mobi/goponents/tree/dev/projects/go-lib/src/lib/components/go-timepicker'; + } + ngOnInit(): void { + setTimeout((): void => { + this.time4.setErrors([ + { + message: 'This time is invalid' + }, + { + type: 'Required', + message: 'This is a required input.' + } + ]); + this.time5.disable(); + this.time6.disable(); + }, 500); + } +} diff --git a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/form-docs.component.ts b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/form-docs.component.ts index 65771efc9..c1483e768 100644 --- a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/form-docs.component.ts +++ b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/form-docs.component.ts @@ -18,7 +18,8 @@ export class FormDocsComponent { { route: './radio', routeTitle: 'Radio' }, { route: './select', routeTitle: 'Select' }, { route: './switch-toggle', routeTitle: 'Switch Toggle' }, - { route: './textarea', routeTitle: 'Text Area' } + { route: './textarea', routeTitle: 'Text Area' }, + { route: './timepicker', routeTitle: 'Timepicker' }, ] } ]; diff --git a/projects/go-style-guide/src/app/features/ui-kit/routes/ui-kit-routing.module.ts b/projects/go-style-guide/src/app/features/ui-kit/routes/ui-kit-routing.module.ts index cee932d20..91be5bcfc 100644 --- a/projects/go-style-guide/src/app/features/ui-kit/routes/ui-kit-routing.module.ts +++ b/projects/go-style-guide/src/app/features/ui-kit/routes/ui-kit-routing.module.ts @@ -59,6 +59,7 @@ import { TreeDocsComponent } from '../components/tree-docs/tree-docs.component'; import { TableTitleTemplateComponent } from '../components/table-docs/components/table-title-template/table-title-template.component'; import { VirtualScrollComponent } from '../components/virtual-scroll/virtual-scroll.component'; import { TableChildRowsComponent } from '../components/table-docs/components/table-child-rows/table-child-rows.component'; +import { TimepickerDocsComponent } from '../components/form-docs/components/timepicker-docs/timepicker-docs.component'; const routes: Routes = [ { path: 'ui-kit', component: UiKitComponent }, @@ -86,7 +87,8 @@ const routes: Routes = [ { path: 'radio', component: RadioButtonDocsComponent }, { path: 'select', component: SelectDocsComponent }, { path: 'switch-toggle', component: SwitchToggleDocsComponent }, - { path: 'textarea', component: TextAreaDocsComponent } + { path: 'textarea', component: TextAreaDocsComponent }, + { path: 'timepicker', component: TimepickerDocsComponent } ]}, { path: 'ui-kit/icon-button', component: IconButtonDocsComponent }, { path: 'ui-kit/layout', component: LayoutDocsComponent, children: [ diff --git a/projects/go-style-guide/src/app/features/ui-kit/ui-kit.module.ts b/projects/go-style-guide/src/app/features/ui-kit/ui-kit.module.ts index 998b49b1f..c33e51ec3 100644 --- a/projects/go-style-guide/src/app/features/ui-kit/ui-kit.module.ts +++ b/projects/go-style-guide/src/app/features/ui-kit/ui-kit.module.ts @@ -32,6 +32,7 @@ import { GoTableModule, GoTabModule, GoTextAreaModule, + GoTimepickerModule, GoToasterService, GoToastModule, GoTreeModule @@ -106,6 +107,7 @@ import { VirtualScrollComponent } from './components/virtual-scroll/virtual-scro import { BasicTestLargeComponent } from './components/basic-test-large/basic-test-large.component'; import { BasicTestSubmitButtonComponent } from './components/basic-test-submit-button/basic-test-submit-button.component'; import { TableChildRowsComponent } from './components/table-docs/components/table-child-rows/table-child-rows.component'; +import { TimepickerDocsComponent } from './components/form-docs/components/timepicker-docs/timepicker-docs.component'; @NgModule({ imports: [ @@ -138,7 +140,8 @@ import { TableChildRowsComponent } from './components/table-docs/components/tabl UiKitRoutesModule, GoSharedModule, FormsModule, - GoTreeModule + GoTreeModule, + GoTimepickerModule ], declarations: [ AccordionDocsComponent, @@ -203,7 +206,8 @@ import { TableChildRowsComponent } from './components/table-docs/components/tabl TableFiltersComponent, TableTitleTemplateComponent, VirtualScrollComponent, - TableChildRowsComponent + TableChildRowsComponent, + TimepickerDocsComponent ], entryComponents: [ BasicTestComponent, diff --git a/projects/go-tester/src/app/app.module.ts b/projects/go-tester/src/app/app.module.ts index c1813fe2a..a52a7d753 100644 --- a/projects/go-tester/src/app/app.module.ts +++ b/projects/go-tester/src/app/app.module.ts @@ -34,6 +34,7 @@ import { GoSwitchToggleModule, GoTableModule, GoTextAreaModule, + GoTimepickerModule, GoToasterModule, GoToastModule } from '../../../go-lib/src/public_api'; @@ -99,7 +100,8 @@ import { AppGuard } from './app.guard'; HttpClientModule, ReactiveFormsModule, ReactiveFormsModule, - GoPortalModule + GoPortalModule, + GoTimepickerModule ], providers: [ AppService, From dc0afdd517ffcf34a1a9268214f6f0342f8f0b27 Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Fri, 27 Nov 2020 01:31:55 +0530 Subject: [PATCH 04/21] Clean some unwanted code --- .../src/lib/components/go-timepicker/go-time.component.scss | 4 ---- .../lib/components/go-timepicker/go-timepicker.component.ts | 1 - 2 files changed, 5 deletions(-) diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss index 6e8ecf1b2..83866242f 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss @@ -38,9 +38,6 @@ font-size: 0.875rem; text-align: center; } -// .go-calendar__close-calendar-content { -// flex-grow: 1; -// } .go-up-arrow { float: left; @@ -68,7 +65,6 @@ padding-left: 31px; } input::placeholder { - // color: red; font-size: 10.8px; } input::-webkit-outer-spin-button, diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts index c427b7f5e..8ed356579 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts @@ -42,7 +42,6 @@ export class GoTimepickerComponent implements OnInit { const ampm = H < 12 || H === 24 ? 'AM' : 'PM'; timeString = hour + timeString.substr(2, 3) + ' ' + ampm; return timeString; - // this.selectedTime = timeString; } public validateTime(): void {} From 587435c67b281c3d6d775f97998f18bf1336eb69 Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Thu, 10 Dec 2020 20:34:47 +0530 Subject: [PATCH 05/21] resolve mention issue --- .../go-timepicker/go-time.component.html | 19 +++++++----- .../go-timepicker/go-time.component.scss | 9 ++++-- .../go-timepicker/go-time.component.ts | 31 ++++++++++++------- .../go-timepicker.component.html | 1 + 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html index 1fb0e8fed..931717dec 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html @@ -11,7 +11,7 @@
    -
    +
    -
    +
    :
    -
    +
    -
    +
    {{ format ? 'AM' : 'PM' }}
    +
    { + document.getElementById('hour-input').focus(); + }); + } + formatAMPM(date: any): void { let hours: any = date.getHours(); let minutes: any = date.getMinutes(); @@ -150,21 +158,22 @@ export class GoTimeComponent implements OnInit { this.minute = Number(this.minute) - 1; } } - twoDigitOnly(event): void { - const value: any = event.target.value; - if (value.length <= 2) { - const hour: any = value.replace(/[^0-9]+/g, ''); - (document.getElementById('hour') as HTMLInputElement).value = ''; - (document.getElementById('hour') as HTMLInputElement).value = hour; - } else if (value.length === 3) { - this.hour = value.substring(0, value.length - 1); - } - } + // twoDigitOnly(event): void { + // const value: any = event.target.value; + // if (value.length <= 2) { + // const hour: any = value.replace(/[^0-9]+/g, ''); + // (document.getElementById('hour') as HTMLInputElement).value = ''; + // (document.getElementById('hour') as HTMLInputElement).value = hour; + // } else if (value.length === 3) { + // this.hour = value.substring(0, value.length - 1); + // } + // } twoDigitNumber(e) { e = e || window.event; const charCode = typeof e.which === 'number' ? e.which : e.keyCode; if (e.target.value.length >= 2) { - return false; + e.target.value = ''; + // return false; } // Allow non-printable keys if (!charCode || charCode === 8 /* Backspace */) { 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 6f037c3d9..a4a5376c0 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 @@ -19,6 +19,7 @@ [(ngModel)]="selectedTime" (blur)="validateTime()" [disabled]="control.disabled" + (click)="toggleTimepicker($event)" readonly /> Date: Thu, 10 Dec 2020 20:36:25 +0530 Subject: [PATCH 06/21] clean few code --- .../lib/components/go-timepicker/go-time.component.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts index f41d81e95..5c611d4ba 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts @@ -158,16 +158,7 @@ export class GoTimeComponent implements OnInit { this.minute = Number(this.minute) - 1; } } - // twoDigitOnly(event): void { - // const value: any = event.target.value; - // if (value.length <= 2) { - // const hour: any = value.replace(/[^0-9]+/g, ''); - // (document.getElementById('hour') as HTMLInputElement).value = ''; - // (document.getElementById('hour') as HTMLInputElement).value = hour; - // } else if (value.length === 3) { - // this.hour = value.substring(0, value.length - 1); - // } - // } + twoDigitNumber(e) { e = e || window.event; const charCode = typeof e.which === 'number' ? e.which : e.keyCode; From 6c17f4c1ca7c2d700a12026f4d9b170c9186308f Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Mon, 14 Dec 2020 00:25:54 +0530 Subject: [PATCH 07/21] clean code and remove unwanted css --- .../go-timepicker/go-time.component.html | 76 +++++++-- .../go-timepicker/go-time.component.scss | 87 ++++------ .../go-timepicker/go-time.component.ts | 155 +++++++++--------- .../go-timepicker.component.html | 2 +- .../go-timepicker.component.scss | 4 + .../go-timepicker/go-timepicker.component.ts | 28 ++-- .../go-timepicker/go-timepicker.module.ts | 5 +- projects/go-lib/src/public_api.ts | 3 - .../timepicker-docs.component.html | 4 +- .../timepicker-docs.component.ts | 4 +- 10 files changed, 201 insertions(+), 167 deletions(-) diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html index 931717dec..c1da878dd 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html @@ -9,7 +9,7 @@ *ngIf="opened" > -
    + -
    + -
    + + + +
    + + + +
    + +
    + : +
    + +
    + + + +
    + +
    + + {{ format ? 'AM' : 'PM' }} + +
    +
    • - +
    • -
    diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss index 1f986114e..4d18052dd 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss @@ -8,7 +8,6 @@ position: absolute; z-index: z-index(toaster); padding: 0px 5px 0px 5px; - width: 179px; } .go-time--above { @@ -26,23 +25,7 @@ .go-time--wrapper { display: flex; } -.hour-minute-input { - width: 36px; - height: 35px; - border: 1px solid lightgray; - border-radius: 4px; - outline: none; - background: transparent; - padding: 0.5rem; - font-family: 'Roboto', 'Lato', 'Helvetica', 'Arial', sans-serif; - font-size: 0.875rem; - text-align: center; -} -.go-up-arrow { - float: left; - width: 50%; -} .go-time-column { float: left; } @@ -50,53 +33,28 @@ max-width: 16%; padding: 0px 32px 0px 20px; } + .colon-content { - max-width: 9%; - padding: 9px 13px; + margin: 37px 8px 1px 8px; } + .minute-content { padding: 0px 0px; max-width: 15%; } + .padding-left-23 { padding-left: 23px; } + .padding-left-42 { padding-left: 42px; } + input::placeholder { - font-size: 10.8px; -} -input::-webkit-outer-spin-button, -input::-webkit-inner-spin-button { - /* display: none; <- Crashes Chrome on hover */ - -webkit-appearance: none; - margin: 0; /* <-- Apparently some margin are still there even though it's hidden */ + font-size: .625rem; } -input[type='number'] { - -moz-appearance: textfield; /* Firefox */ -} -.action-button { - padding: 3px 3px; - font-size: 12px; - border-radius: 4px; - transition-duration: 0.25s; - transition-property: all; - transition-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1); - align-items: center; - border: 0; - cursor: pointer; - display: inline-flex; - font-family: Roboto, Lato, Helvetica, Arial, sans-serif; - font-weight: 500; - letter-spacing: 0.015rem; - line-height: 1.2; - outline: 0; - position: relative; - text-decoration: none; - text-transform: uppercase; -} .clear-btn { background: #fff; color: #313536; @@ -118,6 +76,7 @@ input[type='number'] { border: 1px solid $theme-light-bg-active; } } + .apply-btn { color: #fff; background: #00838f; @@ -135,21 +94,43 @@ input[type='number'] { box-shadow: $form-shadow-active; } } + .go-time-action { float: right; padding-bottom: 4px; + clear: both; } + .go-form__input--error { border-color: $ui-color-negative; } + .apply-button-margin { margin-right: 3px; } + .time-format { font-weight: 500; } -.go-time-column{ - flex-basis: 25%; - width: 25%; - max-width: 13%; + +.go-time-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: center; +} + +.hour-minute-input { + width: 2.25rem; + text-align: center; +} + +.go-time-format{ + margin: 27px 0px 0px 18px; +} + +:host ::ng-deep .go-time-button { + .go-button { + padding: .25rem; + } } diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts index 5c611d4ba..331bb23bf 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts @@ -1,10 +1,13 @@ import { + AfterViewInit, Component, + ElementRef, EventEmitter, HostListener, Input, OnInit, Output, + ViewChild } from '@angular/core'; import { fadeAnimation } from '../../animations/fade.animation'; @@ -15,13 +18,14 @@ import { GoTime } from './go-time'; templateUrl: './go-time.component.html', animations: [fadeAnimation], }) -export class GoTimeComponent implements OnInit { +export class GoTimeComponent implements OnInit, AfterViewInit { + @Input() appendToContent: boolean; @Input() goTime: GoTime; @Input() displayAbove: boolean; @Input() displayFromRight: boolean; - @Output() timePicked: any = new EventEmitter(); + inputHourError: boolean = false; inputMinuteError: boolean = false; format: boolean = true; @@ -30,8 +34,10 @@ export class GoTimeComponent implements OnInit { clickActionButton: boolean = false; timeFormat: any = { hours: '', minutes: '', ampm: '' }; subscription: any; - hour: any; - minute: any; + hour: string; + minute: string; + + @ViewChild('hourInput', { static: false }) hourInput: ElementRef; constructor() {} @@ -59,36 +65,32 @@ export class GoTimeComponent implements OnInit { this.closeTimePicker(); this.resetTimeInput(); break; + case 'Enter': + this.apply(); + break; default: return; } } + public closeTimePicker(): void { this.goTime.closeTime(); } + ngOnInit(): void { - this.subscription = this.goTime.timeWindowOpen.subscribe( - (value: boolean) => { - if (value) { - if (this.goTime.selectedTime) { - this.changeTimeFormat(this.goTime.selectedTime); - } else { - this.timeFormat = this.formatAMPM(new Date()); - this.hour = this.timeFormat.hours; - this.minute = this.timeFormat.minutes; - this.format = this.timeFormat.ampm === 'am' ? true : false; - } - this.autoFocousInput(); - } - this.opened = value; - } - ); + if (this.goTime.selectedTime) { + this.changeTimeFormat(this.goTime.selectedTime); + } else { + this.timeFormat = this.formatAMPM(new Date()); + this.hour = this.timeFormat.hours; + this.minute = this.timeFormat.minutes; + this.format = this.timeFormat.ampm === 'am' ? true : false; + } + this.opened = true; } - autoFocousInput(): void { - setTimeout(() => { - document.getElementById('hour-input').focus(); - }); + ngAfterViewInit(): void { + this.hourInput.nativeElement.focus(); } formatAMPM(date: any): void { @@ -97,103 +99,89 @@ export class GoTimeComponent implements OnInit { const ampm: any = hours >= 12 ? 'pm' : 'am'; hours = hours % 12; hours = hours ? hours : 12; // the hour '0' should be '12' - hours = hours > 9 ? hours : '0' + hours; - minutes = minutes > 9 ? minutes : '0' + minutes; + hours = this.addZeroIfNeeded(hours); + minutes = this.addZeroIfNeeded(minutes); const formatTime: any = { hours, minutes, ampm }; return formatTime; } - changeTimeFormat(timeString: any): void { - const H: any = +timeString.substr(0, 2); + + changeTimeFormat(timeString: string): void { + const H: number = +timeString.substr(0, 2); const h: any = H % 12 || 12; - const ampm: any = H < 12 || H === 24 ? 'AM' : 'PM'; + const ampm: string = H < 12 || H === 24 ? 'AM' : 'PM'; const minute: any = timeString.substr(3, 2); this.hour = h > 9 ? h : '0' + h; - this.minute = (minute > 9 || minute === '00' || minute.length === 2) ? minute : '0' + minute; + this.minute = this.addZeroIfNeeded(minute); this.format = ampm === 'AM' ? true : false; } + changeFormat(): void { this.format = !this.format; } + increaseHour(): void { - if (this.hour >= 12) { - this.hour = '00'; + if (Number(this.hour) >= 12) { + this.hour = '01'; return; } - if (Number(this.hour) < 9) { - this.hour = '0' + (Number(this.hour) + 1); - } else { - this.hour = Number(this.hour) + 1; - } + this.hour = (Number(this.hour) + 1).toString(); + this.hour = this.addZeroIfNeeded(this.hour); } + increaseMinute(): void { - if (this.minute >= 59) { + if (Number(this.minute) >= 59) { this.minute = '00'; return; } - if (Number(this.minute) < 9) { - this.minute = '0' + (Number(this.minute) + 1); - } else { - this.minute = Number(this.minute) + 1; - } + this.minute = (Number(this.minute) + 1).toString(); + this.minute = this.addZeroIfNeeded(this.minute); } + decreaseHour(): void { - if (this.hour === '00') { - this.hour = '00'; + if (this.hour === '01') { + this.hour = '01'; return; } - if (Number(this.hour) <= 10) { - this.hour = '0' + (Number(this.hour) - 1); - } else { - this.hour = Number(this.hour) - 1; - } + this.hour = (Number(this.hour) - 1).toString(); + this.hour = this.addZeroIfNeeded(this.hour); } + decreaseMinute(): void { if (this.minute === '00') { this.minute = '00'; return; } - if (Number(this.minute) <= 10) { - this.minute = '0' + (Number(this.minute) - 1); - } else { - this.minute = Number(this.minute) - 1; - } + this.minute = (Number(this.minute) - 1).toString(); + this.minute = this.addZeroIfNeeded(this.minute); } - twoDigitNumber(e) { - e = e || window.event; - const charCode = typeof e.which === 'number' ? e.which : e.keyCode; - if (e.target.value.length >= 2) { - e.target.value = ''; - // return false; - } - // Allow non-printable keys - if (!charCode || charCode === 8 /* Backspace */) { - return; + addZeroIfNeeded(value: string): string { + if (Number(value) < 10) { + value = '0' + Number(value); } + return value; + } - const typedChar = String.fromCharCode(charCode); - - // Allow numeric characters - if (/\d/.test(typedChar)) { - return; - } + validateInput(event: KeyboardEvent, regex: string): boolean { + const input: HTMLInputElement = (event.target as HTMLInputElement); - // Allow the minus sign (-) if the user enters it first - if (typedChar === '-' && this.hour === '') { - return; + if (/\d/.test(event.key)) { + const newString: string = input.value.slice(0, input.selectionStart) + input.value.slice(input.selectionEnd); + if (new RegExp(regex).test(newString + event.key)) { + return; + } } - // In all other cases, suppress the event return false; } + clear(): void { - this.clickActionButton = true; - this.resetTimeInput(); this.closeTimePicker(); this.timePicked.emit(); } + apply(): void { - if (this.hour > 12 || this.minute > 59) { + if (Number(this.hour) > 12 || Number(this.minute) > 59) { this.inputTimeError(); return; } else { @@ -206,8 +194,8 @@ export class GoTimeComponent implements OnInit { if (!this.minute) { this.minute = '00'; } - this.hour = (this.minute.toString()).length > 1 ? this.hour : '0' + this.hour; - this.minute = (this.minute.toString()).length > 1 ? this.minute : '0' + this.minute; + this.hour = this.addZeroIfNeeded(this.hour); + this.minute = this.addZeroIfNeeded(this.minute); this.timeFormat = { hours: this.hour, minutes: this.minute, @@ -216,15 +204,18 @@ export class GoTimeComponent implements OnInit { this.timePicked.emit(this.timeFormat); this.closeTimePicker(); } + inputTimeError(): void { - if (this.hour > 12) { + if (Number(this.hour) > 12) { this.inputHourError = true; - } else if (this.minute > 59) { + } else if (Number(this.minute) > 59) { this.inputMinuteError = true; } } + resetTimeInput(): void { this.inputHourError = false; this.inputMinuteError = false; } + } 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 a4a5376c0..ae231eb3d 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 @@ -17,7 +17,6 @@ 'go-form__input--dark': theme == 'dark' }" [(ngModel)]="selectedTime" - (blur)="validateTime()" [disabled]="control.disabled" (click)="toggleTimepicker($event)" readonly @@ -29,6 +28,7 @@ (click)="toggleTimepicker($event)" > 9 ? h : '0' + h; - const ampm = H < 12 || H === 24 ? 'AM' : 'PM'; + const H: number = +timeString.substr(0, 2); + const h: any = H % 12 || 12; + const hour: any = h > 9 ? h : '0' + h; + const ampm: string = H < 12 || H === 24 ? 'AM' : 'PM'; timeString = hour + timeString.substr(2, 3) + ' ' + ampm; return timeString; } - public validateTime(): void {} public toggleTimepicker(event: Event): void { event.stopPropagation(); // Have to disable this here because of the event that we need to stop propagation on. @@ -64,20 +66,22 @@ export class GoTimepickerComponent implements OnInit { this.goTime.openTime(openTimeValue); } } - public timePicked(event) { + + public timePicked(event: any): void { if (event) { const selctedTime: string = event.hours + ':' + event.minutes + ' ' + event.ampm; - this.control.setValue(selctedTime); + this.control.setValue(this.convertTo24Hour(selctedTime)); this.selectedTime = selctedTime; } else { this.selectedTime = ''; } } - convertTo24Hour(time12h) { - if (time12h){ - const [time, modifier] = time12h.split(' '); - let [hours, minutes] = time.split(':'); + convertTo24Hour(time12h: string): string { + if (time12h) { + const [time, modifier]: string[] = time12h.split(' '); + + let [hours, minutes]: any[] = time.split(':'); if (hours === '12') { hours = '00'; } diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.module.ts b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.module.ts index c764f0588..fb3b97888 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.module.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.module.ts @@ -11,7 +11,10 @@ import { GoIconModule } from '../go-icon/go-icon.module'; import { GoHintModule } from '../go-hint/go-hint.module'; @NgModule({ - declarations: [GoTimepickerComponent, GoTimeComponent], + declarations: [ + GoTimepickerComponent, + GoTimeComponent + ], imports: [ CommonModule, FormsModule, diff --git a/projects/go-lib/src/public_api.ts b/projects/go-lib/src/public_api.ts index 5210b68f2..e74a98e26 100644 --- a/projects/go-lib/src/public_api.ts +++ b/projects/go-lib/src/public_api.ts @@ -165,9 +165,6 @@ export * from './lib/components/go-tree/go-tree.module'; export * from './lib/components/go-tree/go-tree-node-config.model'; // Timepicker -// export * from './lib/components/go-datepicker/calendar-cell.model'; -// export * from './lib/components/go-datepicker/go-datepicker.component'; -// export * from './lib/components/go-datepicker/go-datepicker.module'; export * from './lib/components/go-timepicker/go-time.component'; export * from './lib/components/go-timepicker/go-timepicker.module'; /***** Utils *****/ diff --git a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.html b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.html index cd5a57e06..61a7bb661 100644 --- a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.html +++ b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.html @@ -13,8 +13,8 @@

    Component Control

    As with most of the form components, the only @Input required of the timepicker component is a FormControl. The FormControl can be passed in via the [control] - attribute on the <go-timepicker> component. A date can be initialized into the timepicker - by setting a time on the control. It can be initialized by either a string or a time object. + attribute on the <go-timepicker> component. A time can be initialized into the timepicker + by setting a time on the control. It can be initialized by either a string or a date object. If using a string it can be entered as format (hh:mm:ss)

    diff --git a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.ts b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.ts index 1e30fbba9..593e67630 100644 --- a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.ts +++ b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/timepicker-docs/timepicker-docs.component.ts @@ -59,7 +59,7 @@ export class TimepickerDocsComponent implements OnInit { basicErrorsTemplate: string = ` this.time.setErrors([ { - message: 'This date is invalid' + message: 'This time is invalid' }, { type: 'Required', @@ -94,7 +94,7 @@ export class TimepickerDocsComponent implements OnInit { constructor(private subNavService: SubNavService) { this.subNavService.pageTitle = 'Timepicker'; - this.subNavService.linkToSource = 'https://github.com/mobi/goponents/tree/dev/projects/go-lib/src/lib/components/go-timepicker'; + this.subNavService.linkToSource = ''; } ngOnInit(): void { setTimeout((): void => { From a31ed41453c0f0239f4e76c7b6141a70d15a2d72 Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Mon, 14 Dec 2020 00:30:22 +0530 Subject: [PATCH 08/21] clean html code --- .../go-timepicker/go-time.component.html | 82 +------------------ 1 file changed, 1 insertion(+), 81 deletions(-) diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html index c1da878dd..4eafdf42b 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html @@ -8,79 +8,7 @@ }" *ngIf="opened" > - - - - - - - - -
    +
    :
    -
    {{ format ? 'AM' : 'PM' }}
    -
    • - Clear
    • - Apply From a702e7963f49125f7cb47cef5dbd148ce2abe0d6 Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Thu, 17 Dec 2020 16:48:54 +0530 Subject: [PATCH 09/21] clean code and resolve UI issues --- .../go-timepicker/go-time-format.model.ts | 5 + .../go-timepicker/go-time.component.html | 29 +++--- .../go-timepicker/go-time.component.scss | 96 +++---------------- .../go-timepicker/go-time.component.ts | 64 ++++++------- .../lib/components/go-timepicker/go-time.ts | 30 ------ .../go-timepicker.component.html | 7 +- .../go-timepicker.component.scss | 2 +- .../go-timepicker/go-timepicker.component.ts | 54 +++++------ 8 files changed, 94 insertions(+), 193 deletions(-) create mode 100644 projects/go-lib/src/lib/components/go-timepicker/go-time-format.model.ts delete mode 100644 projects/go-lib/src/lib/components/go-timepicker/go-time.ts diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time-format.model.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time-format.model.ts new file mode 100644 index 000000000..842a3f083 --- /dev/null +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time-format.model.ts @@ -0,0 +1,5 @@ +export interface GoTimeFormat { + hours: string; + minutes: string; + ampm: string; + } diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html index 4eafdf42b..b5e8b8b2c 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.html @@ -6,7 +6,6 @@ 'go-time--right': displayFromRight, 'go-time--append-to-content': appendToContent }" - *ngIf="opened" >
      - {{ format ? 'AM' : 'PM' }} + {{ format ? 'AM' : 'PM' }}
      -
        -
      • - - Clear - -
      • -
      • - - Apply - -
      • -
      +
      +
        +
      • + + Clear + +
      • +
      • + + Apply + +
      • +
      +
    diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss index 4d18052dd..7ec63638e 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.scss @@ -1,5 +1,5 @@ -@import '../../../styles/variables'; -@import '../../../styles/mixins'; +@import "../../../styles/variables"; +@import "../../../styles/mixins"; .go-time { background: $theme-light-bg; @@ -7,7 +7,7 @@ border-radius: $global-radius; position: absolute; z-index: z-index(toaster); - padding: 0px 5px 0px 5px; + padding: 0 $column-gutter--half $column-gutter--half $column-gutter--half; } .go-time--above { @@ -26,91 +26,17 @@ display: flex; } -.go-time-column { - float: left; -} -.hour-content { - max-width: 16%; - padding: 0px 32px 0px 20px; -} - .colon-content { - margin: 37px 8px 1px 8px; -} - -.minute-content { - padding: 0px 0px; - max-width: 15%; + margin-top: 1.8rem; + padding: $column-gutter--half; } -.padding-left-23 { - padding-left: 23px; -} - -.padding-left-42 { - padding-left: 42px; -} - -input::placeholder { - font-size: .625rem; -} - -.clear-btn { - background: #fff; - color: #313536; - border: 1px solid #cbcbcb; - &:hover, - &:focus { - background: $theme-light-bg-hover; - border: 1px solid $theme-light-bg-hover; - } - &:hover, - &:focus, - &:active { - border: 1px solid lighten($base-light-secondary, 10%); - box-shadow: 0 0 0 3px transparentize($base-light-tertiary, 0.75); - } - - &:active { - background: $theme-light-bg-active; - border: 1px solid $theme-light-bg-active; - } -} - -.apply-btn { - color: #fff; - background: #00838f; - border: 1px solid #00838f; - &:hover, - &:focus { - background: $ui-color-primary-hover; - border: 1px solid $ui-color-primary-hover; - box-shadow: $form-shadow-active; - } - - &:active { - background: $ui-color-primary-active; - border: 1px solid $ui-color-primary-active; - box-shadow: $form-shadow-active; - } +.hour-minute-input::placeholder { + font-size: 0.625rem; } .go-time-action { float: right; - padding-bottom: 4px; - clear: both; -} - -.go-form__input--error { - border-color: $ui-color-negative; -} - -.apply-button-margin { - margin-right: 3px; -} - -.time-format { - font-weight: 500; } .go-time-column { @@ -118,6 +44,7 @@ input::placeholder { display: flex; flex-direction: column; justify-content: center; + float: left; } .hour-minute-input { @@ -125,12 +52,13 @@ input::placeholder { text-align: center; } -.go-time-format{ - margin: 27px 0px 0px 18px; +.go-time-format { + margin-top: 1.8rem; + padding-left: $column-gutter--half; } :host ::ng-deep .go-time-button { .go-button { - padding: .25rem; + padding: 0.25rem; } } diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts index 331bb23bf..e794d8db9 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts @@ -10,8 +10,8 @@ import { ViewChild } from '@angular/core'; import { fadeAnimation } from '../../animations/fade.animation'; +import { GoTimeFormat } from './go-time-format.model'; -import { GoTime } from './go-time'; @Component({ selector: 'go-time', styleUrls: ['./go-time.component.scss'], @@ -21,41 +21,36 @@ import { GoTime } from './go-time'; export class GoTimeComponent implements OnInit, AfterViewInit { @Input() appendToContent: boolean; - @Input() goTime: GoTime; + @Input() selectedTime: string; @Input() displayAbove: boolean; @Input() displayFromRight: boolean; - @Output() timePicked: any = new EventEmitter(); + @Output() timePicked = new EventEmitter(); + @Output() closeTime = new EventEmitter(); inputHourError: boolean = false; inputMinuteError: boolean = false; format: boolean = true; - opened: boolean = false; clickInside: boolean = false; - clickActionButton: boolean = false; - timeFormat: any = { hours: '', minutes: '', ampm: '' }; - subscription: any; + goTimeFormat: GoTimeFormat; hour: string; minute: string; @ViewChild('hourInput', { static: false }) hourInput: ElementRef; - constructor() {} - @HostListener('click') ClickInside(): void { - this.clickInside = this.clickActionButton ? false : true; - this.opened = true; + this.clickInside = true; } @HostListener('document: click') onDocumentClick(): void { - if (this.opened && !this.clickInside) { + if (!this.clickInside) { this.closeTimePicker(); this.resetTimeInput(); } this.clickInside = false; - this.clickActionButton = false; } + @HostListener('window:keydown', ['$event']) keyEvent(event: KeyboardEvent): void { switch (event.key) { @@ -74,43 +69,46 @@ export class GoTimeComponent implements OnInit, AfterViewInit { } public closeTimePicker(): void { - this.goTime.closeTime(); + this.closeTime.emit(); } ngOnInit(): void { - if (this.goTime.selectedTime) { - this.changeTimeFormat(this.goTime.selectedTime); + if (this.selectedTime) { + this.changeTimeFormat(this.selectedTime); } else { - this.timeFormat = this.formatAMPM(new Date()); - this.hour = this.timeFormat.hours; - this.minute = this.timeFormat.minutes; - this.format = this.timeFormat.ampm === 'am' ? true : false; + this.goTimeFormat = this.formatAMPM(new Date()); + this.hour = this.goTimeFormat.hours; + this.minute = this.goTimeFormat.minutes; + this.format = this.goTimeFormat.ampm === 'am' ? true : false; } - this.opened = true; } ngAfterViewInit(): void { this.hourInput.nativeElement.focus(); } - formatAMPM(date: any): void { + formatAMPM(date: Date) { let hours: any = date.getHours(); let minutes: any = date.getMinutes(); - const ampm: any = hours >= 12 ? 'pm' : 'am'; + const ampm: string = hours >= 12 ? 'pm' : 'am'; hours = hours % 12; hours = hours ? hours : 12; // the hour '0' should be '12' hours = this.addZeroIfNeeded(hours); minutes = this.addZeroIfNeeded(minutes); - const formatTime: any = { hours, minutes, ampm }; - return formatTime; + this.goTimeFormat = { + hours, + minutes, + ampm + }; + return this.goTimeFormat; } changeTimeFormat(timeString: string): void { const H: number = +timeString.substr(0, 2); const h: any = H % 12 || 12; const ampm: string = H < 12 || H === 24 ? 'AM' : 'PM'; - const minute: any = timeString.substr(3, 2); - this.hour = h > 9 ? h : '0' + h; + const minute: string = timeString.substr(3, 2); + this.hour = this.addZeroIfNeeded(h); // h > 9 ? h : '0' + h; this.minute = this.addZeroIfNeeded(minute); this.format = ampm === 'AM' ? true : false; } @@ -139,7 +137,7 @@ export class GoTimeComponent implements OnInit, AfterViewInit { decreaseHour(): void { if (this.hour === '01') { - this.hour = '01'; + this.hour = '12'; return; } this.hour = (Number(this.hour) - 1).toString(); @@ -148,7 +146,7 @@ export class GoTimeComponent implements OnInit, AfterViewInit { decreaseMinute(): void { if (this.minute === '00') { - this.minute = '00'; + this.minute = '59'; return; } this.minute = (Number(this.minute) - 1).toString(); @@ -157,7 +155,7 @@ export class GoTimeComponent implements OnInit, AfterViewInit { addZeroIfNeeded(value: string): string { if (Number(value) < 10) { - value = '0' + Number(value); + value = '0' + +value; } return value; } @@ -171,7 +169,6 @@ export class GoTimeComponent implements OnInit, AfterViewInit { return; } } - // In all other cases, suppress the event return false; } @@ -187,7 +184,6 @@ export class GoTimeComponent implements OnInit, AfterViewInit { } else { this.resetTimeInput(); } - this.clickActionButton = true; if (!this.hour) { this.hour = '12'; } @@ -196,12 +192,12 @@ export class GoTimeComponent implements OnInit, AfterViewInit { } this.hour = this.addZeroIfNeeded(this.hour); this.minute = this.addZeroIfNeeded(this.minute); - this.timeFormat = { + this.goTimeFormat = { hours: this.hour, minutes: this.minute, ampm: this.format ? 'AM' : 'PM', }; - this.timePicked.emit(this.timeFormat); + this.timePicked.emit(this.goTimeFormat); this.closeTimePicker(); } diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time.ts deleted file mode 100644 index 1a587df50..000000000 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Subject } from 'rxjs'; - -export class GoTime { - private timeOpen: boolean = false; - timeWindowOpen: Subject = new Subject(); - - selectedTime: string; - - constructor() { - this.setTimeStatus(false); - } - - public openTime(time): void { - this.selectedTime = time; - this.setTimeStatus(true); - } - - public closeTime(): void { - this.setTimeStatus(false); - } - - get isOpen(): boolean { - return this.timeOpen; - } - - private setTimeStatus(isOpen: boolean = true): void { - this.timeOpen = isOpen; - this.timeWindowOpen.next(isOpen); - } -} 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 ae231eb3d..cfe267480 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 @@ -9,7 +9,7 @@
    diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.scss b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.scss index d909cca4b..3200b6be8 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.scss +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.scss @@ -8,6 +8,6 @@ top: 0.25rem; } -.go-form__input{ +.go-input-time{ cursor: pointer; } diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts index edd9131a5..c512c0a5d 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts @@ -1,16 +1,19 @@ import { Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import { FormControl } from '@angular/forms'; import { generateId } from '../../utilities/form.utils'; -import { GoTime } from './go-time'; + @Component({ selector: 'go-timepicker', styleUrls: ['./go-timepicker.component.scss'], templateUrl: './go-timepicker.component.html', }) + export class GoTimepickerComponent implements OnInit { displayAbove: boolean = false; displayFromRight: boolean = true; + timeOpen: boolean = false; id: string; + openTimeValue: string; @Input() key: string; @Input() label: string; @@ -20,16 +23,10 @@ export class GoTimepickerComponent implements OnInit { @Input() theme: string = 'light'; @Input() appendToContent: boolean = false; - goTime: GoTime; - selectedTime: string; @ViewChild('datepickerInput', { static: true }) datepickerInput: ElementRef; - constructor() { - this.goTime = new GoTime(); - } - ngOnInit(): void { this.id = this.key || generateId(this.label, 'timepicker'); this.selectedTime = this.changeTimeFormat(this.control.value); @@ -41,7 +38,7 @@ export class GoTimepickerComponent implements OnInit { } const H: number = +timeString.substr(0, 2); const h: any = H % 12 || 12; - const hour: any = h > 9 ? h : '0' + h; + const hour: string = h > 9 ? h : '0' + h; const ampm: string = H < 12 || H === 24 ? 'AM' : 'PM'; timeString = hour + timeString.substr(2, 3) + ' ' + ampm; return timeString; @@ -54,22 +51,21 @@ export class GoTimepickerComponent implements OnInit { return; } - if (this.goTime.isOpen) { - this.goTime.closeTime(); - } else { - const position: string = 'top'; - const distance: object = this.datepickerInput.nativeElement.getBoundingClientRect(); - this.displayAbove = + this.timeOpen = !this.timeOpen; + const position: string = 'top'; + const distance: object = this.datepickerInput.nativeElement.getBoundingClientRect(); + this.displayAbove = window.innerHeight - distance[position] < 350 && !this.appendToContent; - const convert24Hr: string = (/^\s*$/).test(this.selectedTime) ? undefined : this.convertTo24Hour(this.selectedTime); - const openTimeValue: string = convert24Hr ? convert24Hr : undefined; - this.goTime.openTime(openTimeValue); - } + const convert24Hr: string = /^\s*$/.test(this.selectedTime) + ? undefined + : this.convertTo24Hour(this.selectedTime); + this.openTimeValue = convert24Hr ? convert24Hr : undefined; } public timePicked(event: any): void { if (event) { - const selctedTime: string = event.hours + ':' + event.minutes + ' ' + event.ampm; + const selctedTime: string = + event.hours + ':' + event.minutes + ' ' + event.ampm; this.control.setValue(this.convertTo24Hour(selctedTime)); this.selectedTime = selctedTime; } else { @@ -77,18 +73,22 @@ export class GoTimepickerComponent implements OnInit { } } + closeTime(): void { + this.timeOpen = false; + } + convertTo24Hour(time12h: string): string { if (time12h) { const [time, modifier]: string[] = time12h.split(' '); - let [hours, minutes]: any[] = time.split(':'); - if (hours === '12') { - hours = '00'; - } - if (modifier === 'PM') { - hours = parseInt(hours, 10) + 12; - } - return `${hours}:${minutes}`; + let [hours, minutes]: any[] = time.split(':'); + if (hours === '12') { + hours = '00'; + } + if (modifier === 'PM') { + hours = parseInt(hours, 10) + 12; + } + return `${hours}:${minutes}`; } } } From 8ab84902c35374ef067f0806060a2cdc83e946bb Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Mon, 21 Dec 2020 16:50:09 +0530 Subject: [PATCH 10/21] update few code --- .../go-select/go-select.component.ts | 3 +- .../select-docs/select-docs.component.html | 8 +--- .../select-docs/select-docs.component.ts | 30 ++++++------- .../off-canvas-test.component.html | 43 +++++++++++++++---- 4 files changed, 50 insertions(+), 34 deletions(-) diff --git a/projects/go-lib/src/lib/components/go-select/go-select.component.ts b/projects/go-lib/src/lib/components/go-select/go-select.component.ts index 8911d10b0..db1d7a318 100644 --- a/projects/go-lib/src/lib/components/go-select/go-select.component.ts +++ b/projects/go-lib/src/lib/components/go-select/go-select.component.ts @@ -33,7 +33,7 @@ export class GoSelectComponent implements OnInit { @Input() typeahead?: Subject; @Input() typeToSearchText: string = 'Type to Search'; @Input() theme: 'light' | 'dark' = 'light'; - @Input() virtualScroll: any = false; + @Input() virtualScroll: boolean = false; @Output() scrollToEnd: EventEmitter = new EventEmitter(); @Output() scroll: EventEmitter<{ start: number, end: number }> = new EventEmitter<{ start: number; end: number }>(); @@ -43,7 +43,6 @@ export class GoSelectComponent implements OnInit { ngOnInit(): void { this.id = this.key || generateId(this.label, 'select'); - this.virtualScroll = Boolean(JSON.parse(this.virtualScroll)); } onSelectAll(): void { diff --git a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/select-docs/select-docs.component.html b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/select-docs/select-docs.component.html index 436e0bb41..a4675bab4 100644 --- a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/select-docs/select-docs.component.html +++ b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/select-docs/select-docs.component.html @@ -792,12 +792,6 @@

    Component Virtual scroll

    -

    Sometimes the data that needs to be rendered for the options of the select would cause performance and user experience issues. In this case, virtual scroll should be implemented. @@ -834,7 +828,7 @@

    View

    label="Select an Option" (scrollToEnd)="scrollToEnd()" (scroll)="scroll($event)" - virtualScroll=true> + [virtualScroll]="true">
    diff --git a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/select-docs/select-docs.component.ts b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/select-docs/select-docs.component.ts index d651da08a..8f4ea587e 100644 --- a/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/select-docs/select-docs.component.ts +++ b/projects/go-style-guide/src/app/features/ui-kit/components/form-docs/components/select-docs/select-docs.component.ts @@ -457,22 +457,20 @@ export class SelectDocsComponent implements OnInit { } ] `; + select19Code: string = ` - - - `; + + + `; select19ComponentCode: string = ` scrollToEnd(): void { @@ -482,7 +480,7 @@ export class SelectDocsComponent implements OnInit { scroll($event: { start: number; end: number }): void { // Code here } -`; + `; constructor( private goModalService: GoModalService, private subNavService: SubNavService diff --git a/projects/go-tester/src/app/components/off-canvas-test/off-canvas-test.component.html b/projects/go-tester/src/app/components/off-canvas-test/off-canvas-test.component.html index 2e62e8636..f15c63979 100644 --- a/projects/go-tester/src/app/components/off-canvas-test/off-canvas-test.component.html +++ b/projects/go-tester/src/app/components/off-canvas-test/off-canvas-test.component.html @@ -1,7 +1,7 @@
    - +
    - - + +
    - - + +
    - +
    - +
    @@ -48,7 +72,8 @@ bindValue="value" bindLabel="name" placeholder="Select Box Placeholder" - label="Select Box Here"> + label="Select Box Here" + >
    From 1443bde16d116e617d83f9d60a87d2fa1d08b7d9 Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Fri, 8 Jan 2021 22:43:08 +0530 Subject: [PATCH 11/21] reslove the type issues --- .../src/lib/components/go-timepicker/go-time.component.ts | 8 ++++---- .../components/go-timepicker/go-timepicker.component.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts index e794d8db9..2f119c737 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts @@ -88,13 +88,13 @@ export class GoTimeComponent implements OnInit, AfterViewInit { } formatAMPM(date: Date) { - let hours: any = date.getHours(); - let minutes: any = date.getMinutes(); + let hours: number | string = date.getHours(); + let minutes: number | string = date.getMinutes(); const ampm: string = hours >= 12 ? 'pm' : 'am'; hours = hours % 12; hours = hours ? hours : 12; // the hour '0' should be '12' - hours = this.addZeroIfNeeded(hours); - minutes = this.addZeroIfNeeded(minutes); + hours = this.addZeroIfNeeded(hours.toString()); + minutes = this.addZeroIfNeeded(minutes.toString()); this.goTimeFormat = { hours, minutes, diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts index c512c0a5d..22187b313 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts @@ -37,8 +37,8 @@ export class GoTimepickerComponent implements OnInit { return; } const H: number = +timeString.substr(0, 2); - const h: any = H % 12 || 12; - const hour: string = h > 9 ? h : '0' + h; + const h: number | string = H % 12 || 12; + const hour: number | string = h > 9 ? h : '0' + h; const ampm: string = H < 12 || H === 24 ? 'AM' : 'PM'; timeString = hour + timeString.substr(2, 3) + ' ' + ampm; return timeString; From 56ed5768914eca8ab95ac1284c2e07bc621150c8 Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Tue, 12 Jan 2021 17:04:34 +0530 Subject: [PATCH 12/21] Write some code for unit testing --- debug.log | 6 ++ .../go-timepicker.component.ts.spec.ts | 76 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 debug.log create mode 100644 projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts.spec.ts diff --git a/debug.log b/debug.log new file mode 100644 index 000000000..df0ecc9a1 --- /dev/null +++ b/debug.log @@ -0,0 +1,6 @@ +[0108/231730.052:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) +[0111/151430.229:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) +[0111/173350.995:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) +[0111/202505.530:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) +[0112/115100.062:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) +[0112/150608.041:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 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 new file mode 100644 index 000000000..8c1df5f78 --- /dev/null +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts.spec.ts @@ -0,0 +1,76 @@ +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'; + +describe('GoTimepickerComponent', () => { + let component: GoTimepickerComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [GoTimeComponent, GoTimepickerComponent], + imports: [ + GoIconButtonModule, + GoButtonModule, + GoHintModule, + FormsModule, + GoHintModule, + GoRequiredTextModule, + ReactiveFormsModule, + ], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(GoTimepickerComponent); + component = fixture.componentInstance; + component.control = new FormControl(''); + }); + + it('should create', () => { + fixture.detectChanges(); + expect(component).toBeTruthy(); + }); + + describe('onInit', () => { + afterEach(() => { + component.selectedTime = null; + }); + + it('set the time', () => { + const time: string = '10:20 AM'; + const goTimeFormat: GoTimeFormat = { + hours: '10', + minutes: '20', + ampm: 'AM', + }; + fixture.detectChanges(); + component.timePicked(goTimeFormat); + + expect(component.selectedTime).toEqual(time); + }); + + it('clear selected time', () => { + const time: string = ''; + fixture.detectChanges(); + component.timePicked(null); + + expect(component.selectedTime).toEqual(time); + }); + + it('change the time format 24hr to 12hr', () => { + const time: string = '06:15 PM'; + const timeString: string = '18:15:00'; + fixture.detectChanges(); + + expect(component.changeTimeFormat(timeString)).toBe(time); + }); + }); +}); From 7ab11f9d7bb4d7930e33929716a0ff14b7185124 Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Tue, 12 Jan 2021 17:14:08 +0530 Subject: [PATCH 13/21] remove debug.log file --- debug.log | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 debug.log diff --git a/debug.log b/debug.log deleted file mode 100644 index df0ecc9a1..000000000 --- a/debug.log +++ /dev/null @@ -1,6 +0,0 @@ -[0108/231730.052:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) -[0111/151430.229:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) -[0111/173350.995:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) -[0111/202505.530:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) -[0112/115100.062:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) -[0112/150608.041:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) From 514e6be50c654ca9094f33696ab99378fd322210 Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Tue, 12 Jan 2021 17:24:40 +0530 Subject: [PATCH 14/21] uncomment few code --- .../components/off-canvas-test/off-canvas-test.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/go-tester/src/app/components/off-canvas-test/off-canvas-test.component.html b/projects/go-tester/src/app/components/off-canvas-test/off-canvas-test.component.html index f15c63979..0288eccf0 100644 --- a/projects/go-tester/src/app/components/off-canvas-test/off-canvas-test.component.html +++ b/projects/go-tester/src/app/components/off-canvas-test/off-canvas-test.component.html @@ -1,7 +1,7 @@
    - + Date: Mon, 18 Jan 2021 20:34:24 +0530 Subject: [PATCH 15/21] write test cases --- debug.log | 6 ++ .../go-timepicker/go-time.component.ts | 10 +-- .../go-timepicker/go-timepicker.component.ts | 27 +++++--- .../go-timepicker.component.ts.spec.ts | 68 ++++++++++++++++--- 4 files changed, 87 insertions(+), 24 deletions(-) create mode 100644 debug.log diff --git a/debug.log b/debug.log new file mode 100644 index 000000000..1602b32b7 --- /dev/null +++ b/debug.log @@ -0,0 +1,6 @@ +[0112/172211.719:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) +[0118/131000.329:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) +[0118/153205.511:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) +[0118/161058.568:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) +[0118/182111.929:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) +[0118/190608.387:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts index 2f119c737..fb491c741 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts @@ -24,7 +24,7 @@ export class GoTimeComponent implements OnInit, AfterViewInit { @Input() selectedTime: string; @Input() displayAbove: boolean; @Input() displayFromRight: boolean; - @Output() timePicked = new EventEmitter(); + @Output() timePicked: EventEmitter = new EventEmitter(); @Output() closeTime = new EventEmitter(); inputHourError: boolean = false; @@ -60,9 +60,9 @@ export class GoTimeComponent implements OnInit, AfterViewInit { this.closeTimePicker(); this.resetTimeInput(); break; - case 'Enter': - this.apply(); - break; + case 'Enter': + this.apply(); + break; default: return; } @@ -108,7 +108,7 @@ export class GoTimeComponent implements OnInit, AfterViewInit { const h: any = H % 12 || 12; const ampm: string = H < 12 || H === 24 ? 'AM' : 'PM'; const minute: string = timeString.substr(3, 2); - this.hour = this.addZeroIfNeeded(h); // h > 9 ? h : '0' + h; + this.hour = this.addZeroIfNeeded(h); this.minute = this.addZeroIfNeeded(minute); this.format = ampm === 'AM' ? true : false; } diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts index 22187b313..3f9f66497 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts @@ -1,6 +1,7 @@ import { Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import { FormControl } from '@angular/forms'; import { generateId } from '../../utilities/form.utils'; +import { GoTimeFormat } from './go-time-format.model'; @Component({ selector: 'go-timepicker', @@ -23,7 +24,7 @@ export class GoTimepickerComponent implements OnInit { @Input() theme: string = 'light'; @Input() appendToContent: boolean = false; - selectedTime: string; + selectedTime: string = null; @ViewChild('datepickerInput', { static: true }) datepickerInput: ElementRef; @@ -32,13 +33,16 @@ export class GoTimepickerComponent implements OnInit { this.selectedTime = this.changeTimeFormat(this.control.value); } - public changeTimeFormat(timeString: string): string { - if (!timeString) { + public changeTimeFormat(timeString: string | Date): string { + if (!timeString || timeString == 'Invalid Date') { return; } + if (typeof(timeString) === 'object') { + timeString = `${this.addZeroIfNeeded(timeString.getHours())}:${this.addZeroIfNeeded(timeString.getMinutes())}:00`; + } const H: number = +timeString.substr(0, 2); const h: number | string = H % 12 || 12; - const hour: number | string = h > 9 ? h : '0' + h; + const hour: number | string = this.addZeroIfNeeded(h); const ampm: string = H < 12 || H === 24 ? 'AM' : 'PM'; timeString = hour + timeString.substr(2, 3) + ' ' + ampm; return timeString; @@ -62,22 +66,22 @@ export class GoTimepickerComponent implements OnInit { this.openTimeValue = convert24Hr ? convert24Hr : undefined; } - public timePicked(event: any): void { + public timePicked(event: GoTimeFormat): void { if (event) { const selctedTime: string = event.hours + ':' + event.minutes + ' ' + event.ampm; this.control.setValue(this.convertTo24Hour(selctedTime)); this.selectedTime = selctedTime; } else { - this.selectedTime = ''; + this.selectedTime = null; } } - closeTime(): void { + public closeTime(): void { this.timeOpen = false; } - convertTo24Hour(time12h: string): string { + private convertTo24Hour(time12h: string): string { if (time12h) { const [time, modifier]: string[] = time12h.split(' '); @@ -91,4 +95,11 @@ export class GoTimepickerComponent implements OnInit { return `${hours}:${minutes}`; } } + + addZeroIfNeeded(value: string | number): string | number { + if (Number(value) < 10) { + value = '0' + +value; + } + return value; + } } 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 8c1df5f78..d8431985c 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 @@ -35,42 +35,88 @@ describe('GoTimepickerComponent', () => { }); it('should create', () => { - fixture.detectChanges(); + component.ngOnInit(); expect(component).toBeTruthy(); }); - describe('onInit', () => { + describe('ngOnInit', () => { afterEach(() => { component.selectedTime = null; }); - it('set the time', () => { + 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'; + component.ngOnInit(); + + expect(component.selectedTime).toEqual(time); + }); + }); + + describe('timePicked', () => { + afterEach(() => { + component.selectedTime = null; + }); + + it('set the time with AM', () => { const time: string = '10:20 AM'; const goTimeFormat: GoTimeFormat = { hours: '10', minutes: '20', ampm: 'AM', }; - fixture.detectChanges(); + component.timePicked(goTimeFormat); + + expect(component.selectedTime).toEqual(time); + }); + + it('set the time with PM', () => { + const time: string = '10:20 PM'; + const goTimeFormat: GoTimeFormat = { + hours: '10', + minutes: '20', + ampm: 'PM', + }; component.timePicked(goTimeFormat); expect(component.selectedTime).toEqual(time); }); it('clear selected time', () => { - const time: string = ''; - fixture.detectChanges(); + const time: string = null; component.timePicked(null); expect(component.selectedTime).toEqual(time); }); + }); - it('change the time format 24hr to 12hr', () => { - const time: string = '06:15 PM'; - const timeString: string = '18:15:00'; - fixture.detectChanges(); + describe('toggleTimepicker', () => { + afterEach(() => { + component.selectedTime = null; + }); + + it('should not open timepicker if control is disabled', () => { + component.control.disable(); + + 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'; - expect(component.changeTimeFormat(timeString)).toBe(time); + component.toggleTimepicker(new Event('click')); + expect(component.openTimeValue).toBe(convertTime); }); }); }); From 9d109661376aabc146bf289a2966d40cfb79d629 Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Mon, 18 Jan 2021 23:26:50 +0530 Subject: [PATCH 16/21] Update code --- .../lib/components/go-timepicker/go-timepicker.component.ts | 5 +++-- .../go-timepicker/go-timepicker.component.ts.spec.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts index 3f9f66497..e14e16492 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-timepicker.component.ts @@ -24,7 +24,7 @@ export class GoTimepickerComponent implements OnInit { @Input() theme: string = 'light'; @Input() appendToContent: boolean = false; - selectedTime: string = null; + selectedTime: string = ''; @ViewChild('datepickerInput', { static: true }) datepickerInput: ElementRef; @@ -73,7 +73,8 @@ export class GoTimepickerComponent implements OnInit { this.control.setValue(this.convertTo24Hour(selctedTime)); this.selectedTime = selctedTime; } else { - this.selectedTime = null; + this.selectedTime = ''; + this.control.setValue(null); } } 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 d8431985c..1df3bebb4 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 @@ -91,7 +91,7 @@ describe('GoTimepickerComponent', () => { }); it('clear selected time', () => { - const time: string = null; + const time: string = ''; component.timePicked(null); expect(component.selectedTime).toEqual(time); From 92b7143172bb94f7e6c639194ad42457df688452 Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Tue, 19 Jan 2021 18:29:33 +0530 Subject: [PATCH 17/21] write some test cases for go-time.component --- debug.log | 6 -- .../go-timepicker/go-time.component.spec.ts | 74 +++++++++++++++++++ .../go-timepicker/go-time.component.ts | 4 +- .../go-timepicker.component.ts.spec.ts | 6 +- 4 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 projects/go-lib/src/lib/components/go-timepicker/go-time.component.spec.ts diff --git a/debug.log b/debug.log index 1602b32b7..e69de29bb 100644 --- a/debug.log +++ b/debug.log @@ -1,6 +0,0 @@ -[0112/172211.719:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) -[0118/131000.329:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) -[0118/153205.511:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) -[0118/161058.568:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) -[0118/182111.929:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) -[0118/190608.387:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.spec.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.spec.ts new file mode 100644 index 000000000..34d8e4d75 --- /dev/null +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.spec.ts @@ -0,0 +1,74 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { GoTimeComponent } from './go-time.component'; +import { FormsModule } from '@angular/forms'; +import { GoIconButtonModule } from '../go-icon-button/go-icon-button.module'; +import { GoButtonModule } from '../go-button/go-button.module'; +import { GoTimeFormat } from './go-time-format.model'; + +describe('GoTimeComponent', () => { + let component: GoTimeComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [GoTimeComponent], + imports: [GoIconButtonModule, GoButtonModule, FormsModule], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(GoTimeComponent); + component = fixture.componentInstance; + }); + + it('should create', () => { + component.ngOnInit(); + expect(component).toBeTruthy(); + }); + + describe('ngOnInit', () => { + afterEach(() => { + component.selectedTime = null; + }); + + it('check hour with time format', () => { + component.selectedTime = '18:15'; + const hour: string = '06'; + component.ngOnInit(); + + component.changeTimeFormat(component.selectedTime); + expect(component.hour).toBe(hour); + }); + + it('check minute with time format', () => { + component.selectedTime = '18:15'; + const minute: string = '15'; + component.ngOnInit(); + + component.changeTimeFormat(component.selectedTime); + expect(component.minute).toBe(minute); + }); + + it('check time with format for AM and PM button display', () => { + component.selectedTime = '18:15'; + const format: boolean = false; + component.ngOnInit(); + + component.changeTimeFormat(component.selectedTime); + expect(component.format).toBe(format); + }); + + it('check time format with no selected time', () => { + component.selectedTime = null; + const goTimeFormat: GoTimeFormat = { + hours: '05', + minutes: '15', + ampm: 'am', + }; + component.ngOnInit(); + + component.formatAMPM(new Date('2017-04-30 05:15:00')); + expect(component.goTimeFormat).toEqual(goTimeFormat); + }); + }); +}); diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts index fb491c741..7a5f58fa8 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts @@ -25,7 +25,7 @@ export class GoTimeComponent implements OnInit, AfterViewInit { @Input() displayAbove: boolean; @Input() displayFromRight: boolean; @Output() timePicked: EventEmitter = new EventEmitter(); - @Output() closeTime = new EventEmitter(); + @Output() closeTime: EventEmitter = new EventEmitter(); inputHourError: boolean = false; inputMinuteError: boolean = false; @@ -87,7 +87,7 @@ export class GoTimeComponent implements OnInit, AfterViewInit { this.hourInput.nativeElement.focus(); } - formatAMPM(date: Date) { + formatAMPM(date: Date): GoTimeFormat { let hours: number | string = date.getHours(); let minutes: number | string = date.getMinutes(); const ampm: string = hours >= 12 ? 'pm' : 'am'; 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 1df3bebb4..26d310d20 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 @@ -15,13 +15,15 @@ describe('GoTimepickerComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [GoTimeComponent, GoTimepickerComponent], + declarations: [ + GoTimeComponent, + GoTimepickerComponent + ], imports: [ GoIconButtonModule, GoButtonModule, GoHintModule, FormsModule, - GoHintModule, GoRequiredTextModule, ReactiveFormsModule, ], From f7ffa9d6de8aff2ada280554687895e3c24d373c Mon Sep 17 00:00:00 2001 From: Amit Patra Date: Fri, 22 Jan 2021 19:20:13 +0530 Subject: [PATCH 18/21] Add test cases --- debug.log | 0 .../go-timepicker/go-time.component.spec.ts | 122 +++++++++++++----- .../go-timepicker/go-time.component.ts | 8 +- 3 files changed, 95 insertions(+), 35 deletions(-) delete mode 100644 debug.log diff --git a/debug.log b/debug.log deleted file mode 100644 index e69de29bb..000000000 diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.spec.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.spec.ts index 34d8e4d75..546e4e77f 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.spec.ts @@ -12,7 +12,11 @@ describe('GoTimeComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [GoTimeComponent], - imports: [GoIconButtonModule, GoButtonModule, FormsModule], + imports: [ + GoIconButtonModule, + GoButtonModule, + FormsModule + ], }).compileComponents(); })); @@ -26,49 +30,105 @@ describe('GoTimeComponent', () => { expect(component).toBeTruthy(); }); - describe('ngOnInit', () => { - afterEach(() => { - component.selectedTime = null; + + describe('increaseHour', () => { + + it('Hour will increase by one', () => { + + component.hour = '10'; + component.increaseHour(); + expect(component.hour).toEqual('11'); + }); + + it('Hour will reset to 01 if hour will more than 12', () => { + + component.hour = '13'; + component.increaseHour(); + expect(component.hour).toEqual('01'); + }); + }); + + describe('increaseMinute', () => { + it('Minute will increase by one', () => { + + component.minute = '10'; + component.increaseMinute(); + expect(component.minute).toEqual('11'); }); - it('check hour with time format', () => { - component.selectedTime = '18:15'; - const hour: string = '06'; - component.ngOnInit(); + it('Minute will reset to 00 if minute will more than 59', () => { - component.changeTimeFormat(component.selectedTime); - expect(component.hour).toBe(hour); + component.minute = '60'; + component.increaseMinute(); + expect(component.minute).toEqual('00'); }); + }); - it('check minute with time format', () => { - component.selectedTime = '18:15'; - const minute: string = '15'; - component.ngOnInit(); + describe('decreaseHour', () => { + it('Hour will decrease by one', () => { - component.changeTimeFormat(component.selectedTime); - expect(component.minute).toBe(minute); + component.hour = '10'; + component.decreaseHour(); + expect(component.hour).toEqual('09'); }); - it('check time with format for AM and PM button display', () => { - component.selectedTime = '18:15'; - const format: boolean = false; - component.ngOnInit(); + it('Hour will reset to 12 if hour will decrease to 01', () => { - component.changeTimeFormat(component.selectedTime); - expect(component.format).toBe(format); + component.hour = '01'; + component.decreaseHour(); + expect(component.hour).toEqual('12'); }); + }); + + describe('decreaseMinute', () => { + it('Minute will decrease by one', () => { - it('check time format with no selected time', () => { - component.selectedTime = null; - const goTimeFormat: GoTimeFormat = { - hours: '05', - minutes: '15', - ampm: 'am', + component.minute = '10'; + component.decreaseMinute(); + expect(component.minute).toEqual('09'); + }); + + it('Minute will reset to 59 if it will decrease to 00', () => { + + component.minute = '00'; + component.decreaseMinute(); + expect(component.minute).toEqual('59'); + }); + }); + + describe('apply time', () => { + it('check with time format after apply', () => { + component.hour = '06'; + component.minute = '09'; + component.format = false; + const timeFormat: GoTimeFormat = { + hours: '06', + minutes: '09', + ampm: 'PM', }; - component.ngOnInit(); - component.formatAMPM(new Date('2017-04-30 05:15:00')); - expect(component.goTimeFormat).toEqual(goTimeFormat); + component.apply(); + expect(component.goTimeFormat).toEqual(timeFormat); + }); + + it('check with time format if hour and minute is not exist ', () => { + const timeFormat: GoTimeFormat = { + hours: '12', + minutes: '00', + ampm: 'AM', + }; + + component.apply(); + expect(component.goTimeFormat).toEqual(timeFormat); + }); + }); + + describe('validateInput', () => { + it('hour and minute will not support more than two digit', () => { + const event: KeyboardEvent = new KeyboardEvent('keypress', {key: '', }); + const regex: string = '^([0-1]|[0][0-9]|[1][0-2])$'; + + expect(component.validateInput(event, regex)).toBe(false); }); }); }); diff --git a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts index 7a5f58fa8..a8444603e 100644 --- a/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts +++ b/projects/go-lib/src/lib/components/go-timepicker/go-time.component.ts @@ -87,7 +87,7 @@ export class GoTimeComponent implements OnInit, AfterViewInit { this.hourInput.nativeElement.focus(); } - formatAMPM(date: Date): GoTimeFormat { + private formatAMPM(date: Date): GoTimeFormat { let hours: number | string = date.getHours(); let minutes: number | string = date.getMinutes(); const ampm: string = hours >= 12 ? 'pm' : 'am'; @@ -103,7 +103,7 @@ export class GoTimeComponent implements OnInit, AfterViewInit { return this.goTimeFormat; } - changeTimeFormat(timeString: string): void { + private changeTimeFormat(timeString: string): void { const H: number = +timeString.substr(0, 2); const h: any = H % 12 || 12; const ampm: string = H < 12 || H === 24 ? 'AM' : 'PM'; @@ -153,7 +153,7 @@ export class GoTimeComponent implements OnInit, AfterViewInit { this.minute = this.addZeroIfNeeded(this.minute); } - addZeroIfNeeded(value: string): string { + private addZeroIfNeeded(value: string): string { if (Number(value) < 10) { value = '0' + +value; } @@ -201,7 +201,7 @@ export class GoTimeComponent implements OnInit, AfterViewInit { this.closeTimePicker(); } - inputTimeError(): void { + private inputTimeError(): void { if (Number(this.hour) > 12) { this.inputHourError = true; } else if (Number(this.minute) > 59) { From 95bd0d6529544a8fcae058cc3749a563006fe68c Mon Sep 17 00:00:00 2001 From: Graham Hency Date: Mon, 25 Jan 2021 10:06:30 -0500 Subject: [PATCH 19/21] Bug Table SelectAll Subscription --- projects/go-lib/karma.conf.js | 4 +- .../go-table/go-table.component.spec.ts | 41 ++++++++---- .../components/go-table/go-table.component.ts | 65 ++++++++++--------- 3 files changed, 66 insertions(+), 44 deletions(-) diff --git a/projects/go-lib/karma.conf.js b/projects/go-lib/karma.conf.js index 255dc98be..8c1ef43f1 100644 --- a/projects/go-lib/karma.conf.js +++ b/projects/go-lib/karma.conf.js @@ -16,9 +16,9 @@ module.exports = function (config) { reporters: ['dots'], port: 9876, colors: true, - logLevel: config.LOG_INFO, + logLevel: config.LOG_WARN, autoWatch: true, - browsers: ['Chrome'], + browsers: ['ChromeHeadless'], singleRun: false }); }; diff --git a/projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts b/projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts index 20e6072e5..d7ebde656 100644 --- a/projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts @@ -149,18 +149,6 @@ describe('GoTableComponent', () => { }); }); - describe('afterViewInit', () => { - afterEach(() => { - component.selectAllControl.setValue(false); - }); - - it('should select all rows if preselected', () => { - component.tableConfig.preselected = true; - component.ngAfterViewInit(); - expect(component.selectAllControl.value).toBe(true); - }); - }); - describe('setPageByPageNumber', () => { beforeEach(() => { component.localTableConfig.totalCount = 135; @@ -399,8 +387,12 @@ describe('GoTableComponent', () => { }); it('should set selectAllIndeterminate to false if selectAll toggled off', () => { + component.ngOnInit(); + component.selectAllControl.setValue(false); + component['selectionSubscriptions'].unsubscribe(); + expect(component.selectAllIndeterminate).toBe(false); }); @@ -414,14 +406,22 @@ describe('GoTableComponent', () => { }); it('should reset targetedRows if toggling selectAll on', () => { + component.ngOnInit(); + component.selectAllControl.setValue(true); + component['selectionSubscriptions'].unsubscribe(); + expect(component.targetedRows).toEqual([]); }); it('should reset targetedRows if toggling selectAll off', () => { + component.ngOnInit(); + component.selectAllControl.setValue(false); + component['selectionSubscriptions'].unsubscribe(); + expect(component.targetedRows).toEqual([]); }); @@ -433,8 +433,12 @@ describe('GoTableComponent', () => { }; spyOn(component.selectAllEvent, 'emit'); + component.ngOnInit(); + component.selectAllControl.setValue(false); + component['selectionSubscriptions'].unsubscribe(); + expect(component.selectAllEvent.emit).toHaveBeenCalledWith(selectionEventData); }); }); @@ -946,11 +950,14 @@ describe('GoTableComponent', () => { component.tableConfig.selectBy = 'id'; component.renderTable(); + component.ngOnInit(); expect(component.rowSelectForm.value['selection_1']).toBe(false); component.selectAllControl.setValue(true); + component['selectionSubscriptions'].unsubscribe(); + expect(component.rowSelectForm.value['selection_1']).toBe(true); }); }); @@ -1100,6 +1107,16 @@ describe('GoTableComponent', () => { component.tableConfig.tableData = fakeTableData; }); + afterEach(() => { + component.selectAllControl.setValue(false); + }); + + it('should select all rows if preselected', () => { + component.tableConfig.preselected = true; + component.ngAfterViewInit(); + expect(component.selectAllControl.value).toBe(true); + }); + it('performs a search if datamode is client and table is searchable', () => { component.tableConfig.searchConfig.searchTerm = 'koala'; component.tableConfig.searchConfig.searchable = true; diff --git a/projects/go-lib/src/lib/components/go-table/go-table.component.ts b/projects/go-lib/src/lib/components/go-table/go-table.component.ts index 16422ebd4..b14e2b33b 100644 --- a/projects/go-lib/src/lib/components/go-table/go-table.component.ts +++ b/projects/go-lib/src/lib/components/go-table/go-table.component.ts @@ -20,7 +20,7 @@ import { FormControl, FormGroup } from '@angular/forms'; -import { Subject } from 'rxjs'; +import { Subject, Subscription } from 'rxjs'; import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators'; import { GoConfigService } from '../../go-config.service'; @@ -103,6 +103,7 @@ export class GoTableComponent implements OnInit, OnChanges, OnDestroy, AfterView searchTerm: FormControl = new FormControl(); selectAllControl: FormControl = new FormControl(false); selectAllIndeterminate: boolean = false; + selectionSubscriptions: Subscription = new Subscription(); showTable: boolean = false; targetedRows: any[] = []; @@ -125,6 +126,7 @@ export class GoTableComponent implements OnInit, OnChanges, OnDestroy, AfterView this.setupSearch(); this.setupPageSizes(); this.setupConfigService(); + this.setupSelectAllControlSub(); } } @@ -153,6 +155,7 @@ export class GoTableComponent implements OnInit, OnChanges, OnDestroy, AfterView this.pageChange$.complete(); this.destroy$.next(); this.destroy$.complete(); + this.selectionSubscriptions.unsubscribe(); } renderTable(): void { @@ -164,10 +167,6 @@ export class GoTableComponent implements OnInit, OnChanges, OnDestroy, AfterView this.handleSort(); this.setPage(this.localTableConfig.pageConfig.offset); this.setSearchTerm(); - - if (this.localTableConfig.selectable) { - this.setupSelectAllControlSub(); - } } this.showTable = Boolean(this.tableConfig); @@ -545,35 +544,41 @@ export class GoTableComponent implements OnInit, OnChanges, OnDestroy, AfterView private setupRowSelectFormControlsSubs(): void { this.getDisplayData().forEach((row: any) => { - this.rowSelectForm.get(`selection_${row[this.localTableConfig.selectBy]}`) - .valueChanges.pipe(takeUntil(this.pageChange$)) - .subscribe((value: boolean) => { - this.selectionChange(value, row); - }); + this.selectionSubscriptions.add( + this.rowSelectForm.get(`selection_${row[this.localTableConfig.selectBy]}`) + .valueChanges.pipe(takeUntil(this.pageChange$)) + .subscribe((value: boolean) => { + this.selectionChange(value, row); + }) + ); }); } private setupSelectAllControlSub(): void { - this.selectAllControl.valueChanges - .pipe( - distinctUntilChanged(), - takeUntil(this.destroy$) - ) - .subscribe(() => { - this.targetedRows = []; - this.updateRowSelectForm(); - - if (!this.selectAllControl.value) { - this.selectAllIndeterminate = false; - } - - this.selectAllEvent.emit({ - deselectedRows: this.selectAllControl.value ? this.targetedRows : [], - selectionMode: this.determineSelectionMode(), - selectedRows: !this.selectAllControl.value ? this.targetedRows : [] - }); - } - ); + if (this.tableConfig.selectable) { + this.selectionSubscriptions.add( + this.selectAllControl.valueChanges + .pipe( + distinctUntilChanged(), + takeUntil(this.destroy$) + ) + .subscribe(() => { + this.targetedRows = []; + this.updateRowSelectForm(); + + if (!this.selectAllControl.value) { + this.selectAllIndeterminate = false; + } + + this.selectAllEvent.emit({ + deselectedRows: this.selectAllControl.value ? this.targetedRows : [], + selectionMode: this.determineSelectionMode(), + selectedRows: !this.selectAllControl.value ? this.targetedRows : [] + }); + } + ) + ); + } } private updateRowSelectForm(): void { From b32b4548c54b575aff35b56cd7d600f64d740aa9 Mon Sep 17 00:00:00 2001 From: Graham Hency Date: Mon, 25 Jan 2021 11:47:02 -0500 Subject: [PATCH 20/21] Change subscriptions to destroy --- .../go-table/go-table.component.spec.ts | 10 ++-- .../components/go-table/go-table.component.ts | 60 +++++++++---------- 2 files changed, 33 insertions(+), 37 deletions(-) diff --git a/projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts b/projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts index d7ebde656..1988d06d7 100644 --- a/projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts @@ -391,7 +391,7 @@ describe('GoTableComponent', () => { component.selectAllControl.setValue(false); - component['selectionSubscriptions'].unsubscribe(); + component.ngOnDestroy(); expect(component.selectAllIndeterminate).toBe(false); }); @@ -410,7 +410,7 @@ describe('GoTableComponent', () => { component.selectAllControl.setValue(true); - component['selectionSubscriptions'].unsubscribe(); + component.ngOnDestroy(); expect(component.targetedRows).toEqual([]); }); @@ -420,7 +420,7 @@ describe('GoTableComponent', () => { component.selectAllControl.setValue(false); - component['selectionSubscriptions'].unsubscribe(); + component.ngOnDestroy(); expect(component.targetedRows).toEqual([]); }); @@ -437,7 +437,7 @@ describe('GoTableComponent', () => { component.selectAllControl.setValue(false); - component['selectionSubscriptions'].unsubscribe(); + component.ngOnDestroy(); expect(component.selectAllEvent.emit).toHaveBeenCalledWith(selectionEventData); }); @@ -956,7 +956,7 @@ describe('GoTableComponent', () => { component.selectAllControl.setValue(true); - component['selectionSubscriptions'].unsubscribe(); + component.ngOnDestroy(); expect(component.rowSelectForm.value['selection_1']).toBe(true); }); diff --git a/projects/go-lib/src/lib/components/go-table/go-table.component.ts b/projects/go-lib/src/lib/components/go-table/go-table.component.ts index b14e2b33b..4ff167645 100644 --- a/projects/go-lib/src/lib/components/go-table/go-table.component.ts +++ b/projects/go-lib/src/lib/components/go-table/go-table.component.ts @@ -12,8 +12,7 @@ import { Output, QueryList, SimpleChanges, - TemplateRef, - ViewChild + TemplateRef } from '@angular/core'; import { FormBuilder, @@ -103,7 +102,6 @@ export class GoTableComponent implements OnInit, OnChanges, OnDestroy, AfterView searchTerm: FormControl = new FormControl(); selectAllControl: FormControl = new FormControl(false); selectAllIndeterminate: boolean = false; - selectionSubscriptions: Subscription = new Subscription(); showTable: boolean = false; targetedRows: any[] = []; @@ -155,7 +153,6 @@ export class GoTableComponent implements OnInit, OnChanges, OnDestroy, AfterView this.pageChange$.complete(); this.destroy$.next(); this.destroy$.complete(); - this.selectionSubscriptions.unsubscribe(); } renderTable(): void { @@ -544,40 +541,39 @@ export class GoTableComponent implements OnInit, OnChanges, OnDestroy, AfterView private setupRowSelectFormControlsSubs(): void { this.getDisplayData().forEach((row: any) => { - this.selectionSubscriptions.add( - this.rowSelectForm.get(`selection_${row[this.localTableConfig.selectBy]}`) - .valueChanges.pipe(takeUntil(this.pageChange$)) - .subscribe((value: boolean) => { - this.selectionChange(value, row); - }) - ); + this.rowSelectForm.get(`selection_${row[this.localTableConfig.selectBy]}`) + .valueChanges.pipe( + takeUntil(this.pageChange$), + takeUntil(this.destroy$) + ) + .subscribe((value: boolean) => { + this.selectionChange(value, row); + }); }); } private setupSelectAllControlSub(): void { if (this.tableConfig.selectable) { - this.selectionSubscriptions.add( - this.selectAllControl.valueChanges - .pipe( - distinctUntilChanged(), - takeUntil(this.destroy$) - ) - .subscribe(() => { - this.targetedRows = []; - this.updateRowSelectForm(); - - if (!this.selectAllControl.value) { - this.selectAllIndeterminate = false; - } - - this.selectAllEvent.emit({ - deselectedRows: this.selectAllControl.value ? this.targetedRows : [], - selectionMode: this.determineSelectionMode(), - selectedRows: !this.selectAllControl.value ? this.targetedRows : [] - }); - } + this.selectAllControl.valueChanges + .pipe( + distinctUntilChanged(), + takeUntil(this.destroy$) ) - ); + .subscribe(() => { + this.targetedRows = []; + this.updateRowSelectForm(); + + if (!this.selectAllControl.value) { + this.selectAllIndeterminate = false; + } + + this.selectAllEvent.emit({ + deselectedRows: this.selectAllControl.value ? this.targetedRows : [], + selectionMode: this.determineSelectionMode(), + selectedRows: !this.selectAllControl.value ? this.targetedRows : [] + }); + } + ) } } From b47660a53aa9e20b793c9cfc2b37a22ebe1c7f2c Mon Sep 17 00:00:00 2001 From: Graham Hency Date: Tue, 26 Jan 2021 09:55:59 -0500 Subject: [PATCH 21/21] Chore v1.8.0 Documentation Update --- README.md | 2 +- projects/go-lib/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7dcd0ff2a..20bfecaa5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Goponents -###### Currently `v1.7.1` +###### Currently `v1.8.0` This project houses a set of UI components for Angular 7+ and designed around the 'Go' design system. diff --git a/projects/go-lib/package.json b/projects/go-lib/package.json index 184fa5361..dc040662a 100644 --- a/projects/go-lib/package.json +++ b/projects/go-lib/package.json @@ -1,6 +1,6 @@ { "name": "@tangoe/goponents", - "version": "1.7.1", + "version": "1.8.0", "repository": { "type": "git", "url": "git+https://github.com/mobi/goponents.git"