Skip to content

Commit

Permalink
fix(datepicker): fixed viewed date if min max is set
Browse files Browse the repository at this point in the history
if no date is selected and min or max dates are excluding current month
show minimal or maximal provided date

fixes #3123 fixes #2711
  • Loading branch information
valorkin committed Nov 28, 2017
1 parent d9822f0 commit 52865f5
Showing 1 changed file with 65 additions and 37 deletions.
102 changes: 65 additions & 37 deletions src/datepicker/reducer/bs-datepicker.reducer.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,24 @@
// tslint:disable:max-file-line-count
import {
BsDatepickerState,
initialDatepickerState
} from './bs-datepicker.state';
import { BsDatepickerState, initialDatepickerState } from './bs-datepicker.state';
import { Action } from '../../mini-ngrx/index';
import { BsDatepickerActions } from './bs-datepicker.actions';
import { calcDaysCalendar } from '../engine/calc-days-calendar';
import { formatDaysCalendar } from '../engine/format-days-calendar';
import { flagDaysCalendar } from '../engine/flag-days-calendar';
import { shiftDate, setDate } from '../../bs-moment/utils/date-setters';
import { setDate, shiftDate } from '../../bs-moment/utils/date-setters';
import { canSwitchMode } from '../engine/view-mode';
import { formatMonthsCalendar } from '../engine/format-months-calendar';
import { flagMonthsCalendar } from '../engine/flag-months-calendar';
import {
formatYearsCalendar,
yearsPerCalendar
} from '../engine/format-years-calendar';
import { formatYearsCalendar, yearsPerCalendar } from '../engine/format-years-calendar';
import { flagYearsCalendar } from '../engine/flag-years-calendar';
import {
BsViewNavigationEvent,
DatepickerFormatOptions
} from '../models/index';
import { isArray, isDateValid } from '../../bs-moment/utils/type-checks';
import { BsViewNavigationEvent, DatepickerFormatOptions } from '../models/index';
import { isArray } from '../../bs-moment/utils/type-checks';
import { startOf } from '../../bs-moment/utils/start-end-of';
import { getLocale } from '../../bs-moment/locale/locales.service';
import { isAfter, isBefore } from '../../bs-moment/utils/date-compare';

export function bsDatepickerReducer(
state = initialDatepickerState,
action: Action
): BsDatepickerState {
export function bsDatepickerReducer(state = initialDatepickerState,
action: Action): BsDatepickerState {
switch (action.type) {
case BsDatepickerActions.CALCULATE: {
return calculateReducer(state);
Expand Down Expand Up @@ -97,24 +87,46 @@ export function bsDatepickerReducer(

case BsDatepickerActions.SET_OPTIONS: {
const newState = action.payload;
// looks not really good
// preserve view mode
const mode = state.view.mode;
const _viewDate = newState.value && newState.value || state.view.date;
const date = getViewDate(_viewDate, newState.minDate, newState.maxDate);
newState.view = { mode, date };
// update selected value
if (newState.value) {
newState.view = state.view;
// if new value is array we work with date range
if (isArray(newState.value)) {
newState.view = {
mode: state.view.mode,
date: isDateValid(newState.value[0]) ? newState.value[0] : newState.view.date
};
newState.selectedRange = newState.value;
} else {
newState.view = {
mode: state.view.mode,
date: newState.value
};
}

// if new value is a date -> datepicker
if (newState.value instanceof Date) {
newState.selectedDate = newState.value;
}

// provided value is not supported :)
// need to report it somehow
}

// // looks not really good
// if (newState.value) {
// newState.view = state.view;
// if (isArray(newState.value)) {
// newState.view = {
// mode: state.view.mode,
// date: isDateValid(newState.value[0]) ? newState.value[0] : newState.view.date
// };
// newState.selectedRange = newState.value;
// } else {
// newState.view = {
// mode: state.view.mode,
// date: newState.value
// };
//
// newState.selectedDate = newState.value;
// }
// }

return Object.assign({}, state, newState);
}

Expand Down Expand Up @@ -205,10 +217,8 @@ function calculateReducer(state: BsDatepickerState): BsDatepickerState {
return state;
}

function formatReducer(
state: BsDatepickerState,
action: Action
): BsDatepickerState {
function formatReducer(state: BsDatepickerState,
action: Action): BsDatepickerState {
if (state.view.mode === 'day') {
const formattedMonths = state.monthsModel.map((month, monthIndex) =>
formatDaysCalendar(month, getFormatOptions(state), monthIndex)
Expand Down Expand Up @@ -262,10 +272,8 @@ function formatReducer(
return state;
}

function flagReducer(
state: BsDatepickerState,
action: Action
): BsDatepickerState {
function flagReducer(state: BsDatepickerState,
action: Action): BsDatepickerState {
if (state.view.mode === 'day') {
const flaggedMonths = state.formattedMonths.map(
(formattedMonth, monthIndex) =>
Expand Down Expand Up @@ -333,3 +341,23 @@ function getFormatOptions(state: BsDatepickerState): DatepickerFormatOptions {
weekNumbers: state.weekNumbers
};
}

/**
* if view date is provided (bsValue|ngModel) it should be shown
* if view date is not provider:
* if minDate>currentDate (default view value), show minDate
* if maxDate<currentDate(default view value) show maxDate
*/
function getViewDate(viewDate: Date | Date[], minDate: Date, maxDate: Date) {
const _date = Array.isArray(viewDate) ? viewDate[0] : viewDate;

if (minDate && isAfter(minDate, _date, 'day')) {
return minDate;
}

if (maxDate && isBefore(maxDate, _date, 'day')) {
return maxDate;
}

return _date;
}

0 comments on commit 52865f5

Please sign in to comment.