Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Commit

Permalink
Merge pull request #854 from plotly/hg-700-persistence
Browse files Browse the repository at this point in the history
PersistenceTransforms for date in datePickerRange and datePickerSingle
  • Loading branch information
harryturr authored Sep 4, 2020
2 parents 8a36e62 + 0519d89 commit 49c42db
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Fixed
- [#854](https://github.com/plotly/dash-core-components/pull/854) Used `persistenceTransforms` to strip the time part of the datetime in the persited props of DatePickerSingle (date) and DatePickerRange (end_date, start_date), fixing [dcc#700](https://github.com/plotly/dash-core-components/issues/700).

### Added
- [#850](https://github.com/plotly/dash-core-components/pull/850) Add property `prependData` to `Graph` to support `Plotly.prependTraces`
+ refactored the existing `extendTraces` API to be a single `mergeTraces` API that can handle both `prepend` as well as `extend`.
Expand Down
6 changes: 6 additions & 0 deletions src/components/DatePickerRange.react.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import PropTypes from 'prop-types';
import React, {Component, lazy, Suspense} from 'react';
import datePickerRange from '../utils/LazyLoader/datePickerRange';
import transformDate from '../utils/DatePickerPersistence';

const RealDatePickerRange = lazy(datePickerRange);

Expand Down Expand Up @@ -263,6 +264,11 @@ DatePickerRange.propTypes = {
persistence_type: PropTypes.oneOf(['local', 'session', 'memory']),
};

DatePickerRange.persistenceTransforms = {
end_date: transformDate,
start_date: transformDate,
};

DatePickerRange.defaultProps = {
calendar_orientation: 'horizontal',
is_RTL: false,
Expand Down
5 changes: 5 additions & 0 deletions src/components/DatePickerSingle.react.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import PropTypes from 'prop-types';
import React, {Component, lazy, Suspense} from 'react';
import datePickerSingle from '../utils/LazyLoader/datePickerSingle';
import transformDate from '../utils/DatePickerPersistence';

const RealDateSingleRange = lazy(datePickerSingle);

Expand Down Expand Up @@ -220,6 +221,10 @@ DatePickerSingle.propTypes = {
persistence_type: PropTypes.oneOf(['local', 'session', 'memory']),
};

DatePickerSingle.persistenceTransforms = {
date: transformDate,
};

DatePickerSingle.defaultProps = {
calendar_orientation: 'horizontal',
is_RTL: false,
Expand Down
14 changes: 14 additions & 0 deletions src/utils/DatePickerPersistence.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import moment from 'moment';
import {isNil} from 'ramda';

export default {
extract: propValue => {
if (!isNil(propValue)) {
return moment(propValue)
.startOf('day')
.format('YYYY-MM-DD');
}
return propValue;
},
apply: storedValue => storedValue,
};
87 changes: 87 additions & 0 deletions tests/integration/calendar/test_date_picker_persistence.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from datetime import datetime

import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output


def test_rdpr001_persisted_dps(dash_dcc):
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.Button("fire callback", id="btn", n_clicks=1),
html.Div(children=[html.Div(id="container"), html.P("dps", id="dps-p")]),
]
)

# changing value of date with each callback to verify
# persistenceTransforms is stripping the time-part from the date-time
@app.callback(Output("container", "children"), [Input("btn", "n_clicks")])
def update_output(value):
return dcc.DatePickerSingle(
id="dps",
min_date_allowed=datetime(2020, 1, 1),
max_date_allowed=datetime(2020, 1, 7),
date=datetime(2020, 1, 3, 1, 1, 1, value),
persistence=True,
persistence_type="session",
)

@app.callback(Output("dps-p", "children"), [Input("dps", "date")])
def display_dps(value):
return value

dash_dcc.start_server(app)

dash_dcc.select_date_single("dps", day="2")
dash_dcc.wait_for_text_to_equal("#dps-p", "2020-01-02")
dash_dcc.find_element("#btn").click()
dash_dcc.wait_for_text_to_equal("#dps-p", "2020-01-02")


def test_rdpr002_persisted_dpr(dash_dcc):
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.Button("fire callback", id="btn", n_clicks=1),
html.Div(
children=[
html.Div(id="container"),
html.P("dpr", id="dpr-p-start"),
html.P("dpr", id="dpr-p-end"),
]
),
]
)

# changing value of start_date and end_date with each callback to verify
# persistenceTransforms is stripping the time-part from the date-time
@app.callback(Output("container", "children"), [Input("btn", "n_clicks")])
def update_output(value):
return dcc.DatePickerRange(
id="dpr",
min_date_allowed=datetime(2020, 1, 1),
max_date_allowed=datetime(2020, 1, 7),
start_date=datetime(2020, 1, 3, 1, 1, 1, value),
end_date=datetime(2020, 1, 4, 1, 1, 1, value),
persistence=True,
persistence_type="session",
)

@app.callback(Output("dpr-p-start", "children"), [Input("dpr", "start_date")])
def display_dpr_start(value):
return value

@app.callback(Output("dpr-p-end", "children"), [Input("dpr", "end_date")])
def display_dpr_end(value):
return value

dash_dcc.start_server(app)

dash_dcc.select_date_range("dpr", (2, 5))
dash_dcc.wait_for_text_to_equal("#dpr-p-start", "2020-01-02")
dash_dcc.wait_for_text_to_equal("#dpr-p-end", "2020-01-05")
dash_dcc.find_element("#btn").click()
dash_dcc.wait_for_text_to_equal("#dpr-p-start", "2020-01-02")
dash_dcc.wait_for_text_to_equal("#dpr-p-end", "2020-01-05")

0 comments on commit 49c42db

Please sign in to comment.