Skip to content
Merged
40 changes: 30 additions & 10 deletions src/components/BrowserFilter/BrowserFilter.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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();
Expand Down Expand Up @@ -63,6 +65,7 @@ export default class BrowserFilter extends React.Component {
name: '',
confirmName: false,
editMode: this.props.filters.size === 0,
relativeDates: false, // Reset relative dates state when opening/closing
}));
this.props.setCurrent(null);
}
Expand Down Expand Up @@ -114,7 +117,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();
}

Expand All @@ -137,6 +140,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}
Expand Down Expand Up @@ -180,17 +185,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
Expand Down
10 changes: 6 additions & 4 deletions src/components/CategoryList/CategoryList.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ export default class CategoryList extends React.Component {
const query = new URLSearchParams(this.props.params);
if (query.has('filters')) {
const queryFilter = query.get('filters');
const filterId = query.get('filterId');
for (let i = 0; i < c.filters?.length; i++) {
const filter = c.filters[i];
if (queryFilter === filter.filter) {
if (queryFilter === filter.filter || filterId && filterId === filter.id) {
height += (i + 1) * 20;
break;
}
Expand Down Expand Up @@ -108,9 +109,10 @@ export default class CategoryList extends React.Component {
const query = new URLSearchParams(this.props.params);
if (query.has('filters')) {
const queryFilter = query.get('filters');
const queryFilterId = query.get('filterId');
for (let i = 0; i < c.filters?.length; i++) {
const filter = c.filters[i];
if (queryFilter === filter.filter) {
if (queryFilter === filter.filter || queryFilterId && queryFilterId === filter.id) {
selectedFilter = i;
className = '';
break;
Expand Down Expand Up @@ -138,10 +140,10 @@ export default class CategoryList extends React.Component {
</div>
{this.state.openClasses.includes(id) &&
c.filters.map((filterData, index) => {
const { name, filter } = filterData;
const { name, filter, id } = filterData;
const url = `${this.props.linkPrefix}${c.name}?filters=${encodeURIComponent(
filter
)}`;
)}&filterId=${id}`;
return (
<div key={index} className={styles.childLink}>
<Link
Expand Down
24 changes: 22 additions & 2 deletions src/dashboard/Data/Browser/Browser.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -1071,15 +1071,34 @@ 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
);
if (!preferences.filters.includes(_filters)) {
preferences.filters.push({
name,
id: crypto.randomUUID(),
filter: _filters,
});
}
Expand All @@ -1088,6 +1107,7 @@ class Browser extends DashboardView {
this.context.applicationId,
this.props.params.className
);

super.forceUpdate();
}

Expand Down
26 changes: 26 additions & 0 deletions src/lib/generatePath.js
Original file line number Diff line number Diff line change
@@ -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}`;
}
Expand Down
Loading