2023-03-15 16:00:52 +00:00
/ * *
* Copyright ( c ) HashiCorp , Inc .
* SPDX - License - Identifier : MPL - 2.0
* /
2022-01-11 18:05:38 +00:00
import Component from '@glimmer/component' ;
import { action } from '@ember/object' ;
import { tracked } from '@glimmer/tracking' ;
2023-01-27 02:21:12 +00:00
import { ARRAY _OF _MONTHS , parseAPITimestamp } from 'core/utils/date-formatters' ;
import { addYears , isSameYear , subYears } from 'date-fns' ;
2022-01-11 18:05:38 +00:00
/ * *
* @ module CalendarWidget
2023-01-27 02:21:12 +00:00
* CalendarWidget component is used in the client counts dashboard to select a month / year to query the / activity endpoint .
* The component returns an object with selected date info , example : { dateType : 'endDate' , monthIdx : 0 , monthName : 'January' , year : 2022 }
2022-01-11 18:05:38 +00:00
*
* @ example
* ` ` ` js
2023-01-27 02:21:12 +00:00
* < CalendarWidget @ startTimestamp = { { this . startTime } } @ endTimestamp = { { this . endTime } } @ selectMonth = { { this . handleSelection } } / >
2022-01-11 18:05:38 +00:00
*
2023-01-27 02:21:12 +00:00
* @ param { string } startTimestamp - ISO timestamp string of the calendar widget ' s start time , displays in dropdown trigger
* @ param { string } endTimestamp - ISO timestamp string for the calendar widget ' s end time , displays in dropdown trigger
* @ param { function } selectMonth - callback function from parent - fires when selecting a month or clicking "Current billing period"
* / >
2022-01-11 18:05:38 +00:00
* ` ` `
* /
2023-01-27 02:21:12 +00:00
export default class CalendarWidget extends Component {
2022-01-11 18:05:38 +00:00
currentDate = new Date ( ) ;
2023-01-27 02:21:12 +00:00
@ tracked calendarDisplayDate = this . currentDate ; // init to current date, updates when user clicks on calendar chevrons
2022-01-11 18:05:38 +00:00
@ tracked showCalendar = false ;
2022-02-10 16:43:40 +00:00
@ tracked tooltipTarget = null ;
@ tracked tooltipText = null ;
2022-01-11 18:05:38 +00:00
2023-01-27 02:21:12 +00:00
// both date getters return a date object
get startDate ( ) {
return parseAPITimestamp ( this . args . startTimestamp ) ;
}
get endDate ( ) {
return parseAPITimestamp ( this . args . endTimestamp ) ;
}
get displayYear ( ) {
return this . calendarDisplayDate . getFullYear ( ) ;
2022-06-03 21:22:50 +00:00
}
get disableFutureYear ( ) {
2023-01-27 02:21:12 +00:00
return isSameYear ( this . calendarDisplayDate , this . currentDate ) ;
2022-01-11 18:05:38 +00:00
}
2022-06-03 21:22:50 +00:00
get disablePastYear ( ) {
2023-01-27 02:21:12 +00:00
// calendar widget should only go as far back as the passed in start time
return isSameYear ( this . calendarDisplayDate , this . startDate ) ;
2022-06-03 21:22:50 +00:00
}
get widgetMonths ( ) {
2023-01-27 02:21:12 +00:00
const startYear = this . startDate . getFullYear ( ) ;
const startMonthIdx = this . startDate . getMonth ( ) ;
return ARRAY _OF _MONTHS . map ( ( month , index ) => {
2022-06-03 21:22:50 +00:00
let readonly = false ;
2023-01-27 02:21:12 +00:00
// if widget is showing same year as @startTimestamp year, disable if month is before start month
if ( startYear === this . displayYear && index < startMonthIdx ) {
2022-06-03 21:22:50 +00:00
readonly = true ;
}
2022-01-11 18:05:38 +00:00
2023-01-27 02:21:12 +00:00
// if widget showing current year, disable if month is later than current month
if ( this . displayYear === this . currentDate . getFullYear ( ) && index > this . currentDate . getMonth ( ) ) {
2022-06-03 21:22:50 +00:00
readonly = true ;
}
return {
2023-01-27 02:21:12 +00:00
index ,
year : this . displayYear ,
name : month ,
2022-06-03 21:22:50 +00:00
readonly ,
} ;
} ) ;
2022-01-11 18:05:38 +00:00
}
2022-02-10 16:43:40 +00:00
@ action
addTooltip ( ) {
2022-06-03 21:22:50 +00:00
if ( this . disablePastYear ) {
2023-01-27 02:21:12 +00:00
const previousYear = this . displayYear - 1 ;
this . tooltipText = ` ${ previousYear } is unavailable because it is before your start date. Change your start month to a date in ${ previousYear } to see data for this year. ` ;
2022-02-10 16:43:40 +00:00
this . tooltipTarget = '#previous-year' ;
}
}
2022-01-11 18:05:38 +00:00
@ action
2023-01-27 02:21:12 +00:00
removeTooltip ( ) {
2022-02-10 16:43:40 +00:00
this . tooltipTarget = null ;
}
2022-01-11 18:05:38 +00:00
@ action
2023-01-27 02:21:12 +00:00
addYear ( ) {
this . calendarDisplayDate = addYears ( this . calendarDisplayDate , 1 ) ;
2022-01-11 18:05:38 +00:00
}
@ action
subYear ( ) {
2023-01-27 02:21:12 +00:00
this . calendarDisplayDate = subYears ( this . calendarDisplayDate , 1 ) ;
2022-01-11 18:05:38 +00:00
}
@ action
toggleShowCalendar ( ) {
this . showCalendar = ! this . showCalendar ;
2023-01-27 02:21:12 +00:00
this . calendarDisplayDate = this . endDate ;
}
@ action
handleDateShortcut ( dropdown , { target } ) {
this . args . selectMonth ( { dateType : target . name } ) ; // send clicked shortcut to parent callback
this . showCalendar = false ;
dropdown . close ( ) ;
}
@ action
selectMonth ( month , dropdown ) {
const { index , year , name } = month ;
this . toggleShowCalendar ( ) ;
this . args . selectMonth ( { monthIdx : index , monthName : name , year , dateType : 'endDate' } ) ;
dropdown . close ( ) ;
2022-01-11 18:05:38 +00:00
}
}