From d7059745f53bf20cc92705d79d601722a43898b5 Mon Sep 17 00:00:00 2001 From: Sandro Castillo Date: Mon, 14 Dec 2020 15:57:59 -0500 Subject: [PATCH] TT-39 feat: allow switching amongyears --- package-lock.json | 39 ++++-- .../month-picker/month-picker.component.html | 67 +++++++-- .../month-picker/month-picker.component.ts | 130 ++++++++++++++++-- .../pages/time-entries.component.html | 2 +- .../pages/time-entries.component.ts | 24 +++- 5 files changed, 226 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6084b8d87..118dda7b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4610,6 +4610,16 @@ "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npm.taobao.org/bindings/download/bindings-1.5.0.tgz", + "integrity": "sha1-EDU8npRTNLwFEabZCzj7x8nFBN8=", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bl": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", @@ -5951,8 +5961,8 @@ }, "serialize-javascript": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "resolved": "https://registry.npm.taobao.org/serialize-javascript/download/serialize-javascript-3.1.0.tgz?cache=0&sync_timestamp=1599742605902&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-javascript%2Fdownload%2Fserialize-javascript-3.1.0.tgz", + "integrity": "sha1-i/OpFwcSZk7yVhtEtpHq/jmSFOo=", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -7707,6 +7717,13 @@ "schema-utils": "^2.6.5" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/file-uri-to-path/download/file-uri-to-path-1.0.0.tgz", + "integrity": "sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90=", + "dev": true, + "optional": true + }, "file-url": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/file-url/-/file-url-3.0.0.tgz", @@ -18026,8 +18043,8 @@ "dependencies": { "node-forge": { "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "resolved": "https://registry.npm.taobao.org/node-forge/download/node-forge-0.10.0.tgz?cache=0&sync_timestamp=1599010781800&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-forge%2Fdownload%2Fnode-forge-0.10.0.tgz", + "integrity": "sha1-Mt6ir7Ppkm8C7lzoeUkCaRpna/M=", "dev": true } } @@ -19879,8 +19896,8 @@ }, "serialize-javascript": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "resolved": "https://registry.npm.taobao.org/serialize-javascript/download/serialize-javascript-3.1.0.tgz?cache=0&sync_timestamp=1599742605902&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-javascript%2Fdownload%2Fserialize-javascript-3.1.0.tgz", + "integrity": "sha1-i/OpFwcSZk7yVhtEtpHq/jmSFOo=", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -20753,6 +20770,7 @@ "dev": true, "optional": true, "requires": { + "bindings": "^1.5.0", "nan": "^2.12.1" } }, @@ -21075,8 +21093,8 @@ }, "serialize-javascript": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "resolved": "https://registry.npm.taobao.org/serialize-javascript/download/serialize-javascript-3.1.0.tgz?cache=0&sync_timestamp=1599742605902&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-javascript%2Fdownload%2Fserialize-javascript-3.1.0.tgz", + "integrity": "sha1-i/OpFwcSZk7yVhtEtpHq/jmSFOo=", "requires": { "randombytes": "^2.1.0" } @@ -21117,8 +21135,8 @@ "dependencies": { "serialize-javascript": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "resolved": "https://registry.npm.taobao.org/serialize-javascript/download/serialize-javascript-3.1.0.tgz?cache=0&sync_timestamp=1599742605902&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-javascript%2Fdownload%2Fserialize-javascript-3.1.0.tgz", + "integrity": "sha1-i/OpFwcSZk7yVhtEtpHq/jmSFOo=", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -21322,6 +21340,7 @@ "dev": true, "optional": true, "requires": { + "bindings": "^1.5.0", "nan": "^2.12.1" } }, diff --git a/src/app/modules/shared/components/month-picker/month-picker.component.html b/src/app/modules/shared/components/month-picker/month-picker.component.html index 204ecb6d7..71f0a4223 100644 --- a/src/app/modules/shared/components/month-picker/month-picker.component.html +++ b/src/app/modules/shared/components/month-picker/month-picker.component.html @@ -1,10 +1,59 @@ -
-
-
{{ month }}
+ +
+
+
+
+ + + + +
-
+
+
+
+
+
+ +
+
+
+ + +
+
+
+ +
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/src/app/modules/shared/components/month-picker/month-picker.component.ts b/src/app/modules/shared/components/month-picker/month-picker.component.ts index 1a404f058..32581eb92 100644 --- a/src/app/modules/shared/components/month-picker/month-picker.component.ts +++ b/src/app/modules/shared/components/month-picker/month-picker.component.ts @@ -1,4 +1,5 @@ -import { Component, OnInit, Output, EventEmitter } from '@angular/core'; +import { Component, OnInit, Output, Input, EventEmitter } from '@angular/core'; +import * as moment from 'moment'; @Component({ selector: 'app-month-picker', @@ -6,18 +7,127 @@ import { Component, OnInit, Output, EventEmitter } from '@angular/core'; styleUrls: ['./month-picker.component.scss'] }) export class MonthPickerComponent implements OnInit { - @Output() monthSelected = new EventEmitter(); - activeMonth: number; - months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + @Input() year: number; + @Input() month: number; + @Output() changeDate = new EventEmitter<{ monthIndex: number, year: number }>(); - constructor() { } + model: MonthPickerModel; + isShowYears: boolean; + years: Array = []; - ngOnInit(): void { - this.activeMonth = new Date().getMonth(); + ngOnInit() { + + this.model = new MonthPickerModel(); + + if (this.year) { + this.model.selectedYearMoment = moment().year(this.year); + this.model.updateYearText(); + } + + if (this.month) { + this.model.selectedMonthIndex = this.month; + this.model.selectedMonthMoment = moment().month(this.month); + if (this.year) { this.model.selectedMonthYear = this.year; } + } + + this.onChange(this.model.selectedMonthIndex, this.model.selectedMonthYear); + } + + decrement() { + this.model.decrementYear(); + if (this.isShowYears) { + this.renderYears(); + } + } + + increment() { + this.model.incrementYear(); + if (this.isShowYears) { + this.renderYears(); + } + } + + selectMonth(index: number) { + this.model.selectMonth(index); + this.onChange(this.model.selectedMonthIndex, this.model.selectedMonthYear); + } + + isSelectedMonth(monthIndex: number) { + return this.model.selectedMonthIndex === monthIndex && this.model.selectedMonthYear === this.model.selectedYearMoment.year(); + } + + onChange(monthIndex: number, year: number) { + // tslint:disable-next-line:no-unused-expression + this.changeDate.emit({monthIndex, year}); + } + + // tslint:disable-next-line:no-unused-expression + toggleShowYears() { + this.isShowYears = !this.isShowYears; + this.renderYears(); + } + + renderYears() { + this.years = []; + for (let i = 5; i > 0; i--) { + this.years.push(this.model.selectedYearMoment.year() - i); + } + for (let i = 0; i <= 6; i++) { + this.years.push(this.model.selectedYearMoment.year() + i); + } + } + + selectYear(year: number) { + this.isShowYears = false; + this.model.selectedYearMoment = moment().year(year); + this.model.updateYearText(); // in set get aendern + } + + isSelectedYear(year: number){ + return this.model.selectedYearMoment.year() === year; } +} + +export class MonthPickerModel { + constructor() { + this.selectedYearMoment = moment(); + this.updateYearText(); - getMonth(month: number) { - this.monthSelected.emit(month + 1); - this.activeMonth = month; + this.selectedMonthMoment = moment(); + + this.months = moment.months(); + + this.selectedMonthIndex = this.selectedMonthMoment.month(); + this.selectedMonthYear = this.selectedYearMoment.year(); } + + selectedYearMoment: moment.Moment; + selectedYearText: string; + + selectedMonthMoment: moment.Moment; + selectedMonthIndex: number; + selectedMonthYear: number; + + months: Array = []; + + updateYearText() { + this.selectedYearText = moment(this.selectedYearMoment).format('YYYY'); + } + + selectMonth(index: number) { + this.selectedMonthMoment = moment().month(index); + this.selectedMonthIndex = this.selectedMonthMoment.month() + 1; + this.selectedMonthYear = this.selectedYearMoment.year(); + } + + incrementYear() { + this.selectedYearMoment = this.selectedYearMoment.add(1, 'year'); + this.updateYearText(); + } + + decrementYear() { + this.selectedYearMoment = this.selectedYearMoment.subtract(1, 'year'); + this.updateYearText(); + } + } diff --git a/src/app/modules/time-entries/pages/time-entries.component.html b/src/app/modules/time-entries/pages/time-entries.component.html index 8928eb656..dfcf49196 100644 --- a/src/app/modules/time-entries/pages/time-entries.component.html +++ b/src/app/modules/time-entries/pages/time-entries.component.html @@ -13,7 +13,7 @@
- +
diff --git a/src/app/modules/time-entries/pages/time-entries.component.ts b/src/app/modules/time-entries/pages/time-entries.component.ts index 5116b3254..d95b2c911 100644 --- a/src/app/modules/time-entries/pages/time-entries.component.ts +++ b/src/app/modules/time-entries/pages/time-entries.component.ts @@ -8,6 +8,7 @@ import { SaveEntryEvent } from '../../shared/components/details-fields/save-entr import { Entry } from '../../shared/models'; import { DataSource } from '../../shared/models/data-source.model'; import * as entryActions from '../../time-clock/store/entry.actions'; +import * as moment from 'moment'; import { EntryState } from '../../time-clock/store/entry.reducer'; import { EntryActionTypes } from './../../time-clock/store/entry.actions'; import { getActiveTimeEntry, getTimeEntriesDataSource } from './../../time-clock/store/entry.selectors'; @@ -26,6 +27,9 @@ export class TimeEntriesComponent implements OnInit, OnDestroy { entriesSubscription: Subscription; canMarkEntryAsWIP = true; timeEntriesDataSource$: Observable>; + selectedYearAsText: string; + selectedMonthIndex: number; + selectedMonthAsText: string; constructor(private store: Store, private toastrService: ToastrService, private actionsSubject$: ActionsSubject) { this.timeEntriesDataSource$ = this.store.pipe(delay(0), select(getTimeEntriesDataSource)); @@ -36,7 +40,7 @@ export class TimeEntriesComponent implements OnInit, OnDestroy { } ngOnInit(): void { - this.store.dispatch(new entryActions.LoadEntries(new Date().getMonth() + 1)); + // this.store.dispatch(new entryActions.LoadEntries(new Date().getMonth() + 1)); this.loadActiveEntry(); this.entriesSubscription = this.actionsSubject$.pipe( @@ -48,7 +52,7 @@ export class TimeEntriesComponent implements OnInit, OnDestroy { ) ).subscribe((action) => { this.loadActiveEntry(); - this.store.dispatch(new entryActions.LoadEntries(new Date().getMonth() + 1)); + // this.store.dispatch(new entryActions.LoadEntries(new Date().getMonth() + 1)); }); } @@ -107,7 +111,7 @@ export class TimeEntriesComponent implements OnInit, OnDestroy { const isEditingEntryEqualToActiveEntry = this.entryId === this.activeTimeEntry.id; const isStartDateGreaterThanActiveEntry = startDateAsLocalDate > activeEntryAsLocalDate; const isEndDateGreaterThanActiveEntry = endDateAsLocalDate > activeEntryAsLocalDate; - if(!isEditingEntryEqualToActiveEntry && (isStartDateGreaterThanActiveEntry || isEndDateGreaterThanActiveEntry)){ + if (!isEditingEntryEqualToActiveEntry && (isStartDateGreaterThanActiveEntry || isEndDateGreaterThanActiveEntry)){ this.toastrService.error('You are on the clock and this entry overlaps it, try with earlier times.'); } else { this.doSave(event); @@ -160,13 +164,21 @@ export class TimeEntriesComponent implements OnInit, OnDestroy { this.showModal = false; } - getMonth(month: number) { - this.store.dispatch(new entryActions.LoadEntries(month)); - } openModal(item: any) { this.idToDelete = item.id; this.message = `Are you sure you want to delete ${item.activity_name}?`; this.showModal = true; } + + // getMonth(month: number) { + // this.store.dispatch(new entryActions.LoadEntries(month)); + // } + + onChange(event: { year: number, monthIndex: number }) { + this.selectedYearAsText = event.year.toString(); + this.selectedMonthIndex = event.monthIndex + 1; + this.selectedMonthAsText = moment().month(event.monthIndex).format('MMMM'); + this.store.dispatch(new entryActions.LoadEntries(event.monthIndex)); + } }