diff --git a/src/components/BrowserFilter/BrowserFilter.react.js b/src/components/BrowserFilter/BrowserFilter.react.js index 38aeba2825..c71fa51cb2 100644 --- a/src/components/BrowserFilter/BrowserFilter.react.js +++ b/src/components/BrowserFilter/BrowserFilter.react.js @@ -17,6 +17,7 @@ import Label from 'components/Label/Label.react'; import Position from 'lib/Position'; import React from 'react'; import styles from 'components/BrowserFilter/BrowserFilter.scss'; +import Checkbox from 'components/Checkbox/Checkbox.react'; import { List, Map } from 'immutable'; const POPOVER_CONTENT_ID = 'browserFilterPopover'; @@ -32,6 +33,7 @@ export default class BrowserFilter extends React.Component { confirmName: false, name: '', blacklistedFilters: Filters.BLACKLISTED_FILTERS.concat(props.blacklistedFilters), + relativeDates: false, }; this.toggle = this.toggle.bind(this); this.wrapRef = React.createRef(); @@ -114,7 +116,7 @@ export default class BrowserFilter extends React.Component { } return filter; }); - this.props.onSaveFilter(formatted, this.state.name); + this.props.onSaveFilter(formatted, this.state.name, this.state.relativeDates); this.toggle(); } @@ -137,6 +139,8 @@ export default class BrowserFilter extends React.Component { this.state.blacklistedFilters, this.state.filters ); + + const hasDateState = this.state.filters.some(filter => filter.get('compareTo')?.__type === 'Date'); popover = ( <Popover fixed={true} @@ -180,17 +184,32 @@ export default class BrowserFilter extends React.Component { )} /> {this.state.confirmName && ( - <Field - label={<Label text="Filter view name" />} - input={ - <TextInput - placeholder="Give it a good name..." - value={this.state.name} - onChange={name => this.setState({ name })} - /> + <> + <Field + label={<Label text="Filter view name" />} + input={ + <TextInput + placeholder="Give it a good name..." + value={this.state.name} + onChange={name => this.setState({ name })} + /> + } + /> + {hasDateState && + <Field + label={<Label text="Relative dates" />} + input={ + <Checkbox + checked={this.state.relativeDates} + onChange={checked => this.setState({ relativeDates: checked })} + className={styles.checkbox} + /> + } + /> } - /> + </> )} + {this.state.confirmName && ( <div className={styles.footer}> <Button diff --git a/src/dashboard/Data/Browser/Browser.react.js b/src/dashboard/Data/Browser/Browser.react.js index 86c90182f9..70519a31f5 100644 --- a/src/dashboard/Data/Browser/Browser.react.js +++ b/src/dashboard/Data/Browser/Browser.react.js @@ -1068,8 +1068,26 @@ class Browser extends DashboardView { }); } - saveFilters(filters, name) { - const _filters = JSON.stringify(filters.toJSON()); + saveFilters(filters, name, relativeDate) { + const jsonFilters = filters.toJSON(); + if (relativeDate && jsonFilters?.length) { + for (let i = 0; i < jsonFilters.length; i++) { + const filter = jsonFilters[i]; + const compareTo = filter.get('compareTo'); + if (compareTo?.__type === 'Date') { + compareTo.__type = 'RelativeDate'; + const now = new Date(); + const date = new Date(compareTo.iso); + const diff = date.getTime() - now.getTime(); + compareTo.value = Math.floor(diff / 1000); + delete compareTo.iso; + filter.set('compareTo', compareTo); + jsonFilters[i] = filter; + } + } + } + + const _filters = JSON.stringify(jsonFilters); const preferences = ClassPreferences.getPreferences( this.context.applicationId, this.props.params.className @@ -1085,6 +1103,7 @@ class Browser extends DashboardView { this.context.applicationId, this.props.params.className ); + super.forceUpdate(); } diff --git a/src/lib/generatePath.js b/src/lib/generatePath.js index 208245f1da..3dd6b9c5b8 100644 --- a/src/lib/generatePath.js +++ b/src/lib/generatePath.js @@ -1,6 +1,32 @@ const MOUNT_PATH = window.PARSE_DASHBOARD_PATH; export default function generatePath(currentApp, path, prependMountPath = false) { + + const urlObj = new URL(path, window.location.origin); + const params = new URLSearchParams(urlObj.search); + + const filters = JSON.parse(params.get('filters')) + + if (filters) { + for (let i = 0; i < filters.length; i++) { + const filter = filters[i]; + if (filter.compareTo?.__type === 'RelativeDate') { + const date = new Date(); + date.setTime(date.getTime() + filter.compareTo.value * 1000); + filter.compareTo = { + __type: 'Date', + iso: date.toISOString(), + } + filters[i] = filter; + } + } + + params.set('filters', JSON.stringify(filters)); + urlObj.search = params.toString(); + + path = urlObj.toString().split(window.location.origin)[1].substring(1); + } + if (prependMountPath && MOUNT_PATH) { return `${MOUNT_PATH}apps/${currentApp.slug}/${path}`; }