From c6c6fcf8957b6b02866095c31583262b9f490bfe Mon Sep 17 00:00:00 2001 From: braimbault Date: Wed, 11 Dec 2024 11:43:26 +0100 Subject: [PATCH] fix: refactor Timeline --- src/components/periods/Timeline.js | 101 ++++++++++++++--------------- src/constants/periods.js | 2 + src/util/periods.js | 50 ++++++-------- 3 files changed, 73 insertions(+), 80 deletions(-) diff --git a/src/components/periods/Timeline.js b/src/components/periods/Timeline.js index 62c2a22d1..65138bad4 100644 --- a/src/components/periods/Timeline.js +++ b/src/components/periods/Timeline.js @@ -8,61 +8,56 @@ import { getPeriodTypeFromId, getPeriodLevelFromPeriodType, } from '../../util/periods.js' +import { doubleTicksPeriods } from '../../constants/periods.js' import timeTicks from '../../util/timeTicks.js' import styles from './styles/Timeline.module.css' -const paddingLeft = 40 -const paddingRight = 20 -const labelWidth = 80 -const delay = 1500 -const playBtn = -const pauseBtn = -const doubleTicksPeriods = ['LAST_6_BIMONTHS', 'BIMONTHS_THIS_YEAR'] -const rectHeight = 7 -const rectOffset = 10 - -const addPeriodTypeAndLevel = (item) => { - item.type = getPeriodTypeFromId(item.id) - item.level = getPeriodLevelFromPeriodType(item.type) - return item +// Constants +const PADDING_LEFT = 40 +const PADDING_RIGHT = 20 +const LABEL_WIDTH = 80 +const RECT_HEIGHT = 8 +const RECT_OFFSET = 8 +const DELAY = 1500 +const PLAY_ICON = +const PAUSE_ICON = + +// Utility Functions +const addPeriodDetails = (period) => { + const type = getPeriodTypeFromId(period.id) + const level = getPeriodLevelFromPeriodType(type) + return { ...period, type, level } } -const listLevelsFromPeriods = (periodsWithType) => [ - ...new Set(periodsWithType.map((item) => item.level)), +const getUniqueLevels = (periodsWithLevel) => [ + ...new Set(periodsWithLevel.map((item) => item.level)), ] const countUniqueRanks = (periods) => { - const periodsWithType = periods.map((item) => addPeriodTypeAndLevel(item)) - return listLevelsFromPeriods(periodsWithType).length + const periodsWithDetails = periods.map(addPeriodDetails) + return getUniqueLevels(periodsWithDetails).length } const sortPeriodsByLevelRank = (periods) => { - let periodsWithDetails - periodsWithDetails = periods.map((item) => addPeriodTypeAndLevel(item)) - - const sortedLevels = listLevelsFromPeriods(periodsWithDetails).sort( + const periodsWithDetails = periods.map(addPeriodDetails) + const sortedLevels = getUniqueLevels(periodsWithDetails).sort( (a, b) => b - a ) - periodsWithDetails = periodsWithDetails.map((item) => ({ - ...item, - levelRank: sortedLevels.indexOf(item.level), - })) - - const sortedPeriods = periodsWithDetails.sort( - (a, b) => a.levelRank - b.levelRank - ) - return sortedPeriods + return periodsWithDetails + .map((item) => ({ + ...item, + levelRank: sortedLevels.indexOf(item.level), + })) + .sort((a, b) => a.levelRank - b.levelRank) } -const sortPeriodsByLevelAndStartDate = (periods) => { - let sortedPeriods - sortedPeriods = periods.sort((a, b) => b.level - a.level) - sortedPeriods = periods.sort( - (a, b) => new Date(a.startDate) - new Date(b.startDate) - ) - return sortedPeriods -} +const sortPeriodsByLevelAndStartDate = (periods) => + periods + .map(addPeriodDetails) + .sort((a, b) => b.level - a.level) + .sort((a, b) => new Date(a.startDate) - new Date(b.startDate)) +// Timeline Component class Timeline extends Component { static contextTypes = { map: PropTypes.object, @@ -98,7 +93,7 @@ class Timeline extends Component { const uniqueRanks = countUniqueRanks(this.props.periods) this.setTimeScale() - const rectTotalHeight = rectHeight + (uniqueRanks - 1) * rectOffset + const rectTotalHeight = RECT_HEIGHT + (uniqueRanks - 1) * RECT_OFFSET return ( - {mode === 'play' ? pauseBtn : playBtn} + {mode === 'play' ? PAUSE_ICON : PLAY_ICON} // rectangles - + {this.getPeriodRects()} // x axis (this.node = node)} @@ -150,9 +145,9 @@ class Timeline extends Component { [styles.selected]: isCurrent, })} x={x} - y={item.levelRank * rectOffset} + y={item.levelRank * RECT_OFFSET} width={width} - height={rectHeight} + height={RECT_HEIGHT} onClick={() => this.onPeriodClick(item)} /> ) @@ -192,11 +187,15 @@ class Timeline extends Component { // Set timeline axis setTimeAxis = () => { - const { periodId, periods } = this.props + const { periods } = this.props + const periodsType = periods.map(({ id }) => getPeriodTypeFromId(id)) const numPeriods = - periods.length * (doubleTicksPeriods.includes(periodId) ? 2 : 1) + periods.length * + (doubleTicksPeriods.some((element) => periodsType.includes(element)) + ? 2 + : 1) const { width } = this.state - const maxTicks = Math.round(width / labelWidth) + const maxTicks = Math.round(width / LABEL_WIDTH) const numTicks = maxTicks < numPeriods ? maxTicks : numPeriods const timeAxis = axisBottom(this.timeScale) const [startDate, endDate] = this.timeScale.domain() @@ -212,7 +211,7 @@ class Timeline extends Component { if (this.node) { // clientWith returns 0 for SVG elements in Firefox const box = this.node.parentNode.getBoundingClientRect() - const width = box.right - box.left - paddingLeft - paddingRight + const width = box.right - box.left - PADDING_LEFT - PADDING_RIGHT this.setState({ width }) } @@ -264,8 +263,8 @@ class Timeline extends Component { onChange(sortedPeriods[index + 1]) } - // Call itself after delay - this.timeout = setTimeout(this.play, delay) + // Call itself after DELAY + this.timeout = setTimeout(this.play, DELAY) } // Stop animation diff --git a/src/constants/periods.js b/src/constants/periods.js index 7d8914f33..837eb42f1 100644 --- a/src/constants/periods.js +++ b/src/constants/periods.js @@ -52,6 +52,8 @@ const LAST_FINANCIAL_YEAR = 'LAST_FINANCIAL_YEAR' const THIS_YEAR = 'THIS_YEAR' const LAST_YEAR = 'LAST_YEAR' +export const doubleTicksPeriods = [BIMONTHLY, SIXMONTHLY, SIXMONTHLYAPR] + export const PREDEFINED_PERIODS = 'PREDEFINED_PERIODS' export const RELATIVE_PERIODS = 'RELATIVE_PERIODS' export const FIXED_PERIODS = 'FIXED_PERIODS' diff --git a/src/util/periods.js b/src/util/periods.js index 5ce5eb96b..5237dd883 100644 --- a/src/util/periods.js +++ b/src/util/periods.js @@ -160,33 +160,25 @@ export const getPeriodTypeFromId = (periodId) => { } export const getPeriodLevelFromPeriodType = (periodType) => { - switch (periodType) { - case DAILY: - return 0 - case WEEKLY: - case WEEKLYWED: - case WEEKLYTHU: - case WEEKLYSAT: - case WEEKLYSUN: - return 1 - case BIWEEKLY: - return 2 - case MONTHLY: - return 3 - case BIMONTHLY: - return 4 - case QUARTERLY: - return 5 - case SIXMONTHLY: - case SIXMONTHLYAPR: - return 6 - case YEARLY: - case FYNOV: - case FYOCT: - case FYJUL: - case FYAPR: - return 7 - default: - return 8 - } + const periodTypesByLevel = [ + DAILY, + WEEKLY, + WEEKLYWED, + WEEKLYTHU, + WEEKLYSAT, + WEEKLYSUN, + BIWEEKLY, + MONTHLY, + BIMONTHLY, + QUARTERLY, + SIXMONTHLY, + SIXMONTHLYAPR, + YEARLY, + FINANCIAL, + FYNOV, + FYOCT, + FYJUL, + FYAPR, + ] + return periodTypesByLevel.indexOf(periodType) }