diff --git a/changelog/15789.txt b/changelog/15789.txt new file mode 100644 index 000000000..d6aaaa60f --- /dev/null +++ b/changelog/15789.txt @@ -0,0 +1,3 @@ +```release-note:bug +ui: Fix inconsistent behavior in client count calendar widget +``` \ No newline at end of file diff --git a/ui/app/components/calendar-widget.js b/ui/app/components/calendar-widget.js index eb43ae801..6b7004ea0 100644 --- a/ui/app/components/calendar-widget.js +++ b/ui/app/components/calendar-widget.js @@ -28,35 +28,76 @@ class CalendarWidget extends Component { @tracked allMonthsNodeList = []; @tracked displayYear = this.currentYear; // init to currentYear and then changes as a user clicks on the chevrons - @tracked disablePastYear = this.isObsoleteYear(); // if obsolete year, disable left chevron - @tracked disableFutureYear = this.isCurrentYear(); // if current year, disable right chevron @tracked showCalendar = false; @tracked tooltipTarget = null; @tracked tooltipText = null; + get selectedMonthId() { + if (!this.args.endTimeFromResponse) return ''; + const [year, monthIndex] = this.args.endTimeFromResponse; + return `${monthIndex}-${year}`; + } + get disableFutureYear() { + return this.displayYear === this.currentYear; + } + get disablePastYear() { + let startYear = parseInt(this.args.startTimeDisplay.split(' ')[1]); + return this.displayYear === startYear; // if on startYear then don't let them click back to the year prior + } + get widgetMonths() { + const displayYear = this.displayYear; + const currentYear = this.currentYear; + const currentMonthIdx = this.currentMonth; + const [startMonth, startYear] = this.args.startTimeDisplay.split(' '); + const startMonthIdx = this.args.arrayOfMonths.indexOf(startMonth); + return this.args.arrayOfMonths.map((month, idx) => { + const monthId = `${idx}-${displayYear}`; + let readonly = false; + + // if widget is showing billing start year, disable if month is before start month + if (parseInt(startYear) === displayYear && idx < startMonthIdx) { + readonly = true; + } + + // if widget showing current year, disable if month is current or later + if (displayYear === currentYear && idx >= currentMonthIdx) { + readonly = true; + } + return { + id: monthId, + month, + readonly, + current: monthId === `${currentMonthIdx}-${currentYear}`, + }; + }); + } + // HELPER FUNCTIONS (alphabetically) // addClass(element, classString) { element.classList.add(classString); } - isCurrentYear() { - return this.currentYear === this.displayYear; - } - - isObsoleteYear() { - // do not allow them to choose a year before the this.args.startTimeDisplay - let startYear = this.args.startTimeDisplay.split(' ')[1]; - return this.displayYear.toString() === startYear; // if on startYear then don't let them click back to the year prior - } - removeClass(element, classString) { element.classList.remove(classString); } + resetDisplayYear() { + let setYear = this.currentYear; + if (this.args.endTimeDisplay) { + try { + const year = this.args.endTimeDisplay.split(' ')[1]; + setYear = parseInt(year); + } catch (e) { + console.debug('Error resetting display year', e); + } + } + this.displayYear = setYear; + } + // ACTIONS (alphabetically) // @action addTooltip() { - if (this.isObsoleteYear()) { + if (this.disablePastYear) { let previousYear = Number(this.displayYear) - 1; this.tooltipText = `${previousYear} is unavailable because it is before your billing start month. Change your billing start month to a date in ${previousYear} to see data for this year.`; // set tooltip text this.tooltipTarget = '#previous-year'; @@ -66,53 +107,6 @@ class CalendarWidget extends Component { @action addYear() { this.displayYear = this.displayYear + 1; - this.disableMonths(); - this.disableFutureYear = this.isCurrentYear(); - this.disablePastYear = this.isObsoleteYear(); - } - - @action - disableMonths() { - this.allMonthsNodeList = document.querySelectorAll('.is-month-list'); - this.allMonthsNodeList.forEach((e) => { - // clear all is-readOnly classes and start over. - this.removeClass(e, 'is-readOnly'); - - let elementMonthId = parseInt(e.id.split('-')[0]); // dependent on the shape of the element id - // for current year - - if (this.currentMonth <= elementMonthId) { - // only disable months when current year is selected - if (this.isCurrentYear()) { - e.classList.add('is-readOnly'); - } - } - // compare for startYear view - if (this.displayYear.toString() === this.args.startTimeDisplay.split(' ')[1]) { - // if they are on the view where the start year equals the display year, check which months should not show. - let startMonth = this.args.startTimeDisplay.split(' ')[0]; // returns month name e.g. January - // return the index of the startMonth - let startMonthIndex = this.args.arrayOfMonths.indexOf(startMonth); - // then add readOnly class to any month less than the startMonth index. - if (startMonthIndex > elementMonthId) { - e.classList.add('is-readOnly'); - } - } - // Compare values so the user cannot select an endTime after the endTime returned from counters/activity response on page load. - let yearEndTimeFromResponse = Number(this.args.endTimeFromResponse[0]); - let endMonth = this.args.endTimeFromResponse[1]; - if (this.displayYear === yearEndTimeFromResponse) { - // add readOnly class to any month that is older (higher) than the endMonth index. (e.g. if nov is the endMonth of the endTimeDisplay, then 11 and 12 should not be displayed 10 < 11 and 10 < 12.) - if (endMonth < elementMonthId) { - e.classList.add('is-readOnly'); - } - } - // if the year display higher than the endTime e.g. you're looking at 2022 and the returned endTime is 2021, all months should be disabled. - if (this.displayYear > yearEndTimeFromResponse) { - // all months should be disabled. - e.classList.add('is-readOnly'); - } - }); } @action removeTooltip() { @@ -126,23 +120,22 @@ class CalendarWidget extends Component { D.actions.close(); // close the dropdown. } @action - selectEndMonth(month, year, D) { + selectEndMonth(monthId, D) { + const [monthIdx, year] = monthId.split('-'); this.toggleShowCalendar(); - this.args.handleClientActivityQuery(month, year, 'endTime'); + this.args.handleClientActivityQuery(parseInt(monthIdx), parseInt(year), 'endTime'); D.actions.close(); // close the dropdown. } @action subYear() { this.displayYear = this.displayYear - 1; - this.disableMonths(); - this.disableFutureYear = this.isCurrentYear(); - this.disablePastYear = this.isObsoleteYear(); } @action toggleShowCalendar() { this.showCalendar = !this.showCalendar; + this.resetDisplayYear(); } } export default setComponentTemplate(layout, CalendarWidget); diff --git a/ui/app/styles/components/calendar-widget.scss b/ui/app/styles/components/calendar-widget.scss index be6c13b7b..b96b374b6 100644 --- a/ui/app/styles/components/calendar-widget.scss +++ b/ui/app/styles/components/calendar-widget.scss @@ -82,6 +82,12 @@ $dark-gray: #535f73; color: lighten($dark-gray, 30%); pointer-events: none; } + &.is-selected-month { + background-color: lighten($dark-gray, 30%); + color: white; + text-align: center; + pointer-events: none; + } } } diff --git a/ui/app/templates/components/calendar-widget.hbs b/ui/app/templates/components/calendar-widget.hbs index d8c12b0f7..a5fff1e6f 100644 --- a/ui/app/templates/components/calendar-widget.hbs +++ b/ui/app/templates/components/calendar-widget.hbs @@ -11,7 +11,9 @@