From f59afe880fb172b943da84aebb0ce754a0473430 Mon Sep 17 00:00:00 2001 From: Kiley <110477068+kiley-mitti@users.noreply.github.com> Date: Thu, 30 May 2024 11:26:10 -0400 Subject: [PATCH] Km.can i do months (#1322) * need to add partials and fix bug with start time * note error * for all increments (needs refactor) * stuff not done with partial * secondary ruler for all increments --- packages/web-components/src/components.d.ts | 4 +- .../src/components/rux-timeline/helpers.ts | 6 +- .../rux-timeline/rux-ruler/rux-ruler.tsx | 226 +++++++++++++----- packages/web-components/src/index.html | 162 +------------ 4 files changed, 181 insertions(+), 217 deletions(-) diff --git a/packages/web-components/src/components.d.ts b/packages/web-components/src/components.d.ts index ea07f28b8..1742a5371 100644 --- a/packages/web-components/src/components.d.ts +++ b/packages/web-components/src/components.d.ts @@ -19768,7 +19768,7 @@ export namespace Components { "end": string; "interval": any; /** - * Display the day (MM/DD) at 00:00. Only works when Timeline interval is set to 'hour'. + * Display the day (MM/DD) at 00:00. Only works when Timeline interval is set to 'hour' or 'minutes'. */ "showStartOfDay"?: boolean | undefined; "start": string; @@ -55346,7 +55346,7 @@ declare namespace LocalJSX { "end"?: string; "interval"?: any; /** - * Display the day (MM/DD) at 00:00. Only works when Timeline interval is set to 'hour'. + * Display the day (MM/DD) at 00:00. Only works when Timeline interval is set to 'hour' or 'minutes'. */ "showStartOfDay"?: boolean | undefined; "start"?: string; diff --git a/packages/web-components/src/components/rux-timeline/helpers.ts b/packages/web-components/src/components/rux-timeline/helpers.ts index 59be8518f..46cf18770 100644 --- a/packages/web-components/src/components/rux-timeline/helpers.ts +++ b/packages/web-components/src/components/rux-timeline/helpers.ts @@ -119,7 +119,7 @@ export function dateRange( i === 0 || time.getMonth() === 0 ? formatInTimeZone(time, timezone, 'MM/dd/yy') : formatInTimeZone(time, timezone, 'MM/dd') - return [formattedTime] + return [formattedTime, time] }) return output @@ -142,7 +142,7 @@ export function dateRange( i === 0 || showYear ? formatInTimeZone(time, timezone, 'MM/dd/yy') : formatInTimeZone(time, timezone, 'MM/dd') - return [formattedTime] + return [formattedTime, time] }) return output @@ -157,7 +157,7 @@ export function dateRange( const time = agnosticAddDays(startDate, i) const formattedTime = formatInTimeZone(time, timezone, 'MM/dd') - return [formattedTime] + return [formattedTime, time] }) return output diff --git a/packages/web-components/src/components/rux-timeline/rux-ruler/rux-ruler.tsx b/packages/web-components/src/components/rux-timeline/rux-ruler/rux-ruler.tsx index a26ded5b9..006438bbc 100644 --- a/packages/web-components/src/components/rux-timeline/rux-ruler/rux-ruler.tsx +++ b/packages/web-components/src/components/rux-timeline/rux-ruler/rux-ruler.tsx @@ -1,5 +1,7 @@ import { Prop, Component, Element, Host, h, Fragment } from '@stencil/core' +import { differenceInDays, endOfMonth, getDaysInMonth } from 'date-fns' import { dateRange as getRange } from '../helpers' +import { formatInTimeZone } from 'date-fns-tz' @Component({ tag: 'rux-ruler', styleUrl: 'rux-ruler.scss', @@ -26,7 +28,7 @@ export class RuxRuler { @Prop({ reflect: true }) timezone = 'UTC' /** - * Display the day (MM/DD) at 00:00. Only works when Timeline interval is set to 'hour'. + * Display the day (MM/DD) at 00:00. Only works when Timeline interval is set to 'hour' or 'minutes'. */ @Prop({ attribute: 'show-start-of-day' }) showStartOfDay? = false @@ -42,27 +44,29 @@ export class RuxRuler { getColumn(index: number) { let unitOfTime = 60 - if (this.interval === 'day') { - unitOfTime = 24 + if (['minute', 'hour'].includes(this.interval)) { + this.timePattern = this.timePatterns['day'] } - // same as for days - if (this.interval === 'week') { + if (['day', 'week'].includes(this.interval)) { unitOfTime = 24 + this.timePattern = this.timePatterns['month'] } if (this.interval === 'month') { unitOfTime = 24 + this.timePattern = this.timePatterns['year'] } const start = unitOfTime * index + 2 const end = start + unitOfTime + return `${unitOfTime * index + 2} / ${end}` } getWeekColumn(index: number) { - let unitOfTime = 60 - let intervalOfTime = 60 * 24 + let unitOfTime = 60 // hour and minutes interval of columns + let intervalOfTime = unitOfTime * 24 // by default assume hours 24hours in a day if (this.interval === 'minute') { - intervalOfTime = intervalOfTime * 60 + intervalOfTime = intervalOfTime * 60 // interval * minutes * hours for minutes } const start = unitOfTime * index + 2 const end = start + intervalOfTime @@ -70,27 +74,65 @@ export class RuxRuler { return `${unitOfTime * index + 2} / ${end}` } - getPartialDay() { - let partialDay = { - end: -1, - date: this.dateRange[0][1], + getMonthColumn(index: number) { + const date = this.dateRange[index][1] as Date + let unitOfTime = 24 // day/week/month grid unit + let intervalOfTime = unitOfTime * getDaysInMonth(date) + if (this.interval === 'week') { + const endofMonthDate: Date = endOfMonth(date) + const daysBetween: number = differenceInDays(endofMonthDate, date) + /** + * days between the first day shown of the month and the last day of the month + * divided by days in a week + */ + intervalOfTime = unitOfTime * Math.ceil(daysBetween / 7) } - /** - * If this.firsNewDay exists it means that there is the start of a day within the date range - * so we need to find where it starts and backfill the previous day to the start day - */ - if (this.firstNewDay) { - //Set Last Column - let unitOfTime = 60 - if (this.interval === 'minute') { - unitOfTime = unitOfTime * 60 + const start = unitOfTime * index + 2 + const end = start + intervalOfTime + return `${unitOfTime * index + 2} / ${end}` + } + + getYearColumn(index: number) { + let unitOfTime = 24 // day/week/month grid unit + let intervalOfTime = unitOfTime * 12 // 12 months in a year + const start = unitOfTime * index + 2 + const end = start + intervalOfTime + + return `${unitOfTime * index + 2} / ${end}` + } + + getPartial() { + let partialIncrement: string = '-1' + const getText = () => { + let text: string = '' + if (['minute', 'hour'].includes(this.interval)) { + text = this.dateRange[0][1] as string + } + if (['day', 'week'].includes(this.interval)) { + text = formatInTimeZone( + this.dateRange[0][1] as Date, + this.timezone, + 'MMMM' + ) } - const prevDay = this.dateRange[this.firstNewDay - 1] - const end = unitOfTime * this.firstNewDay! + 2 - partialDay = { - end, - date: prevDay[1], + if (this.interval === 'month') { + text = formatInTimeZone( + this.dateRange[0][1] as Date, + this.timezone, + 'yyyy' + ) } + return text + } + const textContent = getText() + + /** + * If this.firsFullIncrement exists it means that there is the start of a time increment within the date range + * so we need to find where it starts and backfill the previous increment to the start of the new day + */ + if (this.firstFullIncrement) { + partialIncrement = this.firstFullIncrement + this.firstFullIncrement = undefined } /** @@ -103,46 +145,129 @@ export class RuxRuler { class="ruler-new-day-display" style={{ gridRow: '2', - gridColumn: `2 / ${partialDay.end}`, + gridColumn: `2 / ${partialIncrement}`, + display: + Number(partialIncrement) === 2 ? 'none' : undefined, }} > - {partialDay.date} + {textContent} ) } - timePattern = /^00:00+$/ + timePatterns = { + day: /^00:00+$/, + month: /^[0-1][0-9]\/01/, + year: /^01\/([0-3][0-9])/, + } + timePattern: RegExp = this.timePatterns['day'] - shouldShowDate(time: string) { - if (!['hour', 'minute'].includes(this.interval)) { - return false + secondaryRuler(time: string, newDay: string, index: number) { + if (!this.showStartOfDay) return null + let gridColumn + let textDisplay = '' + if ( + ['hour', 'minute'].includes(this.interval) && + this.shouldShow(time) + ) { + if (!this.firstFullIncrement) + this.firstFullIncrement = this.getWeekColumn(index).split( + '/' + )[0] + gridColumn = this.getWeekColumn(index) + textDisplay = newDay + } + if ( + (this.interval === 'day' && this.shouldShow(time)) || + (this.interval === 'week' && this.shouldShowMonth(index)) + ) { + if (!this.firstFullIncrement) { + this.firstFullIncrement = this.getMonthColumn(index).split( + '/' + )[0] + } + gridColumn = this.getMonthColumn(index) + textDisplay = formatInTimeZone( + this.dateRange[index][1] as Date, + this.timezone, + 'MMMM' + ) } - if (!this.showStartOfDay) { - return false + if (['month'].includes(this.interval) && this.shouldShow(time)) { + if (!this.firstFullIncrement) + this.firstFullIncrement = this.getYearColumn(index).split( + '/' + )[0] + gridColumn = this.getYearColumn(index) + textDisplay = formatInTimeZone( + this.dateRange[index][1] as Date, + this.timezone, + 'yyyy' + ) } + return gridColumn ? ( + + {textDisplay} + + ) : null + } + + /** + * Returns boolean value when comparing hour minute day month against pattern + */ + shouldShow(time: string) { return this.timePattern.test(time) } - private firstNewDay: number | undefined + /** + * month is a special case because there is no obvious + * time pattern to tell when a new one happens, it has to + * rely on the dates around it + */ + shouldShowMonth(index: number) { + if (this.interval === 'week') { + if (index === 0) return false + const currentWeek = (this.dateRange[index][0] as string).slice(0, 3) + const prevWeek = (this.dateRange[index - 1][0] as string).slice( + 0, + 3 + ) + if (prevWeek !== currentWeek && !this.firstFullIncrement) + this.firstFullIncrement = this.getMonthColumn(index).split( + '/' + )[0] + return prevWeek !== currentWeek + } + return false + } + + private firstFullIncrement: string | undefined render() { return (
{this.dateRange.map( ([time, newDayDate]: any, index: any) => { - const newDay = this.timePattern.test(time) - ? newDayDate - : '' - if (newDay !== '' && !this.firstNewDay) - this.firstNewDay = index + let newDay + if (['hour', 'minute'].includes(this.interval)) { + newDay = this.timePattern.test(time) + ? newDayDate + : '' + } return ( {time} - {this.shouldShowDate(time) ? ( - - {newDay} - - ) : null} + {this.secondaryRuler(time, newDay, index)} ) } )} - {this.showStartOfDay && - ['hour', 'minute'].includes(this.interval) - ? this.getPartialDay() - : null} + {this.showStartOfDay ? this.getPartial() : null}
) diff --git a/packages/web-components/src/index.html b/packages/web-components/src/index.html index 3ca0c4574..6ad97accf 100644 --- a/packages/web-components/src/index.html +++ b/packages/web-components/src/index.html @@ -88,9 +88,9 @@ id="first" has-played-indicator="false" timezone="America/New_York" - start="2021-02-01T00:00:00.000Z" - end="2021-03-03T01:00:00.000Z" - playhead="2021-02-02T00:00:00.000Z" + start="2021-01-01T00:00:00.000Z" + end="2021-03-01T01:00:00.000Z" + playhead="2021-01-02T00:00:00.000Z" interval="hour" zoom="4" show-grid @@ -108,139 +108,13 @@
Region 2
Event 2.1
- -
Region 3
- - Event 3.1 - -
- -
Region 4
- - Event 4.1 - -
- -
Region 5
- - Event 5.1 - -
- -
Region 6
- - Event 6.1 - -
- -
Region 7
- - Event 7.1 - -
- - - - - -
- Current Zoom: - - - - Toggle Grid -
- - - -
Region 1
- - Event 1.2 - -
- -
Region 2
- - Event 2.1 - -
- -
Region 3
- - Event 3.1 - -
- -
Region 4
- - Event 4.1 - -
@@ -250,15 +124,11 @@