Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Vineela | AP-69 | Add date and week picker and navigator
- Loading branch information
1 parent
8fc8102
commit 39f1af9
Showing
5 changed files
with
246 additions
and
0 deletions.
There are no files selected for viewing
72 changes: 72 additions & 0 deletions
72
ui/react-components/components/DateOrWeekNavigator/DateOrWeekNavigator.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import React, {useState} from "react"; | ||
import classNames from "classnames"; | ||
import moment from 'moment'; | ||
import { | ||
weekNavigator, | ||
labelForDate | ||
} from "./DateOrWeekNavigator.module.scss"; | ||
import PropTypes from "prop-types"; | ||
import {getWeekEndDate, getWeekStartDate} from "../../utils/DateOrWeekNavigator/weekDatesHelper"; | ||
|
||
|
||
const DateOrWeekNavigator = (props) => { | ||
|
||
const {isWeek, weekStart} = props; | ||
|
||
const initialDates = { | ||
viewDate: moment().format('yyyy-MM-DD'), | ||
weekStartDate: getWeekStartDate(moment().toDate(), weekStart), | ||
weekEndDate: getWeekEndDate(moment().toDate(), weekStart) | ||
}; | ||
|
||
const [calendarDates, setCalendarDates] = useState(initialDates); | ||
|
||
|
||
const goToPreviousWeek = () => { | ||
const date = calendarDates.viewDate; | ||
isWeek ? updateViewDateAndWeekDays(moment(date).subtract(7, "days").format('yyyy-MM-DD')) | ||
: updateViewDateAndWeekDays(moment(date).subtract(1, "days").format('yyyy-MM-DD')); | ||
}; | ||
|
||
const goToNextWeek = () => { | ||
const date = calendarDates.viewDate; | ||
isWeek ? updateViewDateAndWeekDays(moment(date).add(7, "days").format('yyyy-MM-DD')) | ||
: updateViewDateAndWeekDays(moment(date).add(1, "days").format('yyyy-MM-DD'));; | ||
}; | ||
|
||
|
||
const updateViewDateAndWeekDays = (date) => { | ||
setCalendarDates({ | ||
viewDate: moment(date).format('yyyy-MM-DD'), | ||
weekStartDate: getWeekStartDate(date, weekStart), | ||
weekEndDate: getWeekEndDate(date, weekStart) | ||
}); | ||
}; | ||
|
||
|
||
return ( | ||
<div className={classNames(weekNavigator)}> | ||
<button data-testid="leftNavigator" onClick={() => goToPreviousWeek()}> | ||
<i className="fa fa-angle-left"></i> | ||
</button> | ||
<span> | ||
{isWeek ? <label htmlFor="weekDates" | ||
className={classNames(labelForDate)}>{calendarDates.weekStartDate} - {calendarDates.weekEndDate} </label> : null} | ||
<input type="date" id="weekDates" value={calendarDates.viewDate} | ||
onChange={date => updateViewDateAndWeekDays(date.target.value)} required/> | ||
</span> | ||
<button data-testid="rightNavigator" onClick={() => goToNextWeek()}> | ||
<i className="fa fa-angle-right"></i> | ||
</button> | ||
</div> | ||
); | ||
}; | ||
|
||
|
||
export default DateOrWeekNavigator; | ||
|
||
|
||
DateOrWeekNavigator.propTypes = { | ||
isWeek: PropTypes.bool, | ||
weekStart: PropTypes.number | ||
}; |
42 changes: 42 additions & 0 deletions
42
ui/react-components/components/DateOrWeekNavigator/DateOrWeekNavigator.module.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
.weekNavigator { | ||
position: absolute; | ||
width: calc(100% - 310px); | ||
text-align: center; | ||
box-sizing: border-box; | ||
top: 126px; | ||
right: 179px; | ||
|
||
|
||
button, input { | ||
background: #F8F8F8; | ||
border: none; | ||
outline: none; | ||
font-size: 14px; | ||
padding: 8px 10px; | ||
border-radius: 3px; | ||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); | ||
transition: all 0.3s cubic-bezier(.25, .8, .25, 1); | ||
display: inline-block; | ||
color: #000; | ||
margin-left: 10px; | ||
&:hover { | ||
box-shadow: 0 4px 9px rgba(0, 0, 0, 0.25), 0 5px 5px rgba(0, 0, 0, 0.22); | ||
opacity: 1; | ||
} | ||
} | ||
|
||
.labelForDate{ | ||
width: 115px; | ||
position: absolute; | ||
cursor: pointer; | ||
background: #F8F8F8; | ||
padding: 9px; | ||
margin-left: 10px; | ||
} | ||
|
||
input { | ||
width: 155px; | ||
position: initial; | ||
font-family: OpenSans, Arial, sans-serif, Arial, sans-serif;; | ||
} | ||
} |
107 changes: 107 additions & 0 deletions
107
ui/react-components/components/DateOrWeekNavigator/DateOrWeekNavigator.test.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import React from 'react'; | ||
import '@testing-library/jest-dom/extend-expect'; | ||
import { fireEvent } from '@testing-library/react'; | ||
import moment from "moment"; | ||
import DateOrWeekNavigator from "./DateOrWeekNavigator"; | ||
import {renderWithReactIntl} from "../../utils/TestUtil"; | ||
|
||
describe('DateOrWeekNavigator', ()=>{ | ||
|
||
it('should have today as default date and current week startDate and endDate displayed for week view on page load',()=>{ | ||
const today = moment().format('YYYY-MM-DD'); | ||
const {container} = renderWithReactIntl(<DateOrWeekNavigator isWeek={true} weekStart={7}/>); | ||
const inputValue = container.querySelector('#weekDates'); | ||
expect(inputValue.value).toBe(today); | ||
const labelOnDatePicker = container.querySelector(".labelForDate"); | ||
expect(labelOnDatePicker).not.toBeNull(); | ||
}); | ||
|
||
it('should have today as default date and no week startDate and endDate be displayed for day view ',()=>{ | ||
const today = moment().format('YYYY-MM-DD'); | ||
const {container} = renderWithReactIntl(<DateOrWeekNavigator isWeek={false} weekStart={7}/>); | ||
const inputValue = container.querySelector('#weekDates'); | ||
expect(inputValue.value).toBe(today); | ||
const labelOnDatePicker = container.querySelector(".labelForDate"); | ||
expect(labelOnDatePicker).toBeNull(); | ||
}); | ||
|
||
it('should update the input value and corresponding week startDate and endDate when date is changed', ()=>{ | ||
const today= moment().format('YYYY-MM-DD'); | ||
const {container} = renderWithReactIntl(<DateOrWeekNavigator isWeek={true} weekStart={7}/>); | ||
const inputField = container.querySelector('#weekDates'); | ||
expect(inputField.value).toBe(today); | ||
const newDate= moment("15-07-2020", 'DD-MM-YYYY').format('YYYY-MM-DD'); | ||
fireEvent.change(inputField, {target:{value:newDate}}); | ||
expect(inputField.value).toBe(newDate); | ||
const labelOnDatePicker = container.querySelector(".labelForDate"); | ||
expect(labelOnDatePicker).toHaveTextContent("12 Jul - 18 Jul"); | ||
}); | ||
|
||
it('should update only input value when date is changed in day view', ()=>{ | ||
const today= moment().format('YYYY-MM-DD'); | ||
const {container} = renderWithReactIntl(<DateOrWeekNavigator isWeek={false} weekStart={7}/>); | ||
const inputField = container.querySelector('#weekDates'); | ||
expect(inputField.value).toBe(today); | ||
const newDate= moment("15-07-2020", 'DD-MM-YYYY').format('YYYY-MM-DD'); | ||
fireEvent.change(inputField, {target:{value:newDate}}); | ||
expect(inputField.value).toBe(newDate); | ||
const labelOnDatePicker = container.querySelector(".labelForDate"); | ||
expect(labelOnDatePicker).toBeNull(); | ||
}); | ||
|
||
it('should display previous week values for selected date when clicked on left navigator', ()=>{ | ||
const {container, getByTestId} = renderWithReactIntl(<DateOrWeekNavigator isWeek={true} weekStart={7}/>); | ||
const inputField = container.querySelector('#weekDates'); | ||
const selectDate= moment("15-07-2020", 'DD-MM-YYYY').format('YYYY-MM-DD'); | ||
fireEvent.change(inputField, {target:{value:selectDate}}); | ||
const previousWeekNavigator = getByTestId("leftNavigator"); | ||
const previousWeekDate = moment(selectDate).subtract(7, "days").format('YYYY-MM-DD'); | ||
fireEvent.click(previousWeekNavigator); | ||
expect(inputField.value).toBe(previousWeekDate); | ||
const labelOnDatePicker = container.querySelector(".labelForDate"); | ||
expect(labelOnDatePicker).toHaveTextContent("05 Jul - 11 Jul"); | ||
|
||
}); | ||
|
||
it('should display previous date for selected date when clicked on left navigator', ()=>{ | ||
const {container, getByTestId} = renderWithReactIntl(<DateOrWeekNavigator isWeek={false} weekStart={7}/>); | ||
const inputField = container.querySelector('#weekDates'); | ||
const selectDate= moment("15-07-2020", 'DD-MM-YYYY').format('YYYY-MM-DD'); | ||
fireEvent.change(inputField, {target:{value:selectDate}}); | ||
const previousDayNavigator = getByTestId("leftNavigator"); | ||
const previousDate = moment(selectDate).subtract(1, "days").format('YYYY-MM-DD'); | ||
fireEvent.click(previousDayNavigator); | ||
expect(inputField.value).toBe(previousDate); | ||
const labelOnDatePicker = container.querySelector(".labelForDate"); | ||
expect(labelOnDatePicker).toBeNull(); | ||
|
||
}); | ||
|
||
it('should display next week values for selected date when clicked on right navigator', ()=>{ | ||
const {container, getByTestId} = renderWithReactIntl(<DateOrWeekNavigator isWeek={true} weekStart={7}/>); | ||
const inputField = container.querySelector('#weekDates'); | ||
const selectDate= moment("15-07-2020", 'DD-MM-YYYY').format('YYYY-MM-DD'); | ||
fireEvent.change(inputField, {target:{value:selectDate}}); | ||
const nextWeekNavigator = getByTestId("rightNavigator"); | ||
const nextWeekDate = moment(selectDate).add(7, "days").format('YYYY-MM-DD'); | ||
fireEvent.click(nextWeekNavigator); | ||
expect(inputField.value).toBe(nextWeekDate); | ||
const labelOnDatePicker = container.querySelector(".labelForDate"); | ||
expect(labelOnDatePicker).toHaveTextContent("19 Jul - 25 Jul"); | ||
|
||
}); | ||
|
||
it('should display next date for selected date when clicked on right navigator', ()=>{ | ||
const {container, getByTestId} = renderWithReactIntl(<DateOrWeekNavigator isWeek={false} weekStart={7}/>); | ||
const inputField = container.querySelector('#weekDates'); | ||
const selectDate= moment("15-07-2020", 'DD-MM-YYYY').format('YYYY-MM-DD'); | ||
fireEvent.change(inputField, {target:{value:selectDate}}); | ||
const nextDayNavigator = getByTestId("rightNavigator"); | ||
const nextDate = moment(selectDate).add(1, "days").format('YYYY-MM-DD'); | ||
fireEvent.click(nextDayNavigator); | ||
expect(inputField.value).toBe(nextDate); | ||
const labelOnDatePicker = container.querySelector(".labelForDate"); | ||
expect(labelOnDatePicker).toBeNull(); | ||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import React from 'react' | ||
import DateOrWeekNavigator from "../components/DateOrWeekNavigator/DateOrWeekNavigator"; | ||
|
||
export default { title: 'DateOrWeekNavigator' }; | ||
|
||
export const dayView = () => ( <DateOrWeekNavigator isWeek = {false}/> ); | ||
|
||
export const weekView = () => ( <DateOrWeekNavigator isWeek = {true} weekStart= {7}/> ); |
17 changes: 17 additions & 0 deletions
17
ui/react-components/utils/DateOrWeekNavigator/weekDatesHelper.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import moment from "moment"; | ||
|
||
export const getWeekStartDate = (date, weekStart) => { | ||
const daysToBeSubtracted = daysToSubtract(date, weekStart); | ||
return moment(date).subtract(daysToBeSubtracted, "days").format('DD MMM'); | ||
}; | ||
|
||
export const getWeekEndDate = (date, weekStart) => { | ||
const daysToBeAdded = 6 - daysToSubtract(date, weekStart); | ||
return moment(date).add(daysToBeAdded, "days").format('DD MMM'); | ||
}; | ||
|
||
const daysToSubtract = (date, weekStart) => { | ||
return moment(date).weekday() >= weekStart ? | ||
moment(date).weekday() - weekStart : | ||
7 + moment(date).weekday() - weekStart; | ||
}; |